summaryrefslogtreecommitdiff
path: root/server/mdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/mdb.c')
-rw-r--r--server/mdb.c237
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 (&lt, 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 (&lt -> pool, pool, MDL);
lease_dereference (&lt, 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 (&lt, lease, MDL))
return;
+ if (lt->scope)
+ binding_scope_dereference(&lt->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 */