diff options
| author | Michael Biebl <biebl@debian.org> | 2018-06-04 00:08:31 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2018-06-04 00:08:31 +0200 |
| commit | 0dd9df69fdbd475c48a0c8d5b0a1882550fe7321 (patch) | |
| tree | 249cf25643b1fe408e10679bb61613bc6540e894 /shared/n-acd | |
| parent | 2e94a3b93171ab3fb95bf689aab1664d23988809 (diff) | |
| parent | 04bc9e1cd3544445d883ad29ea108c1645c8e7b7 (diff) | |
Update upstream source from tag 'upstream/1.11.4'
Update to upstream version '1.11.4' with Debian dir d0638aa2e32d5bae4e8daa021b9a66b7c4d6647e
Diffstat (limited to 'shared/n-acd')
| -rw-r--r-- | shared/n-acd/src/n-acd.c | 41 | ||||
| -rw-r--r-- | shared/n-acd/src/n-acd.h | 2 |
2 files changed, 31 insertions, 12 deletions
diff --git a/shared/n-acd/src/n-acd.c b/shared/n-acd/src/n-acd.c index ae149abb..9164f958 100644 --- a/shared/n-acd/src/n-acd.c +++ b/shared/n-acd/src/n-acd.c @@ -534,7 +534,11 @@ static int n_acd_handle_timeout(NAcd *acd) { */ r = n_acd_send(acd, NULL); - if (r < 0) + /* + * During probe we must respect the total timeout and so + * we ignore errors caused by a down interface. + */ + if (r < 0 && r != -N_ACD_E_DOWN) return r; if (++acd->n_iteration >= N_ACD_RFC_PROBE_NUM) @@ -559,11 +563,26 @@ static int n_acd_handle_timeout(NAcd *acd) { */ r = n_acd_send(acd, &acd->config.ip); - if (r < 0) - return r; + if (r < 0) { + if (r != -N_ACD_E_DOWN) + return r; + /* + * We want to send all the 3 announcements even if the + * interface goes temporarily down. Therefore, if send() + * fails, don't increment the iteration and try again. + */ + } else + acd->n_iteration++; - if (++acd->n_iteration < N_ACD_RFC_ANNOUNCE_NUM) { - r = n_acd_schedule(acd, acd->timeout_multiplier * N_ACD_RFC_ANNOUNCE_INTERVAL_USEC, 0); + if (acd->n_iteration < N_ACD_RFC_ANNOUNCE_NUM) { + /* + * Announcements are always scheduled according to the + * time-intervals specified in the spec. We always use + * the RFC5227-mandated multiplier. + * If you reconsider this, note that timeout_multiplier + * might be 0 here. + */ + r = n_acd_schedule(acd, N_ACD_TIMEOUT_RFC5227 * N_ACD_RFC_ANNOUNCE_INTERVAL_USEC, 0); if (r < 0) return r; } @@ -803,14 +822,12 @@ static int n_acd_dispatch_socket(NAcd *acd, struct epoll_event *event) { return -EIO; } else if (errno == ENETDOWN || errno == ENXIO) { /* - * We get ENETDOWN if the network-device goes down or is - * removed. ENXIO might happen on async send-operations if the - * network-device was unplugged and thus the kernel is no - * longer aware of it. - * In any case, we do not allow proceeding with this socket. We - * stop the engine and notify the user gracefully. + * The network device went down or was removed. Ignore + * such errors and let the pending probe time out. + * Subsequent reads will simply return EAGAIN until the + * device is up again and has data queued. */ - return -N_ACD_E_DOWN; + return 0; } else if (errno == EAGAIN) { /* * We cannot read data from the socket (we got EAGAIN). As a safety net diff --git a/shared/n-acd/src/n-acd.h b/shared/n-acd/src/n-acd.h index 46394dca..75646243 100644 --- a/shared/n-acd/src/n-acd.h +++ b/shared/n-acd/src/n-acd.h @@ -15,6 +15,8 @@ extern "C" { #include <netinet/in.h> #include <stdbool.h> +#define N_ACD_TIMEOUT_RFC5227 (UINT64_C(9000)) + enum { _N_ACD_E_SUCCESS, |