From e1ce5235976d52f7a83012f122fc5b85dbbbcf2e Mon Sep 17 00:00:00 2001 From: Colin McInnes Date: Wed, 5 Feb 2025 13:38:55 -0600 Subject: [PATCH] Always send req for InfoRefreshTime option on Inform-Req (#446) RFC8415 says client must always request Information Request refresh time option 32. Client has other logic for handling if server does not include this in the reply. Resolves #445. --- src/dhcp6.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/dhcp6.c b/src/dhcp6.c index ea0bff53..0eeebdec 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -1742,16 +1742,22 @@ static void dhcp6_startdiscover(void *arg) { struct interface *ifp; + struct if_options *ifo; struct dhcp6_state *state; int llevel; struct ipv6_addr *ia; ifp = arg; state = D6_STATE(ifp); + ifo = ifp->options; #ifndef SMALL if (state->reason == NULL || strcmp(state->reason, "TIMEOUT6") != 0) dhcp6_delete_delegates(ifp); #endif + /* Ensure we never request INFO_REFRESH_TIME, + * this only belongs in Information-Request messages */ + del_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); + if (state->new == NULL && !state->failed) llevel = LOG_INFO; else @@ -1784,9 +1790,11 @@ dhcp6_startinform(void *arg) struct interface *ifp; struct dhcp6_state *state; int llevel; + struct if_options *ifo; ifp = arg; state = D6_STATE(ifp); + ifo = ifp->options; llevel = state->failed ? LOG_DEBUG : LOG_INFO; logmessage(llevel, "%s: requesting DHCPv6 information", ifp->name); state->state = DH6S_INFORM; @@ -1796,6 +1804,9 @@ dhcp6_startinform(void *arg) state->MRT = state->inf_max_rt; state->MRC = 0; + /* Ensure we always request INFO_REFRESH_TIME as per rfc8415 */ + add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); + if (dhcp6_makemessage(ifp) == -1) { logerr("%s: %s", __func__, ifp->name); return; @@ -2815,19 +2826,21 @@ static void dhcp6_startinit(struct interface *ifp) { struct dhcp6_state *state; + struct if_options *ifo; ssize_t r; uint8_t has_ta, has_non_ta; size_t i; state = D6_STATE(ifp); + ifo = ifp->options; state->state = DH6S_INIT; state->expire = ND6_INFINITE_LIFETIME; state->lowpl = ND6_INFINITE_LIFETIME; dhcp6_addrequestedaddrs(ifp); has_ta = has_non_ta = 0; - for (i = 0; i < ifp->options->ia_len; i++) { - switch (ifp->options->ia[i].ia_type) { + for (i = 0; i < ifo->ia_len; i++) { + switch (ifo->ia[i].ia_type) { case D6_OPTION_IA_TA: has_ta = 1; break; @@ -2838,14 +2851,14 @@ dhcp6_startinit(struct interface *ifp) if (!(ifp->ctx->options & DHCPCD_TEST) && !(has_ta && !has_non_ta) && - ifp->options->reboot != 0) + ifo->reboot != 0) { r = dhcp6_readlease(ifp, 1); if (r == -1) { if (errno != ENOENT && errno != ESRCH) logerr("%s: %s", __func__, state->leasefile); } else if (r != 0 && - !(ifp->options->options & DHCPCD_ANONYMOUS)) + !(ifo->options & DHCPCD_ANONYMOUS)) { /* RFC 3633 section 12.1 */ #ifndef SMALL @@ -4059,13 +4072,10 @@ dhcp6_start1(void *arg) del_option_mask(ifo->requestmask6, D6_OPTION_RAPID_COMMIT); #endif - if (state->state == DH6S_INFORM) { - add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); + if (state->state == DH6S_INFORM) dhcp6_startinform(ifp); - } else { - del_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); + else dhcp6_startinit(ifp); - } #ifndef SMALL dhcp6_activateinterfaces(ifp); -- 2.47.2