diff options
Diffstat (limited to 'server/mdb.c')
-rw-r--r-- | server/mdb.c | 237 |
1 files changed, 132 insertions, 105 deletions
diff --git a/server/mdb.c b/server/mdb.c index 123e05e8..e26f23f5 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -3,39 +3,30 @@ Server-specific in-memory database support. */ /* - * Copyright (c) 1996-2001 Internet Software Consortium. - * All rights reserved. + * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-2003 by Internet Software Consortium * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND - * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * <info@isc.org> + * http://www.isc.org/ * - * This software has been written for the Internet Software Consortium + * This software has been written for Internet Systems Consortium * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. - * To learn more about the Internet Software Consortium, see + * To learn more about Internet Systems Consortium, see * ``http://www.isc.org/''. To learn more about Vixie Enterprises, * see ``http://www.vix.com''. To learn more about Nominum, Inc., see * ``http://www.nominum.com''. @@ -43,19 +34,20 @@ #ifndef lint static char copyright[] = -"$Id: mdb.c,v 1.71 2001/07/10 20:36:05 brister Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n"; +"$Id: mdb.c,v 1.72 2005/03/17 20:15:28 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" +#include "omapip/hash.h" struct subnet *subnets; struct shared_network *shared_networks; -struct hash_table *host_hw_addr_hash; -struct hash_table *host_uid_hash; -struct hash_table *lease_uid_hash; -struct hash_table *lease_ip_addr_hash; -struct hash_table *lease_hw_addr_hash; -struct hash_table *host_name_hash; +host_hash_t *host_hw_addr_hash; +host_hash_t *host_uid_hash; +host_hash_t *host_name_hash; +lease_hash_t *lease_uid_hash; +lease_hash_t *lease_ip_addr_hash; +lease_hash_t *lease_hw_addr_hash; int numclasseswritten; @@ -133,10 +125,7 @@ isc_result_t enter_host (hd, dynamicp, commit) struct executable_statement *esp; if (!host_name_hash) { - host_name_hash = - new_hash ((hash_reference)host_reference, - (hash_dereference)host_dereference, 0, MDL); - if (!host_name_hash) + if (!host_new_hash (&host_name_hash, 0, MDL)) log_fatal ("Can't allocate host name hash"); host_hash_add (host_name_hash, (unsigned char *)hd -> name, @@ -153,8 +142,10 @@ isc_result_t enter_host (hd, dynamicp, commit) 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 (hp -> flags & HOST_DECL_STATIC) { hd -> flags |= HOST_DECL_STATIC; + } + host_dereference (&hp, MDL); } /* If we are updating an existing host declaration, we @@ -189,11 +180,7 @@ isc_result_t enter_host (hd, dynamicp, commit) if (hd -> interface.hlen) { if (!host_hw_addr_hash) { - host_hw_addr_hash = - new_hash ((hash_reference)host_reference, - (hash_dereference)host_dereference, - 0, MDL); - if (!host_hw_addr_hash) + if (!host_new_hash (&host_hw_addr_hash, 0, MDL)) log_fatal ("Can't allocate host/hw hash"); } else { /* If there isn't already a host decl matching this @@ -237,11 +224,7 @@ isc_result_t enter_host (hd, dynamicp, commit) /* If there's no uid hash, make one; otherwise, see if there's already an entry in the hash for this host. */ if (!host_uid_hash) { - host_uid_hash = - new_hash ((hash_reference)host_reference, - (hash_dereference)host_dereference, - 0, MDL); - if (!host_uid_hash) + if (!host_new_hash (&host_uid_hash, 0, MDL)) log_fatal ("Can't allocate host/uid hash"); host_hash_add (host_uid_hash, @@ -345,6 +328,8 @@ isc_result_t delete_host (hd, commit) while (foo) { if (foo == hd) break; + if (np) + host_dereference (&np, MDL); host_reference (&np, foo, MDL); host_dereference (&foo, MDL); if (np -> n_ipaddr) @@ -385,6 +370,8 @@ isc_result_t delete_host (hd, commit) while (foo) { if (foo == hd) break; + if (np) + host_dereference (&np, MDL); host_reference (&np, foo, MDL); host_dereference (&foo, MDL); if (np -> n_ipaddr) @@ -522,10 +509,12 @@ int find_host_for_network (struct subnet **sp, struct host_decl **host, return 0; } -void new_address_range (low, high, subnet, pool) +void new_address_range (cfile, low, high, subnet, pool, lpchain) + struct parse *cfile; struct iaddr low, high; struct subnet *subnet; struct pool *pool; + struct lease **lpchain; { struct lease *address_range, *lp, *plp; struct iaddr net; @@ -544,24 +533,15 @@ void new_address_range (low, high, subnet, pool) /* Initialize the hash table if it hasn't been done yet. */ if (!lease_uid_hash) { - lease_uid_hash = - new_hash ((hash_reference)lease_reference, - (hash_dereference)lease_dereference, 0, MDL); - if (!lease_uid_hash) + if (!lease_new_hash (&lease_uid_hash, 0, MDL)) log_fatal ("Can't allocate lease/uid hash"); } if (!lease_ip_addr_hash) { - lease_ip_addr_hash = - new_hash ((hash_reference)lease_reference, - (hash_dereference)lease_dereference, 0, MDL); - if (!lease_uid_hash) + if (!lease_new_hash (&lease_ip_addr_hash, 0, MDL)) log_fatal ("Can't allocate lease/ip hash"); } if (!lease_hw_addr_hash) { - lease_hw_addr_hash = - new_hash ((hash_reference)lease_reference, - (hash_dereference)lease_dereference, 0, MDL); - if (!lease_uid_hash) + if (!lease_new_hash (&lease_hw_addr_hash, 0, MDL)) log_fatal ("Can't allocate lease/hw hash"); } @@ -635,8 +615,9 @@ void new_address_range (low, high, subnet, pool) /* Remember the lease in the IP address hash. */ if (find_lease_by_ip_addr (<, lp -> ip_addr, MDL)) { if (lt -> pool) { - log_error ("duplicate entries for lease %s", - piaddr (lp -> ip_addr)); + parse_warn (cfile, + "lease %s is declared twice!", + piaddr (lp -> ip_addr)); } else pool_reference (< -> pool, pool, MDL); lease_dereference (<, MDL); @@ -644,6 +625,14 @@ void new_address_range (low, high, subnet, pool) lease_hash_add (lease_ip_addr_hash, lp -> ip_addr.iabuf, lp -> ip_addr.len, lp, MDL); + /* Put the lease on the chain for the caller. */ + if (lpchain) { + if (*lpchain) { + lease_reference (&lp -> next, *lpchain, MDL); + lease_dereference (lpchain, MDL); + } + lease_reference (lpchain, lp, MDL); + } lease_dereference (&lp, MDL); } } @@ -912,7 +901,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) comp -> hardware_addr.hlen))))) { log_error ("Lease conflict at %s", piaddr (comp -> ip_addr)); - return 0; } /* If there's a Unique ID, dissociate it from the hash @@ -990,9 +978,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) /* Only retain the agent options if the lease is still affirmatively associated with a client. */ if (lease -> next_binding_state == FTS_ACTIVE || - lease -> next_binding_state == FTS_EXPIRED || - lease -> next_binding_state == FTS_RESERVED || - lease -> next_binding_state == FTS_BOOTP) + lease -> next_binding_state == FTS_EXPIRED) option_chain_head_reference (&comp -> agent_options, lease -> agent_options, MDL); @@ -1062,8 +1048,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) break; case FTS_ACTIVE: - case FTS_RESERVED: - case FTS_BOOTP: lq = &comp -> pool -> active; break; @@ -1102,8 +1086,8 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) if (!lp) { log_error ("Lease with binding state %s not on its queue.", - (comp -> binding_state < 1 && - comp -> binding_state < FTS_BOOTP) + (comp -> binding_state < 1 || + comp -> binding_state > FTS_LAST) ? "unknown" : binding_state_names [comp -> binding_state - 1]); return 0; @@ -1164,11 +1148,22 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) #if defined (FAILOVER_PROTOCOL) if (propogate) { + comp -> desired_binding_state = comp -> binding_state; if (!dhcp_failover_queue_update (comp, pimmediate)) return 0; } #endif + /* If the current binding state has already expired, do an + expiry event right now. */ + /* XXX At some point we should optimize this so that we don't + XXX write the lease twice, but this is a safe way to fix the + XXX problem for 3.0 (I hope!). */ + if ((commit || !pimmediate) && + comp -> sort_time < cur_time && + comp -> next_binding_state != comp -> binding_state) + pool_timer (comp -> pool); + return 1; } @@ -1189,14 +1184,14 @@ void make_binding_state_transition (struct lease *lease) (( #if defined (FAILOVER_PROTOCOL) peer && - lease -> binding_state == FTS_EXPIRED && + (lease -> binding_state == FTS_EXPIRED || + (peer -> i_am == secondary && + lease -> binding_state == FTS_ACTIVE)) && (lease -> next_binding_state == FTS_FREE || lease -> next_binding_state == FTS_BACKUP)) || (!peer && #endif - (lease -> binding_state == FTS_ACTIVE || - lease -> binding_state == FTS_BOOTP || - lease -> binding_state == FTS_RESERVED) && + lease -> binding_state == FTS_ACTIVE && lease -> next_binding_state != FTS_RELEASED))) { #if defined (NSUPDATE) ddns_removals (lease); @@ -1218,8 +1213,19 @@ void make_binding_state_transition (struct lease *lease) if (lease -> on_release) executable_statement_dereference (&lease -> on_release, MDL); + /* Get rid of client-specific bindings that are only + correct when the lease is active. */ if (lease -> billing_class) unbill_class (lease, lease -> billing_class); + if (lease -> agent_options) + option_chain_head_dereference (&lease -> agent_options, + MDL); + if (lease -> client_hostname) { + dfree (lease -> client_hostname, MDL); + lease -> client_hostname = (char *)0; + } + if (lease -> host) + host_dereference (&lease -> host, MDL); /* Send the expiry time to the peer. */ lease -> tstp = lease -> ends; @@ -1236,9 +1242,7 @@ void make_binding_state_transition (struct lease *lease) lease -> next_binding_state == FTS_BACKUP)) || (!peer && #endif - (lease -> binding_state == FTS_ACTIVE || - lease -> binding_state == FTS_BOOTP || - lease -> binding_state == FTS_RESERVED) && + lease -> binding_state == FTS_ACTIVE && lease -> next_binding_state == FTS_RELEASED))) { #if defined (NSUPDATE) ddns_removals (lease); @@ -1260,8 +1264,19 @@ void make_binding_state_transition (struct lease *lease) executable_statement_dereference (&lease -> on_expiry, MDL); + /* Get rid of client-specific bindings that are only + correct when the lease is active. */ if (lease -> billing_class) unbill_class (lease, lease -> billing_class); + if (lease -> agent_options) + option_chain_head_dereference (&lease -> agent_options, + MDL); + if (lease -> client_hostname) { + dfree (lease -> client_hostname, MDL); + lease -> client_hostname = (char *)0; + } + if (lease -> host) + host_dereference (&lease -> host, MDL); /* Send the release time (should be == cur_time) to the peer. */ @@ -1278,7 +1293,6 @@ void make_binding_state_transition (struct lease *lease) lease -> binding_state = lease -> next_binding_state; switch (lease -> binding_state) { case FTS_ACTIVE: - case FTS_BOOTP: #if defined (FAILOVER_PROTOCOL) if (lease -> pool && lease -> pool -> failover_peer) lease -> next_binding_state = FTS_EXPIRED; @@ -1305,7 +1319,6 @@ void make_binding_state_transition (struct lease *lease) case FTS_FREE: case FTS_BACKUP: - case FTS_RESERVED: lease -> next_binding_state = lease -> binding_state; break; } @@ -1456,6 +1469,9 @@ void abandon_lease (lease, message) if (!lease_copy (<, lease, MDL)) return; + if (lt->scope) + binding_scope_dereference(<->scope, MDL); + lt -> ends = cur_time; /* XXX */ lt -> next_binding_state = FTS_ABANDONED; @@ -1883,9 +1899,12 @@ int write_leases () for (i = FREE_LEASES; i <= BACKUP_LEASES; i++) { for (l = *(lptr [i]); l; l = l -> next) { +#if !defined (DEBUG_DUMP_ALL_LEASES) if (l -> hardware_addr.hlen || l -> uid_len || - (l -> binding_state != FTS_FREE)) { + (l -> binding_state != FTS_FREE)) +#endif + { if (!write_lease (l)) return 0; num_written++; @@ -1917,8 +1936,6 @@ int lease_enqueue (struct lease *comp) break; case FTS_ACTIVE: - case FTS_RESERVED: - case FTS_BOOTP: lq = &comp -> pool -> active; comp -> sort_time = comp -> ends; break; @@ -2015,9 +2032,7 @@ void lease_instantiate (const unsigned char *val, unsigned len, if (lease -> binding_state == FTS_ACTIVE || lease -> binding_state == FTS_EXPIRED || lease -> binding_state == FTS_RELEASED || - lease -> binding_state == FTS_RESET || - lease -> binding_state == FTS_RESERVED || - lease -> binding_state == FTS_BOOTP) + lease -> binding_state == FTS_RESET) bill_class (lease, class); class_dereference (&class, MDL); } @@ -2070,8 +2085,10 @@ void expire_all_pools () #if defined (FAILOVER_PROTOCOL) if (p -> failover_peer && l -> tstp > l -> tsfp && - !(l -> flags & ON_UPDATE_QUEUE)) + !(l -> flags & ON_UPDATE_QUEUE)) { + l -> desired_binding_state = l -> binding_state; dhcp_failover_queue_update (l, 1); + } #endif } } @@ -2113,11 +2130,14 @@ void dump_subnets () } } -HASH_FUNCTIONS (lease, const unsigned char *, struct lease) -HASH_FUNCTIONS (host, const unsigned char *, struct host_decl) -HASH_FUNCTIONS (class, const char *, struct class) +HASH_FUNCTIONS (lease, const unsigned char *, struct lease, lease_hash_t, + lease_reference, lease_dereference) +HASH_FUNCTIONS (host, const unsigned char *, struct host_decl, host_hash_t, + host_reference, host_dereference) +HASH_FUNCTIONS (class, const char *, struct class, class_hash_t, + class_reference, class_dereference) -#if defined (DEBUG_MEMORY_LEAKAGE) || \ +#if defined (DEBUG_MEMORY_LEAKAGE) && \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) extern struct hash_table *dns_zone_hash; extern struct interface_info **interface_vector; @@ -2127,7 +2147,9 @@ extern struct hash_table *auth_key_hash; struct hash_table *universe_hash; struct universe **universes; int universe_count, universe_max; +#if 0 extern int end; +#endif #if defined (COMPACT_LEASES) extern struct lease *lease_hunks; @@ -2152,28 +2174,30 @@ void free_everything () /* Get rid of all the hash tables. */ if (host_hw_addr_hash) - free_hash_table (host_hw_addr_hash, MDL); + host_free_hash_table (&host_hw_addr_hash, MDL); host_hw_addr_hash = 0; if (host_uid_hash) - free_hash_table (host_uid_hash, MDL); + host_free_hash_table (&host_uid_hash, MDL); host_uid_hash = 0; if (lease_uid_hash) - free_hash_table (lease_uid_hash, MDL); + lease_free_hash_table (&lease_uid_hash, MDL); lease_uid_hash = 0; if (lease_ip_addr_hash) - free_hash_table (lease_ip_addr_hash, MDL); + lease_free_hash_table (&lease_ip_addr_hash, MDL); lease_ip_addr_hash = 0; if (lease_hw_addr_hash) - free_hash_table (lease_hw_addr_hash, MDL); + lease_free_hash_table (&lease_hw_addr_hash, MDL); lease_hw_addr_hash = 0; if (host_name_hash) - free_hash_table (host_name_hash, MDL); + host_free_hash_table (&host_name_hash, MDL); host_name_hash = 0; if (dns_zone_hash) - free_hash_table (dns_zone_hash, MDL); + dns_zone_free_hash_table (&dns_zone_hash, MDL); dns_zone_hash = 0; +#if 0 if (auth_key_hash) - free_hash_table (auth_key_hash, MDL); + auth_key_free_hash_table (&auth_key_hash, MDL); +#endif auth_key_hash = 0; omapi_object_dereference ((omapi_object_t **)&dhcp_control_object, @@ -2193,7 +2217,7 @@ void free_everything () } group_dereference (&cc -> group, MDL); if (cc -> hash) { - free_hash_table (cc -> hash, MDL); + class_free_hash_table (&cc -> hash, MDL); cc -> hash = (struct hash_table *)0; } class_dereference (&cc, MDL); @@ -2352,7 +2376,7 @@ void free_everything () omapi_object_dereference ((omapi_object_t **)&icmp_state, MDL); - free_hash_table (universe_hash, MDL); + universe_free_hash_table (&universe_hash, MDL); for (i = 0; i < universe_count; i++) { union { const char *c; @@ -2360,13 +2384,16 @@ void free_everything () } foo; if (universes [i]) { if (universes [i] -> hash) - free_hash_table (universes [i] -> hash, MDL); + option_free_hash_table (&universes [i] -> hash, + MDL); +#if 0 if (universes [i] -> name > (char *)&end) { foo.c = universes [i] -> name; dfree (foo.s, MDL); } if (universes [i] > (struct universe *)&end) dfree (universes [i], MDL); +#endif } } dfree (universes, MDL); @@ -2381,4 +2408,4 @@ void free_everything () relinquish_hash_bucket_hunks (); omapi_type_relinquish (); } -#endif /* DEBUG_MEMORY_LEAKAGE */ +#endif /* DEBUG_MEMORY_LEAKAGE_ON_EXIT */ |