From: Ted Lemon Date: Thu, 17 May 2001 19:04:09 +0000 (+0000) Subject: Sync with 3.0rc7 X-Git-Tag: HEAD-MERGE-V3-0-3B1~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=31bbee784cecf4cd3f985cb6fd880148fcac3733;p=thirdparty%2Fdhcp.git Sync with 3.0rc7 --- diff --git a/common/conflex.c b/common/conflex.c index 495088ea9..5f2d895c6 100644 --- a/common/conflex.c +++ b/common/conflex.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: conflex.c,v 1.92 2001/05/02 06:32:54 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; +"$Id: conflex.c,v 1.93 2001/05/17 19:03:43 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -926,6 +926,8 @@ static enum dhcp_token intern (atom, dfv) return TOKEN_RESET; if (!strcasecmp (atom + 1, "eserved")) return TOKEN_RESERVED; + if (!strcasecmp (atom + 1, "emove")) + return REMOVE; break; case 's': if (!strcasecmp (atom + 1, "tate")) diff --git a/common/discover.c b/common/discover.c index 6619fb273..4dc8b25f1 100644 --- a/common/discover.c +++ b/common/discover.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: discover.c,v 1.42 2001/05/02 06:36:54 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; +"$Id: discover.c,v 1.43 2001/05/17 19:03:44 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -184,6 +184,15 @@ void discover_interfaces (state) if (i < 0) log_fatal ("ioctl: SIOCGIFCONF: %m"); +#ifdef SIOCGIFCONF_ZERO_PROBE + /* Workaround for SIOCGIFCONF bug on some Linux versions. */ + if (ic.ifc_ifcu.ifcu_buf == 0 && ic.ifc_len == 0) { + ic.ifc_len = sizeof buf; + ic.ifc_ifcu.ifcu_buf = (caddr_t)buf; + goto gifconf_again; + } +#endif + /* If the SIOCGIFCONF resulted in more data than would fit in a buffer, allocate a bigger buffer. */ if ((ic.ifc_ifcu.ifcu_buf == buf @@ -198,7 +207,7 @@ void discover_interfaces (state) #ifdef SIOCGIFCONF_ZERO_PROBE } else if (ic.ifc_ifcu.ifcu_buf == 0) { ic.ifc_ifcu.ifcu_buf = (caddr_t)buf; - if.ifc_len = sizeof buf; + ic.ifc_len = sizeof buf; goto gifconf_again; #endif } diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c index 70e368ab8..9e3fafa3c 100644 --- a/dhcpctl/dhcpctl.c +++ b/dhcpctl/dhcpctl.c @@ -321,6 +321,43 @@ dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value, return status; } +/* dhcpctl_set_buffer_value + + Sets a NUL-terminated ASCII value on an object referred to by + a dhcpctl_handle. like dhcpctl_set_value, but saves the + trouble of creating a data_string for a NUL-terminated string. + Does not update the server - just sets the value on the handle. */ + +dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h, + const char *value, unsigned len, + const char *value_name) +{ + isc_result_t status; + omapi_typed_data_t *tv = (omapi_typed_data_t *)0; + omapi_data_string_t *name = (omapi_data_string_t *)0; + int ip; + unsigned ll; + + ll = strlen (value_name); + status = omapi_data_string_new (&name, ll, MDL); + if (status != ISC_R_SUCCESS) + return status; + memcpy (name -> value, value_name, ll); + + status = omapi_typed_data_new (MDL, &tv, + omapi_datatype_data, len, value); + if (status != ISC_R_SUCCESS) { + omapi_data_string_dereference (&name, MDL); + return status; + } + memcpy (tv -> u.buffer.value, value, len); + + status = omapi_set_value (h, (omapi_object_t *)0, name, tv); + omapi_data_string_dereference (&name, MDL); + omapi_typed_data_dereference (&tv, MDL); + return status; +} + /* dhcpctl_set_boolean_value Sets a boolean value on an object - like dhcpctl_set_value, diff --git a/dhcpctl/dhcpctl.h b/dhcpctl/dhcpctl.h index e78a64eeb..8cfe133ac 100644 --- a/dhcpctl/dhcpctl.h +++ b/dhcpctl/dhcpctl.h @@ -85,6 +85,8 @@ dhcpctl_status dhcpctl_set_value (dhcpctl_handle, dhcpctl_data_string, const char *); dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle, const char *, const char *); +dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle, + const char *, unsigned, const char *); dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle, int, const char *); dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle, int, const char *); dhcpctl_status dhcpctl_object_update (dhcpctl_handle, dhcpctl_handle); diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c index 24d2b6bfd..bbcd20733 100644 --- a/dhcpctl/omshell.c +++ b/dhcpctl/omshell.c @@ -107,6 +107,13 @@ int main (int argc, char **argv, char **envp) usage(argv[0]); } + /* Initially, log errors to stderr as well as to syslogd. */ +#ifdef SYSLOG_4_2 + openlog ("dhcpd", LOG_NDELAY); + log_priority = DHCPD_LOG_FACILITY; +#else + openlog ("dhcpd", LOG_NDELAY, DHCPD_LOG_FACILITY); +#endif status = dhcpctl_initialize (); if (status != ISC_R_SUCCESS) { fprintf (stderr, "dhcpctl_initialize: %s\n", @@ -208,7 +215,7 @@ int main (int argc, char **argv, char **envp) if (se) port = ntohs (se -> s_port); else { - printf ("unknown service name: %s", val); + printf ("unknown service name: %s\n", val); break; } } else if (token == NUMBER) { @@ -287,7 +294,7 @@ int main (int argc, char **argv, char **envp) s = dmalloc (strlen (val) + 1, MDL); if (!server) { - printf ("no memory to store server name."); + printf ("no memory to store server name.\n"); skip_to_semi (cfile); break; } @@ -305,13 +312,13 @@ int main (int argc, char **argv, char **envp) case KEY: token = next_token (&val, (unsigned *)0, cfile); if (!is_identifier (token)) { - printf ("usage: key "); + printf ("usage: key \n"); skip_to_semi (cfile); break; } s = dmalloc (strlen (val) + 1, MDL); if (!s) { - printf ("no memory for key name."); + printf ("no memory for key name.\n"); skip_to_semi (cfile); break; } @@ -379,7 +386,7 @@ int main (int argc, char **argv, char **envp) } if (!connected) { - printf ("not connected."); + printf ("not connected.\n"); skip_to_semi (cfile); break; } @@ -408,7 +415,7 @@ int main (int argc, char **argv, char **envp) } if (!connected) { - printf ("not connected."); + printf ("not connected.\n"); skip_to_semi (cfile); break; } @@ -434,7 +441,7 @@ int main (int argc, char **argv, char **envp) } if (!connected) { - printf ("not connected."); + printf ("not connected.\n"); skip_to_semi (cfile); break; } @@ -450,23 +457,77 @@ int main (int argc, char **argv, char **envp) switch (token) { case STRING: dhcpctl_set_string_value (oh, val, s1); + token = next_token (&val, (unsigned *)0, cfile); break; case NUMBER: - dhcpctl_set_int_value (oh, atoi (val), s1); + strcpy (buf, val); + token = peek_token (&val, (unsigned *)0, cfile); + /* Colon-seperated hex list? */ + if (token == COLON) + goto cshl; + else if (token == DOT) { + s = buf; + val = buf; + do { + int intval = atoi (val); + if (intval > 255) { + parse_warn (cfile, + "dotted octet > 255: %s", + val); + skip_to_semi (cfile); + goto badnum; + } + *s++ = intval; + token = next_token (&val, + (unsigned *)0, cfile); + if (token != DOT) + break; + token = next_token (&val, + (unsigned *)0, cfile); + } while (token == NUMBER); + dhcpctl_set_data_value (oh, buf, + (unsigned)(s - buf), + s1); + break; + } + dhcpctl_set_int_value (oh, atoi (buf), s1); + token = next_token (&val, (unsigned *)0, cfile); + badnum: break; + case NUMBER_OR_NAME: + strcpy (buf, val); + cshl: + s = buf; + val = buf; + do { + convert_num (cfile, s, val, 16, 8); + ++s; + token = next_token (&val, + (unsigned *)0, cfile); + if (token != COLON) + break; + token = next_token (&val, + (unsigned *)0, cfile); + } while (token == NUMBER || + token == NUMBER_OR_NAME); + dhcpctl_set_data_value (oh, buf, + (unsigned)(s - buf), s1); + break; + default: printf ("invalid value.\n"); + skip_to_semi (cfile); } - token = next_token (&val, (unsigned *)0, cfile); if (token != END_OF_FILE && token != EOL) goto set_usage; break; case TOKEN_CREATE: case TOKEN_OPEN: + i = token; token = next_token (&val, (unsigned *)0, cfile); if (token != END_OF_FILE && token != EOL) { printf ("usage: %s\n", val); @@ -475,14 +536,21 @@ int main (int argc, char **argv, char **envp) } if (!connected) { - printf ("not connected."); + printf ("not connected.\n"); skip_to_semi (cfile); break; } - i = 0; - if (token == TOKEN_CREATE) + if (!oh) { + printf ("you must make a new object first!\n"); + skip_to_semi (cfile); + break; + } + + if (i == TOKEN_CREATE) i = DHCPCTL_CREATE | DHCPCTL_EXCL; + else + i = 0; status = dhcpctl_open_object (oh, connection, i); if (status == ISC_R_SUCCESS) @@ -507,7 +575,7 @@ int main (int argc, char **argv, char **envp) } if (!connected) { - printf ("not connected."); + printf ("not connected.\n"); skip_to_semi (cfile); break; } @@ -524,9 +592,37 @@ int main (int argc, char **argv, char **envp) break; } + break; + + case REMOVE: + token = next_token (&val, (unsigned *)0, cfile); + if (token != END_OF_FILE && token != EOL) { + printf ("usage: %s\n", val); + skip_to_semi (cfile); + break; + } + + if (!connected) { + printf ("not connected.\n"); + skip_to_semi (cfile); + break; + } + + status = dhcpctl_object_remove(connection, oh); + if (status == ISC_R_SUCCESS) + status = dhcpctl_wait_for_completion + (oh, &waitstatus); + if (status == ISC_R_SUCCESS) + status = waitstatus; + if (status != ISC_R_SUCCESS) { + printf ("can't destroy object: %s\n", + isc_result_totext (status)); + break; + } + break; } - } while (token != END_OF_FILE); + } while (1); exit (0); } diff --git a/includes/cf/linux.h b/includes/cf/linux.h index 7ce3e4c7c..808fe8468 100644 --- a/includes/cf/linux.h +++ b/includes/cf/linux.h @@ -125,7 +125,7 @@ extern int h_errno; # define USE_LPF # endif # if !defined (__sparc__) /* XXX hopefully this will be fixed someday */ -# define SIOCGIFCONF_NULL_BUF_GIVES_CORRECT_LEN +# define SIOCGIFCONF_ZERO_PROBE # endif # define LINUX_SLASHPROC_DISCOVERY # define PROCDEV_DEVICE "/proc/net/dev" diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 231c3644c..2c34629e7 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -2475,11 +2475,12 @@ void update_partner PROTO ((struct lease *)); int load_balance_mine (struct packet *, dhcp_failover_state_t *); binding_state_t normal_binding_state_transition_check (struct lease *, dhcp_failover_state_t *, - binding_state_t); + binding_state_t, + u_int32_t); binding_state_t conflict_binding_state_transition_check (struct lease *, dhcp_failover_state_t *, - binding_state_t); + binding_state_t, u_int32_t); int lease_mine_to_reallocate (struct lease *); OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_state, dhcp_failover_state_t, diff --git a/includes/dhctoken.h b/includes/dhctoken.h index dd3aef465..38cb5eea8 100644 --- a/includes/dhctoken.h +++ b/includes/dhctoken.h @@ -312,7 +312,8 @@ enum dhcp_token { END_OF_FILE = 607, RECOVER_WAIT = 608, SERVER = 609, - CONNECT = 610 + CONNECT = 610, + REMOVE = 611 }; #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/includes/version.h b/includes/version.h index b9b804b95..ec4e75ed4 100644 --- a/includes/version.h +++ b/includes/version.h @@ -1,3 +1,3 @@ /* Current version of ISC DHCP Distribution. */ -#define DHCP_VERSION "V3.0rc4" +#define DHCP_VERSION "V3.1-unreleased" diff --git a/omapip/alloc.c b/omapip/alloc.c index 873ec7dc7..c7f075975 100644 --- a/omapip/alloc.c +++ b/omapip/alloc.c @@ -293,35 +293,34 @@ void dmalloc_dump_outstanding () somewhere. */ if (dp -> file) { #if defined (DEBUG_RC_HISTORY) + int i, count, inhistory = 0, noted = 0; + /* If we have the info, see if this is actually new garbage. */ if (rc_history_count < RC_HISTORY_MAX) { - int i, printit = 0, inhistory = 0, prefcnt = 0; - i = rc_history_index - rc_history_count; - if (i < 0) - i += RC_HISTORY_MAX; - do { - if (rc_history [i].addr == dp + 1) { - if (rc_history [i].refcnt == 1 && - prefcnt == 0 && !printit) { - printit = 1; - inhistory = 1; - log_info (" %s(%d): %d", - dp -> file, - dp -> line, - dp -> size); - } - prefcnt = rc_history [i].refcnt; - if (printit) - print_rc_hist_entry (i); - } - if (++i == RC_HISTORY_MAX) - i = 0; - } while (i != rc_history_index); - if (!inhistory) - log_info (" %s(%d): %d", dp -> file, - dp -> line, dp -> size); + count = rc_history_count; } else + count = RC_HISTORY_MAX; + i = rc_history_index - 1; + if (i < 0) + i += RC_HISTORY_MAX; + + do { + if (rc_history [i].addr == dp + 1) { + inhistory = 1; + if (!noted) { + log_info (" %s(%d): %d", dp -> file, + dp -> line, dp -> size); + noted = 1; + } + print_rc_hist_entry (i); + if (!rc_history [i].refcnt) + break; + } + if (--i < 0) + i = RC_HISTORY_MAX - 1; + } while (count--); + if (!inhistory) #endif log_info (" %s(%d): %d", dp -> file, dp -> line, dp -> size); @@ -516,16 +515,20 @@ isc_result_t omapi_object_dereference (omapi_object_t **h, extra_references = 0; for (p = (*h) -> inner; p && !extra_references; p = p -> inner) { - extra_references += p -> refcnt - 1; - if (p -> inner) + extra_references += p -> refcnt; + if (p -> inner && p -> inner -> outer == p) + --extra_references; + if (p -> outer) --extra_references; if (p -> handle) --extra_references; } for (p = (*h) -> outer; p && !extra_references; p = p -> outer) { - extra_references += p -> refcnt - 1; - if (p -> outer) + extra_references += p -> refcnt; + if (p -> outer && p -> outer -> inner == p) + --extra_references; + if (p -> inner) --extra_references; if (p -> handle) --extra_references; @@ -549,6 +552,11 @@ isc_result_t omapi_object_dereference (omapi_object_t **h, ((*h) -> type -> freer (*h, file, line)); else dfree (*h, file, line); + } else { + (*h) -> refcnt--; + if (!(*h) -> type -> freer) + rc_register (file, line, + h, *h, (*h) -> refcnt); } } else { (*h) -> refcnt--; diff --git a/omapip/connection.c b/omapip/connection.c index df811b391..43ad0a96b 100644 --- a/omapip/connection.c +++ b/omapip/connection.c @@ -273,6 +273,7 @@ void omapi_connection_register (omapi_connection_object_t *obj, return; } +#if defined (TRACING) if (trace_record ()) { /* Connection registration packet: @@ -305,6 +306,7 @@ void omapi_connection_register (omapi_connection_object_t *obj, status = trace_write_packet_iov (trace_connect, iov_count, iov, file, line); } +#endif } static void trace_connect_input (trace_type_t *ttype, diff --git a/omapip/hash.c b/omapip/hash.c index 3cd85f7fc..77fa36e91 100644 --- a/omapip/hash.c +++ b/omapip/hash.c @@ -3,7 +3,7 @@ Routines for manipulating hash tables... */ /* - * Copyright (c) 1995-2000 Internet Software Consortium. + * Copyright (c) 1995-2001 Internet Software Consortium. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: hash.c,v 1.1 2000/08/01 22:55:07 neild Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: hash.c,v 1.2 2001/05/17 19:03:57 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include diff --git a/omapip/message.c b/omapip/message.c index 8c0d7f4e4..41c1f21f0 100644 --- a/omapip/message.c +++ b/omapip/message.c @@ -54,13 +54,10 @@ isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line) omapi_object_t *g; isc_result_t status; - m = dmalloc (sizeof *m, file, line); - if (!m) - return ISC_R_NOMEMORY; - memset (m, 0, sizeof *m); - m -> type = omapi_type_message; - rc_register (file, line, &m, m, m -> refcnt); - m -> refcnt = 1; + m = (omapi_message_object_t *)0; + status = omapi_message_allocate (&m, file, line); + if (status != ISC_R_SUCCESS) + return status; g = (omapi_object_t *)0; status = omapi_generic_new (&g, file, line); @@ -84,7 +81,7 @@ isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line) } status = omapi_object_reference (o, (omapi_object_t *)m, file, line); - omapi_object_dereference ((omapi_object_t **)&m, file, line); + omapi_message_dereference (&m, file, line); omapi_object_dereference (&g, file, line); if (status != ISC_R_SUCCESS) return status; @@ -369,7 +366,36 @@ static const char *omapi_message_op_name(int op) { } #endif +static isc_result_t +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 status; +#if defined (DEBUG_MEMORY_LEAKAGE) + unsigned long previous_outstanding = dmalloc_outstanding; +#endif + + status = omapi_message_process_internal (mo, po); + +#if defined (DEBUG_MEMORY_LEAKAGE) && 0 + log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term", + dmalloc_generation, + dmalloc_outstanding - previous_outstanding, + dmalloc_outstanding, dmalloc_longterm); +#endif +#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) && 0 + dmalloc_dump_outstanding (); +#endif +#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0 + dump_rc_history (); +#endif + + return status; +} + +static isc_result_t +omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) { omapi_message_object_t *message, *m; omapi_object_t *object = (omapi_object_t *)0; diff --git a/omapip/protocol.c b/omapip/protocol.c index 17b37cf0e..c8ae79fb3 100644 --- a/omapip/protocol.c +++ b/omapip/protocol.c @@ -357,6 +357,10 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, u_int16_t nlen; u_int32_t vlen; u_int32_t th; +#if defined (DEBUG_MEMORY_LEAKAGE) + unsigned long previous_outstanding = 0xBEADCAFE; + unsigned long connect_outstanding = 0xBEADCAFE; +#endif if (h -> type != omapi_type_protocol) { /* XXX shouldn't happen. Put an assert here? */ @@ -365,6 +369,9 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, p = (omapi_protocol_object_t *)h; if (!strcmp (name, "connect")) { +#if defined (DEBUG_MEMORY_LEAKAGE) + connect_outstanding = dmalloc_outstanding; +#endif /* Send the introductory message. */ status = omapi_protocol_send_intro (h, OMAPI_PROTOCOL_VERSION, @@ -389,6 +396,26 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, } } + /* If we get a disconnect, dump memory usage. */ + if (!strcmp (name, "disconnect") +#if defined (DEBUG_MEMORY_LEAKAGE) + && connect_outstanding != 0xBEADCAFE +#endif + ) { +#if defined (DEBUG_MEMORY_LEAKAGE) + log_info ("generation %ld: %ld new, %ld outstanding, %ld%s", + dmalloc_generation, + dmalloc_outstanding - previous_outstanding, + dmalloc_outstanding, dmalloc_longterm, " long-term"); +#endif +#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) + dmalloc_dump_outstanding (); +#endif +#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) + dump_rc_history (); +#endif + } + /* Not a signal we recognize? */ if (strcmp (name, "ready")) { if (p -> inner && p -> inner -> type -> signal_handler) @@ -449,6 +476,24 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, /* If we already have the data, fall through. */ case omapi_protocol_header_wait: +#if defined (DEBUG_MEMORY_LEAKAGE) + if (previous_outstanding != 0xBEADCAFE) { + log_info ("%s %ld: %ld new, %ld outstanding, %ld%s", + "generation", dmalloc_generation, + dmalloc_outstanding - previous_outstanding, + dmalloc_outstanding, dmalloc_longterm, + " long-term"); +#endif +#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) + dmalloc_dump_outstanding (); +#endif +#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) + dump_rc_history (); +#endif +#if defined (DEBUG_MEMORY_LEAKAGE) + } + previous_outstanding = dmalloc_outstanding; +#endif status = omapi_message_new ((omapi_object_t **)&p -> message, MDL); if (status != ISC_R_SUCCESS) { @@ -690,7 +735,21 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, } omapi_message_dereference (&p -> message, MDL); - +#if defined (DEBUG_MEMORY_LEAKAGE) + log_info ("generation %ld: %ld new, %ld outstanding, %ld%s", + dmalloc_generation, + dmalloc_outstanding - previous_outstanding, + dmalloc_outstanding, dmalloc_longterm, " long-term"); +#endif +#if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) + dmalloc_dump_outstanding (); +#endif +#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) + dump_rc_history (); +#endif +#if defined (DEBUG_MEMORY_LEAKAGE) + previous_outstanding = 0xBEADCAFE; +#endif /* Now wait for the next message. */ goto to_header_wait; diff --git a/omapip/support.c b/omapip/support.c index 40a4fb99e..6d2e8cc35 100644 --- a/omapip/support.c +++ b/omapip/support.c @@ -364,7 +364,9 @@ isc_result_t omapi_set_value_str (omapi_object_t *h, return status; memcpy (nds -> value, name, strlen (name)); - return omapi_set_value (h, id, nds, value); + status = omapi_set_value (h, id, nds, value); + omapi_data_string_dereference (&nds, MDL); + return status; } isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id, @@ -504,9 +506,12 @@ isc_result_t omapi_get_value_str (omapi_object_t *h, for (outer = h; outer -> outer; outer = outer -> outer) ; if (outer -> type -> get_value) - return (*(outer -> type -> get_value)) (outer, - id, nds, value); - return ISC_R_NOTFOUND; + status = (*(outer -> type -> get_value)) (outer, + id, nds, value); + else + status = ISC_R_NOTFOUND; + omapi_data_string_dereference (&nds, MDL); + return status; } isc_result_t omapi_stuff_values (omapi_object_t *c, diff --git a/server/bootp.c b/server/bootp.c index 42972373a..019876f38 100644 --- a/server/bootp.c +++ b/server/bootp.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: bootp.c,v 1.69 2001/02/12 20:51:26 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: bootp.c,v 1.70 2001/05/17 19:04:03 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -341,7 +341,6 @@ void bootp (packet) /* We're done with the option state. */ option_state_dereference (&options, MDL); - static_lease_dereference (lease, MDL); /* Set up the hardware destination address... */ hto.hbuf [0] = packet -> raw -> htype; @@ -403,10 +402,8 @@ void bootp (packet) out: if (options) option_state_dereference (&options, MDL); - if (lease) { - static_lease_dereference (lease, MDL); + if (lease) lease_dereference (&lease, MDL); - } if (hp) host_dereference (&hp, MDL); if (host) diff --git a/server/db.c b/server/db.c index 863b93996..725034282 100644 --- a/server/db.c +++ b/server/db.c @@ -43,11 +43,12 @@ #ifndef lint static char copyright[] = -"$Id: db.c,v 1.63 2001/03/15 23:21:25 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: db.c,v 1.64 2001/05/17 19:04:04 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" #include +#include "version.h" FILE *db_file; @@ -741,7 +742,9 @@ void new_lease_file () "confusing to you, we sincerely\n"); fprintf (db_file, "# apologize. Seriously, though - don't ask.\n"); fprintf (db_file, "# The format of this file is documented in the %s", - "dhcpd.leases(5) manual page.\n\n"); + "dhcpd.leases(5) manual page.\n"); + fprintf (db_file, "# This lease file was written by isc-dhcp-%s\n\n", + DHCP_VERSION); /* Write out all the leases that we know of... */ counting = 0; diff --git a/server/dhcp.c b/server/dhcp.c index a7308ac97..1b4f73176 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: dhcp.c,v 1.192 2001/05/03 18:22:58 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dhcp.c,v 1.193 2001/05/17 19:04:05 mellon Exp $ Copyright (c) 1995-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -476,6 +476,16 @@ void dhcprequest (packet, ms_nulltp, ip_lease) goto out; } } + + /* Don't let a client allocate a lease using DHCPREQUEST + if the lease isn't ours to allocate. */ + if ((lease -> binding_state == FTS_FREE && + peer -> i_am == secondary) || + (lease -> binding_state == FTS_BACKUP && + peer -> i_am == primary)) { + log_debug ("%s: expired", msgbuf); + goto out; + } } else peer = (dhcp_failover_state_t *)0; #endif @@ -1579,7 +1589,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) d1.data [0]); data_string_forget (&d1, MDL); free_lease_state (state, MDL); - static_lease_dereference (lease, MDL); return; } data_string_forget (&d1, MDL); @@ -1639,7 +1648,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) if (!ignorep) log_info ("%s: unknown client", msg); free_lease_state (state, MDL); - static_lease_dereference (lease, MDL); return; } @@ -1656,7 +1664,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) if (!ignorep) log_info ("%s: bootp disallowed", msg); free_lease_state (state, MDL); - static_lease_dereference (lease, MDL); return; } @@ -1673,7 +1680,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) if (!ignorep) log_info ("%s: booting disallowed", msg); free_lease_state (state, MDL); - static_lease_dereference (lease, MDL); return; } @@ -1710,7 +1716,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) msg); free_lease_state (state, MDL); /* XXX probably not necessary: */ - static_lease_dereference (lease, MDL); return; } } @@ -1743,7 +1748,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) log_info ("%s: can't allocate temporary lease structure: %s", msg, isc_result_totext (result)); free_lease_state (state, MDL); - static_lease_dereference (lease, MDL); return; } @@ -2096,7 +2100,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) offer == DHCPACK, offer == DHCPACK)) { log_info ("%s: database update failed", msg); free_lease_state (state, MDL); - static_lease_dereference (lease, MDL); lease_dereference (<, MDL); return; } @@ -2475,7 +2478,6 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) ++outstanding_pings; } else { lease -> timestamp = cur_time; - static_lease_dereference (lease, MDL); dhcp_reply (lease); } } @@ -3366,38 +3368,6 @@ int mockup_lease (struct lease **lp, struct packet *packet, return 1; } -/* Dereference all dynamically-allocated information that may be dangling - off of a static lease. Otherwise, once ack_lease returns, the information - dangling from the lease will be lost, so reference counts will be screwed - up and memory leaks will occur. */ - -void static_lease_dereference (lease, file, line) - struct lease *lease; - const char *file; - int line; -{ - if (!(lease -> flags & STATIC_LEASE)) - return; - if (lease -> on_release) - executable_statement_dereference (&lease -> on_release, - file, line); - if (lease -> on_expiry) - executable_statement_dereference (&lease -> on_expiry, - file, line); - if (lease -> on_commit) - executable_statement_dereference (&lease -> on_commit, - file, line); - if (lease -> scope) - binding_scope_dereference (&lease -> scope, file, line); - if (lease -> agent_options) - option_chain_head_dereference (&lease -> agent_options, - file, line); - if (lease -> uid != lease -> uid_buf) { - dfree (lease -> uid, file, line); - lease -> uid = (unsigned char *)0; - } -} - /* Look through all the pools in a list starting with the specified pool for a free lease. We try to find a virgin lease if we can. If we don't find a virgin lease, we try to find a non-virgin lease that's diff --git a/server/failover.c b/server/failover.c index ec6f99e7c..52683af5b 100644 --- a/server/failover.c +++ b/server/failover.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: failover.c,v 1.53 2001/05/03 18:31:28 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n"; +"$Id: failover.c,v 1.54 2001/05/17 19:04:07 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -1363,6 +1363,7 @@ isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *state, case resolution_interrupted: case partner_down: case communications_interrupted: + case recover: /* Already in the right state? */ if (state -> me.state == startup) return (dhcp_failover_set_state @@ -1373,14 +1374,6 @@ isc_result_t dhcp_failover_state_transition (dhcp_failover_state_t *state, return dhcp_failover_set_state (state, resolution_interrupted); - case recover: - /* XXX I don't think it makes sense to make a - XXX transition from recover to communications- - XXX interrupted, because then when the connect - XXX occurred, we'd make a transition into - XXX normal, not recover. */ - break; /* Kim says stay in recover. */ - case normal: return dhcp_failover_set_state (state, communications_interrupted); @@ -1533,6 +1526,9 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state, { enum failover_state saved_state; TIME saved_stos; + struct pool *p; + struct shared_network *s; + struct lease *l; /* First make the transition out of the current state. */ switch (state -> me.state) { @@ -1658,6 +1654,27 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state, dhcp_failover_send_update_request_all (state); break; + case partner_down: + /* For every expired lease, set a timeout for it to become free. */ + for (s = shared_networks; s; s = s -> next) { + for (p = s -> pools; p; p = p -> next) { + if (p -> failover_peer == state) { + for (l = p -> expired; l; l = l -> next) + l -> tsfp = state -> me.stos + state -> mclt; + if (p -> next_event_time > + state -> me.stos + state -> mclt) { + p -> next_event_time = + state -> me.stos + state -> mclt; + add_timeout (p -> next_event_time, pool_timer, p, + (tvref_t)pool_reference, + (tvunref_t)pool_dereference); + } + } + } + } + break; + + default: break; } @@ -2307,7 +2324,6 @@ int dhcp_failover_queue_ack (dhcp_failover_state_t *state, (tvunref_t)dhcp_failover_state_dereference); } - return 1; } @@ -4234,13 +4250,13 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, if (state -> me.state == normal) { new_binding_state = (normal_binding_state_transition_check - (lease, state, - msg -> binding_status)); + (lease, state, msg -> binding_status, + msg -> potential_expiry)); } else { new_binding_state = (conflict_binding_state_transition_check - (lease, state, - msg -> binding_status)); + (lease, state, msg -> binding_status, + msg -> potential_expiry)); } if (new_binding_state != msg -> binding_status) { char outbuf [100]; @@ -4318,8 +4334,20 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state, if (msg -> options_present & FTB_POTENTIAL_EXPIRY) { /* XXX it could be a problem to do this directly if the XXX lease is sorted by tsfp. */ - lease -> tsfp = msg -> potential_expiry; - write_lease (lease); + if (lease -> binding_state == FTS_EXPIRED) { + lease -> next_binding_state = FTS_FREE; + supersede_lease (lease, (struct lease *)0, 0, 1, 0); + write_lease (lease); + if (state -> me.state == normal) + commit_leases (); + } else { + lease -> tsfp = msg -> potential_expiry; + write_lease (lease); +#if 0 /* XXX This might be needed. */ + if (state -> me.state == normal) + commit_leases (); +#endif + } } unqueue: @@ -4639,7 +4667,8 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state) binding_state_t normal_binding_state_transition_check (struct lease *lease, dhcp_failover_state_t *state, - binding_state_t binding_state) + binding_state_t binding_state, + u_int32_t tsfp) { binding_state_t new_state; @@ -4688,8 +4717,7 @@ normal_binding_state_transition_check (struct lease *lease, case FTS_BACKUP: /* Can't set a lease to free or backup until the peer agrees that it's expired. */ - /* XXX but have we updated tsfp yet? */ - if (lease -> tsfp > cur_time) { + if (tsfp > cur_time) { new_state = lease -> binding_state; goto out; } @@ -4716,8 +4744,7 @@ normal_binding_state_transition_check (struct lease *lease, case FTS_BACKUP: /* Can't set a lease to free or backup until the peer agrees that it's expired. */ - /* XXX but have we updated tsfp yet? */ - if (lease -> tsfp > cur_time) { + if (tsfp > cur_time) { new_state = lease -> binding_state; goto out; } @@ -4738,8 +4765,7 @@ normal_binding_state_transition_check (struct lease *lease, case FTS_BACKUP: /* Can't set a lease to free or backup until the peer agrees that it's expired. */ - /* XXX but have we updated tsfp yet? */ - if (lease -> tsfp > cur_time) { + if (tsfp > cur_time) { new_state = lease -> binding_state; goto out; } @@ -4758,10 +4784,9 @@ normal_binding_state_transition_check (struct lease *lease, switch (binding_state) { case FTS_FREE: case FTS_BACKUP: - /* XXX but have we updated tsfp yet? */ /* Can't set a lease to free or backup until the peer agrees that it's expired. */ - if (lease -> tsfp > cur_time) { + if (tsfp > cur_time) { new_state = lease -> binding_state; goto out; } @@ -4811,7 +4836,8 @@ normal_binding_state_transition_check (struct lease *lease, binding_state_t conflict_binding_state_transition_check (struct lease *lease, dhcp_failover_state_t *state, - binding_state_t binding_state) + binding_state_t binding_state, + u_int32_t tsfp) { binding_state_t new_state; diff --git a/server/mdb.c b/server/mdb.c index 7c3c1db04..0e704814c 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: mdb.c,v 1.67 2001/05/02 07:09:36 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: mdb.c,v 1.68 2001/05/17 19:04:08 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -821,6 +821,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) requested *after* a DHCP lease has been assigned. */ if (lease -> binding_state != FTS_ABANDONED && + lease -> next_binding_state != FTS_ABANDONED && (comp -> binding_state == FTS_ACTIVE || comp -> binding_state == FTS_RESERVED || comp -> binding_state == FTS_BOOTP) && @@ -1066,7 +1067,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) and the expiry code sets the timer if there's anything left to expire after it's run any outstanding expiry events on the pool. */ - if (commit && + if ((commit || !pimmediate) && comp -> sort_time != MIN_TIME && comp -> sort_time > cur_time && (comp -> sort_time < comp -> pool -> next_event_time || @@ -1215,6 +1216,15 @@ void make_binding_state_transition (struct lease *lease) case FTS_ABANDONED: case FTS_RESET: lease -> next_binding_state = FTS_FREE; + /* If we are not in partner_down, leases don't go from + EXPIRED to FREE on a timeout - only on an update. + If we're in partner_down, they expire at mclt past + the time we entered partner_down. */ + if (lease -> pool -> failover_peer && + lease -> pool -> failover_peer -> me.state == partner_down) + lease -> tsfp = + (lease -> pool -> failover_peer -> me.stos + + lease -> pool -> failover_peer -> mclt); break; case FTS_FREE: @@ -1445,7 +1455,22 @@ void pool_timer (vpool) /* If there's nothing on the queue, skip it. */ if (!*(lptr [i])) continue; - + +#if defined (FAILOVER_PROTOCOL) + if (pool -> failover_peer && + pool -> failover_peer -> me.state != partner_down) { + /* The secondary can't remove a lease from the + active state except in partner_down. */ + if (i == ACTIVE_LEASES && + pool -> failover_peer -> i_am == secondary) + continue; + /* Leases in an expired state don't move to + free because of a timeout unless we're in + partner_down. */ + if (i == EXPIRED_LEASES) + continue; + } +#endif lease_reference (&lease, *(lptr [i]), MDL); while (lease) { diff --git a/server/omapi.c b/server/omapi.c index 23b2840b4..991377c1c 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -3,7 +3,7 @@ OMAPI object interfaces for the DHCP server. */ /* - * Copyright (c) 1999-2000 Internet Software Consortium. + * Copyright (c) 1999-2001 Internet Software Consortium. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,7 +50,7 @@ #ifndef lint static char copyright[] = -"$Id: omapi.c,v 1.46 2001/05/02 07:11:38 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: omapi.c,v 1.47 2001/05/17 19:04:09 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -354,35 +354,43 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) return ISC_R_INVALIDARG; lease = (struct lease *)h; - uid_hash_delete (lease); + if (lease -> uid) + uid_hash_delete (lease); hw_hash_delete (lease); - if (lease -> billing_class) - class_dereference - (&lease -> billing_class, file, line); - if (lease -> uid && lease -> uid != &lease -> uid_buf [0]) { + + if (lease -> on_release) + executable_statement_dereference (&lease -> on_release, + file, line); + if (lease -> on_expiry) + executable_statement_dereference (&lease -> on_expiry, + file, line); + if (lease -> on_commit) + executable_statement_dereference (&lease -> on_commit, + file, line); + if (lease -> scope) + binding_scope_dereference (&lease -> scope, file, line); + + if (lease -> agent_options) + option_chain_head_dereference (&lease -> agent_options, + file, line); + if (lease -> uid && lease -> uid != lease -> uid_buf) { dfree (lease -> uid, MDL); lease -> uid = &lease -> uid_buf [0]; lease -> uid_len = 0; } + if (lease -> client_hostname) { dfree (lease -> client_hostname, MDL); lease -> client_hostname = (char *)0; } + if (lease -> host) host_dereference (&lease -> host, file, line); if (lease -> subnet) subnet_dereference (&lease -> subnet, file, line); if (lease -> pool) pool_dereference (&lease -> pool, file, line); - if (lease -> on_expiry) - executable_statement_dereference (&lease -> on_expiry, - file, line); - if (lease -> on_commit) - executable_statement_dereference (&lease -> on_commit, - file, line); - if (lease -> on_release) - executable_statement_dereference (&lease -> on_release, - file, line); + if (lease -> state) { free_lease_state (lease -> state, file, line); lease -> state = (struct lease_state *)0; @@ -390,6 +398,11 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) cancel_timeout (lease_ping_timeout, lease); --outstanding_pings; /* XXX */ } + + if (lease -> billing_class) + class_dereference + (&lease -> billing_class, file, line); + return ISC_R_SUCCESS; }