Mercurial > hg > dhcpcd
changeset 2458:4050e5af02d9 draft
Once reachability + randomisation has passed, wait DELAY_FIRST_PROBE_TIME
seconds and then send MAX_UNICAST_SOLICIT probes at retranstimer intervals.
If no confirmation and another retranstimer interval has passed, expire the
address.
More RFC4861 conformant.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Fri, 02 May 2014 12:31:21 +0000 |
| parents | 7cf4ee9e75b5 |
| children | 4d3db760a69a |
| files | ipv6nd.c ipv6nd.h |
| diffstat | 2 files changed, 35 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/ipv6nd.c Fri May 02 11:03:46 2014 +0000 +++ b/ipv6nd.c Fri May 02 12:31:21 2014 +0000 @@ -121,7 +121,7 @@ // static void ipv6nd_handledata(void *); -static void ipv6nd_proberouter(struct ra *); +static void ipv6nd_startproberouter(struct ra *); /* * Android ships buggy ICMP6 filter headers. @@ -933,7 +933,7 @@ { rap->nsprobes = 0; if (rap->lifetime) - ipv6nd_proberouter(rap); + ipv6nd_startproberouter(rap); } handle_flag: @@ -1107,7 +1107,7 @@ } static void -ipv6nd_proberouter1(void *arg) +ipv6nd_proberouter(void *arg) { struct ra *rap = arg; struct nd_neighbor_solicit *ns; @@ -1116,6 +1116,7 @@ struct cmsghdr *cm; struct in6_pktinfo pi; struct ipv6_ctx *ctx; + struct timeval tv; if (ipv6nd_open(rap->iface->ctx) == -1) { syslog(LOG_ERR, "%s: ipv6nd_open: %m", __func__); @@ -1175,41 +1176,48 @@ return; } - if (rap->nsprobes++ == 0) - eloop_timeout_add_sec(rap->iface->ctx->eloop, - DELAY_FIRST_PROBE_TIME, ipv6nd_unreachable, rap); + ms_to_tv(&tv, rap->retrans ? rap->retrans : RETRANS_TIMER); + eloop_timeout_add_tv(rap->iface->ctx->eloop, &tv, + ++rap->nsprobes < MAX_UNICAST_SOLICIT ? + ipv6nd_proberouter : ipv6nd_unreachable, + rap); +} - if (rap->nsprobes < MAX_UNICAST_SOLICIT) - ipv6nd_proberouter(rap); +static void +ipv6nd_stalerouter(void *arg) +{ + struct ra *rap = arg; + + rap->nsprobes = 0; + eloop_timeout_add_sec(rap->iface->ctx->eloop, DELAY_FIRST_PROBE_TIME, + ipv6nd_proberouter, rap); } static void -ipv6nd_proberouter(struct ra *rap) +ipv6nd_cancelproberouter(struct ra *rap) +{ + + eloop_timeout_delete(rap->iface->ctx->eloop, ipv6nd_proberouter, rap); + eloop_timeout_delete(rap->iface->ctx->eloop, ipv6nd_stalerouter, rap); + eloop_timeout_delete(rap->iface->ctx->eloop, ipv6nd_unreachable, rap); +} + + +static void +ipv6nd_startproberouter(struct ra *rap) { struct timeval tv, rtv; - if (rap->nsprobes == 0) { - ms_to_tv(&tv, rap->reachable ? rap->reachable : REACHABLE_TIME); - } else { - ms_to_tv(&tv, rap->retrans ? rap->retrans : RETRANS_TIMER); - } + ipv6nd_cancelproberouter(rap); + + ms_to_tv(&tv, rap->reachable ? rap->reachable : REACHABLE_TIME); ms_to_tv(&rtv, MIN_RANDOM_FACTOR); timeradd(&tv, &rtv, &tv); rtv.tv_sec = 0; rtv.tv_usec = arc4random() % (MAX_RANDOM_FACTOR_U -MIN_RANDOM_FACTOR_U); timeradd(&tv, &rtv, &tv); eloop_timeout_add_tv(rap->iface->ctx->eloop, - &tv, ipv6nd_proberouter1, rap); - - /* The unreachable timer starts AFTER first probe is actually send */ -} - -static void -ipv6nd_cancelproberouter(struct ra *rap) -{ - - eloop_timeout_delete(rap->iface->ctx->eloop, ipv6nd_proberouter1, rap); - eloop_timeout_delete(rap->iface->ctx->eloop, ipv6nd_unreachable, rap); + &tv, ipv6nd_stalerouter, rap); } void @@ -1405,10 +1413,7 @@ ipv6_buildroutes(ifp->ctx); script_runreason(rap->iface, "ROUTERADVERT"); /* XXX */ } - eloop_timeout_delete(rap->iface->ctx->eloop, - ipv6nd_unreachable, rap); - rap->nsprobes = 0; - ipv6nd_proberouter(rap); + ipv6nd_startproberouter(rap); } }
--- a/ipv6nd.h Fri May 02 11:03:46 2014 +0000 +++ b/ipv6nd.h Fri May 02 12:31:21 2014 +0000 @@ -77,7 +77,7 @@ #define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */ -#define MAX_REACHABLE_TIME 3600 /* seconds */ +#define MAX_REACHABLE_TIME 3600000 /* milliseconds */ #define REACHABLE_TIME 30000 /* milliseconds */ #define RETRANS_TIMER 1000 /* milliseconds */ #define DELAY_FIRST_PROBE_TIME 5 /* seconds */
