From: Ted Lemon Date: Tue, 16 May 2000 23:03:49 +0000 (+0000) Subject: - Fix all the OMAPI objects in the DHCP server and client that weren't X-Git-Tag: V3-BETA-2-PATCH-1~184 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=20916cae759a24cc5c3af899e701102da70b0a33;p=thirdparty%2Fdhcp.git - Fix all the OMAPI objects in the DHCP server and client that weren't being correctly reference-counted. - Make and use object-specific allocators. - Add reference/dereference support to hash functions and to timeout functions. --- diff --git a/client/clparse.c b/client/clparse.c index 7ecbbb996..393df3fe2 100644 --- a/client/clparse.c +++ b/client/clparse.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: clparse.c,v 1.43 2000/04/06 22:31:16 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: clparse.c,v 1.44 2000/05/16 23:01:57 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -97,11 +97,11 @@ isc_result_t read_client_conf () top_level_config.script_name = "/etc/dhclient-script"; top_level_config.requested_options = default_requested_options; - top_level_config.on_receipt = new_group (MDL); + group_allocate (&top_level_config.on_receipt, MDL); if (!top_level_config.on_receipt) log_fatal ("no memory for top-level on_receipt group"); - top_level_config.on_transmission = new_group (MDL); + group_allocate (&top_level_config.on_transmission, MDL); if (!top_level_config.on_transmission) log_fatal ("no memory for top-level on_transmission group"); @@ -642,7 +642,7 @@ void parse_interface_declaration (cfile, outer_config, name) return; } - ip = interface_or_dummy (val); + interface_or_dummy (&ip, val); /* If we were given a name, this is a pseudo-interface. */ if (name) { @@ -687,37 +687,49 @@ void parse_interface_declaration (cfile, outer_config, name) token = next_token (&val, cfile); } -struct interface_info *interface_or_dummy (name) - const char *name; +int interface_or_dummy (struct interface_info **pi, const char *name) { - struct interface_info *ip; + struct interface_info *i; + struct interface_info *ip = (struct interface_info *)0; /* Find the interface (if any) that matches the name. */ - for (ip = interfaces; ip; ip = ip -> next) { - if (!strcmp (ip -> name, name)) + for (i = interfaces; i; i = i -> next) { + if (!strcmp (i -> name, name)) { + interface_reference (&ip, i, MDL); break; + } } /* If it's not a real interface, see if it's on the dummy list. */ if (!ip) { for (ip = dummy_interfaces; ip; ip = ip -> next) { - if (!strcmp (ip -> name, name)) + if (!strcmp (ip -> name, name)) { + interface_reference (&ip, i, MDL); break; + } } } /* If we didn't find an interface, make a dummy interface as a placeholder. */ if (!ip) { - ip = (struct interface_info *)dmalloc (sizeof *ip, MDL); - if (!ip) - log_fatal ("No memory to record interface %s", name); - memset (ip, 0, sizeof *ip); + isc_result_t status; + status = interface_allocate (&ip, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't record interface %s: %s", + name, isc_result_totext (status)); strcpy (ip -> name, name); - ip -> next = dummy_interfaces; - dummy_interfaces = ip; + if (dummy_interfaces) { + interface_reference (&ip -> next, + dummy_interfaces, MDL); + interface_dereference (&dummy_interfaces, MDL); + } + interface_reference (&dummy_interfaces, ip, MDL); } - return ip; + if (pi) + interface_reference (pi, ip, MDL); + interface_dereference (&ip, MDL); + return 1; } void make_client_state (state) @@ -738,10 +750,11 @@ void make_client_config (client, config) if (!client -> config) log_fatal ("no memory for client config\n"); memcpy (client -> config, config, sizeof *config); - client -> config -> on_receipt = - clone_group (config -> on_receipt, MDL); - client -> config -> on_transmission = - clone_group (config -> on_transmission, MDL); + if (!clone_group (&client -> config -> on_receipt, + config -> on_receipt, MDL) || + !clone_group (&client -> config -> on_transmission, + config -> on_transmission, MDL)) + log_fatal ("no memory for client state groups."); } /* client-lease-statement :== @@ -918,8 +931,7 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp) skip_to_semi (cfile); break; } - ip = interface_or_dummy (val); - *ipp = ip; + interface_or_dummy (ipp, val); break; case NAME: diff --git a/client/dhclient.c b/client/dhclient.c index 2a17098a1..2e83b8cde 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -15,7 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names + * 3. Neither the name of Internet Software Consortium nor the names * of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -41,7 +41,7 @@ #ifndef lint static char ocopyright[] = -"$Id: dhclient.c,v 1.101 2000/05/01 17:15:23 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dhclient.c,v 1.102 2000/05/16 23:01:58 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -71,8 +71,7 @@ struct binding_scope global_scope; assert (state_is == state_shouldbe). */ #define ASSERT_STATE(state_is, state_shouldbe) {} -static char copyright[] = -"Copyright 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium."; +static char copyright[] = "Copyright 1995-2000 Internet Software Consortium."; static char arr [] = "All rights reserved."; static char message [] = "Internet Software Consortium DHCP Client"; static char contrib [] = "\nPlease contribute if you find this software useful."; @@ -162,17 +161,20 @@ int main (argc, argv, envp) } else if (argv [i][0] == '-') { usage (); } else { - struct interface_info *tmp = ((struct interface_info *) - dmalloc (sizeof *tmp, MDL)); - if (!tmp) - log_fatal ("Insufficient memory to %s %s", - "record interface", argv [i]); - memset (tmp, 0, sizeof *tmp); + struct interface_info *tmp = (struct interface_info *)0; + status = interface_allocate (&tmp, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't record interface %s:%s", + argv [i], isc_result_totext (status)); strcpy (tmp -> name, argv [i]); - tmp -> next = interfaces; + if (interfaces) { + interface_reference (&tmp -> next, + interfaces, MDL); + interface_dereference (&interfaces, MDL); + } + interface_reference (&interfaces, tmp, MDL); tmp -> flags = INTERFACE_REQUESTED; interfaces_requested = 1; - interfaces = tmp; } } @@ -267,7 +269,10 @@ int main (argc, argv, envp) /* Set up the OMAPI wrappers for various server database internal objects. */ - dhclient_db_objects_setup (); + dhcp_common_objects_setup (); + + dhcp_interface_discovery_hook = dhclient_interface_discovery_hook; + dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook; /* Discover all the network interfaces. */ discover_interfaces (DISCOVER_UNCONFIGURED); @@ -353,7 +358,7 @@ int main (argc, argv, envp) /* Set up a timeout to start the initialization process. */ add_timeout (cur_time + random () % 5, - state_reboot, client); + state_reboot, client, 0, 0); } } } @@ -391,10 +396,10 @@ static void usage () "[-cf config-file] [interface]"); } -struct class *find_class (s) - const char *s; +isc_result_t find_class (struct class **c, + const char *s, const char *file, int line) { - return (struct class *)0; + return 0; } int check_collection (packet, lease, collection) @@ -418,10 +423,10 @@ int unbill_class (lease, class) return 0; } -struct subnet *find_subnet (addr) - struct iaddr addr; +int find_subnet (struct subnet **sp, + struct iaddr addr, const char *file, int line) { - return (struct subnet *)0; + return 0; } /* Individual States: @@ -781,7 +786,7 @@ void bind_lease (client) /* Set up a timeout to start the renewal process. */ add_timeout (client -> active -> renewal, - state_bound, client); + state_bound, client, 0, 0); log_info ("bound to %s -- renewal in %ld seconds.", piaddr (client -> active -> address), @@ -1025,7 +1030,7 @@ void dhcpoffer (packet) if (stop_selecting <= 0) state_selecting (ip); else { - add_timeout (stop_selecting, state_selecting, client); + add_timeout (stop_selecting, state_selecting, client, 0, 0); cancel_timeout (send_discover, client); } } @@ -1269,7 +1274,8 @@ void send_discover (cpp) inaddr_any, &sockaddr_broadcast, (struct hardware *)0); - add_timeout (cur_time + client -> interval, send_discover, client); + add_timeout (cur_time + client -> interval, + send_discover, client, 0, 0); } /* state_panic gets called if we haven't received any offers in a preset @@ -1317,7 +1323,7 @@ void state_panic (cpp) (long)(client -> active -> renewal - cur_time), "seconds"); add_timeout (client -> active -> renewal, - state_bound, client); + state_bound, client, 0, 0); } else { client -> state = S_BOUND; log_info ("bound: immediate renewal."); @@ -1369,7 +1375,7 @@ void state_panic (cpp) add_timeout (cur_time + ((client -> config -> retry_interval + 1) / 2 + (random () % client -> config -> retry_interval)), - state_init, client); + state_init, client, 0, 0); go_daemon (); } @@ -1523,7 +1529,7 @@ void send_request (cpp) (struct hardware *)0); add_timeout (cur_time + client -> interval, - send_request, client); + send_request, client, 0, 0); } void send_decline (cpp) @@ -2383,7 +2389,54 @@ void do_release(client) } } +int dhclient_interface_shutdown_hook (struct interface_info *interface) +{ + do_release (interface -> client); + return 1; +} +int dhclient_interface_discovery_hook (struct interface_info *tmp) +{ + struct interface_info *last, *ip; + /* See if we can find the client from dummy_interfaces */ + last = 0; + for (ip = dummy_interfaces; ip; ip = ip -> next) { + if (!strcmp (ip -> name, tmp -> name)) { + /* Remove from dummy_interfaces */ + if (last) { + ip = (struct interface_info *)0; + interface_reference (&ip, last -> next, MDL); + interface_dereference (&last -> next, MDL); + if (ip -> next) { + interface_reference (&last -> next, + ip -> next, MDL); + interface_dereference (&ip -> next, + MDL); + } + } else { + ip = (struct interface_info *)0; + interface_reference (&ip, + dummy_interfaces, MDL); + interface_dereference (&dummy_interfaces, MDL); + if (ip -> next) { + interface_reference (&dummy_interfaces, + ip -> next, MDL); + interface_dereference (&ip -> next, + MDL); + } + } + /* Copy "client" to tmp */ + if (ip -> client) { + tmp -> client = ip -> client; + tmp -> client -> interface = tmp; + } + interface_dereference (&ip, MDL); + break; + } + last = ip; + } + return 1; +} /* The client should never receive a relay agent information option, so if it does, log it and discard it. */ diff --git a/client/omapi.c b/client/omapi.c index fa1ec8456..fc9e4e2ef 100644 --- a/client/omapi.c +++ b/client/omapi.c @@ -43,286 +43,8 @@ #ifndef lint static char copyright[] = -"$Id: omapi.c,v 1.4 2000/03/17 03:58:56 mellon Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: omapi.c,v 1.5 2000/05/16 23:02:00 mellon Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" #include - -void dhclient_db_objects_setup () -{ - isc_result_t status; - - status = omapi_object_type_register (&dhcp_type_interface, - "interface", - dhclient_interface_set_value, - dhclient_interface_get_value, - dhclient_interface_destroy, - dhclient_interface_signal_handler, - dhclient_interface_stuff_values, - dhclient_interface_lookup, - dhclient_interface_create, - dhclient_interface_remove); - if (status != ISC_R_SUCCESS) - log_fatal ("Can't register interface object type: %s", - isc_result_totext (status)); - -} - -isc_result_t dhclient_interface_set_value (omapi_object_t *h, - omapi_object_t *id, - omapi_data_string_t *name, - omapi_typed_data_t *value) -{ - struct interface_info *interface; - isc_result_t status; - int foo; - - if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; - interface = (struct interface_info *)h; - - if (!omapi_ds_strcmp (name, "name")) { - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { - memcpy (interface -> name, - value -> u.buffer.value, - value -> u.buffer.len); - interface -> name [value -> u.buffer.len] = 0; - } else - return ISC_R_INVALIDARG; - return ISC_R_SUCCESS; - } - - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> set_value) { - status = ((*(h -> inner -> type -> set_value)) - (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) - return status; - } - - return ISC_R_NOTFOUND; -} - - -isc_result_t dhclient_interface_get_value (omapi_object_t *h, - omapi_object_t *id, - omapi_data_string_t *name, - omapi_value_t **value) -{ - return ISC_R_NOTIMPLEMENTED; -} - -isc_result_t dhclient_interface_destroy (omapi_object_t *h, - const char *file, int line) -{ - struct interface_info *interface; - isc_result_t status; - - if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; - interface = (struct interface_info *)h; - - - if (interface -> ifp) - free (interface -> ifp); - dfree (interface, file, line); - return ISC_R_SUCCESS; -} - -isc_result_t dhclient_interface_signal_handler (omapi_object_t *h, - const char *name, va_list ap) -{ - struct interface_info *ip, *interface; - struct client_config *config; - struct client_state *client; - - if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; - interface = (struct interface_info *)h; - - interface -> next = interfaces; - interfaces = interface; - - discover_interfaces (DISCOVER_UNCONFIGURED); - - for (ip = interfaces; ip; ip = ip -> next) { - /* If interfaces were specified, don't configure - interfaces that weren't specified! */ - if (ip -> flags & INTERFACE_RUNNING || - (ip -> flags & (INTERFACE_REQUESTED | - INTERFACE_AUTOMATIC)) != - INTERFACE_REQUESTED) - continue; - script_init (ip -> client, - "PREINIT", (struct string_list *)0); - if (ip -> client -> alias) - script_write_params (ip -> client, "alias_", - ip -> client -> alias); - script_go (ip -> client); - } - - discover_interfaces (interfaces_requested - ? DISCOVER_REQUESTED - : DISCOVER_RUNNING); - - for (ip = interfaces; ip; ip = ip -> next) { - if (ip -> flags & INTERFACE_RUNNING) - continue; - ip -> flags |= INTERFACE_RUNNING; - for (client = ip -> client; client; client = client -> next) { - client -> state = S_INIT; - /* Set up a timeout to start the initialization - process. */ - add_timeout (cur_time + random () % 5, - state_reboot, client); - } - } - return ISC_R_SUCCESS; -} - -isc_result_t dhclient_interface_stuff_values (omapi_object_t *c, - omapi_object_t *id, - omapi_object_t *h) -{ - struct interface_info *interface; - isc_result_t status; - - if (h -> type != dhcp_type_interface) - return ISC_R_INVALIDARG; - interface = (struct interface_info *)h; - - /* Write out all the values. */ - - status = omapi_connection_put_name (c, "state"); - if (status != ISC_R_SUCCESS) - return status; - if (interface -> flags && INTERFACE_REQUESTED) - status = omapi_connection_put_string (c, "up"); - else - status = omapi_connection_put_string (c, "down"); - if (status != ISC_R_SUCCESS) - return status; - - /* Write out the inner object, if any. */ - if (h -> inner && h -> inner -> type -> stuff_values) { - status = ((*(h -> inner -> type -> stuff_values)) - (c, id, h -> inner)); - if (status == ISC_R_SUCCESS) - return status; - } - - return ISC_R_SUCCESS; -} - -isc_result_t dhclient_interface_lookup (omapi_object_t **ip, - omapi_object_t *id, - omapi_object_t *ref) -{ - omapi_value_t *tv = (omapi_value_t *)0; - isc_result_t status; - struct interface_info *interface; - - /* First see if we were sent a handle. */ - status = omapi_get_value_str (ref, id, "handle", &tv); - if (status == ISC_R_SUCCESS) { - status = omapi_handle_td_lookup (ip, tv -> value); - - omapi_value_dereference (&tv, MDL); - if (status != ISC_R_SUCCESS) - return status; - - /* Don't return the object if the type is wrong. */ - if ((*ip) -> type != dhcp_type_interface) { - omapi_object_dereference (ip, MDL); - return ISC_R_INVALIDARG; - } - } - - /* Now look for an interface name. */ - status = omapi_get_value_str (ref, id, "name", &tv); - if (status == ISC_R_SUCCESS) { - for (interface = interfaces; interface; - interface = interface -> next) { - if (strncmp (interface -> name, - (char *)tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len) == 0) - break; - } - omapi_value_dereference (&tv, MDL); - if (*ip && *ip != (omapi_object_t *)interface) { - omapi_object_dereference (ip, MDL); - return ISC_R_KEYCONFLICT; - } else if (!interface) { - if (*ip) - omapi_object_dereference (ip, MDL); - return ISC_R_NOTFOUND; - } else if (!*ip) - /* XXX fix so that hash lookup itself creates - XXX the reference. */ - omapi_object_reference (ip, - (omapi_object_t *)interface, - MDL); - } - - /* If we get to here without finding an interface, no valid key was - specified. */ - if (!*ip) - return ISC_R_NOKEYS; - return ISC_R_SUCCESS; -} - -/* actually just go discover the interface */ -isc_result_t dhclient_interface_create (omapi_object_t **lp, - omapi_object_t *id) -{ - struct interface_info *hp; - - hp = (struct interface_info *)dmalloc (sizeof (struct interface_info), - MDL); - if (!hp) - return ISC_R_NOMEMORY; - memset (hp, 0, sizeof *hp); - hp -> refcnt = 0; - hp -> type = dhcp_type_interface; - hp -> flags = INTERFACE_REQUESTED; - return omapi_object_reference (lp, (omapi_object_t *)hp, MDL); - -} - -isc_result_t dhclient_interface_remove (omapi_object_t *lp, - omapi_object_t *id) -{ - struct interface_info *interface, *ip, *last; - - interface = (struct interface_info *)lp; - - /* remove from interfaces */ - last = 0; - for (ip = interfaces; ip; ip = ip -> next) { - if (!strcmp (ip -> name, interface -> name)) { - if (last) - last -> next = ip -> next; - else - interfaces = ip -> next; - break; - } - last = ip; - } - - /* add the interface to the dummy_interface list */ - interface -> next = dummy_interfaces; - dummy_interfaces = interface; - - /* do a DHCPRELEASE */ - do_release (interface -> client); - - /* remove the io object */ - omapi_io_destroy (interface -> outer, MDL); - - if_deregister_send (interface); - if_deregister_receive (interface); - - return ISC_R_SUCCESS; -} diff --git a/common/Makefile.dist b/common/Makefile.dist index af5a451bf..5c199d695 100644 --- a/common/Makefile.dist +++ b/common/Makefile.dist @@ -22,11 +22,11 @@ SEDMANPAGES = dhcp-options.man5 dhcp-contrib.man5 dhcp-eval.man5 SRC = raw.c parse.c nit.c icmp.c dispatch.c conflex.c upf.c bpf.c socket.c \ lpf.c dlpi.c packet.c tr.c ethernet.c memory.c print.c options.c \ inet.c convert.c tree.c tables.c hash.c alloc.c fddi.c \ - inet_addr.c dns.c resolv.c execute.c discover.c auth.c + inet_addr.c dns.c resolv.c execute.c discover.c comapi.c OBJ = raw.o parse.o nit.o icmp.o dispatch.o conflex.o upf.o bpf.o socket.o \ lpf.o dlpi.o packet.o tr.o ethernet.o memory.o print.o options.o \ inet.o convert.o tree.o tables.o hash.o alloc.o fddi.o \ - inet_addr.o dns.o resolv.o execute.o discover.o auth.o + inet_addr.o dns.o resolv.o execute.o discover.o comapi.o MAN = dhcp-options.5 dhcp-contrib.5 dhcp-eval.5 DEBUG = -g diff --git a/common/alloc.c b/common/alloc.c index 592c863aa..8d2a17049 100644 --- a/common/alloc.c +++ b/common/alloc.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: alloc.c,v 1.46 2000/03/17 03:59:00 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: alloc.c,v 1.47 2000/05/16 23:02:08 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -52,91 +52,161 @@ static char copyright[] = struct dhcp_packet *dhcp_free_list; struct packet *packet_free_list; -struct dhcp_packet *new_dhcp_packet (file, line) - const char *file; - int line; -{ - struct dhcp_packet *rval; - rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet), - file, line); - return rval; -} +OMAPI_OBJECT_ALLOC (subnet, struct subnet, dhcp_type_subnet) +OMAPI_OBJECT_ALLOC (shared_network, struct shared_network, + dhcp_type_shared_network) +OMAPI_OBJECT_ALLOC (group_object, struct group_object, dhcp_type_group) -struct hash_table *new_hash_table (count, file, line) - int count; +int group_allocate (ptr, file, line) + struct group **ptr; const char *file; int line; { - struct hash_table *rval = dmalloc (sizeof (struct hash_table) - - (DEFAULT_HASH_SIZE - * sizeof (struct hash_bucket *)) - + (count - * sizeof (struct hash_bucket *)), - file, line); - rval -> hash_count = count; - return rval; -} + int size; -struct hash_bucket *new_hash_bucket (file, line) - const char *file; - int line; -{ - struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), - file, line); - return rval; + if (!ptr) { + log_error ("%s(%d): null pointer", file, line); +#if defined (POINTER_DEBUG) + abort (); +#else + return 0; +#endif + } + if (*ptr) { + log_error ("%s(%d): non-null pointer", file, line); +#if defined (POINTER_DEBUG) + abort (); +#else + *ptr = (struct group *)0; +#endif + } + + *ptr = dmalloc (sizeof **ptr, file, line); + if (*ptr) { + memset (*ptr, 0, sizeof **ptr); + (*ptr) -> refcnt = 1; + return 1; + } + return 0; } -struct lease *new_leases (n, file, line) - unsigned n; +int group_reference (ptr, bp, file, line) + struct group **ptr; + struct group *bp; const char *file; int line; { - struct lease *rval = dmalloc (n * sizeof (struct lease), file, line); - return rval; + if (!ptr) { + log_error ("%s(%d): null pointer", file, line); +#if defined (POINTER_DEBUG) + abort (); +#else + return 0; +#endif + } + if (*ptr) { + log_error ("%s(%d): non-null pointer", file, line); +#if defined (POINTER_DEBUG) + abort (); +#else + *ptr = (struct group *)0; +#endif + } + *ptr = bp; + bp -> refcnt++; + rc_register (file, line, ptr, bp, bp -> refcnt); + dmalloc_reuse (bp, file, line, 1); + return 1; } -struct lease *new_lease (file, line) +int group_dereference (ptr, file, line) + struct group **ptr; const char *file; int line; { - struct lease *rval = dmalloc (sizeof (struct lease), file, line); - return rval; + int i; + struct group *group; + + if (!ptr || !*ptr) { + log_error ("%s(%d): null pointer", file, line); +#if defined (POINTER_DEBUG) + abort (); +#else + return 0; +#endif + } + + group = *ptr; + *ptr = (struct group *)0; + --group -> refcnt; + rc_register (file, line, ptr, group, group -> refcnt); + if (group -> refcnt > 0) + return 1; + + if (group -> refcnt < 0) { + log_error ("%s(%d): negative refcnt!", file, line); +#if defined (DEBUG_RC_HISTORY) + dump_rc_history (); +#endif +#if defined (POINTER_DEBUG) + abort (); +#else + return 0; +#endif + } + + if (group -> object) + group_object_dereference (&group -> object, MDL); + if (group -> subnet) + subnet_dereference (&group -> subnet, MDL); + if (group -> shared_network) + shared_network_dereference (&group -> shared_network, MDL); + if (group -> statements) + executable_statement_dereference (&group -> statements, MDL); + dfree (group, file, line); + return 1; } -struct subnet *new_subnet (file, line) +struct dhcp_packet *new_dhcp_packet (file, line) const char *file; int line; { - struct subnet *rval = dmalloc (sizeof (struct subnet), file, line); + struct dhcp_packet *rval; + rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet), + file, line); return rval; } -struct class *new_class (file, line) +struct hash_table *new_hash_table (count, file, line) + int count; const char *file; int line; { - struct class *rval = dmalloc (sizeof (struct class), file, line); + struct hash_table *rval = dmalloc (sizeof (struct hash_table) + - (DEFAULT_HASH_SIZE + * sizeof (struct hash_bucket *)) + + (count + * sizeof (struct hash_bucket *)), + file, line); + rval -> hash_count = count; return rval; } -struct shared_network *new_shared_network (file, line) +struct hash_bucket *new_hash_bucket (file, line) const char *file; int line; { - struct shared_network *rval = - dmalloc (sizeof (struct shared_network), file, line); + struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), + file, line); return rval; } -struct group *new_group (file, line) +void free_hash_bucket (ptr, file, line) + struct hash_bucket *ptr; const char *file; int line; { - struct group *rval = - dmalloc (sizeof (struct group), file, line); - if (rval) - memset (rval, 0, sizeof *rval); - return rval; + dfree ((VOIDPTR)ptr, file, line); } struct protocol *new_protocol (file, line) @@ -147,32 +217,6 @@ struct protocol *new_protocol (file, line) return rval; } -struct lease_state *free_lease_states; - -struct lease_state *new_lease_state (file, line) - const char *file; - int line; -{ - struct lease_state *rval; - - if (free_lease_states) { - rval = free_lease_states; - free_lease_states = - (struct lease_state *)(free_lease_states -> next); - dmalloc_reuse (rval, file, line, 0); - } else { - rval = dmalloc (sizeof (struct lease_state), file, line); - if (!rval) - return rval; - } - memset (rval, 0, sizeof *rval); - if (!option_state_allocate (&rval -> options, file, line)) { - free_lease_state (rval, file, line); - return (struct lease_state *)0; - } - return rval; -} - struct domain_search_list *new_domain_search_list (file, line) const char *file; int line; @@ -248,23 +292,6 @@ void free_domain_search_list (ptr, file, line) dfree ((VOIDPTR)ptr, file, line); } -void free_lease_state (ptr, file, line) - struct lease_state *ptr; - const char *file; - int line; -{ - if (ptr -> options) - option_state_dereference (&ptr -> options, file, line); - if (ptr -> packet) - packet_dereference (&ptr -> packet, file, line); - data_string_forget (&ptr -> parameter_request_list, file, line); - data_string_forget (&ptr -> filename, file, line); - data_string_forget (&ptr -> server_name, file, line); - ptr -> next = free_lease_states; - free_lease_states = ptr; - dmalloc_reuse (free_lease_states, (char *)0, 0, 0); -} - void free_protocol (ptr, file, line) struct protocol *ptr; const char *file; @@ -273,54 +300,6 @@ void free_protocol (ptr, file, line) dfree ((VOIDPTR)ptr, file, line); } -void free_group (ptr, file, line) - struct group *ptr; - const char *file; - int line; -{ - dfree ((VOIDPTR)ptr, file, line); -} - -void free_shared_network (ptr, file, line) - struct shared_network *ptr; - const char *file; - int line; -{ - dfree ((VOIDPTR)ptr, file, line); -} - -void free_class (ptr, file, line) - struct class *ptr; - const char *file; - int line; -{ - dfree ((VOIDPTR)ptr, file, line); -} - -void free_subnet (ptr, file, line) - struct subnet *ptr; - const char *file; - int line; -{ - dfree ((VOIDPTR)ptr, file, line); -} - -void free_lease (ptr, file, line) - struct lease *ptr; - const char *file; - int line; -{ - dfree ((VOIDPTR)ptr, file, line); -} - -void free_hash_bucket (ptr, file, line) - struct hash_bucket *ptr; - const char *file; - int line; -{ - dfree ((VOIDPTR)ptr, file, line); -} - void free_hash_table (ptr, file, line) struct hash_table *ptr; const char *file; @@ -353,26 +332,6 @@ void free_client_lease (lease, file, line) dfree (lease, file, line); } -struct pool *new_pool (file, line) - const char *file; - int line; -{ - struct pool *pool = ((struct pool *) - dmalloc (sizeof (struct pool), file, line)); - if (!pool) - return pool; - memset (pool, 0, sizeof *pool); - return pool; -} - -void free_pool (pool, file, line) - struct pool *pool; - const char *file; - int line; -{ - dfree (pool, file, line); -} - struct auth_key *new_auth_key (len, file, line) unsigned len; const char *file; @@ -396,26 +355,6 @@ void free_auth_key (peer, file, line) dfree (peer, file, line); } -struct permit *new_permit (file, line) - const char *file; - int line; -{ - struct permit *permit = ((struct permit *) - dmalloc (sizeof (struct permit), file, line)); - if (!permit) - return permit; - memset (permit, 0, sizeof *permit); - return permit; -} - -void free_permit (permit, file, line) - struct permit *permit; - const char *file; - int line; -{ - dfree (permit, file, line); -} - pair free_pairs; pair new_pair (file, line) @@ -1095,6 +1034,8 @@ int packet_dereference (ptr, file, line) if (packet -> options) option_state_dereference (&packet -> options, file, line); + if (packet -> interface) + interface_dereference (&packet -> interface, MDL); packet -> raw = (struct dhcp_packet *)free_packets; free_packets = packet; dmalloc_reuse (free_packets, (char *)0, 0, 0); diff --git a/common/bpf.c b/common/bpf.c index a07e40e5e..f1a40f4f4 100644 --- a/common/bpf.c +++ b/common/bpf.c @@ -47,7 +47,7 @@ #ifndef lint static char copyright[] = -"$Id: bpf.c,v 1.38 2000/04/14 16:17:35 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: bpf.c,v 1.39 2000/05/16 23:02:09 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -515,12 +515,9 @@ int can_receive_unicast_unconfigured (ip) void maybe_setup_fallback () { isc_result_t status; - struct interface_info *fbi; - fbi = setup_fallback (); - if (fbi) { + struct interface_info *fbi = (struct interface_info *)0; + if (setup_fallback (&fbi, MDL)) { if_register_fallback (fbi); - fbi -> refcnt = 1; - fbi -> type = dhcp_type_interface; status = omapi_register_io_object ((omapi_object_t *)fbi, if_readsocket, 0, fallback_discard, 0, 0); diff --git a/common/conflex.c b/common/conflex.c index 1074a37a4..ca6943a5f 100644 --- a/common/conflex.c +++ b/common/conflex.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: conflex.c,v 1.74 2000/05/04 18:57:57 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: conflex.c,v 1.75 2000/05/16 23:02:11 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -671,6 +671,8 @@ static enum dhcp_token intern (atom, dfv) return HOSTNAME; break; case 'i': + if (!strcasecmp (atom + 1, "nclude")) + return INCLUDE; if (!strcasecmp (atom + 1, "nteger")) return INTEGER; if (!strcasecmp (atom + 1, "nfinite")) diff --git a/common/discover.c b/common/discover.c index 35708416f..c2df1a7ea 100644 --- a/common/discover.c +++ b/common/discover.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: discover.c,v 1.26 2000/05/01 17:31:19 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: discover.c,v 1.27 2000/05/16 23:02:12 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -54,6 +54,8 @@ extern int interfaces_invalidated; int quiet_interface_discovery; u_int16_t local_port; u_int16_t remote_port; +int (*dhcp_interface_setup_hook) (struct interface_info *, struct iaddr *); +int (*dhcp_interface_discovery_hook) (struct interface_info *); struct in_addr limited_broadcast; struct in_addr local_address; @@ -65,6 +67,8 @@ void (*bootp_packet_handler) PROTO ((struct interface_info *, omapi_object_type_t *dhcp_type_interface; +OMAPI_OBJECT_ALLOC (interface, struct interface_info, dhcp_type_interface) + /* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces. For each interface that's of type INET and not the loopback interface, register that interface with the network I/O software, figure out what @@ -97,7 +101,8 @@ void discover_interfaces (state) (&dhcp_type_interface, "interface", interface_set_value, interface_get_value, interface_destroy, interface_signal_handler, - interface_stuff_values, 0, 0, 0); + interface_stuff_values, 0, 0, 0, 0, 0, + sizeof (struct interface_info)); if (status != ISC_R_SUCCESS) log_fatal ("Can't create interface object type: %s", isc_result_totext (status)); @@ -172,45 +177,31 @@ void discover_interfaces (state) /* If there isn't already an interface by this name, allocate one. */ if (!tmp) { - tmp = ((struct interface_info *) dmalloc (sizeof *tmp, - MDL)); - if (!tmp) - log_fatal ("Insufficient memory to %s %s", - "record interface", ifp -> ifr_name); - memset (tmp, 0, sizeof *tmp); + tmp = (struct interface_info *)0; + status = interface_allocate (&tmp, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Error allocating interface %s: %s", + ifp -> ifr_name, + isc_result_totext (status)); strcpy (tmp -> name, ifp -> ifr_name); tmp -> circuit_id = (u_int8_t *)tmp -> name; tmp -> circuit_id_len = strlen (tmp -> name); tmp -> remote_id = 0; tmp -> remote_id_len = 0; - tmp -> next = interfaces; tmp -> flags = ir; - interfaces = tmp; - } - - /* See if we can find the client from dummy_interfaces */ - last = 0; - for (ip = dummy_interfaces; ip; ip = ip -> next) { - if (!strcmp (ip -> name, tmp -> name)) { - /* Remove from dummy_interfaces */ - if (last) - last -> next = ip -> next; - else - dummy_interfaces = ip -> next; - /* Copy "client" to tmp */ - if (ip -> client) { - tmp -> client = ip -> client; - tmp -> client -> interface = tmp; - } - /* free up the dummy_interface */ - if (ip -> ifp) - free (ip -> ifp); - dfree (ip, MDL); - break; + if (interfaces) { + interface_reference (&tmp -> next, + interfaces, MDL); + interface_dereference (&interfaces, MDL); } - last = ip; + interface_reference (&interfaces, tmp, MDL); + interface_dereference (&tmp, MDL); + tmp = interfaces; } + if (dhcp_interface_discovery_hook) + (*dhcp_interface_discovery_hook) (tmp); + /* If we have the capability, extract link information and record it in a linked list. */ #ifdef HAVE_AF_LINK @@ -265,56 +256,17 @@ void discover_interfaces (state) addr.len = 4; memcpy (addr.iabuf, &foo.sin_addr.s_addr, addr.len); - - /* If there's a registered subnet for this address, - connect it together... */ - if ((subnet = find_subnet (addr))) { - /* If this interface has multiple aliases - on the same subnet, ignore all but the - first we encounter. */ - if (!subnet -> interface) { - subnet -> interface = tmp; - subnet -> interface_address = addr; - } else if (subnet -> interface != tmp) { - log_error ("Multiple %s %s: %s %s", - "interfaces match the", - "same subnet", - subnet -> interface -> name, - tmp -> name); - } - share = subnet -> shared_network; - if (tmp -> shared_network && - tmp -> shared_network != share) { - log_fatal ("Interface %s matches %s", - tmp -> name, - "multiple shared networks"); - } else { - tmp -> shared_network = share; - } - - if (!share -> interface) { - share -> interface = tmp; - } else if (share -> interface != tmp) { - log_error ("Multiple %s %s: %s %s", - "interfaces match the", - "same shared network", - share -> interface -> name, - tmp -> name); - } - } + if (dhcp_interface_setup_hook) + (*dhcp_interface_setup_hook) (tmp, &addr); } } #if defined (LINUX_SLASHPROC_DISCOVERY) - /* On Linux, interfaces that don't have IP addresses don't show up - in the SIOCGIFCONF syscall. We got away with this prior to - Linux 2.1 because we would give each interface an IP address of - 0.0.0.0 before trying to boot, but that doesn't work after 2.1 - because we're using LPF, because we can't configure interfaces - with IP addresses of 0.0.0.0 anymore (grumble). This only - matters for the DHCP client, of course - the relay agent and - server should only care about interfaces that are configured - with IP addresses anyway. + /* On Linux, interfaces that don't have IP addresses don't + show up in the SIOCGIFCONF syscall. This only matters for + the DHCP client, of course - the relay agent and server + should only care about interfaces that are configured with + IP addresses anyway. The PROCDEV_DEVICE (/proc/net/dev) is a kernel-supplied file that, when read, prints a human readable network status. We @@ -322,8 +274,7 @@ void discover_interfaces (state) two lines (which are header) and then parsing off everything up to the colon in each subsequent line - these lines start with the interface name, then a colon, then a bunch of - statistics. Yes, Virgina, this is a kludge, but you work - with what you have. */ + statistics. */ if (state == DISCOVER_UNCONFIGURED) { FILE *proc_dev; @@ -362,38 +313,21 @@ void discover_interfaces (state) continue; /* Otherwise, allocate one. */ - tmp = ((struct interface_info *) - dmalloc (sizeof *tmp, MDL)); - if (!tmp) - log_fatal ("Insufficient memory to %s %s", - "record interface", name); - memset (tmp, 0, sizeof *tmp); - strcpy (tmp -> name, name); - + tmp = (struct interface_info *)0; + status = interface_allocate (&tmp, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't allocate interface %s: %s", + name, isc_result_totext (status)); tmp -> flags = ir; - tmp -> next = interfaces; - interfaces = tmp; - /* See if we can find the client from dummy_interfaces */ - last = 0; - for (ip = dummy_interfaces; ip; ip = ip -> next) { - if (!strcmp (ip -> name, tmp -> name)) { - /* remove from dummy_interfaces */ - if (last) - last -> next = ip -> next; - else - dummy_interfaces = ip -> next; - /* copy "client" to tmp */ - if (ip -> client) - tmp -> client = ip -> client; - /* free up the dummy_interface */ - if (ip -> ifp) - free (ip -> ifp); - dfree (ip, MDL); - ip = 0; - break; - } - last = ip; - } + interface_reference (&tmp -> next, interfaces, MDL); + interface_dereference (&interfaces, MDL); + interface_reference (&interfaces, tmp, MDL); + interface_dereference (&tmp, MDL); + tmp = interfaces; + + if (interface_discovery_hook) + (*interface_discovery_hook (tmp); + } fclose (proc_dev); } @@ -503,9 +437,14 @@ void discover_interfaces (state) } /* Weed out the interfaces that did not have IP addresses. */ - last = (struct interface_info *)0; - for (tmp = interfaces; tmp; tmp = next) { - next = tmp -> next; + tmp = last = next = (struct interface_info *)0; + if (interfaces) + interface_reference (&tmp, interfaces, MDL); + while (tmp) { + if (next) + interface_dereference (&next, MDL); + if (tmp -> next) + interface_reference (&next, tmp -> next, MDL); /* skip interfaces that are running already */ if (tmp -> flags & INTERFACE_RUNNING) continue; @@ -516,15 +455,29 @@ void discover_interfaces (state) if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) { if ((tmp -> flags & INTERFACE_REQUESTED) != ir) log_fatal ("%s: not found", tmp -> name); - if (!last) - interfaces = interfaces -> next; - else - last -> next = tmp -> next; + if (!last) { + if (interfaces) + interface_dereference (&interfaces, + MDL); + interface_reference (&interfaces, next, MDL); + } else { + interface_dereference (&last -> next, MDL); + interface_reference (&last -> next, next, MDL); + } + if (tmp -> next) + interface_dereference (&tmp -> next, MDL); /* Remember the interface in case we need to know about it later. */ - tmp -> next = dummy_interfaces; - dummy_interfaces = tmp; + if (dummy_interfaces) { + interface_reference (&tmp -> next, + dummy_interfaces, MDL); + interface_dereference (&dummy_interfaces, MDL); + } + interface_reference (&dummy_interfaces, tmp, MDL); + interface_dereference (&tmp, MDL); + if (next) + interface_reference (&tmp, next, MDL); continue; } last = tmp; @@ -570,6 +523,9 @@ void discover_interfaces (state) tmp -> name); } #endif + interface_dereference (&tmp, MDL); + if (next) + interface_reference (&tmp, next, MDL); } /* Now register all the remaining interfaces as protocols. */ @@ -577,8 +533,6 @@ void discover_interfaces (state) /* not if it's been registered before */ if (tmp -> flags & INTERFACE_RUNNING) continue; - tmp -> refcnt = 1; - tmp -> type = dhcp_type_interface; status = omapi_register_io_object ((omapi_object_t *)tmp, if_readsocket, 0, got_one, 0, 0); @@ -617,21 +571,21 @@ int if_readsocket (h) return ip -> rfdesc; } -struct interface_info *setup_fallback () +int setup_fallback (struct interface_info **fp, const char *file, int line) { - fallback_interface = ((struct interface_info *) - dmalloc (sizeof *fallback_interface, MDL)); - if (!fallback_interface) - log_fatal ("No memory to record fallback interface."); - memset (fallback_interface, 0, sizeof *fallback_interface); + isc_result_t status; + + status = interface_allocate (&fallback_interface, file, line); + if (status != ISC_R_SUCCESS) + log_fatal ("Error allocating fallback interface: %s", + isc_result_totext (status)); strcpy (fallback_interface -> name, "fallback"); - fallback_interface -> shared_network = new_shared_network (MDL); - if (!fallback_interface -> shared_network) - log_fatal ("No memory for shared subnet"); - memset (fallback_interface -> shared_network, 0, - sizeof (struct shared_network)); - fallback_interface -> shared_network -> name = "fallback-net"; - return fallback_interface; + if (dhcp_interface_setup_hook) + (*dhcp_interface_setup_hook) (fallback_interface, + (struct iaddr *)0); + status = interface_reference (fp, fallback_interface, file, line); + interface_dereference (&fallback_interface, file, line); + return status == ISC_R_SUCCESS; } void reinitialize_interfaces () diff --git a/common/dispatch.c b/common/dispatch.c index 1ea4c80c2..05a921047 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: dispatch.c,v 1.61 2000/03/17 03:59:00 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dispatch.c,v 1.62 2000/05/16 23:02:14 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -78,6 +78,8 @@ void dispatch () t = timeouts; timeouts = timeouts -> next; (*(t -> func)) (t -> what); + if (t -> unref) + (*t -> unref) (&t -> what, MDL); t -> next = free_timeouts; free_timeouts = t; goto another; @@ -95,10 +97,12 @@ void dispatch () isc_result_totext (status)); } -void add_timeout (when, where, what) +void add_timeout (when, where, what, ref, unref) TIME when; void (*where) PROTO ((void *)); void *what; + tvref_t ref; + tvunref_t unref; { struct timeout *t, *q; @@ -122,16 +126,20 @@ void add_timeout (when, where, what) if (free_timeouts) { q = free_timeouts; free_timeouts = q -> next; - q -> func = where; - q -> what = what; } else { q = ((struct timeout *) dmalloc (sizeof (struct timeout), MDL)); if (!q) log_fatal ("add_timeout: no memory!"); - q -> func = where; - q -> what = what; } + memset (q, 0, sizeof *q); + q -> func = where; + q -> ref = ref; + q -> unref = unref; + if (q -> ref) + (*q -> ref)(&q -> what, what, MDL); + else + q -> what = what; } q -> when = when; @@ -180,6 +188,8 @@ void cancel_timeout (where, what) /* If we found the timeout, put it on the free list. */ if (q) { + if (q -> unref) + (*q -> unref) (&q -> what, MDL); q -> next = free_timeouts; free_timeouts = q; } diff --git a/common/dlpi.c b/common/dlpi.c index 8ea69dd4a..00b80296c 100644 --- a/common/dlpi.c +++ b/common/dlpi.c @@ -84,7 +84,7 @@ #ifndef lint static char copyright[] = -"$Id: dlpi.c,v 1.19 2000/03/17 03:59:00 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dlpi.c,v 1.20 2000/05/16 23:02:15 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -1306,12 +1306,9 @@ int can_receive_unicast_unconfigured (ip) void maybe_setup_fallback () { isc_result_t status; - struct interface_info *fbi; - fbi = setup_fallback (); - if (fbi) { + struct interface_info *fbi = (struct interface_info *)0; + if (setup_fallback (&fbi, MDL)) { if_register_fallback (fbi); - fbi -> refcnt = 1; - fbi -> type = dhcp_type_interface; status = omapi_register_io_object ((omapi_object_t *)fbi, if_readsocket, 0, fallback_discard, 0, 0); diff --git a/common/dns.c b/common/dns.c index cb1432099..b3ce2cf71 100644 --- a/common/dns.c +++ b/common/dns.c @@ -42,7 +42,7 @@ #ifndef lint static char copyright[] = -"$Id: dns.c,v 1.23 2000/05/03 23:04:43 mellon Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dns.c,v 1.24 2000/05/16 23:02:17 mellon Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -179,7 +179,6 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, memcpy (tkey -> data, zone -> key -> key.data, zone -> key -> key.len); tkey -> len = zone -> key -> key.len; - *key = tkey; return ISC_R_SUCCESS; } @@ -194,16 +193,20 @@ void tkey_free (ns_tsig_key **key) isc_result_t enter_dns_zone (struct dns_zone *zone) { - struct dns_zone *tz; + struct dns_zone *tz = (struct dns_zone *)0; if (dns_zone_hash) { - tz = hash_lookup (dns_zone_hash, - (unsigned char *)zone -> name, 0); - if (tz == zone) + dns_zone_hash_lookup (&tz, + dns_zone_hash, zone -> name, 0, MDL); + if (tz == zone) { + dns_zone_dereference (&tz, MDL); return ISC_R_SUCCESS; - if (tz) - delete_hash_entry (dns_zone_hash, - (unsigned char *)zone -> name, 0); + } + if (tz) { + dns_zone_hash_delete (dns_zone_hash, + zone -> name, 0, MDL); + dns_zone_dereference (&tz, MDL); + } } else { dns_zone_hash = new_hash ((hash_reference)dns_zone_reference, @@ -211,15 +214,16 @@ isc_result_t enter_dns_zone (struct dns_zone *zone) if (!dns_zone_hash) return ISC_R_NOMEMORY; } - add_hash (dns_zone_hash, (unsigned char *)zone -> name, 0, zone); + dns_zone_hash_add (dns_zone_hash, zone -> name, 0, zone, MDL); return ISC_R_SUCCESS; } isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name) { - struct dns_zone *tz; + struct dns_zone *tz = (struct dns_zone *)0; unsigned len; char *tname = (char *)0; + isc_result_t status; if (!dns_zone_hash) return ISC_R_NOTFOUND; @@ -234,28 +238,32 @@ isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name) tname [len + 1] = 0; name = tname; } - tz = hash_lookup (dns_zone_hash, name, 0); + if (!dns_zone_hash_lookup (zone, dns_zone_hash, name, 0, MDL)) + status = ISC_R_NOTFOUND; + else + status = ISC_R_SUCCESS; + if (tname) dfree (tname, MDL); - if (!tz) - return ISC_R_NOTFOUND; - if (!dns_zone_reference (zone, tz, MDL)) - return ISC_R_UNEXPECTED; - return ISC_R_SUCCESS; + return status; } isc_result_t enter_tsig_key (struct tsig_key *tkey) { - struct tsig_key *tk; + struct tsig_key *tk = (struct tsig_key *)0; if (tsig_key_hash) { - tk = hash_lookup (tsig_key_hash, - (unsigned char *)tkey -> name, 0); - if (tk == tkey) + tsig_key_hash_lookup (&tk, tsig_key_hash, + tkey -> name, 0, MDL); + if (tk == tkey) { + tsig_key_dereference (&tk, MDL); return ISC_R_SUCCESS; - if (tk) - delete_hash_entry (tsig_key_hash, - (unsigned char *)tkey -> name, 0); + } + if (tk) { + tsig_key_hash_delete (tsig_key_hash, + tkey -> name, 0, MDL); + tsig_key_dereference (&tk, MDL); + } } else { tsig_key_hash = new_hash ((hash_reference)tsig_key_reference, @@ -263,7 +271,7 @@ isc_result_t enter_tsig_key (struct tsig_key *tkey) if (!tsig_key_hash) return ISC_R_NOMEMORY; } - add_hash (tsig_key_hash, (unsigned char *)tkey -> name, 0, tkey); + tsig_key_hash_add (tsig_key_hash, tkey -> name, 0, tkey, MDL); return ISC_R_SUCCESS; } @@ -273,11 +281,8 @@ isc_result_t tsig_key_lookup (struct tsig_key **tkey, const char *name) { if (!tsig_key_hash) return ISC_R_NOTFOUND; - tk = hash_lookup (tsig_key_hash, (const unsigned char *)name, 0); - if (!tk) + if (!tsig_key_hash_lookup (tkey, tsig_key_hash, name, 0, MDL)) return ISC_R_NOTFOUND; - if (!tsig_key_reference (tkey, tk, MDL)) - return ISC_R_UNEXPECTED; return ISC_R_SUCCESS; } @@ -437,3 +442,6 @@ void repudiate_zone (struct dns_zone **zone) dns_zone_dereference (zone, MDL); } #endif /* NSUPDATE */ + +HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone) +HASH_FUNCTIONS (tsig_key, const char *, struct tsig_key) diff --git a/common/execute.c b/common/execute.c index 87494ab97..0b599feb2 100644 --- a/common/execute.c +++ b/common/execute.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: execute.c,v 1.31 2000/04/13 21:48:34 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: execute.c,v 1.32 2000/05/16 23:02:18 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -352,7 +352,7 @@ int execute_statements (packet, lease, in_options, out_options, scope, break; default: - log_fatal ("bogus statement type %d\n", r -> op); + log_fatal ("bogus statement type %d", r -> op); } } diff --git a/common/hash.c b/common/hash.c index ffc9193ad..870f2e4de 100644 --- a/common/hash.c +++ b/common/hash.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: hash.c,v 1.21 2000/04/20 00:56:20 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: hash.c,v 1.22 2000/05/16 23:02:19 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -119,11 +119,13 @@ static int do_hash (name, len, size) return accum % size; } -void add_hash (table, name, len, pointer) +void add_hash (table, name, len, pointer, file, line) struct hash_table *table; unsigned len; const unsigned char *name; - void *pointer; + hashed_object_t *pointer; + const char *file; + int line; { int hashno; struct hash_bucket *bp; @@ -136,7 +138,7 @@ void add_hash (table, name, len, pointer) len = strlen ((const char *)name); hashno = (*table -> do_hash) (name, len, table -> hash_count); - bp = new_hash_bucket (MDL); + bp = new_hash_bucket (file, line); if (!bp) { log_error ("Can't add %s to hash table.", name); @@ -145,7 +147,7 @@ void add_hash (table, name, len, pointer) bp -> name = name; if (table -> referencer) { foo = &bp -> value; - (*(table -> referencer)) (foo, pointer, MDL); + (*(table -> referencer)) (foo, pointer, file, line); } else bp -> value = pointer; bp -> next = table -> buckets [hashno]; @@ -153,10 +155,12 @@ void add_hash (table, name, len, pointer) table -> buckets [hashno] = bp; } -void delete_hash_entry (table, name, len) +void delete_hash_entry (table, name, len, file, line) struct hash_table *table; unsigned len; const unsigned char *name; + const char *file; + int line; { int hashno; struct hash_bucket *bp, *pbp = (struct hash_bucket *)0; @@ -184,25 +188,28 @@ void delete_hash_entry (table, name, len) } if (table -> dereferencer) { foo = &bp -> value; - (*(table -> dereferencer)) (foo, MDL); + (*(table -> dereferencer)) (foo, file, line); } - free_hash_bucket (bp, MDL); + free_hash_bucket (bp, file, line); break; } pbp = bp; /* jwg, 9/6/96 - nice catch! */ } } -void *hash_lookup (table, name, len) +int hash_lookup (vp, table, name, len, file, line) + hashed_object_t **vp; struct hash_table *table; const unsigned char *name; unsigned len; + const char *file; + int line; { int hashno; struct hash_bucket *bp; if (!table) - return (unsigned char *)0; + return 0; if (!len) len = strlen ((const char *)name); @@ -210,10 +217,16 @@ void *hash_lookup (table, name, len) for (bp = table -> buckets [hashno]; bp; bp = bp -> next) { if (len == bp -> len - && !(*table -> cmp) (bp -> name, name, len)) - return bp -> value; + && !(*table -> cmp) (bp -> name, name, len)) { + if (table -> referencer) + (*table -> referencer) (vp, bp -> value, + file, line); + else + *vp = bp -> value; + return 1; + } } - return (unsigned char *)0; + return 0; } int casecmp (const void *v1, const void *v2, unsigned len) @@ -242,3 +255,7 @@ int casecmp (const void *v1, const void *v2, unsigned len) } return 0; } + +HASH_FUNCTIONS (group, const char *, struct group_object) +HASH_FUNCTIONS (universe, const char *, struct universe) +HASH_FUNCTIONS (option, const char *, struct option) diff --git a/common/icmp.c b/common/icmp.c index 86e974783..de4a177d9 100644 --- a/common/icmp.c +++ b/common/icmp.c @@ -44,7 +44,7 @@ #ifndef lint static char copyright[] = -"$Id: icmp.c,v 1.22 2000/03/17 03:59:01 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: icmp.c,v 1.23 2000/05/16 23:02:21 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -80,7 +80,8 @@ void icmp_startup (routep, handler) log_fatal ("attempted to reinitialize icmp protocol"); result = omapi_object_type_register (&dhcp_type_icmp, - "icmp", 0, 0, 0, 0, 0, 0, 0, 0); + "icmp", 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, sizeof (struct icmp_state)); if (result != ISC_R_SUCCESS) log_fatal ("Can't register icmp object type: %s", diff --git a/common/lpf.c b/common/lpf.c index aeeceba87..24b28ebd0 100644 --- a/common/lpf.c +++ b/common/lpf.c @@ -37,7 +37,7 @@ #ifndef lint static char copyright[] = -"$Id: lpf.c,v 1.23 2000/03/17 03:59:01 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: lpf.c,v 1.24 2000/05/16 23:02:22 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -372,12 +372,9 @@ int can_receive_unicast_unconfigured (ip) void maybe_setup_fallback () { isc_result_t status; - struct interface_info *fbi; - fbi = setup_fallback (); - if (fbi) { + struct interface_info *fbi = (struct interface_info *)0; + if (setup_fallback (&fbi, MDL)) { if_register_fallback (fbi); - fbi -> refcnt = 1; - fbi -> type = dhcp_type_interface; status = omapi_register_io_object ((omapi_object_t *)fbi, if_readsocket, 0, fallback_discard, 0, 0); diff --git a/common/memory.c b/common/memory.c index 14bbc7a81..ad78a9cd1 100644 --- a/common/memory.c +++ b/common/memory.c @@ -43,22 +43,135 @@ #ifndef lint static char copyright[] = -"$Id: memory.c,v 1.65 2000/03/17 03:59:01 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: memory.c,v 1.66 2000/05/16 23:02:23 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" -struct group *clone_group (group, file, line) - struct group *group; - const char *file; - int line; +struct group *root_group; +struct hash_table *group_name_hash; +int (*group_write_hook) (struct group_object *); + +isc_result_t delete_group (struct group_object *group, int writep) { - struct group *g = new_group (file, line); - if (!g) - log_fatal ("%s(%d): can't allocate new group", file, line); - *g = *group; - g -> statements = (struct executable_statement *)0; - g -> next = group; - return g; + struct group_object *d; + + /* The group should exist and be hashed - if not, it's invalid. */ + if (group_name_hash) { + d = (struct group_object *)0; + group_hash_lookup (&d, group_name_hash, group -> name, + strlen (group -> name), MDL); + } else + return ISC_R_INVALIDARG; + if (!d) + return ISC_R_INVALIDARG; + + /* Also not okay to delete a group that's not the one in + the hash table. */ + if (d != group) + return ISC_R_INVALIDARG; + + /* If it's dynamic, and we're deleting it, we can just blow away the + hash table entry. */ + if ((group -> flags & GROUP_OBJECT_DYNAMIC) && + !(group -> flags & GROUP_OBJECT_STATIC)) { + group_hash_delete (group_name_hash, + group -> name, strlen (group -> name), MDL); + } else { + group -> flags |= GROUP_OBJECT_DELETED; + if (group -> group) + group_dereference (&group -> group, MDL); + } + + /* Store the group declaration in the lease file. */ + if (writep && group_write_hook) { + if (!(*group_write_hook) (group)) + return ISC_R_IOERROR; + } + return ISC_R_SUCCESS; } +isc_result_t supersede_group (struct group_object *group, int writep) +{ + struct group_object *t, *u; + isc_result_t status; + + /* Register the group in the group name hash table, + so we can look it up later. */ + if (group_name_hash) { + t = (struct group_object *)0; + group_hash_lookup (&t, group_name_hash, + group -> name, + strlen (group -> name), MDL); + if (t && t != group) { + /* If this isn't a dynamic entry, then we need to flag + the replacement as not dynamic either - otherwise, + if the dynamic entry is deleted later, the static + entry will come back next time the server is stopped + and restarted. */ + if (!(t -> flags & GROUP_OBJECT_DYNAMIC)) + group -> flags |= GROUP_OBJECT_STATIC; + + /* Delete the old object if it hasn't already been + deleted. If it has already been deleted, get rid of + the hash table entry. This is a legitimate + situation - a deleted static object needs to be kept + around so we remember it's deleted. */ + if (!(t -> flags & GROUP_OBJECT_DELETED)) + delete_group (t, 0); + else { + group_hash_delete (group_name_hash, + group -> name, + strlen (group -> name), + MDL); + group_object_dereference (&t, MDL); + } + } + } else { + group_name_hash = new_hash ((hash_reference) + group_object_reference, + (hash_dereference) + group_object_dereference, 0); + t = (struct group_object *)0; + } + + /* Add the group to the group name hash if it's not + already there, and also thread it into the list of + dynamic groups if appropriate. */ + if (!t) { + group_hash_add (group_name_hash, group -> name, + strlen (group -> name), group, MDL); + } + + /* Store the group declaration in the lease file. */ + if (writep && group_write_hook) { + if (!(*group_write_hook) (group)) + return ISC_R_IOERROR; + } + return ISC_R_SUCCESS; +} + +int clone_group (struct group **gp, struct group *group, + const char *file, int line) +{ + isc_result_t status; + struct group *g = (struct group *)0; + + /* Normally gp should contain the null pointer, but for convenience + it's permissible to clone a group into itself. */ + if (*gp && *gp != group) + return 0; + if (!group_allocate (&g, file, line)) + return 0; + if (group == *gp) + *gp = (struct group *)0; + group_reference (gp, g, MDL); + g -> authoritative = group -> authoritative; + if (group -> shared_network) { + shared_network_reference (&g -> shared_network, + group -> shared_network, MDL); + } + group_reference (&g -> next, group, MDL); + group_dereference (&g, MDL); + return 1; +} diff --git a/common/nit.c b/common/nit.c index afe401330..12b542878 100644 --- a/common/nit.c +++ b/common/nit.c @@ -44,7 +44,7 @@ #ifndef lint static char copyright[] = -"$Id: nit.c,v 1.28 2000/03/17 03:59:01 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: nit.c,v 1.29 2000/05/16 23:02:24 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -410,12 +410,9 @@ int can_receive_unicast_unconfigured (ip) void maybe_setup_fallback () { isc_result_t status; - struct interface_info *fbi; - fbi = setup_fallback (); - if (fbi) { + struct interface_info *fbi = (struct interface_info *)0; + if (setup_fallback (&fbi, MDL)) { if_register_fallback (fbi); - fbi -> refcnt = 1; - fbi -> type = dhcp_type_interface; status = omapi_register_io_object ((omapi_object_t *)fbi, if_readsocket, 0, fallback_discard, 0, 0); diff --git a/common/options.c b/common/options.c index 559e3abd5..309e9c916 100644 --- a/common/options.c +++ b/common/options.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: options.c,v 1.58 2000/03/18 03:34:05 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: options.c,v 1.59 2000/05/16 23:02:27 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #define DHCP_OPTION_DATA @@ -1192,8 +1192,9 @@ int option_space_encapsulate (result, packet, lease, { struct universe *u; - u = (struct universe *)hash_lookup (universe_hash, - name -> data, name -> len); + u = (struct universe *)0; + universe_hash_lookup (&u, universe_hash, + name -> data, name -> len, MDL); if (!u) { log_error ("unknown option space %s.", name -> data); return 0; @@ -1332,7 +1333,7 @@ void do_packet (interface, packet, len, from_port, from, hfrom) decoded_packet -> packet_length = len; decoded_packet -> client_port = from_port; decoded_packet -> client_addr = from; - decoded_packet -> interface = interface; + interface_reference (&decoded_packet -> interface, interface, MDL); decoded_packet -> haddr = hfrom; if (packet -> hlen > sizeof packet -> chaddr) { diff --git a/common/parse.c b/common/parse.c index c3e19b9b8..535570034 100644 --- a/common/parse.c +++ b/common/parse.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: parse.c,v 1.72 2000/04/20 00:56:56 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: parse.c,v 1.73 2000/05/16 23:02:28 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -799,12 +799,9 @@ struct option *parse_option_name (cfile, allocate, known) /* Look up the option name hash table for the specified uname. */ - universe = ((struct universe *) - hash_lookup (universe_hash, - (unsigned char *)uname, 0)); - /* If it's not there, we can't parse the rest of the - declaration. */ - if (!universe) { + universe = (struct universe *)0; + if (!universe_hash_lookup (&universe, universe_hash, + uname, 0, MDL)) { parse_warn (cfile, "no option space named %s.", uname); skip_to_semi (cfile); return (struct option *)0; @@ -817,8 +814,8 @@ struct option *parse_option_name (cfile, allocate, known) } /* Look up the actual option info... */ - option = (struct option *)hash_lookup (universe -> hash, - (const unsigned char *)val, 0); + option = (struct option *)0; + option_hash_lookup (&option, universe -> hash, val, 0, MDL); /* If we didn't get an option structure, it's an undefined option. */ if (option) { @@ -913,8 +910,7 @@ void parse_option_space_decl (cfile) nu -> hash = new_hash (0, 0, 1); if (!nu -> hash) log_fatal ("Can't allocate %s option hash table.", nu -> name); - add_hash (universe_hash, - (const unsigned char *)nu -> name, 0, (unsigned char *)nu); + universe_hash_add (universe_hash, nu -> name, 0, nu, MDL); parse_semi (cfile); } @@ -1125,9 +1121,9 @@ int parse_option_code_definition (cfile, option) XXX may start out static. */ } option -> universe -> options [option -> code] = option; - add_hash (option -> universe -> hash, - (const unsigned char *)option -> name, - 0, (unsigned char *)option); + option_hash_add (option -> universe -> hash, + (const unsigned char *)option -> name, + 0, option, MDL); return 1; } @@ -1349,9 +1345,11 @@ int parse_executable_statement (result, cfile, lose, case_context) *lose = 1; return 0; } - cta = find_class (val); - if (!cta) { - parse_warn (cfile, "unknown class %s.", val); + cta = (struct class *)0; + status = find_class (&cta, val, MDL); + if (status != ISC_R_SUCCESS) { + parse_warn (cfile, "class %s: %s", + val, isc_result_totext (status)); skip_to_semi (cfile); *lose = 1; return 0; @@ -1697,9 +1695,9 @@ int parse_executable_statement (result, cfile, lose, case_context) default: if (config_universe && is_identifier (token)) { - option = ((struct option *) - hash_lookup (config_universe -> hash, - (const unsigned char *)val, 0)); + option = (struct option *)0; + option_hash_lookup (&option, config_universe -> hash, + val, 0, MDL); if (option) { token = next_token (&val, cfile); return parse_option_statement diff --git a/common/tables.c b/common/tables.c index e574a21de..de851ac5c 100644 --- a/common/tables.c +++ b/common/tables.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: tables.c,v 1.41 2000/04/08 01:15:46 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: tables.c,v 1.42 2000/05/16 23:02:30 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -888,9 +888,9 @@ void initialize_common_option_spaces() log_fatal ("Can't allocate dhcp option hash table."); for (i = 0; i < 256; i++) { dhcp_universe.options [i] = &dhcp_options [i]; - add_hash (dhcp_universe.hash, - (const unsigned char *)dhcp_options [i].name, 0, - (unsigned char *)&dhcp_options [i]); + option_hash_add (dhcp_universe.hash, + dhcp_options [i].name, 0, + &dhcp_options [i], MDL); } /* Set up the Novell option universe (for option 63)... */ @@ -914,17 +914,17 @@ void initialize_common_option_spaces() log_fatal ("Can't allocate dhcp option hash table."); for (i = 0; i < 256; i++) { nwip_universe.options [i] = &dhcp_options [i]; - add_hash (nwip_universe.hash, - (const unsigned char *)dhcp_options [i].name, 0, - (unsigned char *)&dhcp_options [i]); + option_hash_add (nwip_universe.hash, + dhcp_options [i].name, 0, + &dhcp_options [i], MDL); } /* Set up the hash of universes. */ universe_hash = new_hash (0, 0, 1); - add_hash (universe_hash, - (const unsigned char *)dhcp_universe.name, 0, - (unsigned char *)&dhcp_universe); - add_hash (universe_hash, - (const unsigned char *)nwip_universe.name, 0, - (unsigned char *)&nwip_universe); + universe_hash_add (universe_hash, + dhcp_universe.name, 0, + &dhcp_universe, MDL); + universe_hash_add (universe_hash, + nwip_universe.name, 0, + &nwip_universe, MDL); } diff --git a/common/upf.c b/common/upf.c index acbf56c8d..d590cbfdb 100644 --- a/common/upf.c +++ b/common/upf.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: upf.c,v 1.17 2000/03/17 03:59:02 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: upf.c,v 1.18 2000/05/16 23:02:31 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -356,12 +356,9 @@ int can_receive_unicast_unconfigured (ip) void maybe_setup_fallback () { isc_result_t status; - struct interface_info *fbi; - fbi = setup_fallback (); - if (fbi) { + struct interface_info *fbi = (struct interface_info *)0; + if (setup_fallback (&fbi, MDL)) { if_register_fallback (fbi); - fbi -> refcnt = 1; - fbi -> type = dhcp_type_interface; status = omapi_register_io_object ((omapi_object_t *)fbi, if_readsocket, 0, fallback_discard, 0, 0); diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c index 638a9bfeb..e80402c92 100644 --- a/dhcpctl/dhcpctl.c +++ b/dhcpctl/dhcpctl.c @@ -60,14 +60,18 @@ dhcpctl_status dhcpctl_initialize () dhcpctl_callback_get_value, dhcpctl_callback_destroy, dhcpctl_callback_signal_handler, - dhcpctl_callback_stuff_values, 0, 0, 0); + dhcpctl_callback_stuff_values, + 0, 0, 0, 0, 0, + sizeof (dhcpctl_callback_object_t)); omapi_object_type_register (&dhcpctl_remote_type, "dhcpctl-remote", dhcpctl_remote_set_value, dhcpctl_remote_get_value, dhcpctl_remote_destroy, dhcpctl_remote_signal_handler, - dhcpctl_remote_stuff_values, 0, 0, 0); + dhcpctl_remote_stuff_values, + 0, 0, 0, 0, 0, + sizeof (dhcpctl_remote_object_t)); return ISC_R_SUCCESS; } diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 01c98fb6e..14515ec59 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -453,6 +453,7 @@ struct group_object { struct group { struct group *next; + int refcnt; struct group_object *object; struct subnet *subnet; struct shared_network *shared_network; @@ -514,7 +515,7 @@ struct pool { struct shared_network { OMAPI_OBJECT_PREAMBLE; struct shared_network *next; - const char *name; + char *name; struct subnet *subnets; struct interface_info *interface; struct pool *pools; @@ -944,7 +945,6 @@ int nwip_option_space_encapsulate PROTO ((struct data_string *, /* dhcpd.c */ extern TIME cur_time; -extern struct group root_group; extern const char *path_dhcpd_conf; extern const char *path_dhcpd_db; @@ -956,6 +956,7 @@ int main PROTO ((int, char **, char **)); void cleanup PROTO ((void)); void lease_pinged PROTO ((struct iaddr, u_int8_t *, int)); void lease_ping_timeout PROTO ((void *)); +int dhcpd_interface_setup_hook (struct interface_info *ip, struct iaddr *ia); /* conflex.c */ isc_result_t new_parse PROTO ((struct parse **, int, @@ -966,6 +967,7 @@ enum dhcp_token peek_token PROTO ((const char **, struct parse *)); /* confpars.c */ isc_result_t readconf PROTO ((void)); +isc_result_t parse_conf_file (const char *, struct group *, int); isc_result_t read_leases PROTO ((void)); int parse_statement PROTO ((struct parse *, struct group *, int, struct host_decl *, int)); @@ -980,15 +982,15 @@ void parse_pool_statement PROTO ((struct parse *, struct group *, int)); int parse_boolean PROTO ((struct parse *)); int parse_lbrace PROTO ((struct parse *)); void parse_host_declaration PROTO ((struct parse *, struct group *)); -struct class *parse_class_declaration PROTO ((struct parse *, - struct group *, int)); +int parse_class_declaration PROTO ((struct class **, struct parse *, + struct group *, int)); void parse_shared_net_declaration PROTO ((struct parse *, struct group *)); void parse_subnet_declaration PROTO ((struct parse *, struct shared_network *)); void parse_group_declaration PROTO ((struct parse *, struct group *)); int parse_fixed_addr_param PROTO ((struct option_cache **, struct parse *)); TIME parse_timestamp PROTO ((struct parse *)); -struct lease *parse_lease_declaration PROTO ((struct parse *)); +int parse_lease_declaration PROTO ((struct lease **, struct parse *)); void parse_address_range PROTO ((struct parse *, struct group *, int, struct pool *)); @@ -1147,15 +1149,15 @@ void nak_lease PROTO ((struct packet *, struct iaddr *cip)); void ack_lease PROTO ((struct packet *, struct lease *, unsigned int, TIME, char *, int)); void dhcp_reply PROTO ((struct lease *)); -struct lease *find_lease PROTO ((struct packet *, - struct shared_network *, int *)); -struct lease *mockup_lease PROTO ((struct packet *, - struct shared_network *, - struct host_decl *)); +int find_lease PROTO ((struct lease **, struct packet *, + struct shared_network *, int *, const char *, int)); +int mockup_lease PROTO ((struct lease **, struct packet *, + struct shared_network *, + struct host_decl *)); void static_lease_dereference PROTO ((struct lease *, const char *, int)); -struct lease *allocate_lease PROTO ((struct packet *, - struct pool *, int, int *)); +int allocate_lease PROTO ((struct lease **, struct packet *, + struct pool *, int *)); int permitted PROTO ((struct packet *, struct permit *)); int locate_network PROTO ((struct packet *)); int parse_agent_information_option PROTO ((struct packet *, int, u_int8_t *)); @@ -1167,24 +1169,42 @@ unsigned cons_agent_information_options PROTO ((struct option_state *, void bootp PROTO ((struct packet *)); /* memory.c */ -struct group *clone_group PROTO ((struct group *, const char *, int)); +int (*group_write_hook) (struct group_object *); +extern struct group *root_group; +extern struct hash_table *group_name_hash; +isc_result_t delete_group (struct group_object *, int); +isc_result_t supersede_group (struct group_object *, int); +int clone_group (struct group **, struct group *, const char *, int); +int write_group PROTO ((struct group_object *)); + +/* salloc.c */ +struct lease *new_leases PROTO ((unsigned, const char *, int)); +OMAPI_OBJECT_ALLOC_DECL (lease, struct lease, dhcp_type_lease) +OMAPI_OBJECT_ALLOC_DECL (class, struct class, dhcp_type_class) +OMAPI_OBJECT_ALLOC_DECL (pool, struct pool, dhcp_type_pool) +OMAPI_OBJECT_ALLOC_DECL (host, struct host_decl, dhcp_type_host); /* alloc.c */ +OMAPI_OBJECT_ALLOC_DECL (subnet, struct subnet, dhcp_type_subnet) +OMAPI_OBJECT_ALLOC_DECL (shared_network, struct shared_network, + dhcp_type_shared_network) +OMAPI_OBJECT_ALLOC_DECL (group_object, struct group_object, dhcp_type_group) + +int group_allocate (struct group **, const char *, int); +int group_reference (struct group **, struct group *, const char *, int); +int group_dereference (struct group **, const char *, int); struct dhcp_packet *new_dhcp_packet PROTO ((const char *, int)); struct hash_table *new_hash_table PROTO ((int, const char *, int)); struct hash_bucket *new_hash_bucket PROTO ((const char *, int)); -struct lease *new_lease PROTO ((const char *, int)); -struct lease *new_leases PROTO ((unsigned, const char *, int)); -struct subnet *new_subnet PROTO ((const char *, int)); -struct class *new_class PROTO ((const char *, int)); -struct shared_network *new_shared_network PROTO ((const char *, int)); -struct group *new_group PROTO ((const char *, int)); struct protocol *new_protocol PROTO ((const char *, int)); struct lease_state *new_lease_state PROTO ((const char *, int)); struct domain_search_list *new_domain_search_list PROTO ((const char *, int)); struct name_server *new_name_server PROTO ((const char *, int)); void free_name_server PROTO ((struct name_server *, const char *, int)); struct option *new_option PROTO ((const char *, int)); +int group_allocate (struct group **, const char *, int); +int group_reference (struct group **, struct group *, const char *, int); +int group_dereference (struct group **, const char *, int); void free_option PROTO ((struct option *, const char *, int)); struct universe *new_universe PROTO ((const char *, int)); void free_universe PROTO ((struct universe *, const char *, int)); @@ -1192,18 +1212,11 @@ void free_domain_search_list PROTO ((struct domain_search_list *, const char *, int)); void free_lease_state PROTO ((struct lease_state *, const char *, int)); void free_protocol PROTO ((struct protocol *, const char *, int)); -void free_group PROTO ((struct group *, const char *, int)); -void free_shared_network PROTO ((struct shared_network *, const char *, int)); -void free_class PROTO ((struct class *, const char *, int)); -void free_subnet PROTO ((struct subnet *, const char *, int)); -void free_lease PROTO ((struct lease *, const char *, int)); void free_hash_bucket PROTO ((struct hash_bucket *, const char *, int)); void free_hash_table PROTO ((struct hash_table *, const char *, int)); void free_dhcp_packet PROTO ((struct dhcp_packet *, const char *, int)); struct client_lease *new_client_lease PROTO ((const char *, int)); void free_client_lease PROTO ((struct client_lease *, const char *, int)); -struct pool *new_pool PROTO ((const char *, int)); -void free_pool PROTO ((struct pool *, const char *, int)); struct auth_key *new_auth_key PROTO ((unsigned, const char *, int)); void free_auth_key PROTO ((struct auth_key *, const char *, int)); struct permit *new_permit PROTO ((const char *, int)); @@ -1463,6 +1476,9 @@ extern struct in_addr local_address; extern u_int16_t local_port; extern u_int16_t remote_port; +extern int (*dhcp_interface_setup_hook) (struct interface_info *, + struct iaddr *); +extern int (*dhcp_interface_discovery_hook) (struct interface_info *); extern void (*bootp_packet_handler) PROTO ((struct interface_info *, struct dhcp_packet *, unsigned, @@ -1471,7 +1487,7 @@ extern void (*bootp_packet_handler) PROTO ((struct interface_info *, extern struct timeout *timeouts; extern omapi_object_type_t *dhcp_type_interface; void discover_interfaces PROTO ((int)); -struct interface_info *setup_fallback PROTO ((void)); +int setup_fallback (struct interface_info **, const char *, int); int if_readsocket PROTO ((omapi_object_t *)); void reinitialize_interfaces PROTO ((void)); void dispatch PROTO ((void)); @@ -1495,16 +1511,22 @@ struct protocol *add_protocol PROTO ((const char *, int, void *)); void remove_protocol PROTO ((struct protocol *)); +OMAPI_OBJECT_ALLOC_DECL (interface, + struct interface_info, dhcp_type_interface); /* hash.c */ struct hash_table *new_hash PROTO ((hash_reference, hash_dereference, int)); void add_hash PROTO ((struct hash_table *, - const unsigned char *, unsigned, void *)); -void delete_hash_entry PROTO ((struct hash_table *, - const unsigned char *, unsigned)); -void *hash_lookup PROTO ((struct hash_table *, - const unsigned char *, unsigned)); + const unsigned char *, unsigned, hashed_object_t *, + const char *, int)); +void delete_hash_entry PROTO ((struct hash_table *, const unsigned char *, + unsigned, const char *, int)); +int hash_lookup PROTO ((hashed_object_t **, struct hash_table *, + const unsigned char *, unsigned, const char *, int)); int casecmp (const void *s, const void *t, unsigned len); +HASH_FUNCTIONS_DECL (group, const char *, struct group_object) +HASH_FUNCTIONS_DECL (universe, const char *, struct universe) +HASH_FUNCTIONS_DECL (option, const char *, struct option) /* tables.c */ extern struct universe dhcp_universe; @@ -1610,11 +1632,12 @@ void go_daemon PROTO ((void)); void write_client_pid_file PROTO ((void)); void client_location_changed PROTO ((void)); void do_release PROTO ((struct client_state *)); +int dhclient_interface_shutdown_hook (struct interface_info *); +int dhclient_interface_discovery_hook (struct interface_info *); /* db.c */ int write_lease PROTO ((struct lease *)); int write_host PROTO ((struct host_decl *)); -int write_group PROTO ((struct group_object *)); #if defined (FAILOVER_PROTOCOL) int write_failover_state (dhcp_failover_state_t *); #endif @@ -1624,6 +1647,7 @@ int write_billing_class PROTO ((struct class *)); int commit_leases PROTO ((void)); void db_startup PROTO ((int)); void new_lease_file PROTO ((void)); +int group_writer (struct group_object *); /* packet.c */ u_int32_t checksum PROTO ((unsigned char *, unsigned, u_int32_t)); @@ -1700,7 +1724,7 @@ int parse_X PROTO ((struct parse *, u_int8_t *, unsigned)); void parse_option_list PROTO ((struct parse *, u_int32_t **)); void parse_interface_declaration PROTO ((struct parse *, struct client_config *, char *)); -struct interface_info *interface_or_dummy PROTO ((const char *)); +int interface_or_dummy PROTO ((struct interface_info **, const char *)); void make_client_state PROTO ((struct client_state **)); void make_client_config PROTO ((struct client_state *, struct client_config *)); @@ -1750,6 +1774,8 @@ int find_cached_zone (const char *, ns_class, char *, void forget_zone (struct dns_zone **); void repudiate_zone (struct dns_zone **); #endif /* NSUPDATE */ +HASH_FUNCTIONS_DECL (dns_zone, const char *, struct dns_zone) +HASH_FUNCTIONS_DECL (tsig_key, const char *, struct tsig_key) /* resolv.c */ extern char path_resolv_conf []; @@ -1777,7 +1803,8 @@ void classify_client PROTO ((struct packet *)); int check_collection PROTO ((struct packet *, struct lease *, struct collection *)); void classify PROTO ((struct packet *, struct class *)); -struct class *find_class PROTO ((const char *)); +isc_result_t find_class PROTO ((struct class **, const char *, + const char *, int)); int unbill_class PROTO ((struct lease *, struct class *)); int bill_class PROTO ((struct lease *, struct class *)); @@ -1808,13 +1835,78 @@ struct executable_statement *find_matching_case PROTO ((struct packet *, void enter_auth_key PROTO ((struct data_string *, struct auth_key *)); const struct auth_key *auth_key_lookup PROTO ((struct data_string *)); -/* omapi.c */ +/* comapi.c */ extern omapi_object_type_t *dhcp_type_interface; -extern omapi_object_type_t *dhcp_type_lease; extern omapi_object_type_t *dhcp_type_group; -extern omapi_object_type_t *dhcp_type_pool; extern omapi_object_type_t *dhcp_type_shared_network; extern omapi_object_type_t *dhcp_type_subnet; + +void dhcp_common_objects_setup (void); + +isc_result_t dhcp_group_set_value (omapi_object_t *, omapi_object_t *, + omapi_data_string_t *, + omapi_typed_data_t *); +isc_result_t dhcp_group_get_value (omapi_object_t *, omapi_object_t *, + omapi_data_string_t *, + omapi_value_t **); +isc_result_t dhcp_group_destroy (omapi_object_t *, const char *, int); +isc_result_t dhcp_group_signal_handler (omapi_object_t *, + const char *, va_list); +isc_result_t dhcp_group_stuff_values (omapi_object_t *, + omapi_object_t *, + omapi_object_t *); +isc_result_t dhcp_group_lookup (omapi_object_t **, + omapi_object_t *, omapi_object_t *); +isc_result_t dhcp_group_create (omapi_object_t **, + omapi_object_t *); +isc_result_t dhcp_group_remove (omapi_object_t *, + omapi_object_t *); + +isc_result_t dhcp_subnet_set_value (omapi_object_t *, omapi_object_t *, + omapi_data_string_t *, + omapi_typed_data_t *); +isc_result_t dhcp_subnet_get_value (omapi_object_t *, omapi_object_t *, + omapi_data_string_t *, + omapi_value_t **); +isc_result_t dhcp_subnet_destroy (omapi_object_t *, const char *, int); +isc_result_t dhcp_subnet_signal_handler (omapi_object_t *, + const char *, va_list); +isc_result_t dhcp_subnet_stuff_values (omapi_object_t *, + omapi_object_t *, + omapi_object_t *); +isc_result_t dhcp_subnet_lookup (omapi_object_t **, + omapi_object_t *, omapi_object_t *); +isc_result_t dhcp_subnet_create (omapi_object_t **, + omapi_object_t *); +isc_result_t dhcp_subnet_remove (omapi_object_t *, + omapi_object_t *); + +isc_result_t dhcp_shared_network_set_value (omapi_object_t *, + omapi_object_t *, + omapi_data_string_t *, + omapi_typed_data_t *); +isc_result_t dhcp_shared_network_get_value (omapi_object_t *, + omapi_object_t *, + omapi_data_string_t *, + omapi_value_t **); +isc_result_t dhcp_shared_network_destroy (omapi_object_t *, const char *, int); +isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *, + const char *, va_list); +isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *, + omapi_object_t *, + omapi_object_t *); +isc_result_t dhcp_shared_network_lookup (omapi_object_t **, + omapi_object_t *, omapi_object_t *); +isc_result_t dhcp_shared_network_create (omapi_object_t **, + omapi_object_t *); +isc_result_t dhcp_shared_network_remove (omapi_object_t *, + omapi_object_t *); + +/* omapi.c */ +extern int (*dhcp_interface_shutdown_hook) (struct interface_info *); + +extern omapi_object_type_t *dhcp_type_lease; +extern omapi_object_type_t *dhcp_type_pool; extern omapi_object_type_t *dhcp_type_class; #if defined (FAILOVER_PROTOCOL) @@ -1897,6 +1989,24 @@ isc_result_t dhcp_pool_create (omapi_object_t **, omapi_object_t *); isc_result_t dhcp_pool_remove (omapi_object_t *, omapi_object_t *); +isc_result_t dhcp_class_set_value (omapi_object_t *, omapi_object_t *, + omapi_data_string_t *, + omapi_typed_data_t *); +isc_result_t dhcp_class_get_value (omapi_object_t *, omapi_object_t *, + omapi_data_string_t *, + omapi_value_t **); +isc_result_t dhcp_class_destroy (omapi_object_t *, const char *, int); +isc_result_t dhcp_class_signal_handler (omapi_object_t *, + const char *, va_list); +isc_result_t dhcp_class_stuff_values (omapi_object_t *, + omapi_object_t *, + omapi_object_t *); +isc_result_t dhcp_class_lookup (omapi_object_t **, + omapi_object_t *, omapi_object_t *); +isc_result_t dhcp_class_create (omapi_object_t **, + omapi_object_t *); +isc_result_t dhcp_class_remove (omapi_object_t *, + omapi_object_t *); isc_result_t dhcp_shared_network_set_value (omapi_object_t *, omapi_object_t *, omapi_data_string_t *, @@ -1946,6 +2056,29 @@ isc_result_t dhcp_class_lookup (omapi_object_t **, omapi_object_t *, omapi_object_t *); isc_result_t dhcp_class_create (omapi_object_t **, omapi_object_t *); +isc_result_t dhcp_interface_set_value (omapi_object_t *, + omapi_object_t *, + omapi_data_string_t *, + omapi_typed_data_t *); +isc_result_t dhcp_interface_get_value (omapi_object_t *, + omapi_object_t *, + omapi_data_string_t *, + omapi_value_t **); +isc_result_t dhcp_interface_destroy (omapi_object_t *, + const char *, int); +isc_result_t dhcp_interface_signal_handler (omapi_object_t *, + const char *, + va_list ap); +isc_result_t dhcp_interface_stuff_values (omapi_object_t *, + omapi_object_t *, + omapi_object_t *); +isc_result_t dhcp_interface_lookup (omapi_object_t **, + omapi_object_t *, + omapi_object_t *); +isc_result_t dhcp_interface_create (omapi_object_t **, + omapi_object_t *); +isc_result_t dhcp_interface_remove (omapi_object_t *, + omapi_object_t *); /* mdb.c */ @@ -1957,26 +2090,24 @@ extern struct hash_table *host_name_hash; extern struct hash_table *lease_uid_hash; extern struct hash_table *lease_ip_addr_hash; extern struct hash_table *lease_hw_addr_hash; -extern struct hash_table *group_name_hash; extern omapi_object_type_t *dhcp_type_host; - isc_result_t enter_host PROTO ((struct host_decl *, int, int)); isc_result_t delete_host PROTO ((struct host_decl *, int)); -struct host_decl *find_hosts_by_haddr PROTO ((int, const unsigned char *, - unsigned)); -struct host_decl *find_hosts_by_uid PROTO ((const unsigned char *, unsigned)); -struct subnet *find_host_for_network PROTO ((struct host_decl **, - struct iaddr *, - struct shared_network *)); -isc_result_t delete_group (struct group_object *, int); -isc_result_t supersede_group (struct group_object *, int); +int find_hosts_by_haddr PROTO ((struct host_decl **, int, + const unsigned char *, unsigned, + const char *, int)); +int find_hosts_by_uid PROTO ((struct host_decl **, const unsigned char *, + unsigned, const char *, int)); +int find_host_for_network PROTO ((struct subnet **, struct host_decl **, + struct iaddr *, struct shared_network *)); void new_address_range PROTO ((struct iaddr, struct iaddr, struct subnet *, struct pool *)); -extern struct subnet *find_grouped_subnet PROTO ((struct shared_network *, - struct iaddr)); -extern struct subnet *find_subnet PROTO ((struct iaddr)); +isc_result_t dhcp_lease_free (omapi_object_t *, const char *, int); +int find_grouped_subnet PROTO ((struct subnet **, struct shared_network *, + struct iaddr, const char *, int)); +int find_subnet (struct subnet **, struct iaddr, const char *, int); void enter_shared_network PROTO ((struct shared_network *)); void new_shared_network_interface PROTO ((struct parse *, struct shared_network *, @@ -1985,13 +2116,17 @@ int subnet_inner_than PROTO ((struct subnet *, struct subnet *, int)); void enter_subnet PROTO ((struct subnet *)); void enter_lease PROTO ((struct lease *)); int supersede_lease PROTO ((struct lease *, struct lease *, int, int)); +int lease_copy PROTO ((struct lease **, struct lease *, const char *, int)); void release_lease PROTO ((struct lease *, struct packet *)); void abandon_lease PROTO ((struct lease *, const char *)); void dissociate_lease PROTO ((struct lease *)); void pool_timer PROTO ((void *)); -struct lease *find_lease_by_uid PROTO ((const unsigned char *, unsigned)); -struct lease *find_lease_by_hw_addr PROTO ((const unsigned char *, unsigned)); -struct lease *find_lease_by_ip_addr PROTO ((struct iaddr)); +int find_lease_by_uid PROTO ((struct lease **, const unsigned char *, + unsigned, const char *, int)); +int find_lease_by_hw_addr PROTO ((struct lease **, const unsigned char *, + unsigned, const char *, int)); +int find_lease_by_ip_addr PROTO ((struct lease **, struct iaddr, + const char *, int)); void uid_hash_add PROTO ((struct lease *)); void uid_hash_delete PROTO ((struct lease *)); void hw_hash_add PROTO ((struct lease *)); @@ -1999,6 +2134,9 @@ void hw_hash_delete PROTO ((struct lease *)); void write_leases PROTO ((void)); void expire_all_pools PROTO ((void)); void dump_subnets PROTO ((void)); +HASH_FUNCTIONS_DECL (lease, const unsigned char *, struct lease) +HASH_FUNCTIONS_DECL (host, const unsigned char *, struct host_decl) +HASH_FUNCTIONS_DECL (class, const char *, struct class) /* nsupdate.c */ char *ddns_rev_name (struct lease *, struct lease_state *, struct packet *); @@ -2021,7 +2159,7 @@ void dhcp_failover_startup PROTO ((void)); void dhcp_failover_write_all_states (void); isc_result_t enter_failover_peer PROTO ((dhcp_failover_state_t *)); isc_result_t find_failover_peer PROTO ((dhcp_failover_state_t **, - const char *)); + const char *, const char *, int)); isc_result_t dhcp_failover_link_initiate PROTO ((omapi_object_t *)); isc_result_t dhcp_failover_link_signal PROTO ((omapi_object_t *, const char *, va_list)); @@ -2123,30 +2261,10 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *, void failover_print PROTO ((char *, unsigned *, unsigned, const char *)); void update_partner PROTO ((struct lease *)); int load_balance_mine (struct packet *, dhcp_failover_state_t *); +OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_state, dhcp_failover_state_t, + dhcp_type_failover_state) +OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_listener, dhcp_failover_listener_t, + dhcp_type_failover_listener) +OMAPI_OBJECT_ALLOC_DECL (dhcp_failover_link, dhcp_failover_link_t, + dhcp_type_failover_listener) #endif /* FAILOVER_PROTOCOL */ - -/* client/omapi.c */ -void dhclient_db_objects_setup PROTO ((void)); -isc_result_t dhclient_interface_set_value (omapi_object_t *, - omapi_object_t *, - omapi_data_string_t *, - omapi_typed_data_t *); -isc_result_t dhclient_interface_get_value (omapi_object_t *, - omapi_object_t *, - omapi_data_string_t *, - omapi_value_t **); -isc_result_t dhclient_interface_destroy (omapi_object_t *, - const char *, int); -isc_result_t dhclient_interface_signal_handler (omapi_object_t *, - const char *, - va_list ap); -isc_result_t dhclient_interface_stuff_values (omapi_object_t *, - omapi_object_t *, - omapi_object_t *); -isc_result_t dhclient_interface_lookup (omapi_object_t **, - omapi_object_t *, - omapi_object_t *); -isc_result_t dhclient_interface_create (omapi_object_t **, - omapi_object_t *); -isc_result_t dhclient_interface_remove (omapi_object_t *, - omapi_object_t *); diff --git a/includes/dhctoken.h b/includes/dhctoken.h index 41f86b229..3ed475192 100644 --- a/includes/dhctoken.h +++ b/includes/dhctoken.h @@ -267,7 +267,8 @@ enum dhcp_token { POTENTIAL_CONFLICT_NIC = 465, STATE = 466, UNKNOWN_STATE = 567, - CLTT = 568 + CLTT = 568, + INCLUDE = 569 }; #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/includes/failover.h b/includes/failover.h index 8617cdb36..9105a2104 100644 --- a/includes/failover.h +++ b/includes/failover.h @@ -261,8 +261,8 @@ typedef struct _dhcp_failover_state { enum failover_state my_state; TIME my_stos; - omapi_object_t *link_to_peer; /* Currently-established link - to peer. */ + dhcp_failover_link_t *link_to_peer; /* Currently-established link + to peer. */ enum { primary, secondary diff --git a/includes/hash.h b/includes/hash.h index 5ad37c11b..e780ce1d8 100644 --- a/includes/hash.h +++ b/includes/hash.h @@ -43,14 +43,20 @@ #define DEFAULT_HASH_SIZE 97 -typedef int (*hash_reference) (void *, void *, const char *, int); -typedef int (*hash_dereference) (void *, const char *, int); +/* The purpose of the hashed_object_t struct is to not match anything else. */ +typedef struct { + int foo; +} hashed_object_t; + +typedef int (*hash_reference) (hashed_object_t **, hashed_object_t *, + const char *, int); +typedef int (*hash_dereference) (hashed_object_t **, const char *, int); struct hash_bucket { struct hash_bucket *next; const unsigned char *name; unsigned len; - void *value; + hashed_object_t *value; }; typedef int (*hash_comparator_t)(const void *, const void *, size_t); @@ -69,3 +75,37 @@ struct named_hash { const char *name; struct hash_table *hash; }; + +#define HASH_FUNCTIONS_DECL(name, bufarg, type) \ +void name##_hash_add (struct hash_table *, bufarg, unsigned, type *, \ + const char *, int); \ +void name##_hash_delete (struct hash_table *, bufarg, unsigned, \ + const char *, int); \ +int name##_hash_lookup (type **, struct hash_table *, bufarg, unsigned, \ + const char *, int); + +#define HASH_FUNCTIONS(name, bufarg, type) \ +void name##_hash_add (struct hash_table *table, \ + bufarg buf, unsigned len, type *ptr, \ + const char *file, int line) \ +{ \ + add_hash (table, \ + (const unsigned char *)buf, \ + len, (hashed_object_t *)ptr, file, line); \ +} \ + \ +void name##_hash_delete (struct hash_table *table, \ + bufarg buf, unsigned len, const char *file, int line)\ +{ \ + delete_hash_entry (table, (const unsigned char *)buf, \ + len, file, line); \ +} \ + \ +int name##_hash_lookup (type **ptr, struct hash_table *table, \ + bufarg buf, unsigned len, const char *file, int line) \ +{ \ + return hash_lookup ((hashed_object_t **)ptr, table, \ + (const unsigned char *)buf, len, file, line); \ +} + + diff --git a/includes/omapip/omapip.h b/includes/omapip/omapip.h index bc48f181d..289bb2734 100644 --- a/includes/omapip/omapip.h +++ b/includes/omapip/omapip.h @@ -121,6 +121,9 @@ typedef struct __omapi_object_type_t { omapi_object_t *); isc_result_t (*create) (omapi_object_t **, omapi_object_t *); isc_result_t (*remove) (omapi_object_t *, omapi_object_t *); + isc_result_t (*freer) (omapi_object_t *, const char *, int); + isc_result_t (*sizer) (size_t); + size_t size; } omapi_object_type_t; #define OMAPI_OBJECT_PREAMBLE \ @@ -150,6 +153,31 @@ typedef struct { omapi_addr_t *addresses; } omapi_addr_list_t; +#define OMAPI_OBJECT_ALLOC(name, stype, type) \ +isc_result_t name##_allocate (stype **p, const char *file, int line) \ +{ \ + return omapi_object_allocate ((omapi_object_t **)p, \ + type, 0, file, line); \ +} \ + \ +isc_result_t name##_reference (stype **pptr, stype *ptr, \ + const char *file, int line) \ +{ \ + return omapi_object_reference ((omapi_object_t **)pptr, \ + (omapi_object_t *)ptr, file, line); \ +} \ + \ +isc_result_t name##_dereference (stype **ptr, const char *file, int line) \ +{ \ + return omapi_object_dereference ((omapi_object_t **)ptr, file, line); \ +} + +#define OMAPI_OBJECT_ALLOC_DECL(name, stype, type) \ +isc_result_t name##_allocate (stype **p, const char *file, int line); \ +isc_result_t name##_reference (stype **pptr, stype *ptr, \ + const char *file, int line); \ +isc_result_t name##_dereference (stype **ptr, const char *file, int line); + isc_result_t omapi_protocol_connect (omapi_object_t *, const char *, unsigned, omapi_object_t *); isc_result_t omapi_connect_list (omapi_object_t *, omapi_addr_list_t *, @@ -222,7 +250,6 @@ isc_result_t omapi_connection_put_string (omapi_object_t *, const char *); isc_result_t omapi_connection_put_handle (omapi_object_t *c, omapi_object_t *h); - isc_result_t omapi_listen (omapi_object_t *, unsigned, int); isc_result_t omapi_listen_addr (omapi_object_t *, omapi_addr_t *, int); @@ -335,7 +362,10 @@ isc_result_t omapi_object_type_register (omapi_object_type_t **, isc_result_t (*) (omapi_object_t **, omapi_object_t *), isc_result_t (*) (omapi_object_t *, - omapi_object_t *)); + omapi_object_t *), + isc_result_t (*) (omapi_object_t *, + const char *, int), + isc_result_t (*) (size_t), size_t); isc_result_t omapi_signal (omapi_object_t *, const char *, ...); isc_result_t omapi_signal_in (omapi_object_t *, const char *, ...); isc_result_t omapi_set_value (omapi_object_t *, omapi_object_t *, @@ -385,6 +415,24 @@ isc_result_t omapi_object_handle (omapi_handle_t *, omapi_object_t *); isc_result_t omapi_handle_lookup (omapi_object_t **, omapi_handle_t); isc_result_t omapi_handle_td_lookup (omapi_object_t **, omapi_typed_data_t *); +void * dmalloc (unsigned, const char *, int); +void dfree (void *, const char *, int); +#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) +void dmalloc_reuse (void *, const char *, int, int); +void dmalloc_dump_outstanding (void); +#else +#define dmalloc_reuse(x,y,l,z) +#endif +#define MDL __FILE__, __LINE__ +#if defined (DEBUG_RC_HISTORY) +void dump_rc_history (void); +#endif +isc_result_t omapi_object_allocate (omapi_object_t **, + omapi_object_type_t *, + size_t, const char *, int); +isc_result_t omapi_object_initialize (omapi_object_t *, + omapi_object_type_t *, + size_t, size_t, const char *, int); isc_result_t omapi_object_reference (omapi_object_t **, omapi_object_t *, const char *, int); isc_result_t omapi_object_dereference (omapi_object_t **, const char *, int); @@ -414,16 +462,4 @@ isc_result_t omapi_addr_list_reference (omapi_addr_list_t **, isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **, const char *, int); -void * dmalloc (unsigned, const char *, int); -void dfree (void *, const char *, int); -#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) -void dmalloc_reuse (void *, const char *, int, int); -void dmalloc_dump_outstanding (void); -#else -#define dmalloc_reuse(x,y,l,z) -#endif -#define MDL __FILE__, __LINE__ -#if defined (DEBUG_RC_HISTORY) -void dump_rc_history (void); -#endif #endif /* _OMAPIP_H_ */ diff --git a/includes/omapip/omapip_p.h b/includes/omapip/omapip_p.h index 5fd64cf4a..cb9b995ea 100644 --- a/includes/omapip/omapip_p.h +++ b/includes/omapip/omapip_p.h @@ -3,7 +3,7 @@ Private master include file for the OMAPI library. */ /* - * Copyright (c) 1996-1999 Internet Software Consortium. + * Copyright (c) 1996-2000 Internet Software Consortium. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -146,6 +146,12 @@ typedef struct { #include +typedef struct __omapi_listener_object { + OMAPI_OBJECT_PREAMBLE; + int socket; /* Connection socket. */ + struct sockaddr_in address; +} omapi_listener_object_t; + typedef struct __omapi_connection_object { OMAPI_OBJECT_PREAMBLE; int socket; /* Connection socket. */ @@ -160,16 +166,10 @@ typedef struct __omapi_connection_object { omapi_buffer_t *inbufs; u_int32_t out_bytes; /* Bytes of output in buffers. */ omapi_buffer_t *outbufs; - omapi_object_t *listener; /* Listener that accepted this - connection, if any. */ + omapi_listener_object_t *listener; /* Listener that accepted this + connection, if any. */ } omapi_connection_object_t; -typedef struct __omapi_listener_object { - OMAPI_OBJECT_PREAMBLE; - int socket; /* Connection socket. */ - struct sockaddr_in address; -} omapi_listener_object_t; - typedef struct __omapi_io_object { OMAPI_OBJECT_PREAMBLE; struct __omapi_io_object *next; @@ -206,6 +206,24 @@ typedef struct __omapi_handle_table { #include +OMAPI_OBJECT_ALLOC_DECL (omapi_protocol, omapi_protocol_object_t, + omapi_type_protocol) +OMAPI_OBJECT_ALLOC_DECL (omapi_protocol_listener, + omapi_protocol_listener_object_t, + omapi_type_protocol_listener) +OMAPI_OBJECT_ALLOC_DECL (omapi_connection, + omapi_connection_object_t, omapi_type_connection) +OMAPI_OBJECT_ALLOC_DECL (omapi_listener, + omapi_listener_object_t, omapi_type_listener) +OMAPI_OBJECT_ALLOC_DECL (omapi_io, + omapi_io_object_t, omapi_type_io_object) +OMAPI_OBJECT_ALLOC_DECL (omapi_waiter, + omapi_waiter_object_t, omapi_type_waiter) +OMAPI_OBJECT_ALLOC_DECL (omapi_generic, + omapi_generic_object_t, omapi_type_generic) +OMAPI_OBJECT_ALLOC_DECL (omapi_message, + omapi_message_object_t, omapi_type_message) + extern int log_priority; extern int log_perror; extern void (*log_cleanup) (void); diff --git a/omapip/alloc.c b/omapip/alloc.c index 05f4a196b..88b114911 100644 --- a/omapip/alloc.c +++ b/omapip/alloc.c @@ -309,6 +309,47 @@ void dump_rc_history () } #endif +isc_result_t omapi_object_allocate (omapi_object_t **o, + omapi_object_type_t *type, + size_t size, + const char *file, int line) +{ + size_t tsize; + void *foo; + isc_result_t status; + + if (type -> sizer) + tsize = (*type -> sizer) (size); + else + tsize = type -> size; + + /* Sanity check. */ + if (tsize < sizeof (omapi_object_t)) + return ISC_R_INVALIDARG; + + foo = dmalloc (tsize, file, line); + if (!foo) + return ISC_R_NOMEMORY; + + status = omapi_object_initialize ((omapi_object_t *)foo, + type, size, tsize, file, line); + if (status != ISC_R_SUCCESS) { + dfree (foo, file, line); + return status; + } + return omapi_object_reference (o, (omapi_object_t *)foo, file, line); +} + +isc_result_t omapi_object_initialize (omapi_object_t *o, + omapi_object_type_t *type, + size_t usize, size_t psize, + const char *file, int line) +{ + memset (o, 0, psize); + o -> type = type; + return ISC_R_SUCCESS; +} + isc_result_t omapi_object_reference (omapi_object_t **r, omapi_object_t *h, const char *file, int line) diff --git a/omapip/connection.c b/omapip/connection.c index 194d30ee0..cdeeeb2bc 100644 --- a/omapip/connection.c +++ b/omapip/connection.c @@ -44,6 +44,9 @@ #include #include +OMAPI_OBJECT_ALLOC (omapi_connection, + omapi_connection_object_t, omapi_type_connection) + isc_result_t omapi_connect (omapi_object_t *c, const char *server_name, unsigned port) @@ -66,8 +69,9 @@ isc_result_t omapi_connect (omapi_object_t *c, return ISC_R_HOSTUNKNOWN; hix = i; - if (!omapi_addr_list_new (&addrs, hix, MDL)) - return ISC_R_NOMEMORY; + status = omapi_addr_list_new (&addrs, hix, MDL); + if (status != ISC_R_SUCCESS) + return status; for (i = 0; i < hix; i++) { addrs -> addresses [i].addrtype = he -> h_addrtype; addrs -> addresses [i].addrlen = he -> h_length; @@ -77,8 +81,9 @@ isc_result_t omapi_connect (omapi_object_t *c, addrs -> addresses [i].port = port; } } else { - if (!omapi_addr_list_new (&addrs, 1, MDL)) - return ISC_R_NOMEMORY; + status = omapi_addr_list_new (&addrs, 1, MDL); + if (status != ISC_R_SUCCESS) + return status; addrs -> addresses [0].addrtype = AF_INET; addrs -> addresses [0].addrlen = sizeof foo; memcpy (addrs -> addresses [0].address, &foo, sizeof foo); @@ -99,23 +104,20 @@ isc_result_t omapi_connect_list (omapi_object_t *c, int flag; struct sockaddr_in local_sin; - obj = (omapi_connection_object_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - rc_register_mdl (&obj, obj, obj -> refcnt); - obj -> type = omapi_type_connection; + obj = (omapi_connection_object_t *)0; + status = omapi_connection_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; status = omapi_object_reference (&c -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return status; } status = omapi_object_reference (&obj -> inner, c, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return status; } @@ -123,7 +125,7 @@ isc_result_t omapi_connect_list (omapi_object_t *c, obj -> socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (obj -> socket < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) return ISC_R_NORESOURCES; return ISC_R_UNEXPECTED; @@ -133,8 +135,7 @@ isc_result_t omapi_connect_list (omapi_object_t *c, if (local_addr) { /* Only do TCPv4 so far. */ if (local_addr -> addrtype != AF_INET) { - omapi_object_dereference ((omapi_object_t **)&obj, - MDL); + omapi_connection_dereference (&obj, MDL); return ISC_R_INVALIDARG; } local_sin.sin_port = htons (local_addr -> port); @@ -164,7 +165,7 @@ isc_result_t omapi_connect_list (omapi_object_t *c, #if defined (HAVE_SETFD) if (fcntl (obj -> socket, F_SETFD, 1) < 0) { close (obj -> socket); - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } #endif @@ -173,13 +174,13 @@ isc_result_t omapi_connect_list (omapi_object_t *c, flag = 1; if (setsockopt (obj -> socket, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof flag) < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } /* Set the file to nonblocking mode. */ if (fcntl (obj -> socket, F_SETFL, O_NONBLOCK) < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } @@ -195,7 +196,7 @@ isc_result_t omapi_connect_list (omapi_object_t *c, obj -> state = omapi_connection_unconnected; omapi_connection_connect ((omapi_object_t *)obj); - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return status; } @@ -441,7 +442,7 @@ isc_result_t omapi_connection_destroy (omapi_object_t *h, if (c -> state == omapi_connection_connected) omapi_disconnect (h, 1); if (c -> listener) - omapi_object_dereference (&c -> listener, file, line); + omapi_listener_dereference (&c -> listener, file, line); if (c -> connect_list) omapi_addr_list_dereference (&c -> connect_list, file, line); return ISC_R_SUCCESS; diff --git a/omapip/dispatch.c b/omapip/dispatch.c index 46e5fa4d8..ceecbe144 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -46,6 +46,11 @@ static omapi_io_object_t omapi_io_states; u_int32_t cur_time; +OMAPI_OBJECT_ALLOC (omapi_io, + omapi_io_object_t, omapi_type_io_object) +OMAPI_OBJECT_ALLOC (omapi_waiter, + omapi_waiter_object_t, omapi_type_waiter) + /* Register an I/O handle so that we can do asynchronous I/O on it. */ isc_result_t omapi_register_io_object (omapi_object_t *h, @@ -71,24 +76,21 @@ isc_result_t omapi_register_io_object (omapi_object_t *h, omapi_io_states.type = omapi_type_io_object; } - obj = dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - rc_register_mdl (&obj, obj, obj -> refcnt); - obj -> type = omapi_type_io_object; + obj = (omapi_io_object_t *)0; + status = omapi_io_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; status = omapi_object_reference (&obj -> inner, h, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_io_dereference (&obj, MDL); return status; } status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_io_dereference (&obj, MDL); return status; } @@ -97,12 +99,9 @@ isc_result_t omapi_register_io_object (omapi_object_t *h, p && p -> next; p = p -> next) ; if (p) - omapi_object_reference ((omapi_object_t **)&p -> next, - (omapi_object_t *)obj, MDL); + omapi_io_reference (&p -> next, obj, MDL); else - omapi_object_reference - ((omapi_object_t **)&omapi_io_states.next, - (omapi_object_t *)obj, MDL); + omapi_io_reference (&omapi_io_states.next, obj, MDL); obj -> readfd = readfd; obj -> writefd = writefd; @@ -114,29 +113,26 @@ isc_result_t omapi_register_io_object (omapi_object_t *h, isc_result_t omapi_unregister_io_object (omapi_object_t *h) { - omapi_io_object_t *p, *obj, *last; - omapi_object_t *ph; + omapi_io_object_t *p, *obj, *last, *ph; + if (!h -> outer || h -> outer -> type != omapi_type_io_object) + return ISC_R_INVALIDARG; obj = (omapi_io_object_t *)h -> outer; - ph = (omapi_object_t *)0; - omapi_object_reference (&ph, h -> outer, MDL); + ph = (omapi_io_object_t *)0; + omapi_io_reference (&ph, obj, MDL); /* remove from the list of I/O states */ for (p = omapi_io_states.next; p; p = p -> next) { - if ((omapi_object_t *)p == h -> outer) { - omapi_object_dereference ((omapi_object_t **) - &last -> next, MDL); - omapi_object_reference ((omapi_object_t **) - &last -> next, - (omapi_object_t *)p -> next, - MDL); + if (p == obj) { + omapi_io_dereference (&last -> next, MDL); + omapi_io_reference (&last -> next, p -> next, MDL); break; } last = p; } if (obj -> next) - omapi_object_dereference ((omapi_object_t **)&obj -> next, - MDL); + omapi_io_dereference (&obj -> next, MDL); + if (obj -> outer) { if (obj -> outer -> inner == (omapi_object_t *)obj) omapi_object_dereference (&obj -> outer -> inner, @@ -145,7 +141,7 @@ isc_result_t omapi_unregister_io_object (omapi_object_t *h) } omapi_object_dereference (&obj -> inner, MDL); omapi_object_dereference (&h -> outer, MDL); - omapi_object_dereference (&ph, MDL); + omapi_io_dereference (&ph, MDL); return ISC_R_SUCCESS; } @@ -163,13 +159,10 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, omapi_object_t *inner; if (object) { - waiter = dmalloc (sizeof *waiter, MDL); - if (!waiter) - return ISC_R_NOMEMORY; - memset (waiter, 0, sizeof *waiter); - waiter -> refcnt = 1; - rc_register_mdl (&waiter, waiter, waiter -> refcnt); - waiter -> type = omapi_type_waiter; + waiter = (omapi_waiter_object_t *)0; + status = omapi_waiter_allocate (&waiter, MDL); + if (status != ISC_R_SUCCESS) + return status; /* Paste the waiter object onto the inner object we're waiting on. */ @@ -178,8 +171,7 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, status = omapi_object_reference (&waiter -> outer, inner, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&waiter, - MDL); + omapi_waiter_dereference (&waiter, MDL); return status; } @@ -187,8 +179,7 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, (omapi_object_t *)waiter, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&waiter, - MDL); + omapi_waiter_dereference (&waiter, MDL); return status; } } else @@ -214,7 +205,7 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object, if (waiter -> inner) omapi_object_dereference (&waiter -> inner, MDL); - omapi_object_dereference ((omapi_object_t **)&waiter, MDL); + omapi_waiter_dereference (&waiter, MDL); return ISC_R_SUCCESS; } @@ -334,31 +325,22 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, /* Save a reference to the next pointer, if there is one. */ if (io -> next) - omapi_object_reference - ((omapi_object_t **)&tmp, - (omapi_object_t *)io -> next, - MDL); + omapi_io_reference (&tmp, + io -> next, MDL); if (prev) { - omapi_object_dereference - (((omapi_object_t **) - &prev -> next), MDL); + omapi_io_dereference (&prev -> next, + MDL); if (tmp) - omapi_object_reference - (((omapi_object_t **) - &prev -> next), - (omapi_object_t *)tmp, - MDL); + omapi_io_reference + (&prev -> next, + tmp, MDL); } else { - omapi_object_dereference - (((omapi_object_t **) - &omapi_io_states.next), - MDL); + omapi_io_dereference + (&omapi_io_states.next, MDL); if (tmp) - omapi_object_reference - (((omapi_object_t **) - &omapi_io_states.next), - (omapi_object_t *)tmp, - MDL); + omapi_io_reference + (&omapi_io_states.next, + tmp, MDL); else omapi_signal_in ((omapi_object_t *) @@ -366,8 +348,7 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, "ready"); } if (tmp) - omapi_object_dereference - ((omapi_object_t **)&tmp, MDL); + omapi_io_dereference (&tmp, MDL); } } prev = io; @@ -416,13 +397,9 @@ isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line) /* remove from the list of I/O states */ for (p = omapi_io_states.next; p; p = p -> next) { if (p == obj) { - omapi_object_dereference ((omapi_object_t **) - &last -> next, MDL); - omapi_object_reference ((omapi_object_t **) - &last -> next, - (omapi_object_t *)p -> next, - MDL); - omapi_object_dereference ((omapi_object_t **)&p, MDL); + omapi_io_dereference (&last -> next, MDL); + omapi_io_reference (&last -> next, p -> next, MDL); + omapi_io_dereference (&p, MDL); break; } last = p; diff --git a/omapip/generic.c b/omapip/generic.c index 9832e855c..a056798f9 100644 --- a/omapip/generic.c +++ b/omapip/generic.c @@ -43,19 +43,15 @@ #include +OMAPI_OBJECT_ALLOC (omapi_generic, + omapi_generic_object_t, omapi_type_generic) + isc_result_t omapi_generic_new (omapi_object_t **gen, const char *file, int line) { - omapi_generic_object_t *obj; - - obj = dmalloc (sizeof *obj, file, line); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 0; - obj -> type = omapi_type_generic; - - return omapi_object_reference (gen, (omapi_object_t *)obj, file, line); + /* Backwards compatibility. */ + return omapi_generic_allocate ((omapi_generic_object_t **)gen, + file, line); } isc_result_t omapi_generic_set_value (omapi_object_t *h, diff --git a/omapip/listener.c b/omapip/listener.c index e059567c5..23c6250f7 100644 --- a/omapip/listener.c +++ b/omapip/listener.c @@ -43,6 +43,9 @@ #include +OMAPI_OBJECT_ALLOC (omapi_listener, + omapi_listener_object_t, omapi_type_listener) + isc_result_t omapi_listen (omapi_object_t *h, unsigned port, int max) @@ -68,24 +71,21 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, struct in_addr ia; /* Get the handle. */ - obj = (omapi_listener_object_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - rc_register_mdl (&obj, obj, obj -> refcnt); - obj -> type = omapi_type_listener; + obj = (omapi_listener_object_t *)0; + status = omapi_listener_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; /* Connect this object to the inner object. */ status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); return status; } status = omapi_object_reference (&obj -> inner, h, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); return status; } @@ -108,7 +108,7 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, /* Create a socket on which to listen. */ obj -> socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (!obj -> socket) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) return ISC_R_NORESOURCES; return ISC_R_UNEXPECTED; @@ -117,7 +117,7 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, #if defined (HAVE_SETFD) if (fcntl (obj -> socket, F_SETFD, 1) < 0) { close (obj -> socket); - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } #endif @@ -127,7 +127,7 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, i = bind (obj -> socket, (struct sockaddr *)&obj -> address, sizeof obj -> address); if (i < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); if (errno == EADDRINUSE) return ISC_R_ADDRNOTAVAIL; if (errno == EPERM) @@ -137,24 +137,20 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, /* Now tell the kernel to listen for connections. */ if (listen (obj -> socket, max)) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } if (fcntl (obj -> socket, F_SETFL, O_NONBLOCK) < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_listener_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } status = omapi_register_io_object ((omapi_object_t *)obj, omapi_listener_readfd, 0, omapi_accept, 0, 0); - if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); - return status; - } - - return ISC_R_SUCCESS; + omapi_listener_dereference (&obj, MDL); + return status; } /* Return the socket on which the dispatcher should wait for readiness @@ -184,13 +180,10 @@ isc_result_t omapi_accept (omapi_object_t *h) listener = (omapi_listener_object_t *)h; /* Get the handle. */ - obj = (omapi_connection_object_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - rc_register_mdl (&obj, obj, obj -> refcnt); - obj -> type = omapi_type_connection; + obj = (omapi_connection_object_t *)0; + status = omapi_connection_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; /* Accept the connection. */ len = sizeof obj -> remote_addr; @@ -199,7 +192,7 @@ isc_result_t omapi_accept (omapi_object_t *h) ((struct sockaddr *) &(obj -> remote_addr)), &len); if (obj -> socket < 0) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); if (errno == EMFILE || errno == ENFILE || errno == ENOBUFS) return ISC_R_NORESOURCES; return ISC_R_UNEXPECTED; @@ -214,18 +207,17 @@ isc_result_t omapi_accept (omapi_object_t *h) omapi_connection_writer, omapi_connection_reaper); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return status; } - omapi_object_reference (&obj -> listener, - (omapi_object_t *)listener, MDL); + omapi_listener_reference (&obj -> listener, listener, MDL); status = omapi_signal (h, "connect", obj); /* Lose our reference to the connection, so it'll be gc'd when it's reaped. */ - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_connection_dereference (&obj, MDL); return status; } @@ -264,7 +256,7 @@ isc_result_t omapi_listener_destroy (omapi_object_t *h, if (h -> type != omapi_type_listener) return ISC_R_INVALIDARG; - l = (omapi_listener_object_t *)(h); + l = (omapi_listener_object_t *)h; if (l -> socket != -1) { close (l -> socket); diff --git a/omapip/message.c b/omapip/message.c index d20da511b..60cd68576 100644 --- a/omapip/message.c +++ b/omapip/message.c @@ -43,6 +43,9 @@ #include +OMAPI_OBJECT_ALLOC (omapi_message, + omapi_message_object_t, omapi_type_message) + omapi_message_object_t *omapi_registered_messages; isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line) diff --git a/omapip/protocol.c b/omapip/protocol.c index f28972830..88721babd 100644 --- a/omapip/protocol.c +++ b/omapip/protocol.c @@ -43,6 +43,11 @@ #include +OMAPI_OBJECT_ALLOC (omapi_protocol, omapi_protocol_object_t, + omapi_type_protocol) +OMAPI_OBJECT_ALLOC (omapi_protocol_listener, omapi_protocol_listener_object_t, + omapi_type_protocol_listener) + isc_result_t omapi_protocol_connect (omapi_object_t *h, const char *server_name, unsigned port, @@ -51,34 +56,31 @@ isc_result_t omapi_protocol_connect (omapi_object_t *h, isc_result_t status; omapi_protocol_object_t *obj; - obj = (omapi_protocol_object_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - rc_register_mdl (&obj, obj, obj -> refcnt); - obj -> type = omapi_type_protocol; + obj = (omapi_protocol_object_t *)0; + status = omapi_protocol_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; status = omapi_connect ((omapi_object_t *)obj, server_name, port); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_dereference (&obj, MDL); return status; } status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_dereference (&obj, MDL); return status; } status = omapi_object_reference (&obj -> inner, h, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_dereference (&obj, MDL); return status; } if (authinfo) omapi_object_reference (&obj -> authinfo, authinfo, MDL); - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_dereference (&obj, MDL); return ISC_R_SUCCESS; } @@ -125,16 +127,15 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po, { omapi_protocol_object_t *p; omapi_object_t *c; - omapi_message_object_t *m; - omapi_message_object_t *om; + omapi_message_object_t *m, *om; isc_result_t status; u_int32_t foo; if (po -> type != omapi_type_protocol || !po -> outer || po -> outer -> type != omapi_type_connection || - mo -> type != omapi_type_message) + m -> type != omapi_type_message) return ISC_R_INVALIDARG; - if (omo && omo -> type != omapi_type_message) + if (om && om -> type != omapi_type_message) return ISC_R_INVALIDARG; p = (omapi_protocol_object_t *)po; c = (omapi_object_t *)(po -> outer); @@ -305,8 +306,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, /* If we already have the data, fall through. */ case omapi_protocol_header_wait: - status = omapi_message_new ((omapi_object_t **)&p -> message, - MDL); + status = omapi_message_allocate (&p -> message, MDL); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; @@ -486,8 +486,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, /* XXX unbind the authenticator. */ auth_unbind: - omapi_object_dereference ((omapi_object_t **)&p -> message, - MDL); + omapi_message_dereference (&p -> message, MDL); /* Now wait for the next message. */ goto to_header_wait; @@ -535,8 +534,7 @@ isc_result_t omapi_protocol_destroy (omapi_object_t *h, return ISC_R_INVALIDARG; p = (omapi_protocol_object_t *)h; if (p -> message) - omapi_object_dereference ((omapi_object_t **)&p -> message, - file, line); + omapi_message_dereference (&p -> message, file, line); if (p -> authinfo) return omapi_object_dereference (&p -> authinfo, file, line); return ISC_R_SUCCESS; @@ -570,27 +568,25 @@ isc_result_t omapi_protocol_listen (omapi_object_t *h, isc_result_t status; omapi_protocol_listener_object_t *obj; - obj = (omapi_protocol_listener_object_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - obj -> type = omapi_type_protocol_listener; + obj = (omapi_protocol_listener_object_t *)0; + status = omapi_protocol_listener_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_listener_dereference (&obj, MDL); return status; } status = omapi_object_reference (&obj -> inner, h, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_listener_dereference (&obj, MDL); return status; } status = omapi_listen ((omapi_object_t *)obj, port, max); - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_listener_dereference (&obj, MDL); return status; } @@ -621,17 +617,15 @@ isc_result_t omapi_protocol_listener_signal (omapi_object_t *o, if (!c || c -> type != omapi_type_connection) return ISC_R_INVALIDARG; - obj = (omapi_protocol_object_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - obj -> type = omapi_type_protocol; + obj = (omapi_protocol_object_t *)0; + status = omapi_protocol_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; status = omapi_object_reference (&obj -> outer, c, MDL); if (status != ISC_R_SUCCESS) { lose: - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_dereference (&obj, MDL); omapi_disconnect (c, 1); return status; } @@ -648,7 +642,7 @@ isc_result_t omapi_protocol_listener_signal (omapi_object_t *o, if (status != ISC_R_SUCCESS) goto lose; - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + omapi_protocol_dereference (&obj, MDL); return status; } @@ -712,48 +706,51 @@ isc_result_t omapi_protocol_send_status (omapi_object_t *po, unsigned rid, const char *msg) { isc_result_t status; - omapi_object_t *message = (omapi_object_t *)0; + omapi_message_object_t *message = (omapi_message_object_t *)0; + omapi_object_t *mo; if (po -> type != omapi_type_protocol) return ISC_R_INVALIDARG; - status = omapi_message_new (&message, MDL); + status = omapi_message_allocate (&message, MDL); if (status != ISC_R_SUCCESS) return status; + mo = (omapi_object_t *)message; - status = omapi_set_int_value (message, (omapi_object_t *)0, + status = omapi_set_int_value (mo, (omapi_object_t *)0, "op", OMAPI_OP_STATUS); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } - status = omapi_set_int_value (message, (omapi_object_t *)0, + status = omapi_set_int_value (mo, (omapi_object_t *)0, "rid", (int)rid); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } - status = omapi_set_int_value (message, (omapi_object_t *)0, + status = omapi_set_int_value (mo, (omapi_object_t *)0, "result", (int)waitstatus); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } /* If a message has been provided, send it. */ if (msg) { - status = omapi_set_string_value (message, (omapi_object_t *)0, + status = omapi_set_string_value (mo, (omapi_object_t *)0, "message", msg); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } } - return omapi_protocol_send_message (po, - id, message, (omapi_object_t *)0); + status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0); + omapi_message_dereference (&message, MDL); + return status; } isc_result_t omapi_protocol_send_update (omapi_object_t *po, @@ -762,51 +759,54 @@ isc_result_t omapi_protocol_send_update (omapi_object_t *po, omapi_object_t *object) { isc_result_t status; - omapi_object_t *message = (omapi_object_t *)0; + omapi_message_object_t *message = (omapi_message_object_t *)0; + omapi_object_t *mo; if (po -> type != omapi_type_protocol) return ISC_R_INVALIDARG; - status = omapi_message_new (&message, MDL); + status = omapi_message_allocate (&message, MDL); if (status != ISC_R_SUCCESS) return status; + mo = (omapi_object_t *)message; - status = omapi_set_int_value (message, (omapi_object_t *)0, + status = omapi_set_int_value (mo, (omapi_object_t *)0, "op", OMAPI_OP_UPDATE); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } if (rid) { omapi_handle_t handle; - status = omapi_set_int_value (message, (omapi_object_t *)0, + status = omapi_set_int_value (mo, (omapi_object_t *)0, "rid", (int)rid); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } status = omapi_object_handle (&handle, object); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } - status = omapi_set_int_value (message, (omapi_object_t *)0, + status = omapi_set_int_value (mo, (omapi_object_t *)0, "handle", (int)handle); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } } - status = omapi_set_object_value (message, (omapi_object_t *)0, + status = omapi_set_object_value (mo, (omapi_object_t *)0, "object", object); if (status != ISC_R_SUCCESS) { - omapi_object_dereference (&message, MDL); + omapi_message_dereference (&message, MDL); return status; } - return omapi_protocol_send_message (po, - id, message, (omapi_object_t *)0); + status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0); + omapi_message_dereference (&message, MDL); + return status; } diff --git a/omapip/support.c b/omapip/support.c index 99f449b9c..a1ceb2c2a 100644 --- a/omapip/support.c +++ b/omapip/support.c @@ -70,7 +70,9 @@ isc_result_t omapi_init (void) omapi_connection_destroy, omapi_connection_signal_handler, omapi_connection_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof + (omapi_connection_object_t)); if (status != ISC_R_SUCCESS) return status; @@ -81,7 +83,8 @@ isc_result_t omapi_init (void) omapi_listener_destroy, omapi_listener_signal_handler, omapi_listener_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (omapi_listener_object_t)); if (status != ISC_R_SUCCESS) return status; @@ -92,7 +95,8 @@ isc_result_t omapi_init (void) omapi_io_destroy, omapi_io_signal_handler, omapi_io_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (omapi_io_object_t)); if (status != ISC_R_SUCCESS) return status; @@ -103,7 +107,8 @@ isc_result_t omapi_init (void) omapi_generic_destroy, omapi_generic_signal_handler, omapi_generic_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (omapi_generic_object_t)); if (status != ISC_R_SUCCESS) return status; @@ -114,18 +119,19 @@ isc_result_t omapi_init (void) omapi_protocol_destroy, omapi_protocol_signal_handler, omapi_protocol_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (omapi_protocol_object_t)); if (status != ISC_R_SUCCESS) return status; - status = omapi_object_type_register (&omapi_type_protocol_listener, - "protocol-listener", - omapi_protocol_listener_set_value, - omapi_protocol_listener_get_value, - omapi_protocol_listener_destroy, - omapi_protocol_listener_signal, - omapi_protocol_listener_stuff, - 0, 0, 0); + status = (omapi_object_type_register + (&omapi_type_protocol_listener, "protocol-listener", + omapi_protocol_listener_set_value, + omapi_protocol_listener_get_value, + omapi_protocol_listener_destroy, + omapi_protocol_listener_signal, + omapi_protocol_listener_stuff, + 0, 0, 0, 0, 0, sizeof (omapi_protocol_listener_object_t))); if (status != ISC_R_SUCCESS) return status; @@ -136,7 +142,8 @@ isc_result_t omapi_init (void) omapi_message_destroy, omapi_message_signal_handler, omapi_message_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (omapi_message_object_t)); if (status != ISC_R_SUCCESS) return status; @@ -146,7 +153,8 @@ isc_result_t omapi_init (void) 0, 0, omapi_waiter_signal_handler, 0, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (omapi_waiter_object_t)); if (status != ISC_R_SUCCESS) return status; @@ -185,7 +193,12 @@ isc_result_t omapi_object_type_register (omapi_object_type_t **type, omapi_object_t *), isc_result_t (*remove) (omapi_object_t *, - omapi_object_t *)) + omapi_object_t *), + isc_result_t (*freer) + (omapi_object_t *, + const char *, int), + isc_result_t (*sizer) (size_t), + size_t size) { omapi_object_type_t *t; @@ -204,6 +217,9 @@ isc_result_t omapi_object_type_register (omapi_object_type_t **type, t -> create = create; t -> remove = remove; t -> next = omapi_object_types; + t -> sizer = sizer; + t -> size = size; + t -> freer = freer; omapi_object_types = t; if (type) *type = t; diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 956ae0777..77ea85f58 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -15,7 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names + * 3. Neither the name of Internet Software Consortium nor the names * of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -43,7 +43,7 @@ #ifndef lint static char ocopyright[] = -"$Id: dhcrelay.c,v 1.40 2000/03/17 04:00:27 mellon Exp $ Copyright (c) 1997-2000The Internet Software Consortium. All rights reserved.\n"; +"$Id: dhcrelay.c,v 1.41 2000/05/16 23:03:30 mellon Exp $ Copyright (c) 1997-2000 Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -108,7 +108,7 @@ struct server_list { } *servers; static char copyright [] = -"Copyright 1997, 1998, 1999 The Internet Software Consortium."; +"Copyright 1997, 1998, 1999 Internet Software Consortium."; static char arr [] = "All rights reserved."; static char message [] = "Internet Software Consortium DHCP Relay Agent"; static char contrib [] = "\nPlease contribute if you find this software useful."; @@ -325,11 +325,6 @@ void relay (ip, packet, length, from_port, from, hfrom) return; } - /* XXX Dave: - If you're using the circuit ID to figure out where to - send the reply, you can delete the following code, - but you still need to validate the giaddr and drop the - packet if it's bogus. */ /* Find the interface that corresponds to the giaddr in the packet. */ if (packet -> giaddr.s_addr) { @@ -467,10 +462,10 @@ void dhcp (packet) { } -struct subnet *find_subnet (addr) - struct iaddr addr; +int find_subnet (struct subnet **sp, + struct iaddr addr, const char *file, int line) { - return (struct subnet *)0; + return 0; } /* Strip any Relay Agent Information options from the DHCP packet diff --git a/server/Makefile.dist b/server/Makefile.dist index 1a7b372f0..01a6f429b 100644 --- a/server/Makefile.dist +++ b/server/Makefile.dist @@ -20,9 +20,9 @@ CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5 SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5 SRCS = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ - omapi.c mdb.c stables.c + omapi.c mdb.c stables.c salloc.c OBJS = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \ - omapi.o mdb.o stables.o + omapi.o mdb.o stables.o salloc.o PROG = dhcpd MAN = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 diff --git a/server/bootp.c b/server/bootp.c index 6062a4366..0d85558f9 100644 --- a/server/bootp.c +++ b/server/bootp.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: bootp.c,v 1.62 2000/05/03 22:57:42 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: bootp.c,v 1.63 2000/05/16 23:03:35 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -52,7 +52,7 @@ void bootp (packet) struct packet *packet; { int result; - struct host_decl *hp; + struct host_decl *hp = (struct host_decl *)0; struct host_decl *host = (struct host_decl *)0; struct packet outgoing; struct dhcp_packet raw; @@ -88,52 +88,66 @@ void bootp (packet) return; } - hp = find_hosts_by_haddr (packet -> raw -> htype, - packet -> raw -> chaddr, - packet -> raw -> hlen); + find_hosts_by_haddr (&hp, packet -> raw -> htype, + packet -> raw -> chaddr, + packet -> raw -> hlen, MDL); - lease = find_lease (packet, packet -> shared_network, 0); + lease = (struct lease *)0; + find_lease (&lease, packet, packet -> shared_network, 0, MDL); /* Find an IP address in the host_decl that matches the specified network. */ + subnet = (struct subnet *)0; if (hp) - subnet = find_host_for_network (&hp, &ip_address, - packet -> shared_network); - else - subnet = (struct subnet *)0; + find_host_for_network (&subnet, &hp, &ip_address, + packet -> shared_network); if (!subnet) { + struct host_decl *h; /* We didn't find an applicable host declaration. Just in case we may be able to dynamically assign an address, see if there's a host declaration that doesn't have an ip address associated with it. */ - if (hp) { - for (; hp; hp = hp -> n_ipaddr) { - if (!hp -> fixed_addr) { - host = hp; - break; - } + for (h = hp; h; h = h -> n_ipaddr) { + if (!h -> fixed_addr) { + host_reference (&host, h, MDL); + break; } } + if (hp) { + host_dereference (&hp, MDL); + if (host) + host_reference (&hp, host, MDL); + } /* If a lease has already been assigned to this client, use it. */ if (lease) { + if (host && host != lease -> host) { + if (lease -> host) + host_dereference (&lease -> host, MDL); + host_reference (&lease -> host, host, MDL); + } ack_lease (packet, lease, 0, 0, msgbuf, 0); - return; + goto out; } /* Otherwise, try to allocate one. */ - lease = allocate_lease (packet, - packet -> shared_network -> pools, 0, - &peer_has_leases); + allocate_lease (&lease, packet, + packet -> shared_network -> pools, + &peer_has_leases); if (lease) { - lease -> host = host; + if (host && host != lease -> host) { + if (lease -> host) + host_dereference (&lease -> host, MDL); + host_reference (&lease -> host, host, MDL); + } else if (lease -> host) + host_dereference (&lease -> host, MDL); ack_lease (packet, lease, 0, 0, msgbuf, 0); - return; + goto out; } log_info ("%s: no available leases", msgbuf); - return; + goto out; } /* Run the executable statements to compute the client and server @@ -165,9 +179,7 @@ void bootp (packet) &lease -> scope, oc, MDL)) { if (!ignorep) log_info ("%s: bootp disallowed", msgbuf); - option_state_dereference (&options, MDL); - static_lease_dereference (lease, MDL); - return; + goto out; } if ((oc = lookup_option (&server_universe, @@ -177,9 +189,7 @@ void bootp (packet) &lease -> scope, oc, MDL)) { if (!ignorep) log_info ("%s: booting disallowed", msgbuf); - option_state_dereference (&options, MDL); - static_lease_dereference (lease, MDL); - return; + goto out; } /* Set up the outgoing packet... */ @@ -347,7 +357,7 @@ void bootp (packet) (struct packet *)0, &raw, outgoing.packet_length, from, &to, &hto); - return; + goto out; } /* If it comes from a client that already knows its address @@ -369,4 +379,17 @@ void bootp (packet) result = send_packet (packet -> interface, packet, &raw, outgoing.packet_length, from, &to, &hto); + out: + if (options) + option_state_dereference (&options, MDL); + if (lease) { + static_lease_dereference (lease, MDL); + lease_dereference (&lease, MDL); + } + if (hp) + host_dereference (&hp, MDL); + if (host) + host_dereference (&host, MDL); + if (subnet) + subnet_dereference (&subnet, MDL); } diff --git a/server/class.c b/server/class.c index 717470422..d02ce08db 100644 --- a/server/class.c +++ b/server/class.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: class.c,v 1.19 2000/03/18 02:15:52 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: class.c,v 1.20 2000/05/16 23:03:36 mellon Exp $ Copyright (c) 1998-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ @@ -113,10 +113,10 @@ int check_collection (packet, lease, collection) packet -> options, (struct option_state *)0, &lease -> scope, class -> submatch)); if (status) { - if ((nc = ((struct class *) - hash_lookup (class -> hash, - data.data, - data.len)))) { + nc = (struct class *)0; + if (class_hash_lookup (&nc, class -> hash, + (const char *)data.data, + data.len, MDL)) { #if defined (DEBUG_CLASS_MATCHING) log_info ("matches subclass %s.", print_hex_1 (data.len, @@ -168,10 +168,11 @@ int check_collection (packet, lease, collection) data_string_forget (&data, MDL); if (!class -> hash) class -> hash = new_hash (0, 0, 0); - add_hash (class -> hash, - nc -> hash_string.data, - nc -> hash_string.len, - (unsigned char *)nc); + class_hash_add (class -> hash, + (const char *) + nc -> hash_string.data, + nc -> hash_string.len, + nc, MDL); classify (packet, nc); } } @@ -196,7 +197,8 @@ void classify (packet, class) struct class *class; { if (packet -> class_count < PACKET_MAX_CLASSES) - packet -> classes [packet -> class_count++] = class; + class_reference (&packet -> classes [packet -> class_count++], + class, MDL); else log_error ("too many groups for %s", print_hw_addr (packet -> raw -> htype, @@ -204,18 +206,19 @@ void classify (packet, class) packet -> raw -> chaddr)); } -struct class *find_class (name) - const char *name; +isc_result_t find_class (struct class **class, const char *name, + const char *file, int line) { struct collection *lp; struct class *cp; for (lp = collections; lp; lp = lp -> next) { for (cp = lp -> classes; cp; cp = cp -> nic) - if (cp -> name && !strcmp (name, cp -> name)) - return cp; + if (cp -> name && !strcmp (name, cp -> name)) { + return class_reference (class, cp, file, line); + } } - return (struct class *)0; + return ISC_R_NOTFOUND; } int unbill_class (lease, class) @@ -232,8 +235,8 @@ int unbill_class (lease, class) piaddr (lease -> ip_addr)); return 0; } - lease -> billing_class = (struct class *)0; - class -> billed_leases [i] = (struct lease *)0; + class_dereference (&lease -> billing_class, MDL); + lease_dereference (&class -> billed_leases [i], MDL); class -> leases_consumed--; return 1; } @@ -256,8 +259,8 @@ int bill_class (lease, class) return 0; } - class -> billed_leases [i] = lease; - lease -> billing_class = class; + lease_reference (&class -> billed_leases [i], lease, MDL); + class_reference (&lease -> billing_class, class, MDL); class -> leases_consumed++; return 1; } diff --git a/server/confpars.c b/server/confpars.c index 50f0c5b50..cd3a318a7 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: confpars.c,v 1.109 2000/05/04 18:58:11 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: confpars.c,v 1.110 2000/05/16 23:03:37 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -55,6 +55,16 @@ static TIME parsed_time; declarations :== | declaration | declarations declaration */ isc_result_t readconf () +{ + return parse_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP); +} + +/* conf-file :== parameters declarations EOF + parameters :== | parameter | parameters parameter + declarations :== | declaration | declarations declaration */ + +isc_result_t parse_conf_file (const char *filename, struct group *group, + int group_type) { int file; struct parse *cfile; @@ -63,18 +73,17 @@ isc_result_t readconf () int declaration = 0; int status; - if ((file = open (path_dhcpd_conf, O_RDONLY)) < 0) - log_fatal ("Can't open %s: %m", path_dhcpd_conf); + if ((file = open (filename, O_RDONLY)) < 0) + log_fatal ("Can't open %s: %m", filename); cfile = (struct parse *)0; - new_parse (&cfile, file, (char *)0, 0, path_dhcpd_conf); + new_parse (&cfile, file, (char *)0, 0, filename); do { token = peek_token (&val, cfile); if (token == EOF) break; - declaration = parse_statement (cfile, &root_group, - ROOT_GROUP, + declaration = parse_statement (cfile, group, group_type, (struct host_decl *)0, declaration); } while (1); @@ -125,9 +134,8 @@ isc_result_t read_leases () if (token == EOF) break; if (token == LEASE) { - struct lease *lease; - lease = parse_lease_declaration (cfile); - if (lease) { + struct lease *lease = (struct lease *)0; + if (parse_lease_declaration (&lease, cfile)) { enter_lease (lease); if (lease -> on_expiry) executable_statement_dereference @@ -138,13 +146,14 @@ isc_result_t read_leases () if (lease -> on_release) executable_statement_dereference (&lease -> on_release, MDL); + lease_dereference (&lease, MDL); } else parse_warn (cfile, "possibly corrupt lease file"); } else if (token == HOST) { - parse_host_declaration (cfile, &root_group); + parse_host_declaration (cfile, root_group); } else if (token == GROUP) { - parse_group_declaration (cfile, &root_group); + parse_group_declaration (cfile, root_group); #if defined (FAILOVER_PROTOCOL) } else if (token == FAILOVER) { parse_failover_state_declaration @@ -217,10 +226,25 @@ int parse_statement (cfile, group, type, host_decl, declaration) int lose; struct data_string key_id; int known; + isc_result_t status; token = peek_token (&val, cfile); switch (token) { + case INCLUDE: + next_token (&val, cfile); + token = next_token (&val, cfile); + if (token != STRING) { + parse_warn (cfile, "filename string expected."); + skip_to_semi (cfile); + } else { + status = parse_conf_file (val, group, type); + if (status != ISC_R_SUCCESS) + parse_warn (cfile, "%s: bad parse.", val); + parse_semi (cfile); + } + return 1; + case HOST: next_token (&val, cfile); if (type != HOST_DECL && type != CLASS_DECL) @@ -283,18 +307,23 @@ int parse_statement (cfile, group, type, host_decl, declaration) /* Otherwise, cons up a fake shared network structure and populate it with the lone subnet... */ - share = new_shared_network (MDL); - if (!share) - log_fatal ("No memory for shared subnet"); - share -> group = clone_group (group, MDL); - share -> group -> shared_network = share; + share = (struct shared_network *)0; + status = shared_network_allocate (&share, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't allocate shared subnet: %s", + isc_result_totext (status)); + if (!clone_group (&share -> group, group, MDL)) + log_fatal ("Can't allocate group for shared subnet."); + shared_network_reference (&share -> group -> shared_network, + share, MDL); parse_subnet_declaration (cfile, share); /* share -> subnets is the subnet we just parsed. */ if (share -> subnets) { - share -> interface = - share -> subnets -> interface; + interface_reference (&share -> interface, + share -> subnets -> interface, + MDL); /* Make the shared network name from network number. */ n = piaddr (share -> subnets -> net); @@ -320,7 +349,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration (cfile, group, 0); + parse_class_declaration ((struct class **)0, cfile, group, 0); return 1; case USER_CLASS: @@ -331,7 +360,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration (cfile, group, 1); + parse_class_declaration ((struct class **)0, cfile, group, 1); return 1; case CLASS: @@ -342,7 +371,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration (cfile, group, 2); + parse_class_declaration ((struct class **)0, cfile, group, 2); return 1; case SUBCLASS: @@ -353,7 +382,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration (cfile, group, 3); + parse_class_declaration ((struct class **)0, cfile, group, 3); return 1; case HARDWARE: @@ -369,13 +398,15 @@ int parse_statement (cfile, group, type, host_decl, declaration) case FIXED_ADDR: next_token (&val, cfile); cache = (struct option_cache *)0; - parse_fixed_addr_param (&cache, cfile); - if (host_decl) - host_decl -> fixed_addr = cache; - else { - parse_warn (cfile, "fixed-address parameter not %s", - "allowed here."); - option_cache_dereference (&cache, MDL); + if (parse_fixed_addr_param (&cache, cfile)) { + if (host_decl) + host_decl -> fixed_addr = cache; + else { + parse_warn (cfile, + "fixed-address parameter not %s", + "allowed here."); + option_cache_dereference (&cache, MDL); + } } break; @@ -612,7 +643,7 @@ void parse_failover_peer (cfile, group, type) /* See if there's a peer declaration by this name. */ peer = (dhcp_failover_state_t *)0; - find_failover_peer (&peer, name); + find_failover_peer (&peer, name, MDL); token = next_token (&val, cfile); if (token == SEMI) { @@ -626,9 +657,11 @@ void parse_failover_peer (cfile, group, type) " failover peer ", name); return; } - group -> shared_network -> failover_peer = - peer; + dhcp_failover_state_reference + (&group -> shared_network -> failover_peer, + peer, MDL); } + dhcp_failover_state_dereference (&peer, MDL); return; } else if (token == STATE) { if (!peer) { @@ -637,6 +670,7 @@ void parse_failover_peer (cfile, group, type) return; } parse_failover_state_declaration (cfile, peer); + dhcp_failover_state_dereference (&peer, MDL); return; } else if (token != LBRACE) { parse_warn (cfile, "expecting left brace"); @@ -647,15 +681,14 @@ void parse_failover_peer (cfile, group, type) if (peer) { parse_warn (cfile, "redeclaration of failover peer %s", name); skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } - peer = dmalloc (sizeof *peer, MDL); - if (!peer) - log_fatal ("no memory for failover peer%s.", name); - memset (peer, 0, sizeof *peer); - peer -> refcnt = 1; - peer -> type = dhcp_type_failover_state; + status = dhcp_failover_state_allocate (&peer, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't allocate failover peer %s: %s", + name, isc_result_totext (status)); /* Save the name. */ peer -> name = name; @@ -693,6 +726,7 @@ void parse_failover_peer (cfile, group, type) parse_warn (cfile, "expecting 'address' or 'port'"); skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } break; @@ -703,6 +737,7 @@ void parse_failover_peer (cfile, group, type) expr = (struct expression *)0; if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) { skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } option_cache (paddr, (struct data_string *)0, expr, @@ -732,6 +767,7 @@ void parse_failover_peer (cfile, group, type) if (token != NUMBER) { parse_warn (cfile, "expecting number."); skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } *tp = atoi (val); @@ -750,6 +786,7 @@ void parse_failover_peer (cfile, group, type) if (!parse_numeric_aggregate (cfile, hba, &hba_len, COLON, 16, 8)) { skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } if (hba_len != 32) { @@ -771,13 +808,14 @@ void parse_failover_peer (cfile, group, type) token = next_token (&val, cfile); if (token != NUMBER) { parse_warn (cfile, "expecting number"); + badsplit: skip_to_rbrace (cfile, 1); - } - split = atoi (val); - if (!parse_semi (cfile)) { - skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } + split = atoi (val); + if (!parse_semi (cfile)) + goto badsplit; if (split > 255) { parse_warn (cfile, "split must be < 256"); } else { @@ -820,10 +858,12 @@ void parse_failover_peer (cfile, group, type) parse_warn (cfile, "invalid statement in peer declaration"); skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } if (token != RBRACE && !parse_semi (cfile)) { skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&peer, MDL); return; } } while (token != RBRACE); @@ -835,6 +875,7 @@ void parse_failover_peer (cfile, group, type) if (status != ISC_R_SUCCESS) parse_warn (cfile, "failover peer %s: %s", peer -> name, isc_result_totext (status)); + dhcp_failover_state_dereference (&peer, MDL); } void parse_failover_state_declaration (struct parse *cfile, @@ -868,7 +909,7 @@ void parse_failover_state_declaration (struct parse *cfile, /* See if there's a peer declaration by this name. */ state = (dhcp_failover_state_t *)0; - find_failover_peer (&state, name); + find_failover_peer (&state, name, MDL); if (!state) { parse_warn (cfile, "unknown failover peer: %s", name); skip_to_semi (cfile); @@ -882,13 +923,16 @@ void parse_failover_state_declaration (struct parse *cfile, skip_to_semi (cfile); return; } - } else - state = peer; + } else { + state = (dhcp_failover_state_t *)0; + dhcp_failover_state_reference (&state, peer, MDL); + } token = next_token (&val, cfile); if (token != LBRACE) { parse_warn (cfile, "expecting left brace"); if (token != SEMI) skip_to_semi (cfile); + dhcp_failover_state_dereference (&state, MDL); return; } do { @@ -900,8 +944,7 @@ void parse_failover_state_declaration (struct parse *cfile, token = next_token (&val, cfile); if (token != STATE) { parse_warn (cfile, "expecting 'state'"); - skip_to_rbrace (cfile, 1); - return; + goto bogus; } parse_failover_state (cfile, &state -> my_state, @@ -911,19 +954,21 @@ void parse_failover_state_declaration (struct parse *cfile, token = next_token (&val, cfile); if (token != STATE) { parse_warn (cfile, "expecting 'state'"); - skip_to_rbrace (cfile, 1); - return; + goto bogus; } parse_failover_state (cfile, &state -> partner_state, &state -> partner_stos); break; default: + bogus: parse_warn (cfile, "expecting state setting."); - skip_to_rbrace (cfile, 1); + skip_to_rbrace (cfile, 1); + dhcp_failover_state_dereference (&state, MDL); return; } } while (token != RBRACE); + dhcp_failover_state_dereference (&state, MDL); } void parse_failover_state (cfile, state, stos) @@ -1005,29 +1050,34 @@ void parse_pool_statement (cfile, group, type) int declaration = 0; isc_result_t status; - pool = new_pool (MDL); - if (!pool) + pool = (struct pool *)0; + status = pool_allocate (&pool, MDL); + if (status != ISC_R_SUCCESS) log_fatal ("no memory for pool."); - pool -> group = clone_group (group, MDL); + clone_group (&pool -> group, group, MDL); if (type == SUBNET_DECL) - pool -> shared_network = group -> subnet -> shared_network; + shared_network_reference (&pool -> shared_network, + group -> subnet -> shared_network, + MDL); else - pool -> shared_network = group -> shared_network; + shared_network_reference (&pool -> shared_network, + group -> shared_network, MDL); #if defined (FAILOVER_PROTOCOL) /* Inherit the failover peer from the shared network. */ if (pool -> shared_network -> failover_peer) - omapi_object_reference ((omapi_object_t **) - &pool -> failover_peer, - (omapi_object_t *) - pool -> shared_network -> failover_peer, - MDL); + dhcp_failover_state_reference + (&pool -> failover_peer, + pool -> shared_network -> failover_peer, MDL); #endif - if (!parse_lbrace (cfile)) + if (!parse_lbrace (cfile)) { + pool_dereference (&pool, MDL); return; + } + do { token = peek_token (&val, cfile); switch (token) { @@ -1043,10 +1093,8 @@ void parse_pool_statement (cfile, group, type) } #if defined (FAILOVER_PROTOCOL) if (pool -> failover_peer) - omapi_object_dereference - ((omapi_object_t **) - &pool -> failover_peer, MDL); - /* XXX Flag error if there's no failover peer? */ + dhcp_failover_state_dereference + (&pool -> failover_peer, MDL); #endif break; @@ -1066,11 +1114,10 @@ void parse_pool_statement (cfile, group, type) break; } if (pool -> failover_peer) - omapi_object_dereference - ((omapi_object_t **) - &pool -> failover_peer, MDL); + dhcp_failover_state_dereference + (&pool -> failover_peer, MDL); status = find_failover_peer (&pool -> failover_peer, - val); + val, MDL); if (status != ISC_R_SUCCESS) parse_warn (cfile, "failover peer %s: %s", val, @@ -1152,7 +1199,8 @@ void parse_pool_statement (cfile, group, type) continue; } permit -> type = permit_class; - permit -> class = find_class (val); + permit -> class = (struct class *)0; + find_class (&permit -> class, val, MDL); if (!permit -> class) parse_warn (cfile, "no such class: %s", val); @@ -1227,15 +1275,11 @@ void parse_pool_statement (cfile, group, type) clash_testing_done: #endif /* FAILOVER_PROTOCOL */ - if (type == SUBNET_DECL) - pool -> shared_network = group -> subnet -> shared_network; - else - pool -> shared_network = group -> shared_network; - p = &pool -> shared_network -> pools; for (; *p; p = &((*p) -> next)) ; - *p = pool; + pool_reference (p, pool, MDL); + pool_dereference (&pool, MDL); } /* boolean :== ON SEMI | OFF SEMI | TRUE SEMI | FALSE SEMI */ @@ -1298,24 +1342,26 @@ void parse_host_declaration (cfile, group) int deleted = 0; isc_result_t status; - token = peek_token (&val, cfile); - if (token != LBRACE) { - name = parse_host_name (cfile); - if (!name) - return; - } else { - name = (char *)0; - } + name = parse_host_name (cfile); + if (!name) + return; - host = (struct host_decl *)dmalloc (sizeof (struct host_decl), MDL); - if (!host) - log_fatal ("can't allocate host decl struct %s.", name); - memset (host, 0, sizeof *host); + host = (struct host_decl *)0; + status = host_allocate (&host, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("can't allocate host decl struct %s: %s", + name, isc_result_totext (status)); host -> name = name; - host -> group = clone_group (group, MDL); + if (clone_group (&host -> group, group, MDL) != ISC_R_SUCCESS) { + log_fatal ("can't clone group for host %s: %s", + name, isc_result_totext (status)); + boom: + host_dereference (&host, MDL); + return; + } if (!parse_lbrace (cfile)) - return; + goto boom; do { token = peek_token (&val, cfile); @@ -1357,22 +1403,18 @@ void parse_host_declaration (cfile, group) skip_to_rbrace (cfile, 1); break; } - go = ((struct group_object *) - hash_lookup (group_name_hash, - (const unsigned char *)val, - strlen (val))); - if (!go) { + go = (struct group_object *)0; + if (!group_hash_lookup (&go, group_name_hash, + val, strlen (val), MDL)) { parse_warn (cfile, "unknown group %s in host %s", val, host -> name); } else { if (host -> named_group) - omapi_object_dereference - ((omapi_object_t **) - &host -> named_group, MDL); - omapi_object_reference - ((omapi_object_t **) - &host -> named_group, - (omapi_object_t *)go, MDL); + group_object_dereference + (&host -> named_group, MDL); + group_object_reference (&host -> named_group, + go, MDL); + group_object_dereference (&go, MDL); } if (!parse_semi (cfile)) break; @@ -1429,28 +1471,26 @@ void parse_host_declaration (cfile, group) } while (1); if (deleted) { - struct host_decl *hp = - (struct host_decl *) - hash_lookup (host_name_hash, - (unsigned char *)host -> name, - strlen (host -> name)); - if (hp) { + struct host_decl *hp = (struct host_decl *)0; + if (host_hash_lookup (&hp, host_name_hash, + (unsigned char *)host -> name, + strlen (host -> name), MDL)) { delete_host (hp, 0); + host_dereference (&hp, MDL); } - dfree (host -> name, MDL); - if (host -> group) - free_group (host -> group, MDL); - dfree (host, MDL); } else { if (host -> named_group && host -> named_group -> group) { if (host -> group -> statements || (host -> group -> authoritative != host -> named_group -> group -> authoritative)) - host -> group -> next = - host -> named_group -> group; + group_reference (&host -> group -> next, + host -> named_group -> group, + MDL); else { - dfree (host -> group, MDL); - host -> group = host -> named_group -> group; + group_dereference (&host -> group, MDL); + group_reference (&host -> group, + host -> named_group -> group, + MDL); } } @@ -1464,19 +1504,21 @@ void parse_host_declaration (cfile, group) parse_warn (cfile, "host %s: %s", host -> name, isc_result_totext (status)); } + host_dereference (&host, MDL); } /* class-declaration :== STRING LBRACE parameters declarations RBRACE */ -struct class *parse_class_declaration (cfile, group, type) +int parse_class_declaration (cp, cfile, group, type) + struct class **cp; struct parse *cfile; struct group *group; int type; { const char *val; enum dhcp_token token; - struct class *class = (struct class *)0, *pc; + struct class *class = (struct class *)0, *pc = (struct class *)0; int declaration = 0; int lose = 0; struct data_string data; @@ -1484,22 +1526,23 @@ struct class *parse_class_declaration (cfile, group, type) struct executable_statement *stmt = (struct executable_statement *)0; struct expression *expr; int new = 1; + isc_result_t status; token = next_token (&val, cfile); if (token != STRING) { parse_warn (cfile, "Expecting class name"); skip_to_semi (cfile); - return (struct class *)0; + return 0; } /* See if there's already a class with the specified name. */ - pc = (struct class *)find_class (val); + find_class (&pc, val, MDL); /* If this isn't a subclass, we're updating an existing class. */ if (pc && type != 0 && type != 1 && type != 3) { - class = pc; + class_reference (&class, pc, MDL); new = 0; - pc = (struct class *)0; + class_dereference (&pc, MDL); } /* If this _is_ a subclass, there _must_ be a class with the @@ -1507,7 +1550,7 @@ struct class *parse_class_declaration (cfile, group, type) if (!pc && (type == 0 || type == 1 || type == 3)) { parse_warn (cfile, "no class named %s", val); skip_to_semi (cfile); - return (struct class *)0; + return 0; } /* The old vendor-class and user-class declarations had an implicit @@ -1521,19 +1564,23 @@ struct class *parse_class_declaration (cfile, group, type) data.len = strlen (val); data.buffer = (struct buffer *)0; if (!buffer_allocate (&data.buffer, data.len + 1, MDL)) - log_fatal ("no memoy for class name."); + log_fatal ("no memory for class name."); data.data = &data.buffer -> data [0]; data.terminated = 1; name = type ? "implicit-vendor-class" : "implicit-user-class"; } else if (type == 2) { + name = val; + } else { + name = (char *)0; + } + + if (name) { char *tname; if (!(tname = dmalloc (strlen (val) + 1, MDL))) log_fatal ("No memory for class name %s.", val); strcpy (tname, val); name = tname; - } else { - name = (char *)0; } /* If this is a straight subclass, parse the hash string. */ @@ -1543,37 +1590,42 @@ struct class *parse_class_declaration (cfile, group, type) token = next_token (&val, cfile); data.len = strlen (val); data.buffer = (struct buffer *)0; - if (!buffer_allocate (&data.buffer, data.len + 1, MDL)) - return (struct class *)0; + if (!buffer_allocate (&data.buffer, + data.len + 1, MDL)) { + if (pc) + class_dereference (&pc, MDL); + + return 0; + } data.terminated = 1; data.data = &data.buffer -> data [0]; strcpy ((char *)data.buffer -> data, val); } else if (token == NUMBER_OR_NAME || token == NUMBER) { memset (&data, 0, sizeof data); - if (!parse_cshl (&data, cfile)) - return (struct class *)0; + if (!parse_cshl (&data, cfile)) { + class_dereference (&pc, MDL); + } + return 0; } else { parse_warn (cfile, "Expecting string or hex list."); - return (struct class *)0; + class_dereference (&pc, MDL); + return 0; } } /* See if there's already a class in the hash table matching the hash data. */ if (type == 0 || type == 1 || type == 3) - class = ((struct class *) - hash_lookup (pc -> hash, data.data, data.len)); + class_hash_lookup (&class, pc -> hash, + (const char *)data.data, data.len, MDL); /* If we didn't find an existing class, allocate a new one. */ if (!class) { /* Allocate the class structure... */ - class = (struct class *)dmalloc (sizeof (struct class), MDL); - if (!class) - log_fatal ("No memory for class %s.", val); - memset (class, 0, sizeof *class); + status = class_allocate (&class, MDL); if (pc) { - class -> group = pc -> group; - class -> superclass = pc; + group_reference (&class -> group, pc -> group, MDL); + class_reference (&class -> superclass, pc, MDL); class -> lease_limit = pc -> lease_limit; if (class -> lease_limit) { class -> billed_leases = @@ -1587,26 +1639,27 @@ struct class *parse_class_declaration (cfile, group, type) } data_string_copy (&class -> hash_string, &data, MDL); if (!pc -> hash) - pc -> hash = new_hash (0, 0, 0); + pc -> hash = + new_hash ((hash_reference) + omapi_object_reference, + (hash_dereference) + omapi_object_dereference, 0); add_hash (pc -> hash, class -> hash_string.data, class -> hash_string.len, - (unsigned char *)class); + (void *)class, MDL); } else { - class -> group = - clone_group (group, MDL); + if (!clone_group (&class -> group, group, MDL)) + log_fatal ("no memory to clone class group."); } /* If this is an implicit vendor or user class, add a statement that causes the vendor or user class ID to be sent back in the reply. */ if (type == 0 || type == 1) { - stmt = ((struct executable_statement *) - dmalloc (sizeof (struct executable_statement), - MDL)); - if (!stmt) + stmt = (struct executable_statement *)0; + if (!executable_statement_allocate (&stmt, MDL)) log_fatal ("no memory for class statement."); - memset (stmt, 0, sizeof *stmt); stmt -> op = supersede_option_statement; if (option_cache_allocate (&stmt -> data.option, MDL)) { @@ -1627,19 +1680,26 @@ struct class *parse_class_declaration (cfile, group, type) if (type == 0 || type == 1 || type == 3) data_string_forget (&data, MDL); - /* Spawned classes don't have their own settings. */ + /* Spawned classes don't have to have their own settings. */ if (class -> superclass) { token = peek_token (&val, cfile); if (token == SEMI) { next_token (&val, cfile); - return class; + if (cp) + status = class_reference (cp, class, MDL); + class_dereference (&class, MDL); + return cp ? (status == ISC_R_SUCCESS) : 1; } /* Give the subclass its own group. */ - class -> group = clone_group (class -> group, MDL); + clone_group (&class -> group, class -> group, MDL); } - if (!parse_lbrace (cfile)) - return (struct class *)0; + if (!parse_lbrace (cfile)) { + class_dereference (&class, MDL); + if (pc) + class_dereference (&pc, MDL); + return 0; + } do { token = peek_token (&val, cfile); @@ -1744,16 +1804,21 @@ struct class *parse_class_declaration (cfile, group, type) } while (1); if (type == 2 && new) { if (!collections -> classes) - collections -> classes = class; + class_reference (&collections -> classes, class, MDL); else { - struct class *cp; - for (cp = collections -> classes; - cp -> nic; cp = cp -> nic) + struct class *c; + for (c = collections -> classes; + c -> nic; c = c -> nic) ; - cp -> nic = class; + class_reference (&c -> nic, class, MDL); } } - return class; + if (cp) + status = class_reference (cp, class, MDL); + class_dereference (&class, MDL); + if (pc) + class_dereference (&pc, MDL); + return cp ? (status == ISC_R_SUCCESS) : 1; } /* shared-network-declaration :== @@ -1768,15 +1833,16 @@ void parse_shared_net_declaration (cfile, group) struct shared_network *share; char *name; int declaration = 0; + isc_result_t status; - share = new_shared_network (MDL); - if (!share) - log_fatal ("No memory for shared subnet"); - share -> pools = (struct pool *)0; - share -> next = (struct shared_network *)0; - share -> interface = (struct interface_info *)0; - share -> group = clone_group (group, MDL); - share -> group -> shared_network = share; + share = (struct shared_network *)0; + status = shared_network_allocate (&share, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Can't allocate shared subnet: %s", + isc_result_totext (status)); + clone_group (&share -> group, group, MDL); + shared_network_reference (&share -> group -> shared_network, + share, MDL); /* Get the name of the shared network... */ token = peek_token (&val, cfile); @@ -1793,24 +1859,28 @@ void parse_shared_net_declaration (cfile, group) strcpy (name, val); } else { name = parse_host_name (cfile); - if (!name) + if (!name) { + shared_network_dereference (&share, MDL); return; + } } share -> name = name; - if (!parse_lbrace (cfile)) + if (!parse_lbrace (cfile)) { + shared_network_dereference (&share, MDL); return; + } do { token = peek_token (&val, cfile); if (token == RBRACE) { token = next_token (&val, cfile); - if (!share -> subnets) { + if (!share -> subnets) parse_warn (cfile, "empty shared-network decl"); - return; - } - enter_shared_network (share); + else + enter_shared_network (share); + shared_network_dereference (&share, MDL); return; } else if (token == EOF) { token = next_token (&val, cfile); @@ -1830,6 +1900,7 @@ void parse_shared_net_declaration (cfile, group) (struct host_decl *)0, declaration); } while (1); + shared_network_dereference (&share, MDL); } /* subnet-declaration :== @@ -1847,17 +1918,23 @@ void parse_subnet_declaration (cfile, share) unsigned len = sizeof addr; int declaration = 0; struct interface_info *ip; + isc_result_t status; - subnet = new_subnet (MDL); - if (!subnet) - log_fatal ("No memory for new subnet"); - subnet -> shared_network = share; - subnet -> group = clone_group (share -> group, MDL); - subnet -> group -> subnet = subnet; + subnet = (struct subnet *)0; + status = subnet_allocate (&subnet, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Allocation of new subnet failed: %s", + isc_result_totext (status)); + shared_network_reference (&subnet -> shared_network, share, MDL); + if (!clone_group (&subnet -> group, share -> group, MDL)) + log_fatal ("allocation of group for new subnet failed."); + subnet_reference (&subnet -> group -> subnet, subnet, MDL); /* Get the network number... */ - if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) + if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) { + subnet_dereference (&subnet, MDL); return; + } memcpy (iaddr.iabuf, addr, len); iaddr.len = len; subnet -> net = iaddr; @@ -1870,16 +1947,30 @@ void parse_subnet_declaration (cfile, share) } /* Get the netmask... */ - if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) + if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) { + subnet_dereference (&subnet, MDL); return; + } memcpy (iaddr.iabuf, addr, len); iaddr.len = len; subnet -> netmask = iaddr; + /* Validate the network number/netmask pair. */ + if (host_addr (subnet -> net, subnet -> netmask)) { + parse_warn (cfile, + "subnet %s: bad subnet number/mask combination.", + piaddr (subnet -> net)); + subnet_dereference (&subnet, MDL); + skip_to_semi (cfile); + return; + } + enter_subnet (subnet); - if (!parse_lbrace (cfile)) + if (!parse_lbrace (cfile)) { + subnet_dereference (&subnet, MDL); return; + } do { token = peek_token (&val, cfile); @@ -1906,23 +1997,33 @@ void parse_subnet_declaration (cfile, share) /* Add the subnet to the list of subnets in this shared net. */ if (!share -> subnets) - share -> subnets = subnet; + subnet_reference (&share -> subnets, subnet, MDL); else { u = (struct subnet *)0; for (t = share -> subnets; t -> next_sibling; t = t -> next_sibling) { if (subnet_inner_than (subnet, t, 0)) { - if (u) - u -> next_sibling = subnet; - else - share -> subnets = subnet; - subnet -> next_sibling = t; + subnet_reference (&subnet -> next_sibling, + t, MDL); + if (u) { + subnet_dereference (&u -> next_sibling, + MDL); + subnet_reference (&u -> next_sibling, + subnet, MDL); + } else { + subnet_dereference (&share -> subnets, + MDL); + subnet_reference (&share -> subnets, + subnet, MDL); + } + subnet_dereference (&subnet, MDL); return; } u = t; } - t -> next_sibling = subnet; + subnet_reference (&t -> next_sibling, subnet, MDL); } + subnet_dereference (&subnet, MDL); } /* group-declaration :== RBRACE parameters declarations LBRACE */ @@ -1942,7 +2043,9 @@ void parse_group_declaration (cfile, group) int dynamicp = 0; int staticp = 0; - g = clone_group (group, MDL); + g = (struct group *)0; + if (!clone_group (&g, group, MDL)) + log_fatal ("no memory for explicit group."); token = peek_token (&val, cfile); if (is_identifier (token) || token == STRING) { @@ -1954,8 +2057,10 @@ void parse_group_declaration (cfile, group) strcpy (name, val); } - if (!parse_lbrace (cfile)) + if (!parse_lbrace (cfile)) { + group_dereference (&g, MDL); return; + } do { token = peek_token (&val, cfile); @@ -1987,27 +2092,28 @@ void parse_group_declaration (cfile, group) if (name) { if (deletedp) { if (group_name_hash) { - t = ((struct group_object *) - hash_lookup (group_name_hash, - (unsigned char *)name, - strlen (name))); - if (t) { + t = (struct group_object *)0; + if (group_hash_lookup (&t, group_name_hash, + name, + strlen (name), MDL)) { delete_group (t, 0); } } } else { - t = dmalloc (sizeof *t, MDL); - if (!t) - log_fatal ("no memory for group decl %s", val); - memset (t, 0, sizeof *t); - t -> type = dhcp_type_group; - t -> group = g; + t = (struct group_object *)0; + status = group_object_allocate (&t, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("no memory for group decl %s: %s", + val, isc_result_totext (status)); + group_reference (&t -> group, g, MDL); t -> name = name; t -> flags = ((staticp ? GROUP_OBJECT_STATIC : 0) | (dynamicp ? GROUP_OBJECT_DYNAMIC : 0) | (deletedp ? GROUP_OBJECT_DELETED : 0)); supersede_group (t, 0); } + if (t) + group_object_dereference (&t, MDL); } } @@ -2090,8 +2196,7 @@ TIME parse_timestamp (cfile) | CLASS identifier SEMI | DYNAMIC_BOOTP SEMI */ -struct lease *parse_lease_declaration (cfile) - struct parse *cfile; +int parse_lease_declaration (struct lease **lp, struct parse *cfile) { const char *val; enum dhcp_token token; @@ -2100,7 +2205,7 @@ struct lease *parse_lease_declaration (cfile) int seenmask = 0; int seenbit; char tbuf [32]; - static struct lease lease; + struct lease *lease; struct executable_statement *on; struct expression *exp; struct data_string ds; @@ -2109,18 +2214,25 @@ struct lease *parse_lease_declaration (cfile) char *s; int noequal, newbinding; struct binding *binding; + isc_result_t status; - /* Zap the lease structure... */ - memset (&lease, 0, sizeof lease); + lease = (struct lease *)0; + status = lease_allocate (&lease, MDL); + if (status != ISC_R_SUCCESS) + return 0; /* Get the address for which the lease has been issued. */ - if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) - return (struct lease *)0; - memcpy (lease.ip_addr.iabuf, addr, len); - lease.ip_addr.len = len; + if (!parse_numeric_aggregate (cfile, addr, &len, DOT, 10, 8)) { + lease_dereference (&lease, MDL); + return 0; + } + memcpy (lease -> ip_addr.iabuf, addr, len); + lease -> ip_addr.len = len; - if (!parse_lbrace (cfile)) - return (struct lease *)0; + if (!parse_lbrace (cfile)) { + lease_dereference (&lease, MDL); + return 0; + } do { token = next_token (&val, cfile); @@ -2145,32 +2257,32 @@ struct lease *parse_lease_declaration (cfile) switch (token) { case STARTS: seenbit = 1; - lease.starts = t; + lease -> starts = t; break; case ENDS: seenbit = 2; - lease.ends = t; + lease -> ends = t; break; case TIMESTAMP: seenbit = 4; - lease.timestamp = t; + lease -> timestamp = t; break; case TSTP: seenbit = 65536; - lease.tstp = t; + lease -> tstp = t; break; case TSFP: seenbit = 131072; - lease.tsfp = t; + lease -> tsfp = t; break; case CLTT: seenbit = 524288; - lease.cltt = t; + lease -> cltt = t; break; default: /* for gcc, we'll never get here. */ @@ -2185,24 +2297,28 @@ struct lease *parse_lease_declaration (cfile) if (token == STRING) { unsigned char *tuid; token = next_token (&val, cfile); - lease.uid_len = strlen (val); + lease -> uid_len = strlen (val); tuid = ((unsigned char *) - dmalloc (lease.uid_len, MDL)); + dmalloc (lease -> uid_len, MDL)); if (!tuid) { log_error ("no space for uid"); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } - memcpy (tuid, val, lease.uid_len); - lease.uid = tuid; + memcpy (tuid, val, lease -> uid_len); + lease -> uid = tuid; } else { - lease.uid_len = 0; - lease.uid = (parse_numeric_aggregate - (cfile, (unsigned char *)0, - &lease.uid_len, ':', 16, 8)); - if (!lease.uid) - return (struct lease *)0; - if (lease.uid_len == 0) { - lease.uid = (unsigned char *)0; + lease -> uid_len = 0; + lease -> uid = (parse_numeric_aggregate + (cfile, (unsigned char *)0, + &lease -> uid_len, ':', + 16, 8)); + if (!lease -> uid) { + lease_dereference (&lease, MDL); + return 0; + } + if (lease -> uid_len == 0) { + lease -> uid = (unsigned char *)0; parse_warn (cfile, "zero-length uid"); seenbit = 0; parse_semi (cfile); @@ -2210,7 +2326,7 @@ struct lease *parse_lease_declaration (cfile) } } parse_semi (cfile); - if (!lease.uid) { + if (!lease -> uid) { log_fatal ("No memory for lease uid"); } break; @@ -2221,7 +2337,8 @@ struct lease *parse_lease_declaration (cfile) if (!is_identifier (token)) { if (token != SEMI) skip_to_rbrace (cfile, 1); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } parse_semi (cfile); /* for now, we aren't using this. */ @@ -2230,12 +2347,12 @@ struct lease *parse_lease_declaration (cfile) case HARDWARE: seenbit = 64; parse_hardware_param (cfile, - &lease.hardware_addr); + &lease -> hardware_addr); break; case DYNAMIC_BOOTP: seenbit = 128; - lease.flags |= BOOTP_LEASE; + lease -> flags |= BOOTP_LEASE; parse_semi (cfile); break; @@ -2244,22 +2361,24 @@ struct lease *parse_lease_declaration (cfile) if (token != IS) { parse_warn (cfile, "expecting \"is\"."); skip_to_rbrace (cfile, 1); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } token = next_token (&val, cfile); if (token != OWNER) { parse_warn (cfile, "expecting \"owner\"."); skip_to_rbrace (cfile, 1); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } seenbit = 262144; - lease.flags |= PEER_IS_OWNER; + lease -> flags |= PEER_IS_OWNER; parse_semi (cfile); break; case ABANDONED: seenbit = 256; - lease.flags |= ABANDONED_LEASE; + lease -> flags |= ABANDONED_LEASE; parse_semi (cfile); break; @@ -2267,15 +2386,15 @@ struct lease *parse_lease_declaration (cfile) seenbit = 512; token = peek_token (&val, cfile); if (token == STRING) - lease.hostname = parse_string (cfile); + lease -> hostname = parse_string (cfile); else { - lease.hostname = parse_host_name (cfile); - if (lease.hostname) + lease -> hostname = parse_host_name (cfile); + if (lease -> hostname) parse_semi (cfile); } - if (!lease.hostname) { + if (!lease -> hostname) { seenbit = 0; - return (struct lease *)0; + return 0; } break; @@ -2283,16 +2402,18 @@ struct lease *parse_lease_declaration (cfile) seenbit = 1024; token = peek_token (&val, cfile); if (token == STRING) - lease.client_hostname = parse_string (cfile); + lease -> client_hostname = + parse_string (cfile); else { - lease.client_hostname = + lease -> client_hostname = parse_host_name (cfile); - if (lease.client_hostname) + if (lease -> client_hostname) parse_semi (cfile); } - if (!lease.client_hostname) { + if (!lease -> client_hostname) { seenbit = 0; - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } break; @@ -2308,15 +2429,18 @@ struct lease *parse_lease_declaration (cfile) token = BILLING; break; } - lease.billing_class = find_class (val); - if (!lease.billing_class) + find_class (&lease -> billing_class, val, MDL); + if (!lease -> billing_class) parse_warn (cfile, "unknown class %s", val); parse_semi (cfile); } else if (token == SUBCLASS) { - lease.billing_class = - (parse_class_declaration - (cfile, (struct group *)0, 3)); + if (lease -> billing_class) + class_dereference + (&lease -> billing_class, MDL); + parse_class_declaration + (&lease -> billing_class, + cfile, (struct group *)0, 3); } else { parse_warn (cfile, "expecting \"class\""); if (token != SEMI) @@ -2329,21 +2453,22 @@ struct lease *parse_lease_declaration (cfile) lose = 0; if (!parse_on_statement (&on, cfile, &lose)) { skip_to_rbrace (cfile, 1); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } seenbit = 0; if ((on -> data.on.evtypes & ON_EXPIRY) && on -> data.on.statements) { seenbit |= 16384; executable_statement_reference - (&lease.on_expiry, + (&lease -> on_expiry, on -> data.on.statements, MDL); } if ((on -> data.on.evtypes & ON_RELEASE) && on -> data.on.statements) { seenbit |= 32768; executable_statement_reference - (&lease.on_release, + (&lease -> on_release, on -> data.on.statements, MDL); } executable_statement_dereference (&on, MDL); @@ -2359,12 +2484,13 @@ struct lease *parse_lease_declaration (cfile) val); badset: skip_to_semi (cfile); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } seenbit = 0; special_set: - binding = find_binding (&lease.scope, val); + binding = find_binding (&lease -> scope, val); if (!binding) { binding = dmalloc (sizeof *binding, MDL); if (!binding) @@ -2422,7 +2548,8 @@ struct lease *parse_lease_declaration (cfile) if (!s) { binding_value_dereference (&binding -> value, MDL); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } if (binding -> value -> value.data.len) { if (!(buffer_allocate @@ -2447,7 +2574,8 @@ struct lease *parse_lease_declaration (cfile) skip_to_semi (cfile); binding_value_dereference (&binding -> value, MDL); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } binding -> value -> type = binding_numeric; binding -> value -> value.intval = atol (val); @@ -2467,12 +2595,13 @@ struct lease *parse_lease_declaration (cfile) skip_to_semi (cfile); binding_value_dereference (&binding -> value, MDL); - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } if (newbinding) { - binding -> next = lease.scope.bindings; - lease.scope.bindings = binding; + binding -> next = lease -> scope.bindings; + lease -> scope.bindings = binding; } parse_semi (cfile); break; @@ -2489,28 +2618,31 @@ struct lease *parse_lease_declaration (cfile) } skip_to_semi (cfile); seenbit = 0; - return (struct lease *)0; + lease_dereference (&lease, MDL); + return 0; } if (seenmask & seenbit) { parse_warn (cfile, "Too many %s parameters in lease %s\n", - tbuf, piaddr (lease.ip_addr)); + tbuf, piaddr (lease -> ip_addr)); } else seenmask |= seenbit; } while (1); - return &lease; + lease_reference (lp, lease, MDL); + lease_dereference (&lease, MDL); + return 1; } /* address-range-declaration :== ip-address ip-address SEMI | DYNAMIC_BOOTP ip-address ip-address SEMI */ -void parse_address_range (cfile, group, type, pool) +void parse_address_range (cfile, group, type, inpool) struct parse *cfile; struct group *group; int type; - struct pool *pool; + struct pool *inpool; { struct iaddr low, high, net; unsigned char addr [4]; @@ -2521,6 +2653,8 @@ void parse_address_range (cfile, group, type, pool) struct subnet *subnet; struct shared_network *share; struct pool *p; + struct pool *pool; + isc_result_t status; if ((token = peek_token (&val, cfile)) == DYNAMIC_BOOTP) { token = next_token (&val, cfile); @@ -2572,7 +2706,7 @@ void parse_address_range (cfile, group, type, pool) } } - if (!pool) { + if (!inpool) { struct pool *last; /* If we're permitting dynamic bootp for this range, @@ -2597,9 +2731,10 @@ void parse_address_range (cfile, group, type, pool) /* If we didn't get a pool, make one. */ if (!pool) { struct permit *p; - pool = new_pool (MDL); - if (!pool) - log_fatal ("no memory for ad-hoc pool."); + status = pool_allocate (&pool, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("no memory for ad-hoc pool: %s", + isc_result_totext (status)); p = new_permit (MDL); if (!p) log_fatal ("no memory for ad-hoc permit."); @@ -2615,14 +2750,18 @@ void parse_address_range (cfile, group, type, pool) } if (share -> pools) - last -> next = pool; + pool_reference (&last -> next, pool, MDL); else - share -> pools = pool; - pool -> shared_network = share; - pool -> group = clone_group (share -> group, MDL); + pool_reference (&share -> pools, pool, MDL); + shared_network_reference (&pool -> shared_network, + share, MDL); + if (!clone_group (&pool -> group, share -> group, MDL)) + log_fatal ("no memory for anon pool group."); } - } + } else + pool_reference (&pool, inpool, MDL); + #if defined (FAILOVER_PROTOCOL) if (pool -> failover_peer && dynamic) { /* Doctor, do you think I'm overly sensitive @@ -2650,6 +2789,7 @@ void parse_address_range (cfile, group, type, pool) /* Create the new address range... */ new_address_range (low, high, subnet, pool); + pool_dereference (&pool, MDL); } /* allow-deny-keyword :== BOOTP diff --git a/server/db.c b/server/db.c index 488c670a6..da252c5fc 100644 --- a/server/db.c +++ b/server/db.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: db.c,v 1.49 2000/05/04 18:58:12 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: db.c,v 1.50 2000/05/16 23:03:39 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -431,7 +431,7 @@ int write_host (host) if (host -> group && (!host -> named_group || host -> group != host -> named_group -> group) && - host -> group != &root_group) { + host -> group != root_group) { errno = 0; write_statements (db_file, host -> group -> statements, 8); @@ -732,3 +732,12 @@ void new_lease_file () counting = 1; } + +int group_writer (struct group_object *group) +{ + if (!write_group (group)) + return 0; + if (!commit_leases ()) + return 0; + return 1; +} diff --git a/server/dhcp.c b/server/dhcp.c index afb982cf8..f8d5b8bf5 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: dhcp.c,v 1.148 2000/05/04 18:58:13 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dhcp.c,v 1.149 2000/05/16 23:03:42 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -104,7 +104,7 @@ void dhcpdiscover (packet, ms_nulltp) struct packet *packet; int ms_nulltp; { - struct lease *lease; + struct lease *lease = (struct lease *)0; char msgbuf [1024]; /* XXX */ TIME when; char *s; @@ -114,7 +114,7 @@ void dhcpdiscover (packet, ms_nulltp) dhcp_failover_state_t *peer; #endif - lease = find_lease (packet, packet -> shared_network, 0); + find_lease (&lease, packet, packet -> shared_network, 0, MDL); if (lease && lease -> client_hostname && db_printable (lease -> client_hostname)) @@ -145,7 +145,7 @@ void dhcpdiscover (packet, ms_nulltp) peer -> my_state == normal) { log_info ("%s: letting peer %s respond.", msgbuf, peer -> name); - return; + goto out; } } #endif @@ -154,15 +154,14 @@ void dhcpdiscover (packet, ms_nulltp) if (!packet -> shared_network) { log_info ("Packet from unknown subnet: %s", inet_ntoa (packet -> raw -> giaddr)); - return; + goto out; } /* If we didn't find a lease, try to allocate one... */ if (!lease) { - lease = allocate_lease (packet, - packet -> shared_network -> pools, - 0, &peer_has_leases); - if (!lease) { + if (!allocate_lease (&lease, packet, + packet -> shared_network -> pools, + &peer_has_leases)) { if (peer_has_leases) log_info ("%s: peer holds all free leases", msgbuf); @@ -196,7 +195,7 @@ void dhcpdiscover (packet, ms_nulltp) if (!load_balance_mine (packet, peer)) { log_debug ("%s: load balance to peer %s", msgbuf, peer -> name); - return; + goto out; } } } @@ -213,6 +212,9 @@ void dhcpdiscover (packet, ms_nulltp) when = lease -> ends; ack_lease (packet, lease, DHCPOFFER, when, msgbuf, ms_nulltp); + out: + if (lease) + lease_dereference (&lease, MDL); } void dhcprequest (packet, ms_nulltp) @@ -244,15 +246,15 @@ void dhcprequest (packet, ms_nulltp) cip.len = 4; memcpy (cip.iabuf, &packet -> raw -> ciaddr.s_addr, 4); } - subnet = find_subnet (cip); /* Find the lease that matches the address requested by the client. */ - if (subnet) - lease = find_lease (packet, subnet -> shared_network, &ours); - else - lease = (struct lease *)0; + subnet = (struct subnet *)0; + lease = (struct lease *)0; + if (find_subnet (&subnet, cip, MDL)) + find_lease (&lease, packet, + subnet -> shared_network, &ours, MDL); if (lease && lease -> client_hostname && db_printable (lease -> client_hostname)) @@ -338,13 +340,15 @@ void dhcprequest (packet, ms_nulltp) } /* Otherwise, ignore it. */ log_info ("%s: ignored (not authoritative).", msgbuf); - return; + goto out; } /* If we do know where it came from and it asked for an address that is not on that shared network, nak it. */ - subnet = find_grouped_subnet (packet -> shared_network, cip); - if (!subnet) { + if (subnet) + subnet_dereference (&subnet, MDL); + if (!find_grouped_subnet (&subnet, packet -> shared_network, + cip, MDL)) { if (packet -> shared_network -> group -> authoritative) { log_info ("%s: wrong network.", msgbuf); @@ -364,7 +368,7 @@ void dhcprequest (packet, ms_nulltp) lookup_option (&dhcp_universe, packet -> options, DHO_DHCP_SERVER_IDENTIFIER)) { log_info ("%s: ignored (not for me)", msgbuf); - return; + goto out; } /* If we found a lease, but it belongs to a failover peer, and @@ -381,7 +385,7 @@ void dhcprequest (packet, ms_nulltp) lease -> pool && lease -> pool -> failover_peer && lease -> pool -> failover_peer -> my_state == normal) { log_info ("%s: ignored (not for me)", msgbuf); - return; + goto out; } #endif /* FAILOVER_PROTOCOL */ @@ -390,7 +394,7 @@ void dhcprequest (packet, ms_nulltp) if (!lease && ours) { log_info ("%s: lease %s unavailable.", msgbuf, piaddr (cip)); nak_lease (packet, &cip); - return; + goto out; } /* Otherwise, send the lease to the client if we found one. */ @@ -398,13 +402,20 @@ void dhcprequest (packet, ms_nulltp) ack_lease (packet, lease, DHCPACK, 0, msgbuf, ms_nulltp); } else log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip)); + + out: + if (subnet) + subnet_dereference (&subnet, MDL); + if (lease) + lease_dereference (&lease, MDL); + return; } void dhcprelease (packet, ms_nulltp) struct packet *packet; int ms_nulltp; { - struct lease *lease; + struct lease *lease = (struct lease *)0; struct iaddr cip; struct option_cache *oc; struct data_string data; @@ -428,7 +439,7 @@ void dhcprelease (packet, ms_nulltp) evaluate_option_cache (&data, packet, (struct lease *)0, packet -> options, (struct option_state *)0, &global_scope, oc, MDL)) { - lease = find_lease_by_uid (data.data, data.len); + find_lease_by_uid (&lease, data.data, data.len, MDL); data_string_forget (&data, MDL); /* See if we can find a lease that matches the IP address @@ -439,8 +450,7 @@ void dhcprelease (packet, ms_nulltp) break; } } - } else - lease = (struct lease *)0; + } /* The client is supposed to pass a valid client-identifier, but the spec on this has changed historically, so try the @@ -448,7 +458,7 @@ void dhcprelease (packet, ms_nulltp) if (!lease) { cip.len = 4; memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4); - lease = find_lease_by_ip_addr (cip); + find_lease_by_ip_addr (&lease, cip, MDL); } @@ -476,15 +486,17 @@ void dhcprelease (packet, ms_nulltp) lease ? "" : "not "); /* If we found a lease, release it. */ - if (lease && lease -> ends > cur_time) + if (lease && lease -> ends > cur_time) { release_lease (lease, packet); + lease_dereference (&lease, MDL); + } } void dhcpdecline (packet, ms_nulltp) struct packet *packet; int ms_nulltp; { - struct lease *lease; + struct lease *lease = (struct lease *)0; struct iaddr cip; struct option_cache *oc; struct data_string data; @@ -508,7 +520,7 @@ void dhcpdecline (packet, ms_nulltp) cip.len = 4; memcpy (cip.iabuf, data.data, 4); data_string_forget (&data, MDL); - lease = find_lease_by_ip_addr (cip); + find_lease_by_ip_addr (&lease, cip, MDL); option_state_allocate (&options, MDL); @@ -569,6 +581,8 @@ void dhcpdecline (packet, ms_nulltp) } option_state_dereference (&options, MDL); + if (lease) + lease_dereference (&lease, MDL); } void dhcpinform (packet, ms_nulltp) @@ -583,7 +597,7 @@ void dhcpinform (packet, ms_nulltp) struct dhcp_packet raw; struct packet outgoing; unsigned char dhcpack = DHCPACK; - struct subnet *subnet; + struct subnet *subnet = (struct subnet *)0; struct iaddr cip; unsigned i, j; int nulltp; @@ -612,7 +626,7 @@ void dhcpinform (packet, ms_nulltp) /* Find the subnet that the client is on. */ oc = (struct option_cache *)0; - subnet = find_subnet (cip); + find_subnet (&subnet , cip, MDL); /* Sourceless packets don't make sense here. */ if (!subnet) { @@ -625,8 +639,23 @@ void dhcpinform (packet, ms_nulltp) there's overhead involved in checking this, so let's see how people react first. */ if (subnet && !subnet -> group -> authoritative) { + static int eso = 0; log_info ("%s: not authoritative for subnet %s", msgbuf, piaddr (subnet -> net)); + if (!eso) { + log_info ("If this DHCP server is authoritative for%s", + " that subnet,"); + log_info ("please write an `authoritative;' directi%s", + "ve either in the"); + log_info ("subnet declaration or in some scope that%s", + "encloses the"); + log_info ("subnet declaration - for example, write %s", + "it at the top"); + log_info ("of the dhcpd.conf file."); + } + if (eso++ == 100) + eso = 0; + subnet_dereference (&subnet, MDL); return; } @@ -801,13 +830,14 @@ void dhcpinform (packet, ms_nulltp) evaluate_option_cache (&d1, packet, (struct lease *)0, packet -> options, options, &global_scope, oc, MDL)) { - const struct universe *u; + struct universe *u = (struct universe *)0; - u = ((const struct universe *) - hash_lookup (universe_hash, d1.data, d1.len)); - if (!u) { + if (!universe_hash_lookup (&u, universe_hash, + d1.data, d1.len, MDL)) { log_error ("unknown option space %s.", d1.data); option_state_dereference (&options, MDL); + if (subnet) + subnet_dereference (&subnet, MDL); return; } @@ -909,6 +939,8 @@ void dhcpinform (packet, ms_nulltp) ? fallback_interface : packet -> interface), &outgoing, &raw, outgoing.packet_length, from, &to, (struct hardware *)0); + if (subnet) + subnet_dereference (&subnet, MDL); } void nak_lease (packet, cip) @@ -922,11 +954,12 @@ void nak_lease (packet, cip) unsigned char nak = DHCPNAK; struct packet outgoing; struct hardware hto; - int i; + unsigned i; struct data_string data; struct option_state *options = (struct option_state *)0; struct expression *expr; struct option_cache *oc = (struct option_cache *)0; + struct iaddr myfrom; option_state_allocate (&options, MDL); memset (&outgoing, 0, sizeof outgoing); @@ -967,6 +1000,43 @@ void nak_lease (packet, cip) save_option (&dhcp_universe, options, oc); option_cache_dereference (&oc, MDL); + i = DHO_DHCP_SERVER_IDENTIFIER; + if (!(oc = lookup_option (&dhcp_universe, options, i))) { + use_primary: + oc = (struct option_cache *)0; + if (option_cache_allocate (&oc, MDL)) { + if (make_const_data + (&oc -> expression, + ((unsigned char *) + &packet -> interface -> primary_address), + sizeof packet -> interface -> primary_address, + 0, 0)) { + oc -> option = + dhcp_universe.options [i]; + save_option (&dhcp_universe, options, oc); + } + option_cache_dereference (&oc, MDL); + } + myfrom.len = sizeof packet -> interface -> primary_address; + memcpy (myfrom.iabuf, + &packet -> interface -> primary_address, myfrom.len); + } else { + memset (&data, 0, sizeof data); + if (evaluate_option_cache (&data, packet, (struct lease *)0, + packet -> options, options, + &global_scope, oc, MDL)) { + if (!data.len || + data.len > sizeof myfrom.iabuf) { + data_string_forget (&data, MDL); + goto use_primary; + } + memcpy (myfrom.iabuf, data.data, data.len); + myfrom.len = data.len; + data_string_forget (&data, MDL); + } else + goto use_primary; + } + /* Do not use the client's requested parameter list. */ delete_option (&dhcp_universe, packet -> options, DHO_DHCP_PARAMETER_REQUEST_LIST); @@ -1022,7 +1092,7 @@ void nak_lease (packet, cip) #endif memset (to.sin_zero, 0, sizeof to.sin_zero); - from = packet -> interface -> primary_address; + memcpy (&from, myfrom.iabuf, sizeof from); /* Make sure that the packet is at least as big as a BOOTP packet. */ if (outgoing.packet_length < BOOTP_MIN_LEN) @@ -1063,7 +1133,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) char *msg; int ms_nulltp; { - struct lease lt; + struct lease *lt; struct lease_state *state; TIME lease_time; TIME offered_lease_time; @@ -1074,6 +1144,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) struct option_cache *oc; struct expression *expr; int status; + isc_result_t result; unsigned i, j; int s1, s2; @@ -1089,7 +1160,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) if (!state) log_fatal ("unable to allocate lease state!"); state -> got_requested_address = packet -> got_requested_address; - state -> shared_network = packet -> interface -> shared_network; + shared_network_reference (&state -> shared_network, + packet -> interface -> shared_network, MDL); /* See if we got a server identifier option. */ if (lookup_option (&dhcp_universe, @@ -1208,21 +1280,27 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) oc, MDL)) { struct lease *seek; if (lease -> uid_len) { + struct lease *s; do { - seek = find_lease_by_uid (lease -> uid, - lease -> uid_len); + seek = (struct lease *)0; + find_lease_by_uid (&seek, lease -> uid, + lease -> uid_len, MDL); + /* Don't release expired leases, and don't release the lease we're going to assign. */ - while (seek) { - if (seek != lease && - seek -> ends > cur_time) + s = seek; + while (s) { + if (s != lease && + s -> ends > cur_time) break; - seek = seek -> n_uid; + s = s -> n_uid; } - if (seek) { + if (s) { release_lease (seek, packet); } - } while (seek); + if (seek) + lease_dereference (&seek, MDL); + } while (s); } if (!lease -> uid_len || (lease -> host && @@ -1234,20 +1312,25 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) state -> options, &lease -> scope, oc, MDL))) { + struct lease *s; do { - seek = (find_lease_by_hw_addr - (lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen)); - while (seek) { - if (seek != lease && - seek -> ends > cur_time) + seek = (struct lease *)0; + find_lease_by_hw_addr + (&seek, lease -> hardware_addr.hbuf, + lease -> hardware_addr.hlen, MDL); + s = seek; + while (s) { + if (s != lease && + s -> ends > cur_time) break; - seek = seek -> n_hw; + s = s -> n_hw; } - if (seek) { - release_lease (seek, packet); + if (s) { + release_lease (s, packet); } - } while (seek); + if (seek) + lease_dereference (&s, MDL); + } while (s); } } @@ -1287,18 +1370,24 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) evaluate_option_cache (&d1, packet, lease, packet -> options, state -> options, &lease -> scope, oc, MDL)) { - hp = find_hosts_by_uid (d1.data, d1.len); + struct host_decl *h; + hp = (struct host_decl *)0; + find_hosts_by_uid (&hp, d1.data, d1.len, MDL); data_string_forget (&d1, MDL); if (!hp) - hp = find_hosts_by_haddr - (packet -> raw -> htype, - packet -> raw -> chaddr, - packet -> raw -> hlen); - for (; hp; hp = hp -> n_ipaddr) { - if (!hp -> fixed_addr) + find_hosts_by_haddr (&hp, + packet -> raw -> htype, + packet -> raw -> chaddr, + packet -> raw -> hlen, + MDL); + for (h = hp; h; h = h -> n_ipaddr) { + if (!h -> fixed_addr) break; } - lease -> host = hp; + if (h) + host_reference (&lease -> host, hp, MDL); + if (hp) + host_dereference (&hp, MDL); } else lease -> host = (struct host_decl *)0; } @@ -1408,14 +1497,22 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) /* At this point, we have a lease that we can offer the client. Now we construct a lease structure that contains what we want, and call supersede_lease to do the right thing with it. */ - memset (<, 0, sizeof lt); - + lt = (struct lease *)0; + result = lease_allocate (<, MDL); + if (result != ISC_R_SUCCESS) { + 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; + } + /* Use the ip address of the lease that we finally found in the database. */ - lt.ip_addr = lease -> ip_addr; + lt -> ip_addr = lease -> ip_addr; /* Start now. */ - lt.starts = cur_time; + lt -> starts = cur_time; /* Figure out how long a lease to assign. If this is a dynamic BOOTP lease, its duration must be infinite. */ @@ -1497,7 +1594,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) #if defined (FAILOVER_PROTOCOL) /* Okay, we know the lease duration. Now check the failover state, if any. */ - if (lease -> pool -> failover_peer) { + if (lease -> pool && lease -> pool -> failover_peer) { dhcp_failover_state_t *peer = lease -> pool -> failover_peer; @@ -1512,7 +1609,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) to update tstp, there's already an update queued. May want to revisit this. */ if (cur_time + lease_time > lease -> tstp) - lt.tstp = cur_time + lease_time; + lt -> tstp = cur_time + lease_time; /* Now choose a lease time that is either MCLT, for a lease that's never before been @@ -1528,7 +1625,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) lease_time = (lease -> tsfp - cur_time + peer -> mclt); } - lt.cltt = cur_time; + lt -> cltt = cur_time; } #endif /* FAILOVER_PROTOCOL */ @@ -1539,9 +1636,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) else state -> offered_expiry = cur_time + lease_time; if (when) - lt.ends = when; + lt -> ends = when; else - lt.ends = state -> offered_expiry; + lt -> ends = state -> offered_expiry; } else { lease_time = MAX_TIME - cur_time; @@ -1570,11 +1667,11 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) } } - lt.ends = state -> offered_expiry = cur_time + lease_time; - lt.flags = BOOTP_LEASE; + lt -> ends = state -> offered_expiry = cur_time + lease_time; + lt -> flags = BOOTP_LEASE; } - lt.timestamp = cur_time; + lt -> timestamp = cur_time; /* Record the uid, if given... */ oc = lookup_option (&dhcp_universe, packet -> options, @@ -1583,28 +1680,32 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) evaluate_option_cache (&d1, packet, lease, packet -> options, state -> options, &lease -> scope, oc, MDL)) { - if (d1.len <= sizeof lt.uid_buf) { - memcpy (lt.uid_buf, d1.data, d1.len); - lt.uid = lt.uid_buf; - lt.uid_max = sizeof lt.uid_buf; - lt.uid_len = d1.len; + if (d1.len <= sizeof lt -> uid_buf) { + memcpy (lt -> uid_buf, d1.data, d1.len); + lt -> uid = lt -> uid_buf; + lt -> uid_max = sizeof lt -> uid_buf; + lt -> uid_len = d1.len; } else { unsigned char *tuid; - lt.uid_max = d1.len; - lt.uid_len = d1.len; - tuid = (unsigned char *)dmalloc (lt.uid_max, MDL); + lt -> uid_max = d1.len; + lt -> uid_len = d1.len; + tuid = (unsigned char *)dmalloc (lt -> uid_max, MDL); /* XXX inelegant */ if (!tuid) log_fatal ("no memory for large uid."); - memcpy (tuid, d1.data, lt.uid_len); - lt.uid = tuid; + memcpy (tuid, d1.data, lt -> uid_len); + lt -> uid = tuid; } data_string_forget (&d1, MDL); } - lt.host = lease -> host; - lt.subnet = lease -> subnet; - lt.billing_class = lease -> billing_class; + if (lease -> host) + host_reference (< -> host, lease -> host, MDL); + if (lease -> subnet) + subnet_reference (< -> subnet, lease -> subnet, MDL); + if (lease -> billing_class) + class_reference (< -> billing_class, + lease -> billing_class, MDL); /* Set a flag if this client is a broken client that NUL terminates string options and expects us to do likewise. */ @@ -1625,7 +1726,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) } /* Save any bindings. */ - lt.scope.bindings = lease -> scope.bindings; + lt -> scope.bindings = lease -> scope.bindings; lease -> scope.bindings = (struct binding *)0; /* Don't call supersede_lease on a mocked-up lease. */ @@ -1639,9 +1740,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) sizeof packet -> raw -> chaddr); /* XXX */ } else { /* Record the hardware address, if given... */ - lt.hardware_addr.hlen = packet -> raw -> hlen + 1; - lt.hardware_addr.hbuf [0] = packet -> raw -> htype; - memcpy (<.hardware_addr.hbuf [1], packet -> raw -> chaddr, + lt -> hardware_addr.hlen = packet -> raw -> hlen + 1; + lt -> hardware_addr.hbuf [0] = packet -> raw -> htype; + memcpy (< -> hardware_addr.hbuf [1], packet -> raw -> chaddr, sizeof packet -> raw -> chaddr); /* Install the new information about this lease in the @@ -1649,12 +1750,13 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) and we can't write the lease, don't ACK it (or BOOTREPLY it) either. */ - if (!(supersede_lease (lease, <, !offer || offer == DHCPACK, + if (!(supersede_lease (lease, lt, !offer || offer == DHCPACK, offer == DHCPACK) || (offer && offer != DHCPACK))) { log_info ("%s: database update failed", msg); free_lease_state (state, MDL); static_lease_dereference (lease, MDL); + lease_dereference (<, MDL); return; } else { /* If this is a DHCPOFFER transaction, supersede_lease @@ -1668,9 +1770,13 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) if (offer == DHCPOFFER && lease -> pool && lease -> pool -> next_expiry == lease) add_timeout (lease -> ends, pool_timer, - lease -> pool); + lease -> pool, + (tvref_t)omapi_object_reference, + (tvunref_t) + omapi_object_dereference); } } + lease_dereference (<, MDL); /* Remember the interface on which the packet arrived. */ state -> ip = packet -> interface; @@ -2001,11 +2107,10 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) evaluate_option_cache (&d1, packet, lease, packet -> options, state -> options, &lease -> scope, oc, MDL)) { - const struct universe *u; - - u = ((const struct universe *) - hash_lookup (universe_hash, d1.data, d1.len)); - if (!u) { + struct universe *u = (struct universe *)0; + + if (!universe_hash_lookup (&u, universe_hash, + d1.data, d1.len, MDL)) { log_error ("unknown option space %s.", d1.data); return; } @@ -2053,7 +2158,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp) cur_time - lease -> timestamp > 60) { lease -> timestamp = cur_time; icmp_echorequest (&lease -> ip_addr); - add_timeout (cur_time + 1, lease_ping_timeout, lease); + add_timeout (cur_time + 1, lease_ping_timeout, lease, + (tvref_t)lease_reference, + (tvunref_t)lease_dereference); ++outstanding_pings; } else { lease -> timestamp = cur_time; @@ -2273,16 +2380,19 @@ void dhcp_reply (lease) lease -> state = (struct lease_state *)0; } -struct lease *find_lease (packet, share, ours) - struct packet *packet; - struct shared_network *share; - int *ours; +int find_lease (struct lease **lp, + struct packet *packet, struct shared_network *share, int *ours, + const char *file, int line) { - struct lease *uid_lease, *ip_lease, *hw_lease; + struct lease *uid_lease = (struct lease *)0; + struct lease *ip_lease = (struct lease *)0; + struct lease *hw_lease = (struct lease *)0; struct lease *lease = (struct lease *)0; struct iaddr cip; - struct host_decl *hp, *host = (struct host_decl *)0; - struct lease *fixed_lease, *next; + struct host_decl *hp = (struct host_decl *)0; + struct host_decl *host = (struct host_decl *)0; + struct lease *fixed_lease = (struct lease *)0; + struct lease *next; struct option_cache *oc; struct data_string d1; int have_client_identifier = 0; @@ -2323,14 +2433,12 @@ struct lease *find_lease (packet, share, ours) /* First, try to find a fixed host entry for the specified client identifier... */ - hp = find_hosts_by_uid (client_identifier.data, - client_identifier.len); - if (hp) { + if (find_hosts_by_uid (&hp, client_identifier.data, + client_identifier.len, MDL)) { /* Remember if we know of this client. */ packet -> known = 1; - fixed_lease = mockup_lease (packet, share, hp); - } else - fixed_lease = (struct lease *)0; + mockup_lease (&fixed_lease, packet, share, hp); + } #if defined (DEBUG_FIND_LEASE) if (fixed_lease) { @@ -2338,27 +2446,28 @@ struct lease *find_lease (packet, share, ours) piaddr (fixed_lease -> ip_addr)); } #endif - if (!fixed_lease) - host = hp; /* Save the host if we found one. */ + if (!fixed_lease) /* Save the host if we found one. */ + host_reference (&host, hp, MDL); + if (hp) + host_dereference (&hp, MDL); - uid_lease = find_lease_by_uid (client_identifier.data, - client_identifier.len); - } else { - uid_lease = (struct lease *)0; - fixed_lease = (struct lease *)0; + find_lease_by_uid (&uid_lease, client_identifier.data, + client_identifier.len, MDL); } /* If we didn't find a fixed lease using the uid, try doing it with the hardware address... */ if (!fixed_lease && !host) { - hp = find_hosts_by_haddr (packet -> raw -> htype, - packet -> raw -> chaddr, - packet -> raw -> hlen); - if (hp) { + if (find_hosts_by_haddr (&hp, packet -> raw -> htype, + packet -> raw -> chaddr, + packet -> raw -> hlen, MDL)) { /* Remember if we know of this client. */ packet -> known = 1; - host = hp; /* Save it for later. */ - fixed_lease = mockup_lease (packet, share, hp); + if (host) + host_dereference (&host, MDL); + host_reference (&host, hp, MDL); + host_dereference (&hp, MDL); + mockup_lease (&fixed_lease, packet, share, host); #if defined (DEBUG_FIND_LEASE) if (fixed_lease) { log_info ("Found host for link address: %s.", @@ -2391,7 +2500,7 @@ struct lease *find_lease (packet, share, ours) can't do this until we get here because we depend on packet -> known, which may be set by either the uid host lookup or the haddr host lookup. */ - for (; uid_lease; uid_lease = next) { + while (uid_lease) { #if defined (DEBUG_FIND_LEASE) log_info ("trying next lease matching client id: %s", piaddr (uid_lease -> ip_addr)); @@ -2402,6 +2511,8 @@ struct lease *find_lease (packet, share, ours) piaddr (uid_lease -> ip_addr)); #endif next = uid_lease -> n_uid; + lease_dereference (&uid_lease, MDL); + lease_reference (&uid_lease, next, MDL); continue; } if ((uid_lease -> pool -> prohibit_list && @@ -2415,6 +2526,8 @@ struct lease *find_lease (packet, share, ours) next = uid_lease -> n_uid; if (!packet -> raw -> ciaddr.s_addr) release_lease (uid_lease, packet); + lease_dereference (&uid_lease, MDL); + lease_reference (&uid_lease, next, MDL); continue; } break; @@ -2431,8 +2544,8 @@ struct lease *find_lease (packet, share, ours) h.hlen = packet -> raw -> hlen + 1; h.hbuf [0] = packet -> raw -> htype; memcpy (&h.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen); - hw_lease = find_lease_by_hw_addr (h.hbuf, h.hlen); - for (; hw_lease; hw_lease = next) { + find_lease_by_hw_addr (&hw_lease, h.hbuf, h.hlen, MDL); + while (hw_lease) { #if defined (DEBUG_FIND_LEASE) log_info ("trying next lease matching hw addr: %s", piaddr (hw_lease -> ip_addr)); @@ -2448,6 +2561,8 @@ struct lease *find_lease (packet, share, ours) piaddr (hw_lease -> ip_addr)); #endif next = hw_lease -> n_hw; + lease_dereference (&hw_lease, MDL); + lease_reference (&hw_lease, next, MDL); continue; } if (hw_lease -> subnet -> shared_network != share) { @@ -2456,6 +2571,8 @@ struct lease *find_lease (packet, share, ours) piaddr (hw_lease -> ip_addr)); #endif next = hw_lease -> n_hw; + lease_dereference (&hw_lease, MDL); + lease_reference (&hw_lease, next, MDL); continue; } if ((hw_lease -> pool -> prohibit_list && @@ -2469,6 +2586,8 @@ struct lease *find_lease (packet, share, ours) next = hw_lease -> n_hw; if (!packet -> raw -> ciaddr.s_addr) release_lease (hw_lease, packet); + lease_dereference (&hw_lease, MDL); + lease_reference (&hw_lease, next, MDL); continue; } break; @@ -2482,9 +2601,7 @@ struct lease *find_lease (packet, share, ours) /* Try to find a lease that's been allocated to the client's IP address. */ if (cip.len) - ip_lease = find_lease_by_ip_addr (cip); - else - ip_lease = (struct lease *)0; + find_lease_by_ip_addr (&ip_lease, cip, MDL); #if defined (DEBUG_FIND_LEASE) if (ip_lease) @@ -2512,7 +2629,7 @@ struct lease *find_lease (packet, share, ours) log_info ("...but it was on the wrong shared network."); #endif strcpy (dhcp_message, "requested address on bad subnet"); - ip_lease = (struct lease *)0; + lease_dereference (&ip_lease, MDL); } /* Toss ip_lease if it hasn't yet expired and doesn't belong to the @@ -2534,7 +2651,7 @@ struct lease *find_lease (packet, share, ours) if (ip_lease) log_info ("rejecting lease for requested address."); #endif - ip_lease = (struct lease *)0; + lease_dereference (&ip_lease, MDL); } /* If for some reason the client has more than one lease @@ -2568,7 +2685,8 @@ struct lease *find_lease (packet, share, ours) packet -> packet_type == DHCPREQUEST) dissociate_lease (uid_lease); } - uid_lease = ip_lease; + lease_dereference (&uid_lease, MDL); + lease_reference (&uid_lease, ip_lease, MDL); } } @@ -2576,7 +2694,7 @@ struct lease *find_lease (packet, share, ours) that there are both a dynamic lease and a fixed-address declaration for the same IP address. */ if (packet -> packet_type == DHCPREQUEST && fixed_lease) { - fixed_lease = (struct lease *)0; + lease_dereference (&fixed_lease, MDL); db_conflict: log_error ("Dynamic and static leases present for %s.", piaddr (cip)); @@ -2591,7 +2709,7 @@ struct lease *find_lease (packet, share, ours) ip_lease -> subnet -> shared_network -> name ); if (fixed_lease) - ip_lease = (struct lease *)0; + lease_dereference (&ip_lease, MDL); strcpy (dhcp_message, "database conflict - call for help!"); } @@ -2610,24 +2728,24 @@ struct lease *find_lease (packet, share, ours) !permitted (packet, ip_lease -> pool -> permit_list)))) { if (!packet -> raw -> ciaddr.s_addr) release_lease (ip_lease, packet); - ip_lease = (struct lease *)0; + lease_dereference (&ip_lease, MDL); } /* Toss extra pointers to the same lease... */ - if (hw_lease == uid_lease) { + if (hw_lease && hw_lease == uid_lease) { #if defined (DEBUG_FIND_LEASE) log_info ("hardware lease and uid lease are identical."); #endif - hw_lease = (struct lease *)0; + lease_dereference (&hw_lease, MDL); } - if (ip_lease == hw_lease) { - hw_lease = (struct lease *)0; + if (ip_lease && ip_lease == hw_lease) { + lease_dereference (&hw_lease, MDL); #if defined (DEBUG_FIND_LEASE) log_info ("hardware lease and ip lease are identical."); #endif } - if (ip_lease == uid_lease) { - uid_lease = (struct lease *)0; + if (ip_lease && ip_lease == uid_lease) { + lease_dereference (&uid_lease, MDL); #if defined (DEBUG_FIND_LEASE) log_info ("uid lease and ip lease are identical."); #endif @@ -2654,7 +2772,8 @@ struct lease *find_lease (packet, share, ours) /* At this point, if fixed_lease is nonzero, we can assign it to this client. */ if (fixed_lease) { - lease = fixed_lease; + lease_reference (&lease, fixed_lease, MDL); + lease_dereference (&fixed_lease, MDL); #if defined (DEBUG_FIND_LEASE) log_info ("choosing fixed address."); #endif @@ -2673,9 +2792,11 @@ struct lease *find_lease (packet, share, ours) #if defined (DEBUG_FIND_LEASE) log_info ("choosing lease on requested address."); #endif - lease = ip_lease; - lease -> host = (struct host_decl *)0; + lease_reference (&lease, ip_lease, MDL); + if (lease -> host) + host_dereference (&lease -> host, MDL); } + lease_dereference (&ip_lease, MDL); } /* If we got a lease that matched the client identifier, we may want @@ -2689,13 +2810,16 @@ struct lease *find_lease (packet, share, ours) #if defined (DEBUG_FIND_LEASE) log_info ("not choosing uid lease."); #endif + lease_dereference (&uid_lease, MDL); } else { - lease = uid_lease; - lease -> host = (struct host_decl *)0; + lease_reference (&lease, uid_lease, MDL); + if (lease -> host) + host_dereference (&lease -> host, MDL); #if defined (DEBUG_FIND_LEASE) log_info ("choosing uid lease."); #endif } + lease_dereference (&uid_lease, MDL); } /* The lease that matched the hardware address is treated likewise. */ @@ -2704,16 +2828,19 @@ struct lease *find_lease (packet, share, ours) if (!packet -> raw -> ciaddr.s_addr && packet -> packet_type == DHCPREQUEST) dissociate_lease (hw_lease); + lease_dereference (&hw_lease, MDL); #if defined (DEBUG_FIND_LEASE) log_info ("not choosing hardware lease."); #endif } else { - lease = hw_lease; - lease -> host = (struct host_decl *)0; + lease_reference (&lease, hw_lease, MDL); + if (lease -> host) + host_dereference (&lease -> host, MDL); #if defined (DEBUG_FIND_LEASE) log_info ("choosing hardware lease."); #endif } + lease_dereference (&hw_lease, MDL); } /* If we found a host_decl but no matching address, try to @@ -2723,7 +2850,7 @@ struct lease *find_lease (packet, share, ours) if (lease && host && !lease -> host) { for (; host; host = host -> n_ipaddr) { if (!host -> fixed_addr) { - lease -> host = host; + host_reference (&lease -> host, host, MDL); break; } } @@ -2745,54 +2872,76 @@ struct lease *find_lease (packet, share, ours) to go back through the allocation process. */ if (ours) *ours = 1; - lease = (struct lease *)0; + lease_dereference (&lease, MDL); } out: if (have_client_identifier) data_string_forget (&client_identifier, MDL); + if (fixed_lease) + lease_dereference (&fixed_lease, MDL); + if (hw_lease) + lease_dereference (&hw_lease, MDL); + if (uid_lease) + lease_dereference (&uid_lease, MDL); + if (ip_lease) + lease_dereference (&ip_lease, MDL); + if (host) + host_dereference (&host, MDL); + + if (lease) { #if defined (DEBUG_FIND_LEASE) - if (lease) log_info ("Returning lease: %s.", piaddr (lease -> ip_addr)); - else - log_info ("Not returning a lease."); #endif - - return lease; + lease_reference (lp, lease, file, line); + lease_dereference (&lease, MDL); + return 1; + } +#if defined (DEBUG_FIND_LEASE) + log_info ("Not returning a lease."); +#endif + return 0; } /* Search the provided host_decl structure list for an address that's on the specified shared network. If one is found, mock up and return a lease structure for it; otherwise return the null pointer. */ -struct lease *mockup_lease (packet, share, hp) - struct packet *packet; - struct shared_network *share; - struct host_decl *hp; +int mockup_lease (struct lease **lp, struct packet *packet, + struct shared_network *share, struct host_decl *hp) { - static struct lease mock; + struct lease *lease = (struct lease *)0; const unsigned char **s; + isc_result_t status; - mock.subnet = find_host_for_network (&hp, &mock.ip_addr, share); - if (!mock.subnet) - return (struct lease *)0; - mock.next = mock.prev = (struct lease *)0; - mock.host = hp; - if (hp -> client_identifier.len > sizeof mock.uid_buf) - mock.uid = dmalloc (hp -> client_identifier.len, MDL); + status = lease_allocate (&lease, MDL); + if (status != ISC_R_SUCCESS) + return 0; + if (!find_host_for_network (&lease -> subnet, + &hp, &lease -> ip_addr, share)) { + lease_dereference (&lease, MDL); + return 0; + } + host_reference (&lease -> host, hp, MDL); + if (hp -> client_identifier.len > sizeof lease -> uid_buf) + lease -> uid = dmalloc (hp -> client_identifier.len, MDL); else - mock.uid = mock.uid_buf; - if (!mock.uid) - return (struct lease *)0; - memcpy (mock.uid, hp -> client_identifier.data, + lease -> uid = lease -> uid_buf; + if (!lease -> uid) { + lease_dereference (&lease, MDL); + return 0; + } + memcpy (lease -> uid, hp -> client_identifier.data, hp -> client_identifier.len); - mock.uid_len = hp -> client_identifier.len; - mock.hardware_addr = hp -> interface; - mock.starts = mock.timestamp = mock.ends = MIN_TIME; - mock.flags = STATIC_LEASE; - return &mock; + lease -> uid_len = hp -> client_identifier.len; + lease -> hardware_addr = hp -> interface; + lease -> starts = lease -> timestamp = lease -> ends = MIN_TIME; + lease -> flags = STATIC_LEASE; + lease_reference (lp, lease, MDL); + lease_dereference (&lease, MDL); + return 1; } /* Dereference all dynamically-allocated information that may be dangling @@ -2831,23 +2980,20 @@ void static_lease_dereference (lease, file, line) lease. If all of these possibilities fail to pan out, we don't return a lease at all. */ -struct lease *allocate_lease (packet, pool, ok, peer_has_leases) - struct packet *packet; - struct pool *pool; - int ok; - int *peer_has_leases; +int allocate_lease (struct lease **lp, struct packet *packet, + struct pool *pool, int *peer_has_leases) { - struct lease *lease, *lp; + struct lease *lease = (struct lease *)0; struct permit *permit; if (!pool) - return (struct lease *)0; + return 0; /* If we aren't elegible to try this pool, try a subsequent one. */ if ((pool -> prohibit_list && permitted (packet, pool -> prohibit_list)) || (pool -> permit_list && !permitted (packet, pool -> permit_list))) - return allocate_lease (packet, pool -> next, ok, + return allocate_lease (lp, packet, pool -> next, peer_has_leases); lease = pool -> last_lease; @@ -2880,8 +3026,8 @@ struct lease *allocate_lease (packet, pool, ok, peer_has_leases) /* If there are no leases in the pool that have expired, try the next one. */ if (!lease || lease -> ends > cur_time) - return allocate_lease (packet, - pool -> next, ok, peer_has_leases); + return allocate_lease (lp, packet, + pool -> next, peer_has_leases); /* If we find an abandoned lease, and no other lease qualifies better, take it. */ @@ -2890,17 +3036,17 @@ struct lease *allocate_lease (packet, pool, ok, peer_has_leases) if ((lease -> flags & ABANDONED_LEASE)) { /* If we already have a non-abandoned lease that we didn't love, but that's okay, don't reclaim the abandoned lease. */ - if (ok) - return allocate_lease (packet, pool -> next, - ok, peer_has_leases); - lp = allocate_lease (packet, pool -> next, 0, peer_has_leases); - if (!lp) { + if (*lp) + return allocate_lease (lp, packet, pool -> next, + peer_has_leases); + if (!allocate_lease (lp, packet, + pool -> next, peer_has_leases)) { log_error ("Reclaiming abandoned IP address %s.", piaddr (lease -> ip_addr)); lease -> flags &= ~ABANDONED_LEASE; - return lease; + lease_reference (lp, lease, MDL); } - return lp; + return 1; } /* If there's a lease we could take, but it had previously been @@ -2909,17 +3055,17 @@ struct lease *allocate_lease (packet, pool, ok, peer_has_leases) if (lease -> uid_len || lease -> hardware_addr.hlen) { /* If we're already in that boat, no need to consider allocating this particular lease. */ - if (ok) - return allocate_lease (packet, pool -> next, - ok, peer_has_leases); + if (*lp) + return allocate_lease (lp, packet, pool -> next, + peer_has_leases); - lp = allocate_lease (packet, pool -> next, 1, peer_has_leases); - if (lp) - return lp; - return lease; + allocate_lease (lp, packet, pool -> next, peer_has_leases); + if (*lp) + return 1; } - return lease; + lease_reference (lp, lease, MDL); + return 1; } /* Determine whether or not a permit exists on a particular permit list @@ -2985,7 +3131,7 @@ int locate_network (packet) { struct iaddr ia; struct data_string data; - struct subnet *subnet; + struct subnet *subnet = (struct subnet *)0; struct option_cache *oc; /* See if there's a subnet selection option. */ @@ -2995,9 +3141,12 @@ int locate_network (packet) /* If there's no SSO and no giaddr, then use the shared_network from the interface, if there is one. If not, fail. */ if (!oc && !packet -> raw -> giaddr.s_addr) { - if ((packet -> shared_network = - packet -> interface -> shared_network)) + if (packet -> interface -> shared_network) { + shared_network_reference + (&packet -> shared_network, + packet -> interface -> shared_network, MDL); return 1; + } return 0; } @@ -3009,11 +3158,9 @@ int locate_network (packet) packet -> options, (struct option_state *)0, &global_scope, oc, MDL)) { - packet -> shared_network = (struct shared_network *)0; return 0; } if (data.len != 4) { - packet -> shared_network = (struct shared_network *)0; return 0; } ia.len = 4; @@ -3025,14 +3172,14 @@ int locate_network (packet) } /* If we know the subnet on which the IP address lives, use it. */ - subnet = find_subnet (ia); - if (subnet) { - packet -> shared_network = subnet -> shared_network; + if (find_subnet (&subnet, ia, MDL)) { + shared_network_reference (&packet -> shared_network, + subnet -> shared_network, MDL); + subnet_dereference (&subnet, MDL); return 1; } /* Otherwise, fail. */ - packet -> shared_network = (struct shared_network *)0; return 0; } diff --git a/server/dhcpd.c b/server/dhcpd.c index acf1941a9..f29ebcee3 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -15,7 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The Internet Software Consortium nor the names + * 3. Neither the name of Internet Software Consortium nor the names * of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -43,11 +43,11 @@ #ifndef lint static char ocopyright[] = -"$Id: dhcpd.c,v 1.90 2000/05/03 06:32:09 mellon Exp $ Copyright 1995-2000 The Internet Software Consortium."; +"$Id: dhcpd.c,v 1.91 2000/05/16 23:03:43 mellon Exp $ Copyright 1995-2000 Internet Software Consortium."; #endif static char copyright[] = -"Copyright 1995-2000 The Internet Software Consortium."; +"Copyright 1995-2000 Internet Software Consortium."; static char arr [] = "All rights reserved."; static char message [] = "Internet Software Consortium DHCP Server"; static char contrib [] = "\nPlease contribute if you find this software useful."; @@ -60,7 +60,6 @@ static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.htm static void usage PROTO ((void)); TIME cur_time; -struct group root_group; struct binding_scope global_scope; struct iaddr server_identifier; @@ -305,12 +304,15 @@ int main (argc, argv, envp) /* Set up the OMAPI wrappers for various server database internal objects. */ dhcp_db_objects_setup (); + dhcp_common_objects_setup (); /* Set up the initial dhcp option universe. */ initialize_common_option_spaces (); initialize_server_option_spaces (); - root_group.authoritative = 0; + if (!group_allocate (&root_group, MDL)) + log_fatal ("Can't allocate root group!"); + root_group -> authoritative = 0; #if defined (NSUPDATE) /* Set up the standard name service updater routine. */ @@ -322,7 +324,7 @@ int main (argc, argv, envp) log_fatal ("can't parse standard name service updater!"); if (!(parse_executable_statements - (&root_group.statements, parse, &lose, context_any))) { + (&root_group -> statements, parse, &lose, context_any))) { end_parse (&parse); log_fatal ("can't parse standard name service updater!"); } @@ -344,7 +346,7 @@ int main (argc, argv, envp) (struct lease *)0, (struct option_state *)0, options, &global_scope, - &root_group, + root_group, (struct group *)0); memset (&db, 0, sizeof db); oc = lookup_option (&server_universe, options, SV_LEASE_FILE_NAME); @@ -448,12 +450,16 @@ int main (argc, argv, envp) /* Don't need the options anymore. */ option_state_dereference (&options, MDL); + group_write_hook = group_writer; + /* Start up the database... */ db_startup (lftest); if (lftest) exit (0); + dhcp_interface_setup_hook = dhcpd_interface_setup_hook; + /* Discover all the network interfaces and initialize them. */ discover_interfaces (DISCOVER_SERVER); @@ -596,21 +602,21 @@ void lease_pinged (from, packet, length) if (!outstanding_pings) return; - lp = find_lease_by_ip_addr (from); - - if (!lp) { - log_info ("unexpected ICMP Echo Reply from %s", piaddr (from)); + lp = (struct lease *)0; + if (!find_lease_by_ip_addr (&lp, from, MDL)) { + log_debug ("unexpected ICMP Echo Reply from %s", + piaddr (from)); return; } if (!lp -> state) { - log_error ("ICMP Echo Reply for %s late or spurious.\n", - piaddr (from)); - return; + log_debug ("ICMP Echo Reply for %s late or spurious.\n", + piaddr (from)); + goto out; } if (lp -> ends > cur_time) { - log_error ("ICMP Echo reply while lease %s valid\n", + log_debug ("ICMP Echo reply while lease %s valid\n", piaddr (from)); } @@ -623,6 +629,8 @@ void lease_pinged (from, packet, length) abandon_lease (lp, "pinged before offer"); cancel_timeout (lease_ping_timeout, lp); --outstanding_pings; + out: + lease_dereference (&lp, MDL); } void lease_ping_timeout (vlp) @@ -647,3 +655,59 @@ void lease_ping_timeout (vlp) dmalloc_dump_outstanding (); #endif } + +int dhcpd_interface_setup_hook (struct interface_info *ip, struct iaddr *ia) +{ + struct subnet *subnet; + struct shared_network *share; + isc_result_t status; + + /* Special case for fallback network - not sure why this is + necessary. */ + if (!ia) { + const char *fnn = "fallback-net"; + char *s; + status = shared_network_allocate (&ip -> shared_network, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("No memory for shared subnet: %s", + isc_result_totext (status)); + ip -> shared_network -> name = dmalloc (strlen (fnn) + 1, MDL); + strcpy (ip -> shared_network -> name, fnn); + return 1; + } + + /* If there's a registered subnet for this address, + connect it together... */ + subnet = (struct subnet *)0; + if (find_subnet (&subnet, *ia, MDL)) { + /* If this interface has multiple aliases on the same + subnet, ignore all but the first we encounter. */ + if (!subnet -> interface) { + subnet -> interface = ip; + subnet -> interface_address = *ia; + } else if (subnet -> interface != ip) { + log_error ("Multiple interfaces match the %s: %s %s", + "same subnet", + subnet -> interface -> name, ip -> name); + } + share = subnet -> shared_network; + if (ip -> shared_network && + ip -> shared_network != share) { + log_fatal ("Interface %s matches multiple shared %s", + ip -> name, "networks"); + } else { + if (!ip -> shared_network) + shared_network_reference + (&ip -> shared_network, share, MDL); + } + + if (!share -> interface) { + interface_reference (&share -> interface, ip, MDL); + } else if (share -> interface != ip) { + log_error ("Multiple interfaces match the %s: %s %s", + "same shared network", + share -> interface -> name, ip -> name); + } + } + return 1; +} diff --git a/server/failover.c b/server/failover.c index ddee88276..6159b5d38 100644 --- a/server/failover.c +++ b/server/failover.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: failover.c,v 1.13 2000/05/04 18:58:15 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: failover.c,v 1.14 2000/05/16 23:03:45 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -69,14 +69,21 @@ void dhcp_failover_startup () if (status != ISC_R_SUCCESS) { add_timeout (cur_time + 90, dhcp_failover_listener_restart, - state); + state, + (tvref_t)omapi_object_reference, + (tvunref_t) + omapi_object_dereference); } } else { status = (dhcp_failover_link_initiate ((omapi_object_t *)state)); if (status != ISC_R_SUCCESS) { add_timeout (cur_time + 90, - dhcp_failover_reconnect, state); + dhcp_failover_reconnect, state, + (tvref_t) + dhcp_failover_state_reference, + (tvunref_t) + dhcp_failover_state_dereference); } } if (status != ISC_R_SUCCESS) { @@ -101,28 +108,28 @@ isc_result_t enter_failover_peer (peer) dhcp_failover_state_t *dup = (dhcp_failover_state_t *)0; isc_result_t status; - status = find_failover_peer (&dup, peer -> name); + status = find_failover_peer (&dup, peer -> name, MDL); if (status == ISC_R_NOTFOUND) { if (failover_states) { - omapi_object_reference - ((omapi_object_t **)&peer -> next, - (omapi_object_t *)failover_states, MDL); - omapi_object_dereference - ((omapi_object_t **)&failover_states, MDL); + dhcp_failover_state_reference (&peer -> next, + failover_states, MDL); + dhcp_failover_state_dereference (&failover_states, + MDL); } - omapi_object_reference ((omapi_object_t **)&failover_states, - (omapi_object_t *)peer, MDL); + dhcp_failover_state_reference (&failover_states, peer, MDL); return ISC_R_SUCCESS; } + dhcp_failover_state_dereference (&dup, MDL); if (status == ISC_R_SUCCESS) return ISC_R_EXISTS; - return status; } -isc_result_t find_failover_peer (peer, name) +isc_result_t find_failover_peer (peer, name, file, line) dhcp_failover_state_t **peer; const char *name; + const char *file; + int line; { dhcp_failover_state_t *p; @@ -130,8 +137,7 @@ isc_result_t find_failover_peer (peer, name) if (!strcmp (name, p -> name)) break; if (p) - return omapi_object_reference ((omapi_object_t **)peer, - (omapi_object_t *)p, MDL); + return dhcp_failover_state_reference (peer, p, file, line); return ISC_R_NOTFOUND; } @@ -174,23 +180,20 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) return ISC_R_INVALIDARG; state = (dhcp_failover_state_t *)o; - obj = (dhcp_failover_link_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - obj -> type = dhcp_type_failover_link; + obj = (dhcp_failover_link_t *)0; + status = dhcp_failover_link_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; option_cache_reference (&obj -> peer_address, state -> address, MDL); obj -> peer_port = state -> port; - omapi_object_reference ((omapi_object_t **)&obj -> state_object, - (omapi_object_t *)state, MDL); + dhcp_failover_state_reference (&obj -> state_object, state, MDL); memset (&ds, 0, sizeof ds); if (!evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0, (struct option_state *)0, (struct option_state *)0, &global_scope, obj -> peer_address, MDL)) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + dhcp_failover_link_dereference (&obj, MDL); return ISC_R_UNEXPECTED; } @@ -198,7 +201,7 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) IPv4 addresses. */ status = omapi_addr_list_new (&addrs, ds.len / 4, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + dhcp_failover_link_dereference (&obj, MDL); return status; } @@ -227,8 +230,7 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) } else { if (ds.len != sizeof (struct in_addr)) { data_string_forget (&ds, MDL); - omapi_object_dereference ((omapi_object_t **)&obj, - MDL); + dhcp_failover_link_dereference (&obj, MDL); omapi_addr_list_dereference (&addrs, MDL); return ISC_R_INVALIDARG; } @@ -246,14 +248,8 @@ isc_result_t dhcp_failover_link_initiate (omapi_object_t *h) addrs, &local_addr); omapi_addr_list_dereference (&addrs, MDL); - /* If we didn't succeed in starting to connect, fail. */ - if (status != ISC_R_SUCCESS) { - loselose: - omapi_object_dereference ((omapi_object_t **)&obj, MDL); - return status; - } - omapi_object_dereference ((omapi_object_t **)&obj, MDL); - return ISC_R_SUCCESS; + dhcp_failover_link_dereference (&obj, MDL); + return status; } isc_result_t dhcp_failover_link_signal (omapi_object_t *h, @@ -284,8 +280,10 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h, if (link -> state_object && link -> state_object -> i_am == primary) { add_timeout (cur_time + 90, dhcp_failover_reconnect, - link -> state_object); - /* XXX this is a reference! */ + link -> state_object, + (tvref_t)dhcp_failover_state_reference, + (tvunref_t) + dhcp_failover_state_dereference); } return ISC_R_SUCCESS; } @@ -419,9 +417,8 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h, } if (!link -> state_object) - omapi_object_reference - ((omapi_object_t **)&link -> state_object, - (omapi_object_t *)state, MDL); + dhcp_failover_state_reference + (&link -> state_object, state, MDL); option_cache_reference (&link -> peer_address, state -> address, MDL); } @@ -732,8 +729,7 @@ isc_result_t dhcp_failover_link_destroy (omapi_object_t *h, link -> imsg = (failover_message_t *)0; } if (link -> state_object) - omapi_object_dereference - ((omapi_object_t **)&link -> state_object, MDL); + dhcp_failover_state_dereference (&link -> state_object, MDL); return ISC_R_SUCCESS; } @@ -826,12 +822,10 @@ isc_result_t dhcp_failover_listen (omapi_object_t *h) omapi_value_dereference (&value, MDL); - obj = (dhcp_failover_listener_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - obj -> type = dhcp_type_failover_listener; + obj = (dhcp_failover_listener_t *)0; + status = dhcp_failover_listener_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; obj -> local_port = local_addr.port; status = omapi_listen_addr ((omapi_object_t *)obj, &local_addr, 1); @@ -841,17 +835,16 @@ isc_result_t dhcp_failover_listen (omapi_object_t *h) status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + dhcp_failover_listener_dereference (&obj, MDL); return status; } status = omapi_object_reference (&obj -> inner, h, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + dhcp_failover_listener_dereference (&obj, MDL); return status; } - status = omapi_object_dereference ((omapi_object_t **)&obj, MDL); - return status; + return dhcp_failover_listener_dereference (&obj, MDL); } /* Signal handler for protocol listener - if we get a connect signal, @@ -882,19 +875,17 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o, if (!c || c -> type != omapi_type_connection) return ISC_R_INVALIDARG; - obj = (dhcp_failover_link_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - obj -> type = dhcp_type_failover_link; + obj = (dhcp_failover_link_t *)0; + status = dhcp_failover_link_allocate (&obj, MDL); + if (status != ISC_R_SUCCESS) + return status; obj -> peer_port = ntohs (c -> remote_addr.sin_port); status = omapi_object_reference (&obj -> outer, (omapi_object_t *)c, MDL); if (status != ISC_R_SUCCESS) { lose: - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + dhcp_failover_link_dereference (&obj, MDL); omapi_disconnect ((omapi_object_t *)c, 1); return status; } @@ -904,8 +895,7 @@ isc_result_t dhcp_failover_listener_signal (omapi_object_t *o, if (status != ISC_R_SUCCESS) goto lose; - omapi_object_dereference ((omapi_object_t **)&obj, MDL); - return status; + return dhcp_failover_link_dereference (&obj, MDL); } isc_result_t dhcp_failover_listener_set_value (omapi_object_t *h, @@ -985,31 +975,24 @@ isc_result_t dhcp_failover_register (omapi_object_t *h) if (status != ISC_R_SUCCESS) return status; - obj = (dhcp_failover_state_t *)dmalloc (sizeof *obj, MDL); - if (!obj) - return ISC_R_NOMEMORY; - memset (obj, 0, sizeof *obj); - obj -> refcnt = 1; - obj -> type = dhcp_type_failover_state; + obj = (dhcp_failover_state_t *)0; + dhcp_failover_state_allocate (&obj, MDL); obj -> listen_port = port; status = omapi_listen ((omapi_object_t *)obj, port, 1); - omapi_object_dereference ((omapi_object_t **)&obj, MDL); - if (status != ISC_R_SUCCESS) + if (status != ISC_R_SUCCESS) { + dhcp_failover_state_dereference (&obj, MDL); return status; + } status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj, MDL); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); + dhcp_failover_state_dereference (&obj, MDL); return status; } status = omapi_object_reference (&obj -> inner, h, MDL); - if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&obj, MDL); - return status; - } - + dhcp_failover_state_dereference (&obj, MDL); return status; } @@ -1043,11 +1026,14 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o, if (!strcmp (name, "disconnect")) { link = va_arg (ap, dhcp_failover_link_t *); - omapi_object_dereference (&state -> link_to_peer, MDL); + dhcp_failover_link_dereference (&state -> link_to_peer, MDL); dhcp_failover_state_transition (state, "disconnect"); if (state -> i_am == primary) add_timeout (cur_time + 90, dhcp_failover_reconnect, - state); /* XXX this is a reference! */ + state, + (tvref_t)dhcp_failover_state_reference, + (tvunref_t) + dhcp_failover_state_dereference); } else if (!strcmp (name, "message")) { link = va_arg (ap, dhcp_failover_link_t *); @@ -1058,17 +1044,17 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o, if (state -> link_to_peer) { omapi_disconnect ((omapi_object_t *) state -> link_to_peer, 1); - omapi_object_dereference + dhcp_failover_link_dereference (&state -> link_to_peer, MDL); dhcp_failover_state_transition (state, "disconnect"); } - omapi_object_reference (&state -> link_to_peer, - (omapi_object_t *)link, MDL); + dhcp_failover_link_reference (&state -> link_to_peer, + link, MDL); status = (dhcp_failover_send_connectack ((omapi_object_t *)link, 0)); if (status != ISC_R_SUCCESS) { - omapi_object_dereference + dhcp_failover_link_dereference (&state -> link_to_peer, MDL); omapi_disconnect (link -> outer, 1); return ISC_R_SUCCESS; @@ -1126,8 +1112,8 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o, FTR_DUP_CONNECTION, 0); omapi_disconnect (link -> outer, 0); } - omapi_object_reference (&state -> link_to_peer, - (omapi_object_t *)link, MDL); + dhcp_failover_link_reference (&state -> link_to_peer, + link, MDL); dhcp_failover_state_transition (state, "connect"); } else if (link -> imsg -> type == FTM_DISCONNECT) { if (link -> imsg -> reject_reason) { @@ -1274,28 +1260,17 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state, /* Now hook the ack queue to the beginning of the update queue. */ if (state -> update_queue_head) { - omapi_object_reference - ((omapi_object_t **) - &state -> ack_queue_tail -> next_pending, - (omapi_object_t *)state -> update_queue_head, - MDL); - omapi_object_dereference ((omapi_object_t **) - &state -> update_queue_head, - MDL); + lease_reference (&state -> ack_queue_tail -> next_pending, + state -> update_queue_head, MDL); + lease_dereference (&state -> update_queue_head, MDL); } - omapi_object_reference ((omapi_object_t **) - &state -> update_queue_head, - (omapi_object_t *)state -> ack_queue_head, - MDL); + lease_reference (&state -> update_queue_head, + state -> ack_queue_head, MDL); if (!state -> update_queue_tail) - omapi_object_reference - ((omapi_object_t **) - &state -> update_queue_tail, - (omapi_object_t *)state -> ack_queue_tail, MDL); - omapi_object_dereference ((omapi_object_t **) - &state -> ack_queue_tail, MDL); - omapi_object_dereference ((omapi_object_t **) - &state -> ack_queue_head, MDL); + lease_reference (&state -> update_queue_tail, + state -> ack_queue_tail, MDL); + lease_dereference (&state -> ack_queue_tail, MDL); + lease_dereference (&state -> ack_queue_head, MDL); state -> cur_unacked_updates = 0; } cancel_timeout (dhcp_failover_keepalive, state); @@ -1458,53 +1433,38 @@ isc_result_t dhcp_failover_send_updates (dhcp_failover_state_t *state) while (state -> max_flying_updates > state -> cur_unacked_updates && state -> update_queue_head) { /* Grab the head of the update queue. */ - omapi_object_reference ((omapi_object_t **)&lp, - (omapi_object_t *) - state -> update_queue_head, MDL); + lease_reference (&lp, state -> update_queue_head, MDL); /* Send the update to the peer. */ status = dhcp_failover_send_bind_update (state, lp); if (status != ISC_R_SUCCESS) { - omapi_object_dereference ((omapi_object_t **)&lp, MDL); + lease_dereference (&lp, MDL); return status; } lp -> flags &= ~ON_UPDATE_QUEUE; /* Take it off the head of the update queue and put the next item in the update queue at the head. */ - omapi_object_dereference ((omapi_object_t **) - &state -> update_queue_head, MDL); + lease_dereference (&state -> update_queue_head, MDL); if (lp -> next_pending) { - omapi_object_reference ((omapi_object_t **) - &state -> update_queue_head, - (omapi_object_t *) - lp -> next_pending, MDL); - omapi_object_dereference ((omapi_object_t **) - &lp -> next_pending, MDL); + lease_reference (&state -> update_queue_head, + lp -> next_pending, MDL); + lease_dereference (&lp -> next_pending, MDL); } else { - omapi_object_dereference ((omapi_object_t **) - &state -> update_queue_tail, - MDL); + lease_dereference (&state -> update_queue_tail, MDL); } if (state -> ack_queue_head) { - omapi_object_reference - ((omapi_object_t **) - &state -> ack_queue_tail -> next_pending, - (omapi_object_t *)lp, MDL); - omapi_object_dereference ((omapi_object_t **) - &state -> ack_queue_tail, - MDL); + lease_reference + (&state -> ack_queue_tail -> next_pending, + lp, MDL); + lease_dereference (&state -> ack_queue_tail, MDL); } else { - omapi_object_reference ((omapi_object_t **) - &state -> ack_queue_head, - (omapi_object_t *)lp, MDL); + lease_reference (&state -> ack_queue_head, lp, MDL); } - omapi_object_reference ((omapi_object_t **) - &state -> ack_queue_tail, - (omapi_object_t *)lp, MDL); + lease_reference (&state -> ack_queue_tail, lp, MDL); lp -> flags |= ON_ACK_QUEUE; - omapi_object_dereference ((omapi_object_t **)&lp, MDL); + lease_dereference (&lp, MDL); /* Count the object as an unacked update. */ state -> cur_unacked_updates++; @@ -1536,20 +1496,17 @@ int dhcp_failover_queue_update (struct lease *lease) dhcp_failover_ack_queue_remove (state, lease); if (state -> update_queue_head) { - omapi_object_reference - ((omapi_object_t **) - &state -> update_queue_tail -> next_pending, - (omapi_object_t *)lease, MDL); - omapi_object_dereference ((omapi_object_t **) - &state -> update_queue_tail, MDL); + if (state -> update_queue_tail -> next_pending) + lease_dereference + (&state -> update_queue_tail -> next_pending, + MDL); + lease_reference (&state -> update_queue_tail -> next_pending, + lease, MDL); + lease_dereference (&state -> update_queue_tail, MDL); } else { - omapi_object_reference ((omapi_object_t **) - &state -> update_queue_head, - (omapi_object_t *)lease, MDL); + lease_reference (&state -> update_queue_head, lease, MDL); } - omapi_object_reference ((omapi_object_t **) - &state -> update_queue_tail, - (omapi_object_t *)lease, MDL); + lease_reference (&state -> update_queue_tail, lease, MDL); lease -> flags |= ON_UPDATE_QUEUE; dhcp_failover_send_updates (state); return 1; @@ -1561,17 +1518,12 @@ void dhcp_failover_ack_queue_remove (dhcp_failover_state_t *state, struct lease *lp; if (state -> ack_queue_head == lease) { - omapi_object_dereference ((omapi_object_t **) - &state -> ack_queue_head, MDL); + lease_dereference (&state -> ack_queue_head, MDL); if (lease -> next_pending) { - omapi_object_reference ((omapi_object_t **) - &state -> ack_queue_head, - (omapi_object_t *) - lease -> next_pending, MDL); + lease_reference (&state -> ack_queue_head, + lease -> next_pending, MDL); } else { - omapi_object_dereference ((omapi_object_t **) - &state -> ack_queue_tail, - MDL); + lease_dereference (&state -> ack_queue_tail, MDL); } lease -> flags &= ~ON_ACK_QUEUE; return; @@ -1580,20 +1532,13 @@ void dhcp_failover_ack_queue_remove (dhcp_failover_state_t *state, lp -> next_pending != lease; lp = lp -> next_pending) ; if (lp) { - omapi_object_dereference ((omapi_object_t **) - &lp -> next_pending, MDL); + lease_dereference (&lp -> next_pending, MDL); if (lease -> next_pending) - omapi_object_reference ((omapi_object_t **) - &lp -> next_pending, - (omapi_object_t *) - lease -> next_pending, MDL); + lease_reference (&lp -> next_pending, + lease -> next_pending, MDL); else { - omapi_object_dereference ((omapi_object_t **) - &state -> ack_queue_tail, - MDL); - omapi_object_reference ((omapi_object_t **) - &state -> ack_queue_tail, - (omapi_object_t *)lp, MDL); + lease_dereference (&state -> ack_queue_tail, MDL); + lease_reference (&state -> ack_queue_tail, lp, MDL); } } lease -> flags &= ~ON_ACK_QUEUE; @@ -1628,7 +1573,9 @@ void dhcp_failover_reconnect (void *vs) log_info ("failover peer %s: %s", state -> name, isc_result_totext (status)); add_timeout (cur_time + 90, - dhcp_failover_listener_restart, state); + dhcp_failover_listener_restart, state, + (tvref_t)dhcp_failover_state_reference, + (tvunref_t)dhcp_failover_state_dereference); } } @@ -1642,7 +1589,9 @@ void dhcp_failover_listener_restart (void *vs) log_info ("failover peer %s: %s", state -> name, isc_result_totext (status)); add_timeout (cur_time + 90, - dhcp_failover_listener_restart, state); + dhcp_failover_listener_restart, state, + (tvref_t)dhcp_failover_state_reference, + (tvunref_t)dhcp_failover_state_dereference); } } @@ -1753,7 +1702,7 @@ isc_result_t dhcp_failover_state_destroy (omapi_object_t *h, return ISC_R_INVALIDARG; s = (dhcp_failover_state_t *)h; if (s -> link_to_peer) - omapi_object_dereference (&s -> link_to_peer, MDL); + dhcp_failover_link_dereference (&s -> link_to_peer, MDL); if (s -> name) dfree (s -> name, MDL); if (s -> address) @@ -2947,64 +2896,69 @@ isc_result_t dhcp_failover_send_poolresp (dhcp_failover_state_t *state, isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, failover_message_t *msg) { - struct lease lt, *lease; + struct lease *lt, *lease; struct iaddr ia; + int reason = FTR_MISC_REJECT; + const char *message; ia.len = sizeof msg -> assigned_addr; memcpy (ia.iabuf, &msg -> assigned_addr, ia.len); - lease = find_lease_by_ip_addr (ia); - if (!lease) { - log_info ("bind update on %s from %s: no such lease.", - piaddr (ia), state -> name); - return ISC_R_SUCCESS; + lease = (struct lease *)0; + if (!find_lease_by_ip_addr (&lease, ia, MDL)) { + message = "unknown IP address"; + reason = FTR_ILLEGAL_IP_ADDR; + goto bad; } /* XXX check for conflicts. */ /* Install the new info. */ - lt = *lease; - lt.on_expiry = 0; - lt.on_release = 0; - lt.on_commit = 0; + lt = (struct lease *)0; + if (!lease_copy (<, lease, MDL)) { + message = "no memory"; + goto bad; + } if (msg -> options_present & FTB_CHADDR) { - if (msg -> chaddr.count > sizeof lt.hardware_addr.hbuf) { - log_info ("bind update on %s from %s: chaddr too long", - piaddr (ia), state -> name); - return ISC_R_SUCCESS; + if (msg -> chaddr.count > sizeof lt -> hardware_addr.hbuf) { + message = "chaddr to long"; + goto bad; } - lt.hardware_addr.hlen = msg -> chaddr.count; - memcpy (lt.hardware_addr.hbuf, msg -> chaddr.data, + lt -> hardware_addr.hlen = msg -> chaddr.count; + memcpy (lt -> hardware_addr.hbuf, msg -> chaddr.data, msg -> chaddr.count); } if (msg -> options_present & FTB_CLIENT_IDENTIFIER) { - lt.uid_len = msg -> client_identifier.count; - if (lt.uid_len > sizeof lt.uid_buf) { - lt.uid_max = lt.uid_len; - lt.uid = dmalloc (lt.uid_len, MDL); - if (!lt.uid) - return ISC_R_SUCCESS; + lt -> uid_len = msg -> client_identifier.count; + if (lt -> uid_len > sizeof lt -> uid_buf) { + lt -> uid_max = lt -> uid_len; + lt -> uid = dmalloc (lt -> uid_len, MDL); + if (!lt -> uid) { + message = "no memory"; + goto bad; + } } else { - lt.uid_max = sizeof lt.uid_buf; - lt.uid = lt.uid_buf; + lt -> uid_max = sizeof lt -> uid_buf; + lt -> uid = lt -> uid_buf; } - memcpy (lt.uid, msg -> client_identifier.data, lt.uid_len); + memcpy (lt -> uid, + msg -> client_identifier.data, lt -> uid_len); } /* XXX Times may need to be adjusted based on clock skew! */ if (msg -> options_present & FTB_STOS) { - lt.starts = msg -> stos; + lt -> starts = msg -> stos; } if (msg -> options_present & FTB_LEASE_EXPIRY) { - lt.ends = msg -> expiry; + lt -> ends = msg -> expiry; } if (msg -> options_present & FTB_CLTT) { - lt.cltt = msg -> client_ltt; + lt -> cltt = msg -> client_ltt; } if (msg -> options_present & FTB_POTENTIAL_EXPIRY) { - lt.tsfp = msg -> potential_expiry; + lt -> tsfp = msg -> potential_expiry; } if (msg -> options_present & FTB_BINDING_STATUS) { @@ -3022,12 +2976,16 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, } /* Try to install the new information. */ - if (!supersede_lease (lease, <, 1, 0)) { + if (!supersede_lease (lease, lt, 1, 0)) { + message = "database update failed"; + bad: dhcp_failover_send_bind_ack (state, lease, msg, - FTR_MISC_REJECT, - "database update failed."); + reason, message); } else dhcp_failover_send_bind_ack (state, lease, msg, 0, 0); + if (lt) + lease_dereference (<, MDL); + lease_dereference (&lease, MDL); return ISC_R_SUCCESS; } @@ -3035,34 +2993,34 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state, failover_message_t *msg) { - struct lease lt, *lease; + struct lease *lt, *lease = (struct lease *)0; struct iaddr ia; + const char *message = "no memory"; ia.len = sizeof msg -> assigned_addr; memcpy (ia.iabuf, &msg -> assigned_addr, ia.len); - lease = find_lease_by_ip_addr (ia); - if (!lease) { - log_info ("bind update on %s from %s: no such lease.", - piaddr (ia), state -> name); - return ISC_R_SUCCESS; + if (!find_lease_by_ip_addr (&lease, ia, MDL)) { + message = "no such lease"; + goto bad; } /* XXX check for conflicts. */ /* Install the new info. */ - lt = *lease; - lt.on_expiry = 0; - lt.on_release = 0; - lt.on_commit = 0; + lt = (struct lease *)0; + if (!lease_copy (<, lease, MDL)) { + lease_dereference (&lease, MDL); + goto bad; + } /* XXX Times may need to be adjusted based on clock skew! */ if (msg -> options_present & FTB_POTENTIAL_EXPIRY) { - lt.tsfp = msg -> potential_expiry; + lt -> tsfp = msg -> potential_expiry; } /* Try to install the new information. */ - supersede_lease (lease, <, 1, 0); + supersede_lease (lease, lt, 1, 0); state -> cur_unacked_updates--; dhcp_failover_ack_queue_remove (state, lease); @@ -3071,7 +3029,17 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state, least one. */ dhcp_failover_send_updates (state); + out: + lease_dereference (&lease, MDL); + if (lt) + lease_dereference (<, MDL); + return ISC_R_SUCCESS; + + bad: + log_info ("bind update on %s from %s: %s.", + piaddr (ia), state -> name, message); + goto out; } #if defined (DEBUG_FAILOVER_MESSAGES) @@ -3168,4 +3136,11 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state) else return !hm; } + +OMAPI_OBJECT_ALLOC (dhcp_failover_state, dhcp_failover_state_t, + dhcp_type_failover_state) +OMAPI_OBJECT_ALLOC (dhcp_failover_listener, dhcp_failover_listener_t, + dhcp_type_failover_listener) +OMAPI_OBJECT_ALLOC (dhcp_failover_link, dhcp_failover_link_t, + dhcp_type_failover_link) #endif /* defined (FAILOVER_PROTOCOL) */ diff --git a/server/mdb.c b/server/mdb.c index 1803e38d7..c6b28978f 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: mdb.c,v 1.31 2000/05/04 18:58:16 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: mdb.c,v 1.32 2000/05/16 23:03:46 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -58,8 +58,6 @@ struct hash_table *lease_hw_addr_hash; struct hash_table *host_name_hash; static struct lease *dangling_leases; -struct hash_table *group_name_hash; - omapi_object_type_t *dhcp_type_host; isc_result_t enter_host (hd, dynamicp, commit) @@ -72,20 +70,21 @@ isc_result_t enter_host (hd, dynamicp, commit) struct executable_statement *esp; if (!host_name_hash) { - host_name_hash = new_hash (0, 0, 0); + host_name_hash = + new_hash ((hash_reference)host_reference, + (hash_dereference)host_dereference, 0); if (!host_name_hash) log_fatal ("Can't allocate host name hash"); } else { - hp = (struct host_decl *) - hash_lookup (host_name_hash, - (unsigned char *)hd -> name, - strlen (hd -> name)); + host_hash_lookup (&hp, host_name_hash, + (unsigned char *)hd -> name, + strlen (hd -> name), MDL); /* If it's deleted, we can supersede it. */ if (hp && (hp -> flags & HOST_DECL_DELETED)) { - delete_hash_entry (host_name_hash, - (unsigned char *)hd -> name, - strlen (hd -> name)); + host_hash_delete (host_name_hash, + (unsigned char *)hd -> name, + strlen (hd -> name), MDL); /* If the old entry wasn't dynamic, then we always have to keep the deletion. */ if (!hp -> flags & HOST_DECL_DYNAMIC) @@ -95,40 +94,42 @@ isc_result_t enter_host (hd, dynamicp, commit) /* If there isn't already a host decl matching this address, add it to the hash table. */ if (!hp) { - add_hash (host_name_hash, - (unsigned char *)hd -> name, - strlen (hd -> name), - (unsigned char *)hd); - hd -> refcnt++; /* XXX */ - } else + host_hash_add (host_name_hash, + (unsigned char *)hd -> name, + strlen (hd -> name), hd, MDL); + } else { /* XXX actually, we have to delete the old one XXX carefully and replace it. Not done yet. */ + host_dereference (&hp, MDL); return ISC_R_EXISTS; + } } - hd -> n_ipaddr = (struct host_decl *)0; + if (hd -> n_ipaddr) + host_dereference (&hd -> n_ipaddr, MDL); if (!hd -> type) hd -> type = dhcp_type_host; if (hd -> interface.hlen) { if (!host_hw_addr_hash) { - host_hw_addr_hash = new_hash (0, 0, 0); + host_hw_addr_hash = + new_hash ((hash_reference)host_reference, + (hash_dereference)host_dereference, + 0); if (!host_hw_addr_hash) log_fatal ("Can't allocate host/hw hash"); - } else - hp = (struct host_decl *) - hash_lookup (host_hw_addr_hash, - hd -> interface.hbuf, - hd -> interface.hlen); - - /* If there isn't already a host decl matching this - address, add it to the hash table. */ - if (!hp) { - add_hash (host_hw_addr_hash, - hd -> interface.hbuf, hd -> interface.hlen, - (unsigned char *)hd); - hd -> refcnt++; /* XXX */ + } else { + /* If there isn't already a host decl matching this + address, add it to the hash table. */ + if (!host_hash_lookup (&hp, host_hw_addr_hash, + hd -> interface.hbuf, + hd -> interface.hlen, MDL)) { + host_hash_add (host_hw_addr_hash, + hd -> interface.hbuf, + hd -> interface.hlen, + hd, MDL); + } } } @@ -138,8 +139,8 @@ isc_result_t enter_host (hd, dynamicp, commit) if (hp) { for (np = hp; np -> n_ipaddr; np = np -> n_ipaddr) ; - np -> n_ipaddr = hd; - hd -> refcnt++; /* XXX */ + host_reference (&np -> n_ipaddr, hd, MDL); + host_dereference (&hp, MDL); } /* See if there's a statement that sets the client identifier. @@ -167,34 +168,35 @@ isc_result_t enter_host (hd, dynamicp, commit) /* If there's no uid hash, make one; otherwise, see if there's already an entry in the hash for this host. */ if (!host_uid_hash) { - host_uid_hash = new_hash (0, 0, 0); + host_uid_hash = + new_hash ((hash_reference)host_reference, + (hash_dereference)host_dereference, + 0); if (!host_uid_hash) log_fatal ("Can't allocate host/uid hash"); - hp = (struct host_decl *)0; - } else - hp = ((struct host_decl *) - hash_lookup (host_uid_hash, - hd -> client_identifier.data, - hd -> client_identifier.len)); - - /* If there's already a host declaration for this - client identifier, add this one to the end of the - list. Otherwise, add it to the hash table. */ - if (hp) { - /* Don't link it in twice... */ - if (!np) { - for (np = hp; np -> n_ipaddr; - np = np -> n_ipaddr) - ; - np -> n_ipaddr = hd; - hd -> refcnt++; /* XXX */ - } } else { - add_hash (host_uid_hash, - hd -> client_identifier.data, - hd -> client_identifier.len, - (unsigned char *)hd); - hd -> refcnt++; /* XXX */ + /* If there's already a host declaration for this + client identifier, add this one to the end of the + list. Otherwise, add it to the hash table. */ + if (host_hash_lookup (&hp, host_uid_hash, + hd -> client_identifier.data, + hd -> client_identifier.len, + MDL)) { + /* Don't link it in twice... */ + if (!np) { + for (np = hp; np -> n_ipaddr; + np = np -> n_ipaddr) + ; + host_reference (&np -> n_ipaddr, + hd, MDL); + } + host_dereference (&hp, MDL); + } else { + host_hash_add (host_uid_hash, + hd -> client_identifier.data, + hd -> client_identifier.len, + hd, MDL); + } } } @@ -214,6 +216,7 @@ isc_result_t delete_host (hd, commit) { struct host_decl *hp = (struct host_decl *)0; struct host_decl *np = (struct host_decl *)0; + struct host_decl *foo; struct executable_statement *esp; int hw_head = 0, uid_head = 1; @@ -225,99 +228,90 @@ isc_result_t delete_host (hd, commit) hd -> flags |= HOST_DECL_DELETED; if (hd -> interface.hlen) { - if (host_hw_addr_hash) { - hp = (struct host_decl *) - hash_lookup (host_hw_addr_hash, - hd -> interface.hbuf, - hd -> interface.hlen); - - if (hp) { - if (hp == hd) { - delete_hash_entry - (host_hw_addr_hash, - hd -> interface.hbuf, - hd -> interface.hlen); - hw_head = 1; - --hd -> refcnt; - } - } else { - for (; hp; hp = hp -> n_ipaddr) { - np = hp; - if (hp == hd) - break; - } - if (hp) { - np -> n_ipaddr = hd -> n_ipaddr; - hd -> refcnt--; - } + if (host_hw_addr_hash) { + if (host_hash_lookup (&hp, host_hw_addr_hash, + hd -> interface.hbuf, + hd -> interface.hlen, MDL)) { + if (hp == hd) { + host_hash_delete (host_hw_addr_hash, + hd -> interface.hbuf, + hd -> interface.hlen, MDL); + hw_head = 1; + } else { + for (foo = hp; foo; foo = foo -> n_ipaddr) { + if (foo == hd) + break; + np = foo; + } + if (foo) { + host_dereference (&np -> n_ipaddr, MDL); + if (hd -> n_ipaddr) + host_reference (&np -> n_ipaddr, + hd -> n_ipaddr, MDL); } + } + host_dereference (&hp, MDL); } + } } /* If we got a client identifier, hash this entry by client identifier. */ if (hd -> client_identifier.len) { - if (host_uid_hash) { - hp = (struct host_decl *) - hash_lookup (host_uid_hash, - hd -> client_identifier.data, - hd -> client_identifier.len); - - if (hp) { - if (hp == hd) { - delete_hash_entry - (host_uid_hash, - hd -> client_identifier.data, - hd -> client_identifier.len); - uid_head = 1; - --hd -> refcnt; - } - } else { - for (; hp; hp = hp -> n_ipaddr) { - np = hp; - if (hp == hd) - break; - } - if (hp) { - np -> n_ipaddr = hd -> n_ipaddr; - hd -> refcnt--; - } + if (host_uid_hash) { + if (host_hash_lookup (&hp, host_uid_hash, + hd -> client_identifier.data, + hd -> client_identifier.len, MDL)) { + if (hp == hd) { + host_hash_delete (host_uid_hash, + hd -> client_identifier.data, + hd -> client_identifier.len, MDL); + uid_head = 1; + } else { + for (foo = hp; foo; foo = foo -> n_ipaddr) { + if (foo == hd) + break; + np = foo; + } + if (foo) { + if (np -> n_ipaddr) + host_dereference (&np -> n_ipaddr, MDL); + host_reference (&np -> n_ipaddr, + hd -> n_ipaddr, MDL); } + } + host_dereference (&hp, MDL); } + } } if (hd -> n_ipaddr) { if (uid_head && hd -> n_ipaddr -> client_identifier.len) { - add_hash (host_uid_hash, - hd -> n_ipaddr -> client_identifier.data, - hd -> n_ipaddr -> client_identifier.len, - (unsigned char *)hd -> n_ipaddr); - hd -> n_ipaddr -> refcnt++; + host_hash_add + (host_uid_hash, + hd -> n_ipaddr -> client_identifier.data, + hd -> n_ipaddr -> client_identifier.len, + hd -> n_ipaddr, MDL); } if (hw_head && hd -> n_ipaddr -> interface.hlen) { - add_hash (host_hw_addr_hash, - hd -> n_ipaddr -> interface.hbuf, - hd -> n_ipaddr -> interface.hlen, - (unsigned char *)hd -> n_ipaddr); - hd -> n_ipaddr -> refcnt++; + host_hash_add (host_hw_addr_hash, + hd -> n_ipaddr -> interface.hbuf, + hd -> n_ipaddr -> interface.hlen, + hd -> n_ipaddr, MDL); } - omapi_object_dereference ((omapi_object_t **)&hd -> n_ipaddr, - MDL); + host_dereference (&hd -> n_ipaddr, MDL); } if (host_name_hash) { - hp = (struct host_decl *) - hash_lookup (host_name_hash, - (unsigned char *)hd -> name, - strlen (hd -> name)); - - if (hp) { + if (host_hash_lookup (&hp, host_name_hash, + (unsigned char *)hd -> name, + strlen (hd -> name), MDL)) { if (hp == hd && !(hp -> flags & HOST_DECL_STATIC)) { - delete_hash_entry (host_name_hash, - (unsigned char *)hd -> name, - strlen (hd -> name)); - --hd -> refcnt; + host_hash_delete (host_name_hash, + (unsigned char *)hd -> name, + strlen (hd -> name), MDL); } + host_dereference (&hp, MDL); } } @@ -330,10 +324,9 @@ isc_result_t delete_host (hd, commit) return ISC_R_SUCCESS; } -struct host_decl *find_hosts_by_haddr (htype, haddr, hlen) - int htype; - const unsigned char *haddr; - unsigned hlen; +int find_hosts_by_haddr (struct host_decl **hp, int htype, + const unsigned char *haddr, unsigned hlen, + const char *file, int line) { struct host_decl *foo; struct hardware h; @@ -342,19 +335,15 @@ struct host_decl *find_hosts_by_haddr (htype, haddr, hlen) h.hbuf [0] = htype; memcpy (&h.hbuf [1], haddr, hlen); - foo = (struct host_decl *)hash_lookup (host_hw_addr_hash, - h.hbuf, h.hlen); - return foo; + return host_hash_lookup (hp, host_hw_addr_hash, + h.hbuf, h.hlen, file, line); } -struct host_decl *find_hosts_by_uid (data, len) - const unsigned char *data; - unsigned len; +int find_hosts_by_uid (struct host_decl **hp, + const unsigned char *data, unsigned len, + const char *file, int line) { - struct host_decl *foo; - - foo = (struct host_decl *)hash_lookup (host_uid_hash, data, len); - return foo; + return host_hash_lookup (hp, host_uid_hash, data, len, file, line); } /* More than one host_decl can be returned by find_hosts_by_haddr or @@ -365,10 +354,8 @@ struct host_decl *find_hosts_by_uid (data, len) the addr pointer, update the host pointer to point at the host_decl that matched, and return the subnet that matched. */ -struct subnet *find_host_for_network (host, addr, share) - struct host_decl **host; - struct iaddr *addr; - struct shared_network *share; +int find_host_for_network (struct subnet **sp, struct host_decl **host, + struct iaddr *addr, struct shared_network *share) { int i; struct subnet *subnet; @@ -392,126 +379,25 @@ struct subnet *find_host_for_network (host, addr, share) ip_address.len = 4; memcpy (ip_address.iabuf, fixed_addr.data + i, 4); - subnet = find_grouped_subnet (share, ip_address); - if (subnet) { + if (find_grouped_subnet (sp, share, ip_address, MDL)) { + struct host_decl *tmp = (struct host_decl *)0; *addr = ip_address; - *host = hp; + /* This is probably not necessary, but + just in case *host is the only reference + to that host declaration, make a temporary + reference so that dereferencing it doesn't + dereference hp out from under us. */ + host_reference (&tmp, *host, MDL); + host_dereference (host, MDL); + host_reference (host, hp, MDL); + host_dereference (&tmp, MDL); data_string_forget (&fixed_addr, MDL); - return subnet; + return 1; } } data_string_forget (&fixed_addr, MDL); } - return (struct subnet *)0; -} - -isc_result_t delete_group (struct group_object *group, int writep) -{ - struct group_object *d; - - /* The group should exist and be hashed - if not, it's invalid. */ - if (group_name_hash) - d = ((struct group_object *) - hash_lookup (group_name_hash, - (unsigned char *)group -> name, - strlen (group -> name))); - else - return ISC_R_INVALIDARG; - if (!d) - return ISC_R_INVALIDARG; - - /* Also not okay to delete a group that's not the one in - the hash table. */ - if (d != group) - return ISC_R_INVALIDARG; - - /* If it's dynamic, and we're deleting it, we can just blow away the - hash table entry. */ - if ((group -> flags & GROUP_OBJECT_DYNAMIC) && - !(group -> flags & GROUP_OBJECT_STATIC)) { - delete_hash_entry (group_name_hash, - (unsigned char *)group -> name, - strlen (group -> name)); - --group -> refcnt; - } else { - group -> flags |= GROUP_OBJECT_DELETED; - if (group -> group) { - dfree (group -> group, MDL); - group -> group = (struct group *)0; - } - } - - /* Store the group declaration in the lease file. */ - if (writep) { - if (!write_group (group)) - return ISC_R_IOERROR; - if (!commit_leases ()) - return ISC_R_IOERROR; - } - return ISC_R_SUCCESS; -} - -isc_result_t supersede_group (struct group_object *group, int writep) -{ - struct group_object *t, *u; - isc_result_t status; - - /* Register the group in the group name hash table, - so we can look it up later. */ - if (group_name_hash) { - t = ((struct group_object *) - hash_lookup (group_name_hash, - (unsigned char *)group -> name, - strlen (group -> name))); - if (t && t != group) { - /* If this isn't a dynamic entry, then we need to flag - the replacement as not dynamic either - otherwise, - if the dynamic entry is deleted later, the static - entry will come back next time the server is stopped - and restarted. */ - if (!(t -> flags & GROUP_OBJECT_DYNAMIC)) - group -> flags |= GROUP_OBJECT_STATIC; - - /* Delete the old object if it hasn't already been - deleted. If it has already been deleted, get rid of - the hash table entry. This is a legitimate - situation - a deleted static object needs to be kept - around so we remember it's deleted. */ - if (!(t -> flags & GROUP_OBJECT_DELETED)) - delete_group (t, 0); - else { - delete_hash_entry - (group_name_hash, - (unsigned char *)group -> name, - strlen (group -> name)); - omapi_object_dereference - ((omapi_object_t **)&t, MDL); - } - } - } else { - group_name_hash = new_hash (0, 0, 0); - t = (struct group_object *)0; - } - - /* Add the group to the group name hash if it's not - already there, and also thread it into the list of - dynamic groups if appropriate. */ - if (!t) { - add_hash (group_name_hash, - (unsigned char *)group -> name, - strlen (group -> name), - (unsigned char *)group); - } - - /* Store the group declaration in the lease file. */ - if (writep) { - if (!write_group (group)) - return ISC_R_IOERROR; - if (!commit_leases ()) - return ISC_R_IOERROR; - } - - return ISC_R_SUCCESS; + return 0; } void new_address_range (low, high, subnet, pool) @@ -524,6 +410,7 @@ void new_address_range (low, high, subnet, pool) unsigned min, max, i; char lowbuf [16], highbuf [16], netbuf [16]; struct shared_network *share = subnet -> shared_network; + isc_result_t status; /* All subnets should have attached shared network structures. */ if (!share) { @@ -534,17 +421,23 @@ void new_address_range (low, high, subnet, pool) /* Initialize the hash table if it hasn't been done yet. */ if (!lease_uid_hash) { - lease_uid_hash = new_hash (0, 0, 0); + lease_uid_hash = + new_hash ((hash_reference)lease_reference, + (hash_dereference)lease_dereference, 0); if (!lease_uid_hash) log_fatal ("Can't allocate lease/uid hash"); } if (!lease_ip_addr_hash) { - lease_ip_addr_hash = new_hash (0, 0, 0); + lease_ip_addr_hash = + new_hash ((hash_reference)lease_reference, + (hash_dereference)lease_dereference, 0); if (!lease_uid_hash) log_fatal ("Can't allocate lease/ip hash"); } if (!lease_hw_addr_hash) { - lease_hw_addr_hash = new_hash (0, 0, 0); + lease_hw_addr_hash = + new_hash ((hash_reference)lease_reference, + (hash_dereference)lease_dereference, 0); if (!lease_uid_hash) log_fatal ("Can't allocate lease/hw hash"); } @@ -579,6 +472,7 @@ void new_address_range (low, high, subnet, pool) } /* Get a lease structure for each address in the range. */ +#if defined (COMPACT_LEASES) address_range = new_leases (max - min + 1, MDL); if (!address_range) { strcpy (lowbuf, piaddr (low)); @@ -586,44 +480,62 @@ void new_address_range (low, high, subnet, pool) log_fatal ("No memory for address range %s-%s.", lowbuf, highbuf); } - memset (address_range, 0, (sizeof *address_range) * (max - min + 1)); - - /* Fill in the last lease if it hasn't been already... */ - if (!pool -> last_lease) { - pool -> last_lease = &address_range [0]; - } +#endif /* Fill out the lease structures with some minimal information. */ for (i = 0; i < max - min + 1; i++) { - address_range [i].ip_addr = - ip_addr (subnet -> net, subnet -> netmask, i + min); - address_range [i].starts = - address_range [i].timestamp = MIN_TIME; - address_range [i].ends = MIN_TIME; - address_range [i].subnet = subnet; - address_range [i].pool = pool; - address_range [i].billing_class = (struct class *)0; + struct lease *lp = (struct lease *)0; +#if defined (COMPACT_LEASES) + omapi_object_initialize ((omapi_object_t *)&address_range [i], + dhcp_type_lease, + 0, sizeof (struct lease), MDL); + lease_reference (&lp, &address_range [i], MDL); +#else + status = lease_allocate (&lp, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("No memory for lease %s: %s", + piaddr (ip_addr (subnet -> net, + subnet -> netmask, + i + min)), + isc_result_totext (status)); + /* Fill in the last lease if it hasn't been already... */ + if (!pool -> last_lease) { + lease_reference (&pool -> last_lease, lp, MDL); + } +#endif + lp -> ip_addr = ip_addr (subnet -> net, + subnet -> netmask, i + min); + lp -> starts = lp -> timestamp = MIN_TIME; + lp -> ends = MIN_TIME; + subnet_reference (&lp -> subnet, subnet, MDL); + pool_reference (&lp -> pool, pool, MDL); #if defined (FAILOVER_PROTOCOL) if (pool -> failover_peer && pool -> failover_peer -> i_am == secondary) - address_range [i].flags = PEER_IS_OWNER; + lp -> flags = PEER_IS_OWNER; else - address_range [i].flags = 0; + lp -> flags = 0; #endif - address_range [i].type = dhcp_type_lease; /* Link this entry into the list. */ - address_range [i].next = pool -> leases; - address_range [i].prev = (struct lease *)0; - pool -> leases = &address_range [i]; - if (address_range [i].next) - address_range [i].next -> prev = pool -> leases; - add_hash (lease_ip_addr_hash, - address_range [i].ip_addr.iabuf, - address_range [i].ip_addr.len, - (unsigned char *)&address_range [i]); - address_range [i].refcnt = 1; /* XXX */ + if (pool -> leases) { + lease_reference (&lp -> next, pool -> leases, MDL); + lease_dereference (&pool -> leases, MDL); + } + lease_reference (&pool -> leases, lp, MDL); + if (lp -> next) + lease_reference (&lp -> next -> prev, + pool -> leases, MDL); + lease_hash_add (lease_ip_addr_hash, lp -> ip_addr.iabuf, + lp -> ip_addr.len, lp, MDL); + } + +#if defined (COMPACT_LEASES) + /* Fill in the last lease if it hasn't been already... */ + if (!pool -> last_lease) { + lease_reference (&pool -> last_lease, &address_range [0], MDL); } +#endif /* Find out if any dangling leases are in range... */ plp = (struct lease *)0; @@ -639,45 +551,72 @@ void new_address_range (low, high, subnet, pool) the list of dangling leases. */ if (addr_eq (lnet, subnet -> net) && lhost >= i && lhost <= max) { + struct lease *lt = (struct lease *)0; if (plp) { - plp -> next = lp -> next; + if (plp -> next) + lease_dereference (&plp -> next, MDL); + lease_reference (&plp -> next, + lp -> next, MDL); } else { - dangling_leases = lp -> next; + lease_dereference (&dangling_leases, MDL); + lease_reference (&dangling_leases, + lp -> next, MDL); + } + lease_dereference (&lp -> next, MDL); + if (find_lease_by_ip_addr (<, lp -> ip_addr, MDL)) { + lt -> hostname = lp -> hostname; + lp -> hostname = (char *)0; + lt -> client_hostname = lp -> client_hostname; + lp -> client_hostname = (char *)0; + supersede_lease (lt, lp, 0, 0); + lease_dereference (<, MDL); } - lp -> next = (struct lease *)0; - address_range [lhost - i].hostname = lp -> hostname; - address_range [lhost - i].client_hostname = - lp -> client_hostname; - supersede_lease (&address_range [lhost - i], lp, 0, 0); - free_lease (lp, MDL); + lease_dereference (&lp, MDL); } else plp = lp; } } -struct subnet *find_subnet (addr) - struct iaddr addr; +/* There's really no way to free a lease, because of the aggregate way + we allocate them. */ + +isc_result_t dhcp_lease_free (omapi_object_t *lease, + const char *file, int line) +{ + return ISC_R_SUCCESS; +} + +int find_subnet (struct subnet **sp, + struct iaddr addr, const char *file, int line) { struct subnet *rv; for (rv = subnets; rv; rv = rv -> next_subnet) { - if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) - return rv; + if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) { + if (subnet_reference (sp, rv, + file, line) != ISC_R_SUCCESS) + return 0; + return 1; + } } - return (struct subnet *)0; + return 0; } -struct subnet *find_grouped_subnet (share, addr) - struct shared_network *share; - struct iaddr addr; +int find_grouped_subnet (struct subnet **sp, + struct shared_network *share, struct iaddr addr, + const char *file, int line) { struct subnet *rv; for (rv = share -> subnets; rv; rv = rv -> next_sibling) { - if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) - return rv; + if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) { + if (subnet_reference (sp, rv, + file, line) != ISC_R_SUCCESS) + return 0; + return 1; + } } - return (struct subnet *)0; + return 0; } int subnet_inner_than (subnet, scan, warnp) @@ -722,10 +661,11 @@ void enter_subnet (subnet) first. */ if (subnet_inner_than (subnet, scan, 1)) { if (prev) { - prev -> next_subnet = subnet; + subnet_reference (&prev -> next_subnet, + subnet, MDL); } else - subnets = subnet; - subnet -> next_subnet = scan; + subnet_reference (&subnets, subnet, MDL); + subnet_reference (&subnet -> next_subnet, scan, MDL); return; } prev = scan; @@ -741,9 +681,12 @@ void enter_subnet (subnet) void enter_shared_network (share) struct shared_network *share; { - /* XXX Sort the nets into a balanced tree to make searching quicker. */ - share -> next = shared_networks; - shared_networks = share; + if (shared_networks) { + shared_network_reference (&share -> next, + shared_networks, MDL); + shared_network_dereference (&shared_networks, MDL); + } + shared_network_reference (&shared_networks, share, MDL); } void new_shared_network_interface (cfile, share, name) @@ -752,6 +695,7 @@ void new_shared_network_interface (cfile, share, name) const char *name; { struct interface_info *ip; + isc_result_t status; if (share -> interface) { parse_warn (cfile, @@ -764,20 +708,24 @@ void new_shared_network_interface (cfile, share, name) if (!strcmp (ip -> name, name)) break; if (!ip) { - ip = dmalloc (sizeof *ip, MDL); - if (!ip) - log_fatal ("No memory to record interface %s", name); - memset (ip, 0, sizeof *ip); + status = interface_allocate (&ip, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("new_shared_network_interface %s: %s", + name, isc_result_totext (status)); if (strlen (name) > sizeof ip -> name) { memcpy (ip -> name, name, (sizeof ip -> name) - 1); ip -> name [(sizeof ip -> name) - 1] = 0; } else strcpy (ip -> name, name); - ip -> next = interfaces; + if (interfaces) { + interface_reference (&ip -> next, interfaces, MDL); + interface_dereference (&interfaces, MDL); + } + interface_reference (&interfaces, ip, MDL); ip -> flags = INTERFACE_REQUESTED; - interfaces = ip; - ip -> shared_network = share; - share -> interface = ip; + /* XXX this is a reference loop. */ + shared_network_reference (&ip -> shared_network, share, MDL); + interface_reference (&share -> interface, ip, MDL); } } @@ -790,25 +738,20 @@ void new_shared_network_interface (cfile, share, name) void enter_lease (lease) struct lease *lease; { - struct lease *comp = find_lease_by_ip_addr (lease -> ip_addr); + struct lease *comp = (struct lease *)0; + isc_result_t status; /* If we don't have a place for this lease yet, save it for later. */ - if (!comp) { - comp = new_lease (MDL); - if (!comp) { - log_fatal ("No memory for lease %s\n", - piaddr (lease -> ip_addr)); - } - memset (comp, 0, sizeof *comp); - *comp = *lease; - comp -> next = dangling_leases; - comp -> prev = (struct lease *)0; - dangling_leases = comp; + if (!find_lease_by_ip_addr (&comp, lease -> ip_addr, MDL)) { + if (comp -> next) + lease_dereference (&comp -> next, MDL); + if (dangling_leases) + lease_reference (&comp -> next, dangling_leases, MDL); + lease_reference (&dangling_leases, comp, MDL); + if (comp -> prev) + lease_dereference (&comp -> prev, MDL); } else { - /* Record the hostname information in the lease. */ - comp -> hostname = lease -> hostname; - comp -> client_hostname = lease -> client_hostname; supersede_lease (comp, lease, 0, 0); } } @@ -884,7 +827,7 @@ int supersede_lease (comp, lease, commit, propogate) /* If the lease has been billed to a class, remove the billing. */ if (comp -> billing_class && comp -> billing_class != lease -> billing_class) - unbill_class (comp, comp -> billing_class); + unbill_class (comp, comp -> billing_class); /* Copy the data files, but not the linkages. */ comp -> starts = lease -> starts; @@ -907,7 +850,9 @@ int supersede_lease (comp, lease, commit, propogate) comp -> uid_max = 0; } comp -> uid_len = lease -> uid_len; - comp -> host = lease -> host; + if (comp -> host) + host_dereference (&comp -> host, MDL); + host_reference (&comp -> host, lease -> host, MDL); comp -> hardware_addr = lease -> hardware_addr; comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) | (comp -> flags & ~EPHEMERAL_FLAGS)); @@ -916,6 +861,16 @@ int supersede_lease (comp, lease, commit, propogate) comp -> scope.bindings = lease -> scope.bindings; lease -> scope.bindings = (struct binding *)0; + /* Record the hostname information in the lease. */ + if (comp -> hostname) + dfree (comp -> hostname, MDL); + comp -> hostname = lease -> hostname; + lease -> hostname = (char *)0; + if (comp -> client_hostname) + dfree (comp -> client_hostname, MDL); + comp -> client_hostname = lease -> client_hostname; + lease -> client_hostname = (char *)0; + if (lease -> on_expiry) { if (comp -> on_expiry) executable_statement_dereference (&comp -> on_expiry, @@ -953,16 +908,37 @@ int supersede_lease (comp, lease, commit, propogate) /* Remove the lease from its current place in the timeout sequence. */ if (comp -> prev) { - comp -> prev -> next = comp -> next; + lease_dereference (&comp -> prev -> next, MDL); + if (comp -> next) { + lease_reference (&comp -> prev -> next, + comp -> next, MDL); + lease_dereference (&comp -> next, MDL); + } } else { - comp -> pool -> leases = comp -> next; + lease_dereference (&comp -> pool -> leases, MDL); + if (comp -> next) { + lease_reference (&comp -> pool -> leases, + comp -> next, MDL); + } } if (comp -> next) { - comp -> next -> prev = comp -> prev; + lease_dereference (&comp -> next -> prev, MDL); + if (comp -> prev) { + lease_reference (&comp -> next -> prev, + comp -> prev, MDL); + } } if (comp -> pool -> last_lease == comp) { - comp -> pool -> last_lease = comp -> prev; + lease_dereference (&comp -> pool -> last_lease, MDL); + if (comp -> prev) + lease_reference (&comp -> pool -> last_lease, + comp -> prev, MDL); } + if (comp -> prev) + lease_dereference (&comp -> prev, MDL); + if (comp -> next) + lease_dereference (&comp -> next, MDL); + /* If there's an expiry event on this lease, get rid of it (we may wind up putting it back, but we can't count on @@ -980,12 +956,16 @@ int supersede_lease (comp, lease, commit, propogate) && lp -> on_expiry #endif ) { - comp -> pool -> next_expiry = lp; + lease_dereference (&comp -> pool -> next_expiry, MDL); + lease_reference (&comp -> pool -> next_expiry, + lp, MDL); if (commit) add_timeout (lp -> ends, - pool_timer, lp -> pool); + pool_timer, lp -> pool, + (tvref_t)pool_reference, + (tvunref_t)pool_dereference); } else { - comp -> pool -> next_expiry = (struct lease *)0; + lease_dereference (&comp -> pool -> next_expiry, MDL); if (commit) cancel_timeout (pool_timer, comp -> pool); } @@ -1002,8 +982,12 @@ int supersede_lease (comp, lease, commit, propogate) if (!lp) { /* Nothing on the list yet? Just make comp the head of the list. */ - comp -> pool -> leases = comp; - comp -> pool -> last_lease = comp; + lease_reference (&comp -> pool -> leases, comp, MDL); + if (comp -> pool -> last_lease) { + lease_dereference (&comp -> pool -> last_lease, MDL); + lease_reference (&comp -> pool -> last_lease, + comp, MDL); + } } else if (lp -> ends > lease -> ends) { /* Skip down the list until we run out of list or find a place for comp. */ @@ -1012,19 +996,32 @@ int supersede_lease (comp, lease, commit, propogate) } if (lp -> ends > lease -> ends) { /* If we ran out of list, put comp at the end. */ - lp -> next = comp; - comp -> prev = lp; - comp -> next = (struct lease *)0; - comp -> pool -> last_lease = comp; + lease_reference (&lp -> next, comp, MDL); + lease_reference (&comp -> prev, lp, MDL); + if (comp -> pool -> last_lease) + lease_dereference (&comp -> pool -> last_lease, + MDL); + lease_reference (&comp -> pool -> last_lease, + comp, MDL); } else { /* If we didn't, put it between lp and the previous item on the list. */ - if ((comp -> prev = lp -> prev)) - comp -> prev -> next = comp; - else - comp -> pool -> leases = comp; - comp -> next = lp; - lp -> prev = comp; + if (lp -> prev) { + lease_reference (&comp -> prev, + lp -> prev, MDL); + lease_dereference (&lp -> prev -> next, MDL); + lease_reference (&comp -> prev -> next, + comp, MDL); + lease_dereference (&lp -> prev, MDL); + } else { + if (comp -> pool -> leases) + lease_dereference + (&comp -> pool -> leases, MDL); + lease_reference (&comp -> pool -> leases, + comp, MDL); + } + lease_reference (&comp -> next, lp, MDL); + lease_reference (&lp -> prev, comp, MDL); } } else { /* Skip up the list until we run out of list @@ -1034,22 +1031,39 @@ int supersede_lease (comp, lease, commit, propogate) } if (lp -> ends < lease -> ends) { /* If we ran out of list, put comp at the beginning. */ - lp -> prev = comp; - comp -> next = lp; - comp -> prev = (struct lease *)0; - comp -> pool -> leases = comp; + lease_reference (&lp -> prev, comp, MDL); + lease_reference (&comp -> next, lp, MDL); + if (comp -> pool -> leases) + lease_dereference (&comp -> pool -> leases, + MDL); + lease_reference (&comp -> pool -> leases, comp, MDL); } else { /* If we didn't, put it between lp and the next item on the list. */ - if ((comp -> next = lp -> next)) - comp -> next -> prev = comp; - else - comp -> pool -> last_lease = comp; - comp -> prev = lp; - lp -> next = comp; + if (lp -> next) { + lease_reference (&comp -> next, + lp -> next, MDL); + lease_dereference (&lp -> next -> prev, MDL); + lease_reference (&lp -> next -> prev, + comp, MDL); + lease_dereference (&lp -> next, MDL); + } else { + /* XXX are we really supposed to + XXX be doing this? */ + if (comp -> pool -> last_lease) + lease_dereference + (&comp -> pool -> last_lease, + MDL); + lease_reference (&comp -> pool -> last_lease, + comp, MDL); + } + lease_reference (&comp -> prev, lp, MDL); + lease_reference (&lp -> next, comp, MDL); } } - comp -> pool -> insertion_point = comp; + if (comp -> pool -> insertion_point) + lease_dereference (&comp -> pool -> insertion_point, MDL); + lease_reference (&comp -> pool -> insertion_point, comp, MDL); #if defined (FAILOVER_PROTOCOL) if (comp -> ends <= cur_time && lease -> ends > cur_time) { if (lease -> flags & PEER_IS_OWNER) @@ -1105,11 +1119,20 @@ int supersede_lease (comp, lease, commit, propogate) if (!comp -> pool -> next_expiry || (comp -> ends < comp -> pool -> next_expiry -> ends)) { - comp -> pool -> next_expiry = comp; + if (comp -> pool -> next_expiry) + lease_dereference + (&comp -> pool -> next_expiry, + MDL); + lease_reference + (&comp -> pool -> next_expiry, + comp, MDL); if (commit) - add_timeout (comp -> ends, - pool_timer, - comp -> pool); + add_timeout (comp -> ends, + pool_timer, + comp -> pool, + (tvref_t)pool_reference, + (tvunref_t) + pool_dereference); } else if (comp -> ends == comp -> pool -> next_expiry -> ends) { /* If there are other leases that expire at @@ -1128,7 +1151,12 @@ int supersede_lease (comp, lease, commit, propogate) #endif install = foo; } - comp -> pool -> next_expiry = install; + lease_dereference + (&comp -> pool -> next_expiry, + MDL); + lease_reference + (&comp -> pool -> next_expiry, + install, MDL); } } } @@ -1145,13 +1173,86 @@ int supersede_lease (comp, lease, commit, propogate) ; } -/* Release the specified lease and re-hash it as appropriate. */ +/* Copy the contents of one lease into another, correctly maintaining + reference counts. */ +int lease_copy (struct lease **lp, + struct lease *lease, const char *file, int line) +{ + struct lease *lt = (struct lease *)0; + isc_result_t status; + status = lease_allocate (<, MDL); + if (status != ISC_R_SUCCESS) + return 0; + + lt -> ip_addr = lease -> ip_addr; + lt -> starts = lease -> starts; + lt -> ends = lease -> ends; + lt -> timestamp = lease -> timestamp; + lt -> uid_len = lease -> uid_len; + lt -> uid_max = lease -> uid_max; + if (lease -> uid == lease -> uid_buf) { + lt -> uid = lt -> uid_buf; + memcpy (lt -> uid_buf, lease -> uid_buf, sizeof lt -> uid_buf); + } else { + lt -> uid = dmalloc (lt -> uid_max, MDL); + if (!lt -> uid) { + lease_dereference (<, MDL); + return 0; + } + memcpy (lt -> uid, lease -> uid, lease -> uid_max); + } + if (lease -> hostname) { + lt -> hostname = dmalloc (strlen (lease -> hostname) + 1, MDL); + if (!lt -> hostname) { + lease_dereference (<, MDL); + return 0; + } + strcpy (lt -> hostname, lease -> hostname); + } + if (lease -> client_hostname) { + lt -> client_hostname = + dmalloc (strlen (lease -> client_hostname) + 1, MDL); + if (!lt -> client_hostname) { + lease_dereference (<, MDL); + return 0; + } + strcpy (lt -> client_hostname, lease -> client_hostname); + } + lt -> scope = lease -> scope; + host_reference (< -> host, lease -> host, file, line); + subnet_reference (< -> subnet, lease -> subnet, file, line); + pool_reference (< -> pool, lease -> pool, file, line); + class_reference (< -> billing_class, + lease -> billing_class, file, line); + lt -> hardware_addr = lease -> hardware_addr; + if (lease -> on_expiry) + executable_statement_reference (< -> on_expiry, + lease -> on_expiry, + file, line); + if (lease -> on_commit) + executable_statement_reference (< -> on_commit, + lease -> on_commit, + file, line); + if (lease -> on_release) + executable_statement_reference (< -> on_release, + lease -> on_release, + file, line); + lt -> flags = lease -> flags; + lt -> tstp = lease -> tstp; + lt -> tsfp = lease -> tsfp; + lt -> cltt = lease -> cltt; + status = lease_reference (lp, lt, file, line); + lease_dereference (<, MDL); + return status == ISC_R_SUCCESS; +} + +/* Release the specified lease and re-hash it as appropriate. */ void release_lease (lease, packet) struct lease *lease; struct packet *packet; { - struct lease lt; + struct lease *lt; /* If there are statements to execute when the lease is released, execute them. */ @@ -1171,20 +1272,21 @@ void release_lease (lease, packet) executable_statement_dereference (&lease -> on_expiry, MDL); if (lease -> ends > cur_time) { - lt = *lease; + if (!lease_copy (<, lease, MDL)) + return; - /* Events are reference-counted, so we can't just randomly - make copies. */ - lt.on_expiry = 0; - lt.on_release = 0; - lt.on_commit = 0; + if (lt -> on_commit) + executable_statement_dereference (< -> on_commit, + MDL); /* Blow away any bindings. */ - lt.scope.bindings = (struct binding *)0; + lt -> scope.bindings = (struct binding *)0; - lt.ends = cur_time; - lt.billing_class = (struct class *)0; - supersede_lease (lease, <, 1, 1); + lt -> ends = cur_time; + if (lt -> billing_class) + class_dereference (< -> billing_class, MDL); + supersede_lease (lease, lt, 1, 1); + lease_dereference (<, MDL); } } @@ -1195,28 +1297,35 @@ void abandon_lease (lease, message) struct lease *lease; const char *message; { - struct lease lt; + struct lease *lt = (struct lease *)0; lease -> flags |= ABANDONED_LEASE; - lt = *lease; + if (!lease_copy (<, lease, MDL)) + return; - /* Events are reference-counted, so we can't just randomly - make copies. */ - lt.on_expiry = 0; - lt.on_release = 0; - lt.on_commit = 0; + if (lt -> on_expiry) + executable_statement_dereference (&lease -> on_expiry, MDL); + if (lt -> on_release) + executable_statement_dereference (&lease -> on_release, MDL); + if (lt -> on_commit) + executable_statement_dereference (&lease -> on_commit, MDL); /* Blow away any bindings. */ - lt.scope.bindings = (struct binding *)0; + lt -> scope.bindings = (struct binding *)0; - lt.ends = cur_time; /* XXX */ + lt -> ends = cur_time; /* XXX */ log_error ("Abandoning IP address %s: %s", piaddr (lease -> ip_addr), message); - lt.hardware_addr.hlen = 0; - lt.uid = (unsigned char *)0; - lt.uid_len = 0; - lt.billing_class = (struct class *)0; - supersede_lease (lease, <, 1, 1); + lt -> hardware_addr.hlen = 0; + if (lt -> uid != lt -> uid_buf) + dfree (lt -> uid, MDL); + lt -> uid = (unsigned char *)0; + lt -> uid_len = 0; + lt -> uid_max = 0; + if (lt -> billing_class) + class_dereference (< -> billing_class, MDL); + supersede_lease (lease, lt, 1, 1); + lease_dereference (<, MDL); } /* Abandon the specified lease (set its timeout to infinity and its @@ -1225,25 +1334,32 @@ void abandon_lease (lease, message) void dissociate_lease (lease) struct lease *lease; { - struct lease lt; + struct lease *lt = (struct lease *)0; - lt = *lease; - /* Events are reference-counted, so we can't just randomly - make copies. */ - lt.on_expiry = 0; - lt.on_release = 0; - lt.on_commit = 0; + if (!lease_copy (<, lease, MDL)) + return; + + if (lt -> on_expiry) + executable_statement_dereference (&lease -> on_expiry, MDL); + if (lt -> on_release) + executable_statement_dereference (&lease -> on_release, MDL); + if (lt -> on_commit) + executable_statement_dereference (&lease -> on_commit, MDL); /* Blow away any bindings. */ - lt.scope.bindings = (struct binding *)0; - - if (lt.ends > cur_time) - lt.ends = cur_time; - lt.hardware_addr.hlen = 0; - lt.uid = (unsigned char *)0; - lt.uid_len = 0; - lt.billing_class = (struct class *)0; - supersede_lease (lease, <, 1, 1); + lt -> scope.bindings = (struct binding *)0; + + lt -> ends = cur_time; /* XXX */ + lt -> hardware_addr.hlen = 0; + if (lt -> uid != lt -> uid_buf) + dfree (lt -> uid, MDL); + lt -> uid = (unsigned char *)0; + lt -> uid_len = 0; + lt -> uid_max = 0; + if (lt -> billing_class) + class_dereference (< -> billing_class, MDL); + supersede_lease (lease, lt, 1, 1); + lease_dereference (<, MDL); } /* Timer called when a lease in a particular pool expires. */ @@ -1309,40 +1425,41 @@ void pool_timer (vpool) pool -> local_leases++; #endif } - pool -> next_expiry = lease; - if (lease) - add_timeout (lease -> ends, pool_timer, pool); + if (pool -> next_expiry) + lease_dereference (&pool -> next_expiry, MDL); + if (lease) { + lease_reference (&pool -> next_expiry, lease, MDL); + add_timeout (lease -> ends, pool_timer, pool, + (tvref_t)pool_reference, + (tvunref_t)pool_dereference); + } } /* Locate the lease associated with a given IP address... */ -struct lease *find_lease_by_ip_addr (addr) - struct iaddr addr; +int find_lease_by_ip_addr (struct lease **lp, struct iaddr addr, + const char *file, int line) { - struct lease *lease = (struct lease *)hash_lookup (lease_ip_addr_hash, - addr.iabuf, - addr.len); - return lease; + return lease_hash_lookup (lp, lease_ip_addr_hash, + addr.iabuf, addr.len, file, line); } -struct lease *find_lease_by_uid (uid, len) - const unsigned char *uid; - unsigned len; +int find_lease_by_uid (struct lease **lp, const unsigned char *uid, + unsigned len, const char *file, int line) { - struct lease *lease = (struct lease *)hash_lookup (lease_uid_hash, - uid, len); - return lease; + if (len == 0) + return 0; + return lease_hash_lookup (lp, lease_uid_hash, uid, len, file, line); } -struct lease *find_lease_by_hw_addr (hwaddr, hwlen) - const unsigned char *hwaddr; - unsigned hwlen; +int find_lease_by_hw_addr (struct lease **lp, + const unsigned char *hwaddr, unsigned hwlen, + const char *file, int line) { - struct lease *lease; - - lease = (struct lease *)hash_lookup (lease_hw_addr_hash, - hwaddr, hwlen); - return lease; + if (hwlen == 0) + return 0; + return lease_hash_lookup (lp, lease_hw_addr_hash, + hwaddr, hwlen, file, line); } /* Add the specified lease to the uid hash. */ @@ -1350,19 +1467,20 @@ struct lease *find_lease_by_hw_addr (hwaddr, hwlen) void uid_hash_add (lease) struct lease *lease; { - struct lease *head = - find_lease_by_uid (lease -> uid, lease -> uid_len); + struct lease *head = (struct lease *)0; struct lease *scan; + /* If it's not in the hash, just add it. */ - if (!head) - add_hash (lease_uid_hash, lease -> uid, - lease -> uid_len, (unsigned char *)lease); + if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL)) + lease_hash_add (lease_uid_hash, lease -> uid, + lease -> uid_len, lease, MDL); else { /* Otherwise, attach it to the end of the list. */ for (scan = head; scan -> n_uid; scan = scan -> n_uid) ; - scan -> n_uid = lease; + lease_reference (&scan -> n_uid, lease, MDL); + lease_dereference (&head, MDL); } } @@ -1371,13 +1489,13 @@ void uid_hash_add (lease) void uid_hash_delete (lease) struct lease *lease; { - struct lease *head = - find_lease_by_uid (lease -> uid, lease -> uid_len); + struct lease *head = (struct lease *)0; struct lease *scan; /* If it's not in the hash, we have no work to do. */ - if (!head) { - lease -> n_uid = (struct lease *)0; + if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL)) { + if (lease -> n_uid) + lease_dereference (&lease -> n_uid, MDL); return; } @@ -1385,25 +1503,33 @@ void uid_hash_delete (lease) remove the hash table entry and add a new one with the next lease on the list (if there is one). */ if (head == lease) { - delete_hash_entry (lease_uid_hash, - lease -> uid, lease -> uid_len); - if (lease -> n_uid) - add_hash (lease_uid_hash, - lease -> n_uid -> uid, - lease -> n_uid -> uid_len, - (unsigned char *)(lease -> n_uid)); + lease_hash_delete (lease_uid_hash, + lease -> uid, lease -> uid_len, MDL); + if (lease -> n_uid) { + lease_hash_add (lease_uid_hash, + lease -> n_uid -> uid, + lease -> n_uid -> uid_len, + lease -> n_uid, MDL); + lease_dereference (&lease -> n_uid, MDL); + } } else { /* Otherwise, look for the lease in the list of leases attached to the hash table entry, and remove it if we find it. */ for (scan = head; scan -> n_uid; scan = scan -> n_uid) { if (scan -> n_uid == lease) { - scan -> n_uid = scan -> n_uid -> n_uid; + lease_dereference (&scan -> n_uid, MDL); + if (lease -> n_uid) { + lease_reference (&scan -> n_uid, + lease -> n_uid, MDL); + lease_dereference (&lease -> n_uid, + MDL); + } break; } } + lease_dereference (&head, MDL); } - lease -> n_uid = (struct lease *)0; } /* Add the specified lease to the hardware address hash. */ @@ -1411,22 +1537,22 @@ void uid_hash_delete (lease) void hw_hash_add (lease) struct lease *lease; { - struct lease *head = - find_lease_by_hw_addr (lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen); + struct lease *head = (struct lease *)0; struct lease *scan; /* If it's not in the hash, just add it. */ - if (!head) - add_hash (lease_hw_addr_hash, - lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen, - (unsigned char *)lease); + if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, + lease -> hardware_addr.hlen, MDL)) + lease_hash_add (lease_hw_addr_hash, + lease -> hardware_addr.hbuf, + lease -> hardware_addr.hlen, + lease, MDL); else { /* Otherwise, attach it to the end of the list. */ for (scan = head; scan -> n_hw; scan = scan -> n_hw) ; - scan -> n_hw = lease; + lease_reference (&scan -> n_hw, lease, MDL); + lease_dereference (&head, MDL); } } @@ -1435,14 +1561,14 @@ void hw_hash_add (lease) void hw_hash_delete (lease) struct lease *lease; { - struct lease *head = - find_lease_by_hw_addr (lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen); + struct lease *head = (struct lease *)0; struct lease *scan; /* If it's not in the hash, we have no work to do. */ - if (!head) { - lease -> n_hw = (struct lease *)0; + if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, + lease -> hardware_addr.hlen, MDL)) { + if (lease -> n_hw) + lease_dereference (&lease -> n_hw, MDL); return; } @@ -1450,26 +1576,34 @@ void hw_hash_delete (lease) remove the hash table entry and add a new one with the next lease on the list (if there is one). */ if (head == lease) { - delete_hash_entry (lease_hw_addr_hash, + lease_hash_delete (lease_hw_addr_hash, lease -> hardware_addr.hbuf, - lease -> hardware_addr.hlen); - if (lease -> n_hw) - add_hash (lease_hw_addr_hash, - lease -> n_hw -> hardware_addr.hbuf, - lease -> n_hw -> hardware_addr.hlen, - (unsigned char *)(lease -> n_hw)); + lease -> hardware_addr.hlen, MDL); + if (lease -> n_hw) { + lease_hash_add (lease_hw_addr_hash, + lease -> n_hw -> hardware_addr.hbuf, + lease -> n_hw -> hardware_addr.hlen, + lease -> n_hw, MDL); + lease_dereference (&lease -> n_hw, MDL); + } } else { /* Otherwise, look for the lease in the list of leases attached to the hash table entry, and remove it if we find it. */ for (scan = head; scan -> n_hw; scan = scan -> n_hw) { if (scan -> n_hw == lease) { - scan -> n_hw = scan -> n_hw -> n_hw; + lease_dereference (&scan -> n_hw, MDL); + if (lease -> n_hw) { + lease_reference (&scan -> n_hw, + lease -> n_hw, MDL); + lease_dereference (&lease -> n_hw, + MDL); + } break; } } } - lease -> n_hw = (struct lease *)0; + lease_dereference (&head, MDL); } /* Write all interesting leases to permanent storage. */ @@ -1633,3 +1767,7 @@ void dump_subnets () } } } + +HASH_FUNCTIONS (lease, const unsigned char *, struct lease) +HASH_FUNCTIONS (host, const unsigned char *, struct host_decl) +HASH_FUNCTIONS (class, const char *, struct class) diff --git a/server/omapi.c b/server/omapi.c index fdb788263..9938668b3 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -50,17 +50,14 @@ #ifndef lint static char copyright[] = -"$Id: omapi.c,v 1.27 2000/03/17 04:00:32 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: omapi.c,v 1.28 2000/05/16 23:03:48 mellon Exp $ Copyright (c) 1999-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" #include omapi_object_type_t *dhcp_type_lease; -omapi_object_type_t *dhcp_type_group; omapi_object_type_t *dhcp_type_pool; -omapi_object_type_t *dhcp_type_shared_network; -omapi_object_type_t *dhcp_type_subnet; omapi_object_type_t *dhcp_type_class; #if defined (FAILOVER_PROTOCOL) omapi_object_type_t *dhcp_type_failover_state; @@ -81,37 +78,26 @@ void dhcp_db_objects_setup () dhcp_lease_stuff_values, dhcp_lease_lookup, dhcp_lease_create, - dhcp_lease_remove); + dhcp_lease_remove, + dhcp_lease_free, 0, + sizeof (struct lease)); if (status != ISC_R_SUCCESS) log_fatal ("Can't register lease object type: %s", isc_result_totext (status)); - status = omapi_object_type_register (&dhcp_type_group, - "group", - dhcp_group_set_value, - dhcp_group_get_value, - dhcp_group_destroy, - dhcp_group_signal_handler, - dhcp_group_stuff_values, - dhcp_group_lookup, - dhcp_group_create, - dhcp_group_remove); + status = omapi_object_type_register (&dhcp_type_class, + "class", + dhcp_class_set_value, + dhcp_class_get_value, + dhcp_class_destroy, + dhcp_class_signal_handler, + dhcp_class_stuff_values, + dhcp_class_lookup, + dhcp_class_create, + dhcp_class_remove, 0, 0, + sizeof (struct class)); if (status != ISC_R_SUCCESS) - log_fatal ("Can't register group object type: %s", - isc_result_totext (status)); - - status = omapi_object_type_register (&dhcp_type_host, - "host", - dhcp_host_set_value, - dhcp_host_get_value, - dhcp_host_destroy, - dhcp_host_signal_handler, - dhcp_host_stuff_values, - dhcp_host_lookup, - dhcp_host_create, - dhcp_host_remove); - if (status != ISC_R_SUCCESS) - log_fatal ("Can't register host object type: %s", + log_fatal ("Can't register class object type: %s", isc_result_totext (status)); status = omapi_object_type_register (&dhcp_type_pool, @@ -123,7 +109,8 @@ void dhcp_db_objects_setup () dhcp_pool_stuff_values, dhcp_pool_lookup, dhcp_pool_create, - dhcp_pool_remove); + dhcp_pool_remove, 0, 0, + sizeof (struct pool)); if (status != ISC_R_SUCCESS) log_fatal ("Can't register pool object type: %s", @@ -139,7 +126,9 @@ void dhcp_db_objects_setup () dhcp_failover_state_stuff, dhcp_failover_state_lookup, dhcp_failover_state_create, - dhcp_failover_state_remove); + dhcp_failover_state_remove, + 0, 0, + sizeof (dhcp_failover_state_t)); if (status != ISC_R_SUCCESS) log_fatal ("Can't register failover state object type: %s", @@ -152,7 +141,8 @@ void dhcp_db_objects_setup () dhcp_failover_link_destroy, dhcp_failover_link_signal, dhcp_failover_link_stuff_values, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof (dhcp_failover_link_t)); if (status != ISC_R_SUCCESS) log_fatal ("Can't register failover link object type: %s", @@ -165,7 +155,9 @@ void dhcp_db_objects_setup () dhcp_failover_listener_destroy, dhcp_failover_listener_signal, dhcp_failover_listener_stuff, - 0, 0, 0); + 0, 0, 0, 0, 0, + sizeof + (dhcp_failover_listener_t)); if (status != ISC_R_SUCCESS) log_fatal ("Can't register failover listener object type: %s", @@ -311,9 +303,8 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) uid_hash_delete (lease); hw_hash_delete (lease); if (lease -> billing_class) - omapi_object_dereference - ((omapi_object_t **)&lease -> billing_class, - file, line); + class_dereference + (&lease -> billing_class, file, line); if (lease -> uid && lease -> uid != &lease -> uid_buf [0]) { dfree (lease -> uid, MDL); lease -> uid = &lease -> uid_buf [0]; @@ -328,14 +319,11 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) lease -> hostname = (char *)0; } if (lease -> host) - omapi_object_dereference ((omapi_object_t **)&lease -> host, - file, line); + host_dereference (&lease -> host, file, line); if (lease -> subnet) - omapi_object_dereference ((omapi_object_t **)&lease -> subnet, - file, line); + subnet_dereference (&lease -> subnet, file, line); if (lease -> pool) - omapi_object_dereference ((omapi_object_t **)&lease -> pool, - file, line); + pool_dereference (&lease -> pool, file, line); if (lease -> on_expiry) executable_statement_dereference (&lease -> on_expiry, file, line); @@ -372,7 +360,11 @@ isc_result_t dhcp_lease_signal_handler (omapi_object_t *h, if (lease -> hardware_addr.hlen == 0 || lease -> hardware_addr.hlen > 17) return ISC_R_INVALIDARG; - if (!write_lease (lease) || !commit_leases ()) { + if (!write_lease (lease) || !commit_leases () +#if defined (FAILOVER_PROTOCOL) + || !dhcp_failover_queue_update (lease) +#endif + ) { return ISC_R_IOERROR; } updatep = 1; @@ -582,10 +574,10 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, /* Now look for an IP address. */ status = omapi_get_value_str (ref, id, "ip-address", &tv); if (status == ISC_R_SUCCESS) { - lease = ((struct lease *) - hash_lookup (lease_ip_addr_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + lease = (struct lease *)0; + lease_hash_lookup (&lease, lease_ip_addr_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); @@ -593,29 +585,33 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, then the query was invalid. */ if (*lp && *lp != (omapi_object_t *)lease) { omapi_object_dereference (lp, MDL); + lease_dereference (&lease, MDL); return ISC_R_KEYCONFLICT; } else if (!lease) { if (*lp) omapi_object_dereference (lp, MDL); return ISC_R_NOTFOUND; - } else if (!*lp) + } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ omapi_object_reference (lp, (omapi_object_t *)lease, MDL); + lease_dereference (&lease, MDL); + } } /* Now look for a client identifier. */ status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv); if (status == ISC_R_SUCCESS) { - lease = ((struct lease *) - hash_lookup (lease_uid_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + lease = (struct lease *)0; + lease_hash_lookup (&lease, lease_uid_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (*lp && *lp != (omapi_object_t *)lease) { omapi_object_dereference (lp, MDL); + lease_dereference (&lease, MDL); return ISC_R_KEYCONFLICT; } else if (!lease) { if (*lp) @@ -630,20 +626,22 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, XXX the reference. */ omapi_object_reference (lp, (omapi_object_t *)lease, MDL); + lease_dereference (&lease, MDL); } } /* Now look for a hardware address. */ status = omapi_get_value_str (ref, id, "hardware-address", &tv); if (status == ISC_R_SUCCESS) { - lease = ((struct lease *) - hash_lookup (lease_hw_addr_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + lease = (struct lease *)0; + lease_hash_lookup (&lease, lease_hw_addr_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (*lp && *lp != (omapi_object_t *)lease) { omapi_object_dereference (lp, MDL); + lease_dereference (&lease, MDL); return ISC_R_KEYCONFLICT; } else if (!lease) { if (*lp) @@ -652,12 +650,14 @@ isc_result_t dhcp_lease_lookup (omapi_object_t **lp, } else if (lease -> n_hw) { if (*lp) omapi_object_dereference (lp, MDL); + lease_dereference (&lease, MDL); return ISC_R_MULTIPLE; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ omapi_object_reference (lp, (omapi_object_t *)lease, MDL); + lease_dereference (&lease, MDL); } } @@ -680,317 +680,6 @@ isc_result_t dhcp_lease_remove (omapi_object_t *lp, return ISC_R_NOTIMPLEMENTED; } -isc_result_t dhcp_group_set_value (omapi_object_t *h, - omapi_object_t *id, - omapi_data_string_t *name, - omapi_typed_data_t *value) -{ - struct group_object *group; - isc_result_t status; - int foo; - - if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; - group = (struct group_object *)h; - - /* XXX For now, we can only set these values on new group objects. - XXX Soon, we need to be able to update group objects. */ - if (!omapi_ds_strcmp (name, "name")) { - if (group -> name) - return ISC_R_EXISTS; - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { - group -> name = dmalloc (value -> u.buffer.len + 1, - MDL); - if (!group -> name) - return ISC_R_NOMEMORY; - memcpy (group -> name, - value -> u.buffer.value, - value -> u.buffer.len); - group -> name [value -> u.buffer.len] = 0; - } else - return ISC_R_INVALIDARG; - return ISC_R_SUCCESS; - } - - if (!omapi_ds_strcmp (name, "statements")) { - if (group -> group && group -> group -> statements) - return ISC_R_EXISTS; - if (!group -> group) - group -> group = clone_group (&root_group, MDL); - if (!group -> group) - return ISC_R_NOMEMORY; - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { - struct parse *parse; - int lose = 0; - parse = (struct parse *)0; - status = new_parse (&parse, -1, - (char *)value -> u.buffer.value, - value -> u.buffer.len, - "network client"); - if (status != ISC_R_SUCCESS) - return status; - if (!(parse_executable_statements - (&group -> group -> statements, parse, &lose, - context_any))) { - end_parse (&parse); - return ISC_R_BADPARSE; - } - end_parse (&parse); - return ISC_R_SUCCESS; - } else - return ISC_R_INVALIDARG; - } - - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> set_value) { - status = ((*(h -> inner -> type -> set_value)) - (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) - return status; - } - - return ISC_R_NOTFOUND; -} - - -isc_result_t dhcp_group_get_value (omapi_object_t *h, omapi_object_t *id, - omapi_data_string_t *name, - omapi_value_t **value) -{ - struct group_object *group; - isc_result_t status; - struct data_string ip_addrs; - - if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; - group = (struct group_object *)h; - - if (!omapi_ds_strcmp (name, "name")) - return omapi_make_string_value (value, - name, group -> name, MDL); - - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> get_value) { - status = ((*(h -> inner -> type -> get_value)) - (h -> inner, id, name, value)); - if (status == ISC_R_SUCCESS) - return status; - } - return ISC_R_NOTFOUND; -} - -isc_result_t dhcp_group_destroy (omapi_object_t *h, const char *file, int line) -{ - struct group_object *group, *t; - isc_result_t status; - - if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; - group = (struct group_object *)h; - - if (group -> name) { - if (group_name_hash) { - t = ((struct group_object *) - hash_lookup (group_name_hash, - (unsigned char *)group -> name, - strlen (group -> name))); - if (t) { - delete_hash_entry (group_name_hash, - (unsigned char *) - group -> name, - strlen (group -> name)); - --group -> refcnt; - } - } - dfree (group -> name, file, line); - group -> name = (char *)0; - } - if (group -> group) - group -> group = (struct group *)0; /* XXX refcounts!!! */ - - return ISC_R_SUCCESS; -} - -isc_result_t dhcp_group_signal_handler (omapi_object_t *h, - const char *name, va_list ap) -{ - struct group_object *group, *t; - isc_result_t status; - int updatep = 0; - - if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; - group = (struct group_object *)h; - - if (!strcmp (name, "updated")) { - /* A group object isn't valid if a subgroup hasn't yet been - associated with it. */ - if (!group -> group) - return ISC_R_INVALIDARG; - - /* Group objects always have to have names. */ - if (!group -> name) { - char hnbuf [64]; - sprintf (hnbuf, "ng%08lx%08lx", - cur_time, (unsigned long)group); - group -> name = dmalloc (strlen (hnbuf) + 1, MDL); - if (!group -> name) - return ISC_R_NOMEMORY; - strcpy (group -> name, hnbuf); - } - - supersede_group (group, 1); - updatep = 1; - } - - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> get_value) { - status = ((*(h -> inner -> type -> signal_handler)) - (h -> inner, name, ap)); - if (status == ISC_R_SUCCESS) - return status; - } - if (updatep) - return ISC_R_SUCCESS; - return ISC_R_NOTFOUND; -} - -isc_result_t dhcp_group_stuff_values (omapi_object_t *c, - omapi_object_t *id, - omapi_object_t *h) -{ - struct group_object *group; - isc_result_t status; - - if (h -> type != dhcp_type_group) - return ISC_R_INVALIDARG; - group = (struct group_object *)h; - - /* Write out all the values. */ - if (group -> name) { - status = omapi_connection_put_name (c, "name"); - if (status != ISC_R_SUCCESS) - return status; - status = omapi_connection_put_string (c, group -> name); - if (status != ISC_R_SUCCESS) - return status; - } - - /* Write out the inner object, if any. */ - if (h -> inner && h -> inner -> type -> stuff_values) { - status = ((*(h -> inner -> type -> stuff_values)) - (c, id, h -> inner)); - if (status == ISC_R_SUCCESS) - return status; - } - - return ISC_R_SUCCESS; -} - -isc_result_t dhcp_group_lookup (omapi_object_t **lp, - omapi_object_t *id, omapi_object_t *ref) -{ - omapi_value_t *tv = (omapi_value_t *)0; - isc_result_t status; - struct group_object *group; - - /* First see if we were sent a handle. */ - status = omapi_get_value_str (ref, id, "handle", &tv); - if (status == ISC_R_SUCCESS) { - status = omapi_handle_td_lookup (lp, tv -> value); - - omapi_value_dereference (&tv, MDL); - if (status != ISC_R_SUCCESS) - return status; - - /* Don't return the object if the type is wrong. */ - if ((*lp) -> type != dhcp_type_group) { - omapi_object_dereference (lp, MDL); - return ISC_R_INVALIDARG; - } - } - - /* Now look for a name. */ - status = omapi_get_value_str (ref, id, "name", &tv); - if (status == ISC_R_SUCCESS) { - if (group_name_hash) { - group = ((struct group_object *) - hash_lookup (group_name_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); - omapi_value_dereference (&tv, MDL); - - /* Don't register a deleted group here. */ - if (group -> flags & GROUP_OBJECT_DELETED) { - if (!*lp) - return ISC_R_NOTFOUND; - group = (struct group_object *)0; - } - - if (*lp && *lp != (omapi_object_t *)group) { - omapi_object_dereference (lp, MDL); - return ISC_R_KEYCONFLICT; - } else if (!group) { - omapi_object_dereference (lp, MDL); - return ISC_R_NOTFOUND; - } else if (!*lp) { - /* XXX fix so that hash lookup itself creates - XXX the reference. */ - omapi_object_reference (lp, - (omapi_object_t *)group, - MDL); - } - } else if (!*lp) - return ISC_R_NOTFOUND; - } - - /* If we get to here without finding a group, no valid key was - specified. */ - if (!*lp) - return ISC_R_NOKEYS; - - if (((struct group_object *)(*lp)) -> flags & GROUP_OBJECT_DELETED) { - omapi_object_dereference (lp, MDL); - return ISC_R_NOTFOUND; - } - return ISC_R_SUCCESS; -} - -isc_result_t dhcp_group_create (omapi_object_t **lp, - omapi_object_t *id) -{ - struct group_object *group; - group = (struct group_object *)dmalloc (sizeof (struct group_object), - MDL); - if (!group) - return ISC_R_NOMEMORY; - memset (group, 0, sizeof *group); - group -> refcnt = 0; - group -> type = dhcp_type_group; - group -> flags = GROUP_OBJECT_DYNAMIC; - return omapi_object_reference (lp, (omapi_object_t *)group, MDL); -} - -isc_result_t dhcp_group_remove (omapi_object_t *lp, - omapi_object_t *id) -{ - struct group_object *group; - isc_result_t status; - if (lp -> type != dhcp_type_group) - return ISC_R_INVALIDARG; - group = (struct group_object *)lp; - - group -> flags |= GROUP_OBJECT_DELETED; - if (!write_group (group) || !commit_leases ()) - return ISC_R_IOERROR; - - status = dhcp_group_destroy ((omapi_object_t *)group, MDL); - - return ISC_R_SUCCESS; -} - isc_result_t dhcp_host_set_value (omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, @@ -1028,20 +717,19 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, if (value -> type == omapi_datatype_data || value -> type == omapi_datatype_string) { struct group_object *group; - group = ((struct group_object *) - hash_lookup (group_name_hash, - value -> u.buffer.value, - value -> u.buffer.len)); + group = (struct group_object *)0; + group_hash_lookup (&group, group_name_hash, + value -> u.buffer.value, + value -> u.buffer.len, MDL); if (!group || (group -> flags & GROUP_OBJECT_DELETED)) return ISC_R_NOTFOUND; - host -> group = group -> group; + group_reference (&host -> group, group -> group, MDL); if (host -> named_group) - omapi_object_dereference - ((omapi_object_t **) - &host -> named_group, MDL); - omapi_object_reference ((omapi_object_t **) - &host -> named_group, - (omapi_object_t *)group, MDL); + group_object_dereference (&host -> named_group, + MDL); + group_object_reference (&host -> named_group, + group, MDL); + group_object_dereference (&group, MDL); } else return ISC_R_INVALIDARG; return ISC_R_SUCCESS; @@ -1126,15 +814,17 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, } if (!omapi_ds_strcmp (name, "statements")) { - if (!host -> group) - host -> group = clone_group (&root_group, MDL); - else { + if (!host -> group) { + if (!clone_group (&host -> group, root_group, MDL)) + return ISC_R_NOMEMORY; + } else { if (host -> group -> statements && (!host -> named_group || host -> group != host -> named_group -> group) && - host -> group != &root_group) + host -> group != root_group) return ISC_R_EXISTS; - host -> group = clone_group (host -> group, MDL); + if (!clone_group (&host -> group, host -> group, MDL)) + return ISC_R_NOMEMORY; } if (!host -> group) return ISC_R_NOMEMORY; @@ -1258,6 +948,7 @@ isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line) /* Currently, this is completely hopeless - have to complete reference counting support for server OMAPI objects. */ + /* XXX okay, that's completed - now what? */ return ISC_R_SUCCESS; } @@ -1437,48 +1128,58 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, /* Now look for a client identifier. */ status = omapi_get_value_str (ref, id, "dhcp-client-identifier", &tv); if (status == ISC_R_SUCCESS) { - host = ((struct host_decl *) - hash_lookup (host_uid_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + host = (struct host_decl *)0; + host_hash_lookup (&host, host_uid_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (*lp && *lp != (omapi_object_t *)host) { omapi_object_dereference (lp, MDL); + if (host) + host_dereference (&host, MDL); return ISC_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { if (*lp) omapi_object_dereference (lp, MDL); + if (host) + host_dereference (&host, MDL); return ISC_R_NOTFOUND; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ omapi_object_reference (lp, (omapi_object_t *)host, MDL); + host_dereference (&host, MDL); } } /* Now look for a hardware address. */ status = omapi_get_value_str (ref, id, "hardware-address", &tv); if (status == ISC_R_SUCCESS) { - host = ((struct host_decl *) - hash_lookup (host_hw_addr_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + host = (struct host_decl *)0; + host_hash_lookup (&host, host_hw_addr_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (*lp && *lp != (omapi_object_t *)host) { omapi_object_dereference (lp, MDL); + if (host) + host_dereference (&host, MDL); return ISC_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { if (*lp) omapi_object_dereference (lp, MDL); + if (host) + host_dereference (&host, MDL); return ISC_R_NOTFOUND; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ omapi_object_reference (lp, (omapi_object_t *)host, MDL); + host_dereference (&host, MDL); } } @@ -1488,10 +1189,10 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, struct lease *l; /* first find the lease for this ip address */ - l = ((struct lease *) - hash_lookup (lease_ip_addr_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + l = (struct lease *)0; + lease_hash_lookup (&l, lease_ip_addr_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (!l && !*lp) @@ -1499,47 +1200,57 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, if (l) { /* now use that to get a host */ - host = ((struct host_decl *) - hash_lookup (host_hw_addr_hash, - l -> hardware_addr.hbuf, - l -> hardware_addr.hlen)); + host = (struct host_decl *)0; + host_hash_lookup (&host, host_hw_addr_hash, + l -> hardware_addr.hbuf, + l -> hardware_addr.hlen, MDL); if (host && *lp && *lp != (omapi_object_t *)host) { omapi_object_dereference (lp, MDL); + if (host) + host_dereference (&host, MDL); return ISC_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { + if (host) + host_dereference (&host, MDL); if (!*lp) return ISC_R_NOTFOUND; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ - omapi_object_reference (lp, - (omapi_object_t *)host, - MDL); + omapi_object_reference (lp, (omapi_object_t *)host, + MDL); + host_dereference (&host, MDL); } + lease_dereference (&l, MDL); } } /* Now look for a name. */ status = omapi_get_value_str (ref, id, "name", &tv); if (status == ISC_R_SUCCESS) { - host = ((struct host_decl *) - hash_lookup (host_name_hash, - tv -> value -> u.buffer.value, - tv -> value -> u.buffer.len)); + host = (struct host_decl *)0; + host_hash_lookup (&host, host_name_hash, + tv -> value -> u.buffer.value, + tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); if (*lp && *lp != (omapi_object_t *)host) { omapi_object_dereference (lp, MDL); + if (host) + host_dereference (&host, MDL); return ISC_R_KEYCONFLICT; } else if (!host || (host -> flags & HOST_DECL_DELETED)) { + if (host) + host_dereference (&host, MDL); return ISC_R_NOTFOUND; } else if (!*lp) { /* XXX fix so that hash lookup itself creates XXX the reference. */ omapi_object_reference (lp, (omapi_object_t *)host, MDL); + host_dereference (&host, MDL); } } @@ -1554,15 +1265,16 @@ isc_result_t dhcp_host_create (omapi_object_t **lp, omapi_object_t *id) { struct host_decl *hp; - hp = (struct host_decl *)dmalloc (sizeof (struct host_decl), MDL); - if (!hp) - return ISC_R_NOMEMORY; - memset (hp, 0, sizeof *hp); - hp -> refcnt = 0; - hp -> type = dhcp_type_host; - hp -> group = &root_group; /* XXX */ + isc_result_t status; + hp = (struct host_decl *)0; + status = host_allocate (&hp, MDL); + if (status != ISC_R_SUCCESS) + return status; + group_reference (&hp -> group, root_group, MDL); hp -> flags = HOST_DECL_DYNAMIC; - return omapi_object_reference (lp, (omapi_object_t *)hp, MDL); + status = omapi_object_reference (lp, (omapi_object_t *)hp, MDL); + host_dereference (&hp, MDL); + return status; } isc_result_t dhcp_host_remove (omapi_object_t *lp, @@ -1581,9 +1293,9 @@ isc_result_t dhcp_host_remove (omapi_object_t *lp, } isc_result_t dhcp_pool_set_value (omapi_object_t *h, - omapi_object_t *id, - omapi_data_string_t *name, - omapi_typed_data_t *value) + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) { struct pool *pool; isc_result_t status; @@ -1608,8 +1320,8 @@ isc_result_t dhcp_pool_set_value (omapi_object_t *h, isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id, - omapi_data_string_t *name, - omapi_value_t **value) + omapi_data_string_t *name, + omapi_value_t **value) { struct pool *pool; isc_result_t status; @@ -1670,8 +1382,8 @@ isc_result_t dhcp_pool_signal_handler (omapi_object_t *h, } isc_result_t dhcp_pool_stuff_values (omapi_object_t *c, - omapi_object_t *id, - omapi_object_t *h) + omapi_object_t *id, + omapi_object_t *h) { struct pool *pool; isc_result_t status; @@ -1694,7 +1406,7 @@ isc_result_t dhcp_pool_stuff_values (omapi_object_t *c, } isc_result_t dhcp_pool_lookup (omapi_object_t **lp, - omapi_object_t *id, omapi_object_t *ref) + omapi_object_t *id, omapi_object_t *ref) { omapi_value_t *tv = (omapi_value_t *)0; isc_result_t status; @@ -1710,7 +1422,7 @@ isc_result_t dhcp_pool_lookup (omapi_object_t **lp, } isc_result_t dhcp_pool_create (omapi_object_t **lp, - omapi_object_t *id) + omapi_object_t *id) { return ISC_R_NOTIMPLEMENTED; } @@ -1721,4 +1433,145 @@ isc_result_t dhcp_pool_remove (omapi_object_t *lp, return ISC_R_NOTIMPLEMENTED; } +isc_result_t dhcp_class_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + struct class *class; + isc_result_t status; + int foo; + + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + class = (struct class *)h; + + /* No values to set yet. */ + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> set_value) { + status = ((*(h -> inner -> type -> set_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) + return status; + } + + return ISC_R_NOTFOUND; +} + + +isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, + omapi_data_string_t *name, + omapi_value_t **value) +{ + struct class *class; + isc_result_t status; + + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + class = (struct class *)h; + + /* No values to get yet. */ + + /* Try to find some inner object that can provide the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> get_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS) + return status; + } + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line) +{ + struct class *class; + isc_result_t status; + + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + class = (struct class *)h; + + /* Can't destroy classs yet. */ + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_class_signal_handler (omapi_object_t *h, + const char *name, va_list ap) +{ + struct class *class; + isc_result_t status; + int updatep = 0; + + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + class = (struct class *)h; + + /* Can't write classs yet. */ + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> get_value) { + status = ((*(h -> inner -> type -> signal_handler)) + (h -> inner, name, ap)); + if (status == ISC_R_SUCCESS) + return status; + } + if (updatep) + return ISC_R_SUCCESS; + return ISC_R_NOTFOUND; +} + +isc_result_t dhcp_class_stuff_values (omapi_object_t *c, + omapi_object_t *id, + omapi_object_t *h) +{ + struct class *class; + isc_result_t status; + + if (h -> type != dhcp_type_class) + return ISC_R_INVALIDARG; + class = (struct class *)h; + + /* Can't stuff class values yet. */ + + /* Write out the inner object, if any. */ + if (h -> inner && h -> inner -> type -> stuff_values) { + status = ((*(h -> inner -> type -> stuff_values)) + (c, id, h -> inner)); + if (status == ISC_R_SUCCESS) + return status; + } + + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_class_lookup (omapi_object_t **lp, + omapi_object_t *id, omapi_object_t *ref) +{ + omapi_value_t *tv = (omapi_value_t *)0; + isc_result_t status; + struct class *class; + + /* Can't look up classs yet. */ + + /* If we get to here without finding a class, no valid key was + specified. */ + if (!*lp) + return ISC_R_NOKEYS; + return ISC_R_SUCCESS; +} + +isc_result_t dhcp_class_create (omapi_object_t **lp, + omapi_object_t *id) +{ + return ISC_R_NOTIMPLEMENTED; +} + +isc_result_t dhcp_class_remove (omapi_object_t *lp, + omapi_object_t *id) +{ + return ISC_R_NOTIMPLEMENTED; +} + /* vim: set tabstop=8: */ diff --git a/server/stables.c b/server/stables.c index 055b4fe22..65cc3619a 100644 --- a/server/stables.c +++ b/server/stables.c @@ -43,7 +43,7 @@ #ifndef lint static char copyright[] = -"$Id: stables.c,v 1.11 2000/05/02 00:25:10 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: stables.c,v 1.12 2000/05/16 23:03:49 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -716,9 +716,9 @@ void initialize_server_option_spaces() log_fatal ("Can't allocate agent option hash table."); for (i = 0; i < 256; i++) { agent_universe.options [i] = &agent_options [i]; - add_hash (agent_universe.hash, - (const unsigned char *)agent_options [i].name, 0, - (unsigned char *)&agent_options [i]); + option_hash_add (agent_universe.hash, + agent_options [i].name, 0, + &agent_options [i], MDL); } /* Set up the server option universe... */ @@ -742,18 +742,16 @@ void initialize_server_option_spaces() log_fatal ("Can't allocate server option hash table."); for (i = 0; i < 256; i++) { server_universe.options [i] = &server_options [i]; - add_hash (server_universe.hash, - (const unsigned char *)server_options [i].name, 0, - (unsigned char *)&server_options [i]); + option_hash_add (server_universe.hash, + server_options [i].name, 0, + &server_options [i], MDL); } /* Add the server and agent option spaces to the option space hash. */ - add_hash (universe_hash, - (const unsigned char *)agent_universe.name, 0, - (unsigned char *)&agent_universe); - add_hash (universe_hash, - (const unsigned char *)server_universe.name, 0, - (unsigned char *)&server_universe); + universe_hash_add (universe_hash, + agent_universe.name, 0, &agent_universe, MDL); + universe_hash_add (universe_hash, + server_universe.name, 0, &server_universe, MDL); /* Make the server universe the configuration option universe. */ config_universe = &server_universe;