RFC3315 Section 18.2.2 states no reply must returned by the server in case no address(es) are present :
If the server is unable to perform this test (for example, the server does not have information about prefixes on the link to which the client is connected),
or there were no addresses in any of the IAs sent by the client, the server MUST NOT send a reply to the client.
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);
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;
if (!is_pd && !is_na)
continue;
if (stype != DHCPV6_OPT_IA_ADDR || slen < sizeof(struct dhcpv6_ia_addr) - 4)
continue;
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;
#ifdef DHCPV6_OPT_PREFIX_CLASS
uint8_t *xdata;
uint16_t xtype, xlen;
a->valid_until = now + 3600; // Block address for 1h
update_state = true;
}
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);
}
status = DHCPV6_STATUS_NOTONLINK;
ia_response_len = append_reply(buf, buflen, status, ia, a, iface, true);
}
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 (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)))