]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- An internal database inconsistency bug was repaired where the server
authorDavid Hankins <dhankins@isc.org>
Wed, 22 Aug 2007 15:42:13 +0000 (15:42 +0000)
committerDavid Hankins <dhankins@isc.org>
Wed, 22 Aug 2007 15:42:13 +0000 (15:42 +0000)
  would segfault if a client attempted to renew a lease that had been
  loaded from persistent storage.  [ISC-Bugs #17068]

RELNOTES
server/confpars.c
server/mdb6.c

index a6c4e95889848a8dd00a4b4a176b17b2b8395298..c679412733668a52ac0275302e125c54247c9e5f 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -51,6 +51,7 @@ The system has only been tested on Linux, FreeBSD, and Solaris, and
 may not work on other platforms. Please report any problems and 
 suggested fixes to <dhcp-users@isc.org>.
 
+
                        Changes since 4.0.0a2
 
 - Fix for startup where there are no IPv4 addresses on an interface.
@@ -67,6 +68,10 @@ suggested fixes to <dhcp-users@isc.org>.
 - DHCPv6 is now the default. You can disable DHCPv6 support using the
   "--disable-dhcpv6" flag when you run the configure script.
 
+- An internal database inconsistency bug was repaired where the server
+  would segfault if a client attempted to renew a lease that had been
+  loaded from persistent storage.
+
                        Changes since 4.0.0a1
 
 - Bug in octal parsing fixed. Thanks to Bernd Fuhrmann for the report
index 3a66ef5ac7599395a192ef65c2dee1365553f2ee..975fe7fccc520203c5644b71e22bd15f5eca5bad 100644 (file)
@@ -3901,18 +3901,6 @@ parse_ia_na_declaration(struct parse *cfile) {
                        return;
                }
                add_lease6(pool, iaaddr, end_time);
-               switch (state) {
-                       case FTS_ABANDONED:
-                               release_lease6(pool, iaaddr);
-                               break;
-                       case FTS_EXPIRED:
-                               decline_lease6(pool, iaaddr);
-                               iaaddr->state = FTS_EXPIRED;
-                               break;
-                       case FTS_RELEASED:
-                               release_lease6(pool, iaaddr);
-                               break;
-               }
                ipv6_pool_dereference(&pool, MDL);
                iaaddr_dereference(&iaaddr, MDL);
        }
index 3bef215ad07965b3348ad43ac004314de5c93b36..6e1def3db313d94249abfaafc95a5d157deca0a7 100644 (file)
@@ -672,7 +672,10 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr,
        struct iaaddr *test_iaaddr;
        struct iaaddr *tmp_iaaddr;
 
-       iaaddr->state = FTS_ACTIVE;
+       /* If a state was not assigned by the caller, assume active. */
+       if (iaaddr->state == 0)
+               iaaddr->state = FTS_ACTIVE;
+
        iaaddr->valid_lifetime_end_time = valid_lifetime_end_time;
        ipv6_pool_reference(&iaaddr->ipv6_pool, pool, MDL);
 
@@ -683,11 +686,26 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr,
        test_iaaddr = NULL;
        if (iaaddr_hash_lookup(&test_iaaddr, pool->addrs,
                               &iaaddr->addr, sizeof(iaaddr->addr), MDL)) {
-               isc_heap_delete(pool->active_timeouts, test_iaaddr->heap_index);
+               /* XXX: we should probably ask the iaaddr what heap it is on
+                * (as a consistency check).
+                * XXX: we should probably have one function to "put this lease
+                * on its heap" rather than doing these if's everywhere.  If
+                * you add more states to this list, don't.
+                */
+               if ((test_iaaddr->state == FTS_ACTIVE) ||
+                   (test_iaaddr->state == FTS_ABANDONED)) {
+                       isc_heap_delete(pool->active_timeouts,
+                                       test_iaaddr->heap_index);
+                       pool->num_active--;
+               } else {
+                       isc_heap_delete(pool->inactive_timeouts,
+                                       test_iaaddr->heap_index);
+                       pool->num_inactive--;
+               }
+
                iaaddr_hash_delete(pool->addrs, &test_iaaddr->addr, 
                                   sizeof(test_iaaddr->addr), MDL);
-               pool->num_active--;
-               
+
                /*
                 * We're going to do a bit of evil trickery here.
                 *
@@ -706,9 +724,20 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr,
         */
        tmp_iaaddr = NULL;
        iaaddr_reference(&tmp_iaaddr, iaaddr, MDL);
-        iaaddr_hash_add(pool->addrs, &tmp_iaaddr->addr, 
+       iaaddr_hash_add(pool->addrs, &tmp_iaaddr->addr, 
                        sizeof(tmp_iaaddr->addr), iaaddr, MDL);
-       insert_result = isc_heap_insert(pool->active_timeouts, tmp_iaaddr);
+       if ((tmp_iaaddr->state == FTS_ACTIVE) ||
+           (tmp_iaaddr->state == FTS_ABANDONED)) {
+               insert_result = isc_heap_insert(pool->active_timeouts,
+                                               tmp_iaaddr);
+               if (insert_result == ISC_R_SUCCESS)
+                       pool->num_active++;
+       } else {
+               insert_result = isc_heap_insert(pool->inactive_timeouts,
+                                               tmp_iaaddr);
+               if (insert_result == ISC_R_SUCCESS)
+                       pool->num_inactive++;
+       }
        if (insert_result != ISC_R_SUCCESS) {
                iaaddr_hash_delete(pool->addrs, &iaaddr->addr, 
                                   sizeof(iaaddr->addr), MDL);
@@ -721,10 +750,6 @@ add_lease6(struct ipv6_pool *pool, struct iaaddr *iaaddr,
         * is a reference in the heap/hash, after all.
         */
 
-       /*
-        * And we're done.
-        */
-       pool->num_active++;
        return ISC_R_SUCCESS;
 }
 
@@ -898,7 +923,7 @@ mark_address_unavailable(struct ipv6_pool *pool, const struct in6_addr *addr) {
        result = iaaddr_allocate(&dummy_iaaddr, MDL);
        if (result == ISC_R_SUCCESS) {
                dummy_iaaddr->addr = *addr;
-               iaaddr_hash_add(pool->addrs, &dummy_iaaddr->addr,
+               iaaddr_hash_add(pool->addrs, &dummy_iaaddr->addr,
                                sizeof(*addr), dummy_iaaddr, MDL);
        }
        return result;