diff options
author | Ted Lemon <source@isc.org> | 1999-07-31 17:53:05 +0000 |
---|---|---|
committer | Ted Lemon <source@isc.org> | 1999-07-31 17:53:05 +0000 |
commit | 7109aa95218693fd402c39312c0d51029d6412a7 (patch) | |
tree | eb6e2938da2493b8c172a01b2c20b6fc64894807 /common/alloc.c | |
parent | 0852a27f3267743cf5b957983c36d8f16d710674 (diff) | |
download | isc-dhcp-7109aa95218693fd402c39312c0d51029d6412a7.tar.gz |
- Fix several cases where a refcounted memory allocator would set the pointer
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.
Diffstat (limited to 'common/alloc.c')
-rw-r--r-- | common/alloc.c | 123 |
1 files changed, 106 insertions, 17 deletions
diff --git a/common/alloc.c b/common/alloc.c index 458053ae..2f2626aa 100644 --- a/common/alloc.c +++ b/common/alloc.c @@ -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; +} |