]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- Fix several cases where a refcounted memory allocator would set the pointer
authorTed Lemon <source@isc.org>
Sat, 31 Jul 1999 17:53:05 +0000 (17:53 +0000)
committerTed Lemon <source@isc.org>
Sat, 31 Jul 1999 17:53:05 +0000 (17:53 +0000)
  to null and then fail to return immediately, possibly causing a core dump.
  Now, the pointer will be set to null and it will return a failure status
  immediately.
- Make packet allocator reference counted, and keep a cache of packet
  structures so that allocating and freeing them will be cheap.

common/alloc.c

index 458053aed205362bc645b5d36748feee622cfa8e..2f2626aac30694265ec04c6e53de94248806d039 100644 (file)
@@ -22,7 +22,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: alloc.c,v 1.32 1999/07/17 17:59:24 mellon Exp $ Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: alloc.c,v 1.33 1999/07/31 17:53:05 mellon Exp $ Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -53,14 +53,6 @@ void dfree (ptr, name)
        free (ptr);
 }
 
-struct packet *new_packet (name)
-       char *name;
-{
-       struct packet *rval;
-       rval = (struct packet *)dmalloc (sizeof (struct packet), name);
-       return rval;
-}
-
 struct dhcp_packet *new_dhcp_packet (name)
        char *name;
 {
@@ -240,7 +232,10 @@ void free_lease_state (ptr, name)
        struct lease_state *ptr;
        char *name;
 {
-       option_state_dereference (&ptr -> options, name);
+       if (ptr -> options)
+               option_state_dereference (&ptr -> options, name);
+       if (ptr -> packet)
+               packet_dereference (&ptr -> packet, name);
        ptr -> next = free_lease_states;
        free_lease_states = ptr;
 }
@@ -301,13 +296,6 @@ void free_hash_table (ptr, name)
        dfree ((VOIDPTR)ptr, name);
 }
 
-void free_packet (ptr, name)
-       struct packet *ptr;
-       char *name;
-{
-       dfree ((VOIDPTR)ptr, name);
-}
-
 void free_dhcp_packet (ptr, name)
        struct dhcp_packet *ptr;
        char *name;
@@ -484,6 +472,7 @@ int expression_reference (ptr, src, name)
                abort ();
 #else
                *ptr = (struct expression *)0;
+               return 0;
 #endif
        }
        *ptr = src;
@@ -532,6 +521,7 @@ int option_cache_reference (ptr, src, name)
                abort ();
 #else
                *ptr = (struct option_cache *)0;
+               return 0;
 #endif
        }
        *ptr = src;
@@ -574,6 +564,7 @@ int buffer_reference (ptr, bp, name)
                abort ();
 #else
                *ptr = (struct buffer *)0;
+               return 0;
 #endif
        }
        *ptr = bp;
@@ -650,6 +641,7 @@ int dns_host_entry_reference (ptr, bp, name)
                abort ();
 #else
                *ptr = (struct dns_host_entry *)0;
+               return 0;
 #endif
        }
        *ptr = bp;
@@ -702,6 +694,7 @@ int option_state_allocate (ptr, name)
                abort ();
 #else
                *ptr = (struct option_state *)0;
+               return 0;
 #endif
        }
 
@@ -737,6 +730,7 @@ int option_state_reference (ptr, bp, name)
                abort ();
 #else
                *ptr = (struct option_state *)0;
+               return 0;
 #endif
        }
        *ptr = bp;
@@ -819,3 +813,98 @@ int executable_statement_reference (ptr, bp, name)
        bp -> refcnt++;
        return 1;
 }
+
+static struct packet *free_packets;
+
+int packet_allocate (ptr, name)
+       struct packet **ptr;
+       char *name;
+{
+       int size;
+
+       if (!ptr) {
+               log_error ("Null pointer passed to packet_allocate: %s",
+                          name);
+#if defined (POINTER_DEBUG)
+               abort ();
+#else
+               return 0;
+#endif
+       }
+       if (*ptr) {
+               log_error ("Non-null pointer in packet_allocate (%s)",
+                          name);
+#if defined (POINTER_DEBUG)
+               abort ();
+#else
+               *ptr = (struct packet *)0;
+               return 0;
+#endif
+       }
+
+       *ptr = dmalloc (sizeof **ptr, name);
+       if (*ptr) {
+               memset (*ptr, 0, sizeof **ptr);
+               (*ptr) -> refcnt = 1;
+               return 1;
+       }
+       return 0;
+}
+
+int packet_reference (ptr, bp, name)
+       struct packet **ptr;
+       struct packet *bp;
+       char *name;
+{
+       if (!ptr) {
+               log_error ("Null pointer in packet_reference: %s",
+                          name);
+#if defined (POINTER_DEBUG)
+               abort ();
+#else
+               return 0;
+#endif
+       }
+       if (*ptr) {
+               log_error ("Non-null pointer in packet_reference (%s)",
+                          name);
+#if defined (POINTER_DEBUG)
+               abort ();
+#else
+               *ptr = (struct packet *)0;
+#endif
+       }
+       *ptr = bp;
+       bp -> refcnt++;
+       return 1;
+}
+
+int packet_dereference (ptr, name)
+       struct packet **ptr;
+       char *name;
+{
+       int i;
+       struct packet *packet;
+
+       if (!ptr || !*ptr) {
+               log_error ("Null pointer in packet_dereference: %s",
+                          name);
+#if defined (POINTER_DEBUG)
+               abort ();
+#else
+               return 0;
+#endif
+       }
+
+       packet = *ptr;
+       *ptr = (struct packet *)0;
+       --packet -> refcnt;
+       if (packet -> refcnt)
+               return 1;
+
+       if (packet -> options)
+               option_state_dereference (&packet -> options, name);
+       packet -> raw = (struct dhcp_packet *)free_packets;
+       free_packets = packet;
+       return 1;
+}