summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2018-04-23 11:56:27 +0200
committerHans Dedecker <dedeckeh@gmail.com>2018-04-23 12:14:31 +0200
commit200cc8f556c1cdb8daa3b591116755e4a80ac655 (patch)
tree47536edd61a61929397396f4b8ce2b288b485c60
parentdcfc06a7cf32e21ae575ea491ba0206844596516 (diff)
dhcpv6-ia: make assignment lookup more strict
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>
-rw-r--r--src/dhcpv6-ia.c5
-rw-r--r--src/odhcpd.h5
2 files changed, 7 insertions, 3 deletions
diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index 9afde3f..737b328 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -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)))) &&
- (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;
@@ -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;
+ a->flags |= OAF_TENTATIVE;
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->flags &= ~OAF_TENTATIVE;
a->flags |= OAF_BOUND;
apply_lease(iface, a, true);
} else if (!assigned && a && a->managed_size == 0) {
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 48ee51e..9a27708 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -133,8 +133,9 @@ enum odhcpd_mode {
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 {