mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-30 05:47:45 +00:00
- Get rid of the obnoxious doubly-linked list and seperate timeout queue
and just make six lists with six kinds of leases sorted as timeout queues.
This commit is contained in:
parent
6f0b9ed09c
commit
0756bc8ae9
267
server/mdb.c
267
server/mdb.c
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
static char copyright[] =
|
||||||
"$Id: mdb.c,v 1.33 2000/06/02 21:27:19 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
|
"$Id: mdb.c,v 1.34 2000/06/07 00:15:53 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@ -56,7 +56,6 @@ struct hash_table *lease_uid_hash;
|
|||||||
struct hash_table *lease_ip_addr_hash;
|
struct hash_table *lease_ip_addr_hash;
|
||||||
struct hash_table *lease_hw_addr_hash;
|
struct hash_table *lease_hw_addr_hash;
|
||||||
struct hash_table *host_name_hash;
|
struct hash_table *host_name_hash;
|
||||||
static struct lease *dangling_leases;
|
|
||||||
|
|
||||||
omapi_object_type_t *dhcp_type_host;
|
omapi_object_type_t *dhcp_type_host;
|
||||||
|
|
||||||
@ -411,6 +410,7 @@ void new_address_range (low, high, subnet, pool)
|
|||||||
char lowbuf [16], highbuf [16], netbuf [16];
|
char lowbuf [16], highbuf [16], netbuf [16];
|
||||||
struct shared_network *share = subnet -> shared_network;
|
struct shared_network *share = subnet -> shared_network;
|
||||||
isc_result_t status;
|
isc_result_t status;
|
||||||
|
struct lease *lt = (struct lease *)0;
|
||||||
|
|
||||||
/* All subnets should have attached shared network structures. */
|
/* All subnets should have attached shared network structures. */
|
||||||
if (!share) {
|
if (!share) {
|
||||||
@ -509,64 +509,32 @@ void new_address_range (low, high, subnet, pool)
|
|||||||
lp -> next_binding_state = FTS_FREE;
|
lp -> next_binding_state = FTS_FREE;
|
||||||
lp -> flags = 0;
|
lp -> flags = 0;
|
||||||
|
|
||||||
/* Link this entry into the list. */
|
/* Remember the lease in the IP address hash. */
|
||||||
if (pool -> free) {
|
if (find_lease_by_ip_addr (<, lp -> ip_addr, MDL)) {
|
||||||
lease_reference (&lp -> next, pool -> free, MDL);
|
if (lt -> pool) {
|
||||||
lease_dereference (&pool -> free, MDL);
|
log_error ("duplicate entries for lease %s",
|
||||||
}
|
piaddr (lp -> ip_addr));
|
||||||
lease_reference (&pool -> free, lp, MDL);
|
} else
|
||||||
lease_hash_add (lease_ip_addr_hash, lp -> ip_addr.iabuf,
|
pool_reference (< -> pool, pool, MDL);
|
||||||
|
lease_dereference (<, MDL);
|
||||||
|
} else
|
||||||
|
lease_hash_add (lease_ip_addr_hash,
|
||||||
|
lp -> ip_addr.iabuf,
|
||||||
lp -> ip_addr.len, lp, MDL);
|
lp -> ip_addr.len, lp, MDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find out if any dangling leases are in range... */
|
|
||||||
plp = (struct lease *)0;
|
|
||||||
for (lp = dangling_leases; lp; lp = lp -> next) {
|
|
||||||
struct iaddr lnet;
|
|
||||||
int lhost;
|
|
||||||
|
|
||||||
lnet = subnet_number (lp -> ip_addr, subnet -> netmask);
|
|
||||||
lhost = host_addr (lp -> ip_addr, subnet -> netmask);
|
|
||||||
|
|
||||||
/* If it's in range, fill in the real lease structure with
|
|
||||||
the dangling lease's values, and remove the lease from
|
|
||||||
the list of dangling leases. */
|
|
||||||
if (addr_eq (lnet, subnet -> net) &&
|
|
||||||
lhost >= i && lhost <= max) {
|
|
||||||
struct lease *lt = (struct lease *)0;
|
|
||||||
if (plp) {
|
|
||||||
if (plp -> next)
|
|
||||||
lease_dereference (&plp -> next, MDL);
|
|
||||||
lease_reference (&plp -> next,
|
|
||||||
lp -> next, MDL);
|
|
||||||
} else {
|
|
||||||
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, 0);
|
|
||||||
lease_dereference (<, MDL);
|
|
||||||
}
|
|
||||||
lease_dereference (&lp, MDL);
|
|
||||||
} else
|
|
||||||
plp = lp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There's really no way to free a lease, because of the aggregate way
|
|
||||||
we allocate them. */
|
#if defined (COMPACT_LEASES)
|
||||||
|
/* If we are allocating leases in aggregations, there's really no way
|
||||||
|
to free one, although perhaps we can maintain a free list. */
|
||||||
|
|
||||||
isc_result_t dhcp_lease_free (omapi_object_t *lease,
|
isc_result_t dhcp_lease_free (omapi_object_t *lease,
|
||||||
const char *file, int line)
|
const char *file, int line)
|
||||||
{
|
{
|
||||||
return ISC_R_SUCCESS;
|
return ISC_R_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int find_subnet (struct subnet **sp,
|
int find_subnet (struct subnet **sp,
|
||||||
struct iaddr addr, const char *file, int line)
|
struct iaddr addr, const char *file, int line)
|
||||||
@ -723,17 +691,25 @@ void enter_lease (lease)
|
|||||||
struct lease *comp = (struct lease *)0;
|
struct lease *comp = (struct lease *)0;
|
||||||
isc_result_t status;
|
isc_result_t status;
|
||||||
|
|
||||||
/* If we don't have a place for this lease yet, save it for
|
if (find_lease_by_ip_addr (&comp, lease -> ip_addr, MDL)) {
|
||||||
later. */
|
if (!comp -> pool) {
|
||||||
if (!find_lease_by_ip_addr (&comp, lease -> ip_addr, MDL)) {
|
log_error ("undeclared lease found in database: %s",
|
||||||
if (lease -> next)
|
piaddr (lease -> ip_addr));
|
||||||
lease_dereference (&lease -> next, MDL);
|
} else
|
||||||
if (dangling_leases)
|
pool_reference (&lease -> pool, comp -> pool, MDL);
|
||||||
lease_reference (&lease -> next, dangling_leases, MDL);
|
|
||||||
lease_reference (&dangling_leases, lease, MDL);
|
if (comp -> subnet)
|
||||||
} else {
|
subnet_reference (&lease -> subnet,
|
||||||
supersede_lease (comp, lease, 0, 0, 0);
|
comp -> subnet, MDL);
|
||||||
|
|
||||||
|
lease_hash_delete (lease_ip_addr_hash,
|
||||||
|
lease -> ip_addr.iabuf,
|
||||||
|
lease -> ip_addr.len, MDL);
|
||||||
|
lease_dereference (&comp, MDL);
|
||||||
}
|
}
|
||||||
|
lease_hash_add (lease_ip_addr_hash,
|
||||||
|
lease -> ip_addr.iabuf,
|
||||||
|
lease -> ip_addr.len, lease, MDL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace the data in an existing lease with the data in a new lease;
|
/* Replace the data in an existing lease with the data in a new lease;
|
||||||
@ -972,66 +948,10 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
|
|||||||
if (commit)
|
if (commit)
|
||||||
process_state_transition (comp);
|
process_state_transition (comp);
|
||||||
|
|
||||||
/* Figure out which queue it's going to. */
|
/* Put the lease back on the appropriate queue. If the lease
|
||||||
switch (comp -> binding_state) {
|
is corrupt (as detected by lease_enqueue), don't go any farther. */
|
||||||
case FTS_FREE:
|
if (!lease_enqueue (comp))
|
||||||
lq = &comp -> pool -> free;
|
|
||||||
comp -> pool -> free_leases++;
|
|
||||||
comp -> sort_time = comp -> ends;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FTS_ACTIVE:
|
|
||||||
case FTS_RESERVED:
|
|
||||||
case FTS_BOOTP:
|
|
||||||
lq = &comp -> pool -> active;
|
|
||||||
comp -> sort_time = comp -> ends;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FTS_EXPIRED:
|
|
||||||
case FTS_RELEASED:
|
|
||||||
case FTS_RESET:
|
|
||||||
lq = &comp -> pool -> expired;
|
|
||||||
comp -> sort_time = comp -> ends;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FTS_ABANDONED:
|
|
||||||
lq = &comp -> pool -> abandoned;
|
|
||||||
comp -> sort_time = comp -> ends;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FTS_BACKUP:
|
|
||||||
lq = &comp -> pool -> backup;
|
|
||||||
comp -> pool -> backup_leases++;
|
|
||||||
comp -> sort_time = comp -> ends;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
log_error ("Lease with bogus binding state: %d",
|
|
||||||
comp -> binding_state);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* Insertion sort the lease onto the appropriate queue. */
|
|
||||||
prev = (struct lease *)0;
|
|
||||||
for (lp = *lq; lp; lp = lp -> next) {
|
|
||||||
if (lp -> sort_time > comp -> sort_time)
|
|
||||||
break;
|
|
||||||
prev = lp;
|
|
||||||
}
|
|
||||||
if (prev) {
|
|
||||||
if (prev -> next) {
|
|
||||||
lease_reference (&comp -> next, prev -> next, MDL);
|
|
||||||
lease_dereference (&prev -> next, MDL);
|
|
||||||
}
|
|
||||||
lease_reference (&prev -> next, comp, MDL);
|
|
||||||
} else {
|
|
||||||
if (*lq) {
|
|
||||||
lease_reference (&comp -> next, *lq, MDL);
|
|
||||||
lease_dereference (lq, MDL);
|
|
||||||
}
|
|
||||||
lease_reference (lq, comp, MDL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this is the next lease that will timeout on the pool,
|
/* If this is the next lease that will timeout on the pool,
|
||||||
zap the old timeout and set the timeout on this pool to the
|
zap the old timeout and set the timeout on this pool to the
|
||||||
@ -1673,6 +1593,111 @@ void write_leases ()
|
|||||||
log_fatal ("Can't commit leases to new database: %m");
|
log_fatal ("Can't commit leases to new database: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lease_enqueue (struct lease *comp)
|
||||||
|
{
|
||||||
|
struct lease **lq, *prev, *lp;
|
||||||
|
|
||||||
|
/* No queue to put it on? */
|
||||||
|
if (!comp -> pool)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Figure out which queue it's going to. */
|
||||||
|
switch (comp -> binding_state) {
|
||||||
|
case FTS_FREE:
|
||||||
|
lq = &comp -> pool -> free;
|
||||||
|
comp -> pool -> free_leases++;
|
||||||
|
comp -> sort_time = comp -> ends;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_ACTIVE:
|
||||||
|
case FTS_RESERVED:
|
||||||
|
case FTS_BOOTP:
|
||||||
|
lq = &comp -> pool -> active;
|
||||||
|
comp -> sort_time = comp -> ends;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_EXPIRED:
|
||||||
|
case FTS_RELEASED:
|
||||||
|
case FTS_RESET:
|
||||||
|
lq = &comp -> pool -> expired;
|
||||||
|
comp -> sort_time = comp -> ends;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_ABANDONED:
|
||||||
|
lq = &comp -> pool -> abandoned;
|
||||||
|
comp -> sort_time = comp -> ends;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_BACKUP:
|
||||||
|
lq = &comp -> pool -> backup;
|
||||||
|
comp -> pool -> backup_leases++;
|
||||||
|
comp -> sort_time = comp -> ends;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_error ("Lease with bogus binding state: %d",
|
||||||
|
comp -> binding_state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insertion sort the lease onto the appropriate queue. */
|
||||||
|
prev = (struct lease *)0;
|
||||||
|
for (lp = *lq; lp; lp = lp -> next) {
|
||||||
|
if (lp -> sort_time > comp -> sort_time)
|
||||||
|
break;
|
||||||
|
prev = lp;
|
||||||
|
}
|
||||||
|
if (prev) {
|
||||||
|
if (prev -> next) {
|
||||||
|
lease_reference (&comp -> next, prev -> next, MDL);
|
||||||
|
lease_dereference (&prev -> next, MDL);
|
||||||
|
}
|
||||||
|
lease_reference (&prev -> next, comp, MDL);
|
||||||
|
} else {
|
||||||
|
if (*lq) {
|
||||||
|
lease_reference (&comp -> next, *lq, MDL);
|
||||||
|
lease_dereference (lq, MDL);
|
||||||
|
}
|
||||||
|
lease_reference (lq, comp, MDL);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For a given lease, sort it onto the right list in its pool and put it
|
||||||
|
in each appropriate hash, understanding that it's already by definition
|
||||||
|
in lease_ip_addr_hash. */
|
||||||
|
|
||||||
|
void lease_instantiate (const unsigned char *val, unsigned len,
|
||||||
|
struct lease *lease)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* XXX If the lease doesn't have a pool at this point, it's an
|
||||||
|
XXX orphan, which we *should* keep around until it expires,
|
||||||
|
XXX but which right now we just forget. */
|
||||||
|
if (!lease -> pool) {
|
||||||
|
lease_hash_delete (lease_ip_addr_hash,
|
||||||
|
lease -> ip_addr.iabuf,
|
||||||
|
lease -> ip_addr.len, MDL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put the lease on the right queue. */
|
||||||
|
lease_enqueue (lease);
|
||||||
|
|
||||||
|
/* Record the lease in the uid hash if possible. */
|
||||||
|
if (lease -> uid) {
|
||||||
|
uid_hash_add (lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record it in the hardware address hash if possible. */
|
||||||
|
if (lease -> hardware_addr.hlen) {
|
||||||
|
hw_hash_add (lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Run expiry events on every pool. This is called on startup so that
|
/* Run expiry events on every pool. This is called on startup so that
|
||||||
any expiry events that occurred after the server stopped and before it
|
any expiry events that occurred after the server stopped and before it
|
||||||
was restarted can be run. At the same time, if failover support is
|
was restarted can be run. At the same time, if failover support is
|
||||||
@ -1687,6 +1712,10 @@ void expire_all_pools ()
|
|||||||
struct lease *l;
|
struct lease *l;
|
||||||
struct lease **lptr [5];
|
struct lease **lptr [5];
|
||||||
|
|
||||||
|
/* First, go over the hash list and actually put all the leases
|
||||||
|
on the appropriate lists. */
|
||||||
|
lease_hash_foreach (lease_ip_addr_hash, lease_instantiate);
|
||||||
|
|
||||||
/* Loop through each pool in each shared network and call the
|
/* Loop through each pool in each shared network and call the
|
||||||
expiry routine on the pool. */
|
expiry routine on the pool. */
|
||||||
for (s = shared_networks; s; s = s -> next) {
|
for (s = shared_networks; s; s = s -> next) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user