dhcpv6-ia: make assignment lookup more strict
authorHans Dedecker <dedeckeh@gmail.com>
Mon, 23 Apr 2018 09:56:27 +0000 (11:56 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Mon, 23 Apr 2018 10:14:31 +0000 (12:14 +0200)
Whe doing an assignment lookup do a strict match between the assignment
IAID and the IAID received form the client in case the BOUND or TENTATIVE
assignment flags are set.
This fixes a wrong assignment being returned for a client which uses a
different IAID than the IAID used in a previous DHCPv6 exchange.

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

index 9afde3f..737b328 100644 (file)
@@ -1161,7 +1161,8 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                        if (((c->clid_len == clid_len && !memcmp(c->clid_data, clid_data, clid_len)) ||
                                        (c->clid_len >= clid_len && !c->clid_data[0] && !c->clid_data[1]
                                                && !memcmp(c->mac, mac, sizeof(mac)))) &&
                        if (((c->clid_len == clid_len && !memcmp(c->clid_data, clid_data, clid_len)) ||
                                        (c->clid_len >= clid_len && !c->clid_data[0] && !c->clid_data[1]
                                                && !memcmp(c->mac, mac, sizeof(mac)))) &&
-                                       (c->iaid == ia->iaid || INFINITE_VALID(c->valid_until) || now < c->valid_until) &&
+                                       (!(c->flags & (OAF_BOUND|OAF_TENTATIVE)) || c->iaid == ia->iaid) &&
+                                       (INFINITE_VALID(c->valid_until) || now < c->valid_until) &&
                                        ((is_pd && c->length <= 64) || (is_na && c->length == 128))) {
                                a = c;
 
                                        ((is_pd && c->length <= 64) || (is_na && c->length == 128))) {
                                a = c;
 
@@ -1257,6 +1258,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                        /* Was only a solicitation: mark binding for removal */
                        if (assigned && hdr->msg_type == DHCPV6_MSG_SOLICIT) {
                                a->flags &= ~OAF_BOUND;
                        /* Was only a solicitation: mark binding for removal */
                        if (assigned && hdr->msg_type == DHCPV6_MSG_SOLICIT) {
                                a->flags &= ~OAF_BOUND;
+                               a->flags |= OAF_TENTATIVE;
 
                                if (!(a->flags & OAF_STATIC))
                                        a->valid_until = now;
 
                                if (!(a->flags & OAF_STATIC))
                                        a->valid_until = now;
@@ -1271,6 +1273,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                                        }
                                }
                                a->accept_reconf = accept_reconf;
                                        }
                                }
                                a->accept_reconf = accept_reconf;
+                               a->flags &= ~OAF_TENTATIVE;
                                a->flags |= OAF_BOUND;
                                apply_lease(iface, a, true);
                        } else if (!assigned && a && a->managed_size == 0) {
                                a->flags |= OAF_BOUND;
                                apply_lease(iface, a, true);
                        } else if (!assigned && a && a->managed_size == 0) {
index 48ee51e..9a27708 100644 (file)
@@ -133,8 +133,9 @@ enum odhcpd_mode {
 
 
 enum odhcpd_assignment_flags {
 
 
 enum odhcpd_assignment_flags {
-       OAF_BOUND       = (1 << 0),
-       OAF_STATIC      = (1 << 1),
+       OAF_TENTATIVE   = (1 << 0),
+       OAF_BOUND       = (1 << 1),
+       OAF_STATIC      = (1 << 2),
 };
 
 struct config {
 };
 
 struct config {