From: Roy Marples Date: Fri, 17 May 2024 22:12:26 +0000 (+0000) Subject: DHCP6: Wait for IRT to elapse before requesting advertisments X-Git-Tag: v10.0.7~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8dc7f72c63f1a4ba50e5b3c42c85f42f34f41fbf;p=thirdparty%2Fdhcpcd.git DHCP6: Wait for IRT to elapse before requesting advertisments RFC 8415 15 and 18.2.1 list this as a MUST. Fixes #317. --- diff --git a/src/dhcp6.c b/src/dhcp6.c index e187a376..7cc51f99 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -181,6 +181,7 @@ static void dhcp6_bind(struct interface *, const char *, const char *); static void dhcp6_failinform(void *); static void dhcp6_recvaddr(void *, unsigned short); static void dhcp6_startdecline(struct interface *); +static void dhcp6_startrequest(struct interface *); #ifdef SMALL #define dhcp6_hasprefixdelegation(a) (0) @@ -1427,11 +1428,38 @@ dhcp6_sendinform(void *arg) dhcp6_sendmessage(arg, dhcp6_sendinform); } +static void +dhcp6_senddiscover2(void *arg) +{ + + dhcp6_sendmessage(arg, dhcp6_senddiscover2); +} + +static void +dhcp6_senddiscover1(void *arg) +{ + /* + * So the initial RT has elapsed. + * If we have any ADVERTs we can now REQUEST them. + * RFC 8415 15 and 18.2.1 + */ + struct interface *ifp = arg; + struct dhcp6_state *state = D6_STATE(ifp); + + if (state->recv == NULL || state->recv->type != DHCP6_ADVERTISE) + dhcp6_sendmessage(arg, dhcp6_senddiscover2); + else + dhcp6_startrequest(ifp); +} + static void dhcp6_senddiscover(void *arg) { + struct interface *ifp = arg; + struct dhcp6_state *state = D6_STATE(ifp); - dhcp6_sendmessage(arg, dhcp6_senddiscover); + dhcp6_sendmessage(arg, + state->IMD != 0 ? dhcp6_senddiscover : dhcp6_senddiscover1); } static void @@ -1890,7 +1918,6 @@ dhcp6_startrebind(void *arg) #endif } - static void dhcp6_startrequest(struct interface *ifp) { @@ -3461,6 +3488,16 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom, valid_op = false; break; } + if (state->recv_len && state->recv->type == DHCP6_ADVERTISE) { + /* We already have an advertismemnt. + * RFC 8415 says we have to wait for the IRT to elapse. + * To keep the same behaviour we won't do anything with + * this. In the future we should make a lists of + * ADVERTS and pick the "best" one. */ + logdebugx("%s: discarding ADVERTISMENT from %s", + ifp->name, sfrom); + return; + } /* RFC7083 */ o = dhcp6_findmoption(r, len, D6_OPTION_SOL_MAX_RT, &ol); if (o && ol == sizeof(uint32_t)) { @@ -3586,7 +3623,7 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom, else loginfox("%s: ADV %s from %s", ifp->name, ia->saddr, sfrom); - dhcp6_startrequest(ifp); + // We will request when the IRT elapses return; }