being correctly reference-counted.
- Make and use object-specific allocators.
- Add reference/dereference support to hash functions and to timeout
functions.
#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"
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");
return;
}
- ip = interface_or_dummy (val);
+ interface_or_dummy (&ip, val);
/* If we were given a name, this is a pseudo-interface. */
if (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)
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 :==
skip_to_semi (cfile);
break;
}
- ip = interface_or_dummy (val);
- *ipp = ip;
+ interface_or_dummy (ipp, val);
break;
case NAME:
* 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.
*
#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"
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.";
} 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;
}
}
/* 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);
/* Set up a timeout to start the initialization
process. */
add_timeout (cur_time + random () % 5,
- state_reboot, client);
+ state_reboot, client, 0, 0);
}
}
}
"[-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)
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:
/* 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),
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);
}
}
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
(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.");
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 ();
}
(struct hardware *)0);
add_timeout (cur_time + client -> interval,
- send_request, client);
+ send_request, client, 0, 0);
}
void send_decline (cpp)
}
}
+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. */
#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 <omapip/omapip_p.h>
-
-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;
-}
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
#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"
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)
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;
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;
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;
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;
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)
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);
#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"
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);
#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"
return HOSTNAME;
break;
case 'i':
+ if (!strcasecmp (atom + 1, "nclude"))
+ return INCLUDE;
if (!strcasecmp (atom + 1, "nteger"))
return INTEGER;
if (!strcasecmp (atom + 1, "nfinite"))
#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"
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;
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
(&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));
/* 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
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
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;
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);
}
}
/* 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;
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;
tmp -> name);
}
#endif
+ interface_dereference (&tmp, MDL);
+ if (next)
+ interface_reference (&tmp, next, MDL);
}
/* Now register all the remaining interfaces as protocols. */
/* 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);
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 ()
#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"
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;
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;
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;
/* 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;
}
#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"
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);
#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"
memcpy (tkey -> data,
zone -> key -> key.data, zone -> key -> key.len);
tkey -> len = zone -> key -> key.len;
- *key = tkey;
return ISC_R_SUCCESS;
}
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,
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;
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,
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;
}
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;
}
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)
#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"
break;
default:
- log_fatal ("bogus statement type %d\n", r -> op);
+ log_fatal ("bogus statement type %d", r -> op);
}
}
#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"
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;
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);
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];
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;
}
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);
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)
}
return 0;
}
+
+HASH_FUNCTIONS (group, const char *, struct group_object)
+HASH_FUNCTIONS (universe, const char *, struct universe)
+HASH_FUNCTIONS (option, const char *, struct option)
#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"
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",
#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"
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);
#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;
+}
#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"
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);
#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
{
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;
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) {
#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"
/* 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;
}
/* 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) {
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);
}
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;
}
*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;
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
#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"
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)... */
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);
}
#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"
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);
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;
}
struct group {
struct group *next;
+ int refcnt;
struct group_object *object;
struct subnet *subnet;
struct shared_network *shared_network;
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;
/* dhcpd.c */
extern TIME cur_time;
-extern struct group root_group;
extern const char *path_dhcpd_conf;
extern const char *path_dhcpd_db;
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,
/* 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));
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 *));
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 *));
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));
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));
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,
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));
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;
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
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));
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 *));
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 [];
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 *));
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)
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 *,
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 */
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 *,
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 *));
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 *);
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));
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 *);
POTENTIAL_CONFLICT_NIC = 465,
STATE = 466,
UNKNOWN_STATE = 567,
- CLTT = 568
+ CLTT = 568,
+ INCLUDE = 569
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
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
#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);
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); \
+}
+
+
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 \
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 *,
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);
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 *,
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);
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_ */
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
#include <omapip/buffer.h>
+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. */
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;
#include <omapip/alloc.h>
+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);
}
#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)
#include <omapip/omapip_p.h>
#include <arpa/inet.h>
+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)
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;
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);
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;
}
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;
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);
#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
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;
}
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;
}
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;
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,
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;
}
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;
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,
}
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;
}
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. */
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;
}
(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
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;
}
/* 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 *)
"ready");
}
if (tmp)
- omapi_object_dereference
- ((omapi_object_t **)&tmp, MDL);
+ omapi_io_dereference (&tmp, MDL);
}
}
prev = io;
/* 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;
#include <omapip/omapip_p.h>
+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,
#include <omapip/omapip_p.h>
+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)
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;
}
/* 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;
#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
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)
/* 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
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;
((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;
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;
}
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);
#include <omapip/omapip_p.h>
+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)
#include <omapip/omapip_p.h>
+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,
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;
}
{
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);
/* 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;
/* 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;
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;
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;
}
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;
}
if (status != ISC_R_SUCCESS)
goto lose;
- omapi_object_dereference ((omapi_object_t **)&obj, MDL);
+ omapi_protocol_dereference (&obj, MDL);
return status;
}
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,
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;
}
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;
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;
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;
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;
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;
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;
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;
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;
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;
* 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.
*
#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"
} *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.";
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) {
{
}
-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
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
#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"
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;
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
&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,
&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... */
(struct packet *)0,
&raw, outgoing.packet_length,
from, &to, &hto);
- return;
+ goto out;
}
/* If it comes from a client that already knows its address
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);
}
#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 */
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,
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);
}
}
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,
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)
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;
}
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;
}
#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"
declarations :== <nil> | declaration | declarations declaration */
isc_result_t readconf ()
+{
+ return parse_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP);
+}
+
+/* conf-file :== parameters declarations EOF
+ parameters :== <nil> | parameter | parameters parameter
+ declarations :== <nil> | declaration | declarations declaration */
+
+isc_result_t parse_conf_file (const char *filename, struct group *group,
+ int group_type)
{
int file;
struct parse *cfile;
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);
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
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
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)
/* 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);
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:
skip_to_semi (cfile);
break;
}
- parse_class_declaration (cfile, group, 1);
+ parse_class_declaration ((struct class **)0, cfile, group, 1);
return 1;
case CLASS:
skip_to_semi (cfile);
break;
}
- parse_class_declaration (cfile, group, 2);
+ parse_class_declaration ((struct class **)0, cfile, group, 2);
return 1;
case SUBCLASS:
skip_to_semi (cfile);
break;
}
- parse_class_declaration (cfile, group, 3);
+ parse_class_declaration ((struct class **)0, cfile, group, 3);
return 1;
case HARDWARE:
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;
/* 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) {
" 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) {
return;
}
parse_failover_state_declaration (cfile, peer);
+ dhcp_failover_state_dereference (&peer, MDL);
return;
} else if (token != LBRACE) {
parse_warn (cfile, "expecting left brace");
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;
parse_warn (cfile,
"expecting 'address' or 'port'");
skip_to_rbrace (cfile, 1);
+ dhcp_failover_state_dereference (&peer, MDL);
return;
}
break;
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,
if (token != NUMBER) {
parse_warn (cfile, "expecting number.");
skip_to_rbrace (cfile, 1);
+ dhcp_failover_state_dereference (&peer, MDL);
return;
}
*tp = atoi (val);
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) {
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 {
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);
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,
/* 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);
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 {
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,
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)
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) {
}
#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;
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,
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);
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 */
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);
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;
} 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);
}
}
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;
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
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
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. */
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 =
}
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)) {
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);
} 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 :==
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);
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);
(struct host_decl *)0,
declaration);
} while (1);
+ shared_network_dereference (&share, MDL);
}
/* subnet-declaration :==
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;
}
/* 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);
/* 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 */
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) {
strcpy (name, val);
}
- if (!parse_lbrace (cfile))
+ if (!parse_lbrace (cfile)) {
+ group_dereference (&g, MDL);
return;
+ }
do {
token = peek_token (&val, cfile);
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);
}
}
| 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;
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;
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);
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. */
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);
}
}
parse_semi (cfile);
- if (!lease.uid) {
+ if (!lease -> uid) {
log_fatal ("No memory for lease uid");
}
break;
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. */
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;
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;
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;
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;
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)
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);
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)
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
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);
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;
}
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];
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);
}
}
- if (!pool) {
+ if (!inpool) {
struct pool *last;
/* If we're permitting dynamic bootp for this range,
/* 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.");
}
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
/* Create the new address range... */
new_address_range (low, high, subnet, pool);
+ pool_dereference (&pool, MDL);
}
/* allow-deny-keyword :== BOOTP
#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"
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);
counting = 1;
}
+
+int group_writer (struct group_object *group)
+{
+ if (!write_group (group))
+ return 0;
+ if (!commit_leases ())
+ return 0;
+ return 1;
+}
#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"
struct packet *packet;
int ms_nulltp;
{
- struct lease *lease;
+ struct lease *lease = (struct lease *)0;
char msgbuf [1024]; /* XXX */
TIME when;
char *s;
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))
peer -> my_state == normal) {
log_info ("%s: letting peer %s respond.",
msgbuf, peer -> name);
- return;
+ goto out;
}
}
#endif
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);
if (!load_balance_mine (packet, peer)) {
log_debug ("%s: load balance to peer %s",
msgbuf, peer -> name);
- return;
+ goto out;
}
}
}
when = lease -> ends;
ack_lease (packet, lease, DHCPOFFER, when, msgbuf, ms_nulltp);
+ out:
+ if (lease)
+ lease_dereference (&lease, MDL);
}
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))
}
/* 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);
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
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 */
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. */
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;
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
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
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);
}
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;
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);
}
option_state_dereference (&options, MDL);
+ if (lease)
+ lease_dereference (&lease, MDL);
}
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;
/* 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) {
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;
}
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;
}
? 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)
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);
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);
#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)
char *msg;
int ms_nulltp;
{
- struct lease lt;
+ struct lease *lt;
struct lease_state *state;
TIME lease_time;
TIME offered_lease_time;
struct option_cache *oc;
struct expression *expr;
int status;
+ isc_result_t result;
unsigned i, j;
int s1, s2;
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,
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 &&
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);
}
}
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;
}
/* 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. */
#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;
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
lease_time = (lease -> tsfp - cur_time
+ peer -> mclt);
}
- lt.cltt = cur_time;
+ lt -> cltt = cur_time;
}
#endif /* FAILOVER_PROTOCOL */
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;
}
}
- 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,
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. */
}
/* 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. */
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
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
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;
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;
}
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;
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;
/* 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) {
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.",
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));
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 &&
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;
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));
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) {
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 &&
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;
/* 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)
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
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
packet -> packet_type == DHCPREQUEST)
dissociate_lease (uid_lease);
}
- uid_lease = ip_lease;
+ lease_dereference (&uid_lease, MDL);
+ lease_reference (&uid_lease, ip_lease, MDL);
}
}
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));
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!");
}
!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
/* 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
#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
#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. */
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
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;
}
}
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
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;
/* 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. */
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
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
{
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. */
/* 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;
}
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;
}
/* 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;
}
* 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.
*
#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.";
static void usage PROTO ((void));
TIME cur_time;
-struct group root_group;
struct binding_scope global_scope;
struct iaddr server_identifier;
/* 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. */
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!");
}
(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);
/* 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);
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));
}
abandon_lease (lp, "pinged before offer");
cancel_timeout (lease_ping_timeout, lp);
--outstanding_pings;
+ out:
+ lease_dereference (&lp, MDL);
}
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;
+}
#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"
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) {
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;
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;
}
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;
}
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;
}
} 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;
}
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,
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;
}
}
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);
}
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;
}
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);
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,
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;
}
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,
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;
}
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 *);
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;
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) {
/* 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);
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++;
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;
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;
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;
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);
}
}
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);
}
}
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)
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) {
}
/* 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;
}
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);
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)
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) */
#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"
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)
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)
/* 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);
+ }
}
}
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.
/* 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);
+ }
}
}
{
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;
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);
}
}
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;
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
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;
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)
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) {
/* 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");
}
}
/* 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));
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;
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)
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;
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)
const char *name;
{
struct interface_info *ip;
+ isc_result_t status;
if (share -> interface) {
parse_warn (cfile,
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);
}
}
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);
}
}
/* 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;
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));
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,
/* 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
&& 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);
}
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. */
}
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
}
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)
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
#endif
install = foo;
}
- comp -> pool -> next_expiry = install;
+ lease_dereference
+ (&comp -> pool -> next_expiry,
+ MDL);
+ lease_reference
+ (&comp -> pool -> next_expiry,
+ install, MDL);
}
}
}
;
}
-/* 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. */
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);
}
}
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
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. */
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. */
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);
}
}
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;
}
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. */
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);
}
}
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;
}
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. */
}
}
}
+
+HASH_FUNCTIONS (lease, const unsigned char *, struct lease)
+HASH_FUNCTIONS (host, const unsigned char *, struct host_decl)
+HASH_FUNCTIONS (class, const char *, struct class)
#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 <omapip/omapip_p.h>
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;
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,
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",
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",
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",
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",
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];
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);
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;
/* 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);
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)
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)
} 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);
}
}
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,
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;
}
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;
/* 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;
}
/* 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);
}
}
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)
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);
}
}
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,
}
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;
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;
}
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;
}
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;
}
isc_result_t dhcp_pool_create (omapi_object_t **lp,
- omapi_object_t *id)
+ omapi_object_t *id)
{
return ISC_R_NOTIMPLEMENTED;
}
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: */
#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"
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... */
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;