Commit 95fd7038 authored by David Hankins's avatar David Hankins

- Memory leak in the load_balance_mine() function is fixed. This would

  leak ~20-30 octets per DHCPDISCOVER packet while failover was in use
  and in normal state. [ISC-Bugs #19548]

- Various compilation fixes have been included for the memory related
  DEBUG #defines in includes/site.h.  [ISC-Bugs #19548]
parent e6b3a140
...@@ -99,6 +99,13 @@ work on other platforms. Please report any problems and suggested fixes to ...@@ -99,6 +99,13 @@ work on other platforms. Please report any problems and suggested fixes to
be removed at expiration or release time. Thanks to a patch submitted by be removed at expiration or release time. Thanks to a patch submitted by
Christof Chen. Christof Chen.
- Memory leak in the load_balance_mine() function is fixed. This would
leak ~20-30 octets per DHCPDISCOVER packet while failover was in use
and in normal state.
- Various compilation fixes have been included for the memory related
DEBUG #defines in includes/site.h.
Changes since 4.1.0b1 Changes since 4.1.0b1
- A missing "else" in dhcrelay.c could have caused an interface not to - A missing "else" in dhcrelay.c could have caused an interface not to
......
...@@ -1673,6 +1673,9 @@ extern enum dhcp_shutdown_state shutdown_state; ...@@ -1673,6 +1673,9 @@ extern enum dhcp_shutdown_state shutdown_state;
isc_result_t dhcp_io_shutdown (omapi_object_t *, void *); isc_result_t dhcp_io_shutdown (omapi_object_t *, void *);
isc_result_t dhcp_set_control_state (control_object_state_t oldstate, isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
control_object_state_t newstate); control_object_state_t newstate);
#if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
void relinquish_ackqueue(void);
#endif
/* conflex.c */ /* conflex.c */
isc_result_t new_parse PROTO ((struct parse **, int, isc_result_t new_parse PROTO ((struct parse **, int,
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
noticing memory leaks quickly. */ noticing memory leaks quickly. */
/* #define DEBUG_MEMORY_LEAKAGE */ /* #define DEBUG_MEMORY_LEAKAGE */
/* #define DEBUG_MEMORY_LEAKAGE_ON_EXIT */
/* Define this if you want exhaustive (and very slow) checking of the /* Define this if you want exhaustive (and very slow) checking of the
malloc pool for corruption. */ malloc pool for corruption. */
......
...@@ -255,8 +255,9 @@ void dmalloc_dump_outstanding () ...@@ -255,8 +255,9 @@ void dmalloc_dump_outstanding ()
{ {
static unsigned long dmalloc_cutoff_point; static unsigned long dmalloc_cutoff_point;
struct dmalloc_preamble *dp; struct dmalloc_preamble *dp;
#if defined(DEBUG_MALLOC_POOL)
unsigned char *foo; unsigned char *foo;
int i; #endif
if (!dmalloc_cutoff_point) if (!dmalloc_cutoff_point)
dmalloc_cutoff_point = dmalloc_cutoff_generation; dmalloc_cutoff_point = dmalloc_cutoff_generation;
...@@ -307,7 +308,7 @@ void dmalloc_dump_outstanding () ...@@ -307,7 +308,7 @@ void dmalloc_dump_outstanding ()
if (rc_history [i].addr == dp + 1) { if (rc_history [i].addr == dp + 1) {
inhistory = 1; inhistory = 1;
if (!noted) { if (!noted) {
log_info (" %s(%d): %d", dp -> file, log_info (" %s(%d): %ld", dp -> file,
dp -> line, dp -> size); dp -> line, dp -> size);
noted = 1; noted = 1;
} }
...@@ -320,7 +321,7 @@ void dmalloc_dump_outstanding () ...@@ -320,7 +321,7 @@ void dmalloc_dump_outstanding ()
} while (count--); } while (count--);
if (!inhistory) if (!inhistory)
#endif #endif
log_info (" %s(%d): %d", log_info (" %s(%d): %ld",
dp -> file, dp -> line, dp -> size); dp -> file, dp -> line, dp -> size);
} }
#endif #endif
...@@ -353,7 +354,7 @@ void dump_rc_history (void *addr) ...@@ -353,7 +354,7 @@ void dump_rc_history (void *addr)
i += RC_HISTORY_MAX; i += RC_HISTORY_MAX;
} }
rc_history_count = 0; rc_history_count = 0;
while (rc_history [i].file) { while (rc_history [i].file) {
if (!addr || addr == rc_history [i].addr) if (!addr || addr == rc_history [i].addr)
print_rc_hist_entry (i); print_rc_hist_entry (i);
...@@ -427,7 +428,6 @@ static int dmalloc_find_entry (struct dmalloc_preamble *dp, ...@@ -427,7 +428,6 @@ static int dmalloc_find_entry (struct dmalloc_preamble *dp,
int min, int max) int min, int max)
{ {
int middle; int middle;
int cmp;
middle = (min + max) / 2; middle = (min + max) / 2;
if (middle == min) if (middle == min)
...@@ -448,8 +448,7 @@ static int dmalloc_find_entry (struct dmalloc_preamble *dp, ...@@ -448,8 +448,7 @@ static int dmalloc_find_entry (struct dmalloc_preamble *dp,
void omapi_print_dmalloc_usage_by_caller () void omapi_print_dmalloc_usage_by_caller ()
{ {
struct dmalloc_preamble *dp; struct dmalloc_preamble *dp;
unsigned char *foo; int ccur, cmax, i;
int ccur, cmax, i, j;
struct caller cp [1024]; struct caller cp [1024];
cmax = 1024; cmax = 1024;
...@@ -494,7 +493,9 @@ void omapi_print_dmalloc_usage_by_caller () ...@@ -494,7 +493,9 @@ void omapi_print_dmalloc_usage_by_caller ()
for (i = 0; i < ccur; i++) { for (i = 0; i < ccur; i++) {
printf ("%d\t%s:%d\t%d\n", i, printf ("%d\t%s:%d\t%d\n", i,
cp [i].dp -> file, cp [i].dp -> line, cp [i].count); cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
#if defined(DUMP_RC_HISTORY)
dump_rc_history (cp [i].dp + 1); dump_rc_history (cp [i].dp + 1);
#endif
} }
} }
#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */ #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
......
...@@ -364,7 +364,7 @@ omapi_message_process_internal (omapi_object_t *, omapi_object_t *); ...@@ -364,7 +364,7 @@ omapi_message_process_internal (omapi_object_t *, omapi_object_t *);
isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po) isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
{ {
isc_result_t status; isc_result_t status;
#if defined (DEBUG_MEMORY_LEAKAGE) #if defined (DEBUG_MEMORY_LEAKAGE) && 0
unsigned long previous_outstanding = dmalloc_outstanding; unsigned long previous_outstanding = dmalloc_outstanding;
#endif #endif
......
...@@ -2955,7 +2955,7 @@ relinquish_ackqueue(void) ...@@ -2955,7 +2955,7 @@ relinquish_ackqueue(void)
{ {
struct leasequeue *q, *n; struct leasequeue *q, *n;
for (q = ackqueue ; q ; q = n) { for (q = ackqueue_head ; q ; q = n) {
n = q->next; n = q->next;
dfree(q, MDL); dfree(q, MDL);
} }
......
...@@ -5729,6 +5729,8 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state) ...@@ -5729,6 +5729,8 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state)
packet -> options, (struct option_state *)0, packet -> options, (struct option_state *)0,
&global_scope, oc, MDL)) { &global_scope, oc, MDL)) {
hbaix = loadb_p_hash (ds.data, ds.len); hbaix = loadb_p_hash (ds.data, ds.len);
data_string_forget(&ds, MDL);
} else { } else {
hbaix = loadb_p_hash (packet -> raw -> chaddr, hbaix = loadb_p_hash (packet -> raw -> chaddr,
packet -> raw -> hlen); packet -> raw -> hlen);
......
...@@ -714,7 +714,9 @@ void new_address_range (cfile, low, high, subnet, pool, lpchain) ...@@ -714,7 +714,9 @@ void new_address_range (cfile, low, high, subnet, pool, lpchain)
struct pool *pool; struct pool *pool;
struct lease **lpchain; struct lease **lpchain;
{ {
#if defined(COMPACT_LEASES)
struct lease *address_range; struct lease *address_range;
#endif
unsigned min, max, i; unsigned min, max, i;
char lowbuf [16], highbuf [16], netbuf [16]; char lowbuf [16], highbuf [16], netbuf [16];
struct shared_network *share = subnet -> shared_network; struct shared_network *share = subnet -> shared_network;
...@@ -2614,7 +2616,7 @@ extern int end; ...@@ -2614,7 +2616,7 @@ extern int end;
extern struct lease *lease_hunks; extern struct lease *lease_hunks;
#endif #endif
void free_everything () void free_everything(void)
{ {
struct subnet *sc = (struct subnet *)0, *sn = (struct subnet *)0; struct subnet *sc = (struct subnet *)0, *sn = (struct subnet *)0;
struct shared_network *nc = (struct shared_network *)0, struct shared_network *nc = (struct shared_network *)0,
...@@ -2625,12 +2627,8 @@ void free_everything () ...@@ -2625,12 +2627,8 @@ void free_everything ()
*in = (struct interface_info *)0; *in = (struct interface_info *)0;
struct class *cc = (struct class *)0, *cn = (struct class *)0; struct class *cc = (struct class *)0, *cn = (struct class *)0;
struct collection *lp; struct collection *lp;
void *st = (shared_networks
? (shared_networks -> next
? shared_networks -> next -> next : 0) : 0);
int i; int i;
/* Get rid of all the hash tables. */ /* Get rid of all the hash tables. */
if (host_hw_addr_hash) if (host_hw_addr_hash)
host_free_hash_table (&host_hw_addr_hash, MDL); host_free_hash_table (&host_hw_addr_hash, MDL);
...@@ -2639,13 +2637,13 @@ void free_everything () ...@@ -2639,13 +2637,13 @@ void free_everything ()
host_free_hash_table (&host_uid_hash, MDL); host_free_hash_table (&host_uid_hash, MDL);
host_uid_hash = 0; host_uid_hash = 0;
if (lease_uid_hash) if (lease_uid_hash)
lease_free_hash_table (&lease_uid_hash, MDL); lease_id_free_hash_table (&lease_uid_hash, MDL);
lease_uid_hash = 0; lease_uid_hash = 0;
if (lease_ip_addr_hash) if (lease_ip_addr_hash)
lease_free_hash_table (&lease_ip_addr_hash, MDL); lease_ip_free_hash_table (&lease_ip_addr_hash, MDL);
lease_ip_addr_hash = 0; lease_ip_addr_hash = 0;
if (lease_hw_addr_hash) if (lease_hw_addr_hash)
lease_free_hash_table (&lease_hw_addr_hash, MDL); lease_id_free_hash_table (&lease_hw_addr_hash, MDL);
lease_hw_addr_hash = 0; lease_hw_addr_hash = 0;
if (host_name_hash) if (host_name_hash)
host_free_hash_table (&host_name_hash, MDL); host_free_hash_table (&host_name_hash, MDL);
...@@ -2751,7 +2749,15 @@ void free_everything () ...@@ -2751,7 +2749,15 @@ void free_everything ()
} }
/* So are shared networks. */ /* So are shared networks. */
/* XXX: this doesn't work presently, but i'm ok just filtering
* it out of the noise (you get a bigger spike on the real leaks).
* It would be good to fix this, but it is not a "real bug," so not
* today. This hack is incomplete, it doesn't trim out sub-values.
*/
if (shared_networks) { if (shared_networks) {
shared_network_dereference (&shared_networks, MDL);
/* This is the old method (tries to free memory twice, broken) */
} else if (0) {
shared_network_reference (&nn, shared_networks, MDL); shared_network_reference (&nn, shared_networks, MDL);
do { do {
if (nn) { if (nn) {
...@@ -2848,14 +2854,21 @@ void free_everything () ...@@ -2848,14 +2854,21 @@ void free_everything ()
universe_free_hash_table (&universe_hash, MDL); universe_free_hash_table (&universe_hash, MDL);
for (i = 0; i < universe_count; i++) { for (i = 0; i < universe_count; i++) {
#if 0
union { union {
const char *c; const char *c;
char *s; char *s;
} foo; } foo;
#endif
if (universes [i]) { if (universes [i]) {
if (universes [i] -> hash) if (universes[i]->name_hash)
option_free_hash_table (&universes [i] -> hash, option_name_free_hash_table(
MDL); &universes[i]->name_hash,
MDL);
if (universes[i]->code_hash)
option_code_free_hash_table(
&universes[i]->code_hash,
MDL);
#if 0 #if 0
if (universes [i] -> name > (char *)&end) { if (universes [i] -> name > (char *)&end) {
foo.c = universes [i] -> name; foo.c = universes [i] -> name;
...@@ -2874,7 +2887,9 @@ void free_everything () ...@@ -2874,7 +2887,9 @@ void free_everything ()
relinquish_free_binding_values (); relinquish_free_binding_values ();
relinquish_free_option_caches (); relinquish_free_option_caches ();
relinquish_free_packets (); relinquish_free_packets ();
#if defined(COMPACT_LEASES)
relinquish_lease_hunks (); relinquish_lease_hunks ();
#endif
relinquish_hash_bucket_hunks (); relinquish_hash_bucket_hunks ();
omapi_type_relinquish (); omapi_type_relinquish ();
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment