diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dhcpv6-ia.c | 6 | ||||
-rw-r--r-- | src/dhcpv6.c | 2 |
2 files changed, 5 insertions, 3 deletions
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 844dfd3..5e34b5c 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -972,6 +972,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, dhcpv6_for_each_option(start, end, otype, olen, odata) { bool is_pd = (otype == DHCPV6_OPT_IA_PD); bool is_na = (otype == DHCPV6_OPT_IA_NA); + bool ia_addr_present = false; if (!is_pd && !is_na) continue; @@ -1024,6 +1025,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, if (stype != DHCPV6_OPT_IA_ADDR || slen < sizeof(struct dhcpv6_ia_addr) - 4) continue; + ia_addr_present = true; #ifdef DHCPV6_OPT_PREFIX_CLASS uint8_t *xdata; uint16_t xtype, xlen; @@ -1178,8 +1180,8 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, a->valid_until = now + 3600; // Block address for 1h update_state = true; } - } else if (hdr->msg_type == DHCPV6_MSG_CONFIRM) { - // Always send NOTONLINK for CONFIRM so that clients restart connection + } else if (hdr->msg_type == DHCPV6_MSG_CONFIRM && ia_addr_present) { + // Send NOTONLINK for CONFIRM with addr present so that clients restart connection status = DHCPV6_STATUS_NOTONLINK; ia_response_len = append_reply(buf, buflen, status, ia, a, iface, true); } diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 62f30e2..55b9ea9 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -320,7 +320,7 @@ static void handle_client_request(void *addr, void *data, size_t len, if (opts[-4] != DHCPV6_MSG_INFORMATION_REQUEST) { ssize_t ialen = dhcpv6_handle_ia(pdbuf, sizeof(pdbuf), iface, addr, &opts[-4], opts_end); iov[6].iov_len = ialen; - if (ialen < 0 || (ialen == 0 && opts[-4] == DHCPV6_MSG_REBIND)) + if (ialen < 0 || (ialen == 0 && (opts[-4] == DHCPV6_MSG_REBIND || opts[-4] == DHCPV6_MSG_CONFIRM))) return; } |