dhcpv6-ia: create assignment for unknown IA in rebind messages
authorHans Dedecker <dedeckeh@gmail.com>
Wed, 12 Apr 2017 14:35:21 +0000 (16:35 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Thu, 13 Apr 2017 08:30:57 +0000 (10:30 +0200)
Create assignment for unknown identity association in rebind messages which is
equivalent to the handling of identity association for solicit/request messages.
However don't consider identity associations in rebind messages as a request so
that addresses/prefixes which are not apropriate for the link are returned with
lifetimes of 0.
This aligns with the behavior of the ISC DHCPv6 server.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/dhcpv6-ia.c

index 09022a4..0eaa886 100644 (file)
@@ -1094,7 +1094,9 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                if (a && a->managed_size < 0)
                        return -1;
 
-               if (hdr->msg_type == DHCPV6_MSG_SOLICIT || hdr->msg_type == DHCPV6_MSG_REQUEST) {
+               if (hdr->msg_type == DHCPV6_MSG_SOLICIT ||
+                               hdr->msg_type == DHCPV6_MSG_REQUEST ||
+                               (hdr->msg_type == DHCPV6_MSG_REBIND && !a)) {
                        bool assigned = !!a;
 
                        if (!a && !iface->no_dynamic_dhcp) {
@@ -1130,7 +1132,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                        if (!assigned || iface->ia_addr_len == 0)
                                /* Set error status */
                                status = (is_pd) ? DHCPV6_STATUS_NOPREFIXAVAIL : DHCPV6_STATUS_NOADDRSAVAIL;
-                       else if (assigned && !first) {
+                       else if (assigned && !first && hdr->msg_type != DHCPV6_MSG_REBIND) {
                                size_t handshake_len = 4;
                                buf[0] = 0;
                                buf[1] = DHCPV6_OPT_RECONF_ACCEPT;
@@ -1158,7 +1160,8 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                                first = a;
                        }
 
-                       ia_response_len = append_reply(buf, buflen, status, ia, a, iface, true);
+                       ia_response_len = append_reply(buf, buflen, status, ia, a, iface,
+                                                       hdr->msg_type == DHCPV6_MSG_REBIND ? false : true);
 
                        /* Was only a solicitation: mark binding for removal */
                        if (assigned && hdr->msg_type == DHCPV6_MSG_SOLICIT) {
@@ -1166,7 +1169,9 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
 
                                if (!(a->flags & OAF_STATIC))
                                        a->valid_until = now;
-                       } else if (assigned && hdr->msg_type == DHCPV6_MSG_REQUEST) {
+                       } else if (assigned &&
+                                       (hdr->msg_type == DHCPV6_MSG_REQUEST ||
+                                        hdr->msg_type == DHCPV6_MSG_REBIND)) {
                                if (hostname_len > 0) {
                                        a->hostname = realloc(a->hostname, hostname_len + 1);
                                        if (a->hostname) {