From: Shane Kerr Date: Tue, 9 Oct 2007 08:16:09 +0000 (+0000) Subject: Fix a number of bugs with the internal lease state handling. X-Git-Tag: v4_0_0b2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4f8a4a8894d4745a4ad9bee9cd8fddbfe03ca3bf;p=thirdparty%2Fdhcp.git Fix a number of bugs with the internal lease state handling. See RT ticket #17196 for more information. --- diff --git a/server/confpars.c b/server/confpars.c index 800919c3c..9aef2b801 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -4041,7 +4041,6 @@ parse_ia_na_declaration(struct parse *cfile) { ia_na_hash_delete(ia_active, (unsigned char *)ia_na->iaid_duid.data, ia_na->iaid_duid.len, MDL); - ia_na_remove_all_iaaddr(old_ia_na, MDL); ia_na_dereference(&old_ia_na, MDL); } diff --git a/server/mdb6.c b/server/mdb6.c index 87269ee70..14aad83c6 100644 --- a/server/mdb6.c +++ b/server/mdb6.c @@ -338,6 +338,7 @@ ia_na_remove_all_iaaddr(struct ia_na *ia_na, const char *file, int line) { int i; for (i=0; inum_iaaddr; i++) { + ia_na_dereference(&(ia_na->iaaddr[i]->ia_na), file, line); iaaddr_dereference(&(ia_na->iaaddr[i]), file, line); } ia_na->num_iaaddr = 0; @@ -834,7 +835,9 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iaaddr *addr, /* Binding scopes are no longer valid after expiry or * release. */ - binding_scope_dereference(&addr->scope, MDL); + if (addr->scope != NULL) { + binding_scope_dereference(&addr->scope, MDL); + } iaaddr_hash_delete(pool->addrs, &addr->addr, sizeof(addr->addr), MDL); @@ -967,7 +970,8 @@ static void cleanup_old_expired(struct ipv6_pool *pool) { struct iaaddr *tmp; struct ia_na *ia_na; - char addr_buf[INET6_ADDRSTRLEN]; + struct ia_na *ia_na_active; + unsigned char *tmpd; while (pool->num_inactive > 0) { tmp = (struct iaaddr *)isc_heap_element(pool->inactive_timeouts, @@ -980,18 +984,22 @@ cleanup_old_expired(struct ipv6_pool *pool) { isc_heap_delete(pool->inactive_timeouts, tmp->heap_index); pool->num_inactive--; - ia_na = NULL; - if (tmp->ia_na == NULL) { - inet_ntop(AF_INET6, &tmp->addr, addr_buf, - sizeof(addr_buf)); - log_error("%s(%d): no IA_NA cleaning up address %s", - MDL, addr_buf); - } else { + if (tmp->ia_na != NULL) { + /* + * Check to see if this IA_NA is in the active list, + * but has no remaining addresses. If so, remove it + * from the active list. + */ + ia_na = NULL; ia_na_reference(&ia_na, tmp->ia_na, MDL); ia_na_remove_iaaddr(ia_na, tmp, MDL); - if (ia_na->num_iaaddr <= 0) { - unsigned char *tmpd = - (unsigned char *)ia_na->iaid_duid.data; + ia_na_active = NULL; + tmpd = (unsigned char *)ia_na->iaid_duid.data; + if ((ia_na->num_iaaddr <= 0) && + (ia_na_hash_lookup(&ia_na_active, ia_active, tmpd, + ia_na->iaid_duid.len, + MDL) == 0) && + (ia_na_active == ia_na)) { ia_na_hash_delete(ia_active, tmpd, ia_na->iaid_duid.len, MDL); }