Commit 3933e2aa authored by Shawn Routhier's avatar Shawn Routhier
Browse files

[master] Add support for manipulating lease queues via a binary search.

Add support for manipluating the queues holding leaes for time
based events (free, backup, active, expired, abandoned and reserved)
via a binary search instead of walking through the linked list.
parent 4136513e
......@@ -118,6 +118,14 @@ by Eric Young (eay@cryptsoft.com).
of as a token.
[ISC-Bugs #39529]
- Add support for accessing the v4 lease queues (active, free etc) in a
binary fashion instead of needing to walk through a linear list to
insert, find or remove an entry from the queues. In addition add a
compile time option "--enable-binary-leases" to enable the new code
or to continue using the old code. The old code is the default.
Thanks to Fernando Soto from BlueCat Networks for the patch.
[ISC-Bugs #39078]
Changes since 4.3.2rc2
- None
......
......@@ -751,6 +751,7 @@ enable_ipv4_pktinfo
enable_use_sockets
enable_secs_byteorder
enable_log_pid
enable_binary_leases
with_atf
with_srv_lease_file
with_srv6_lease_file
......@@ -1420,6 +1421,8 @@ Optional Features:
--enable-secs-byteorder Correct bad byteorders in the secs field (default is
no).
--enable-log-pid Include PIDs in syslog messages (default is no).
--enable-binary-leases enable support for binary insertion of leases
(default is no)
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
......@@ -5426,6 +5429,19 @@ $as_echo "#define USE_LOG_PID 1" >>confdefs.h
fi
# Allow for binary search when inserting v4 leases into queues
# Check whether --enable-binary_leases was given.
if test "${enable_binary_leases+set}" = set; then :
enableval=$enable_binary_leases;
fi
# binary_leases is off by default.
if test "$enable_binary_leases" = "yes"; then
$as_echo "#define BINARY_LEASES 1" >>confdefs.h
fi
# Testing section
atf_path="no"
......@@ -8315,6 +8331,7 @@ Features:
debug: $enable_debug
failover: $enable_failover
execute: $enable_execute
binary-leases: $enable_binary_leases
Developer:
ATF unittests : $atf_path
......
......@@ -187,6 +187,15 @@ if test "$enable_log_pid" = "yes" ; then
[Define to include PIDs in syslog messages.])
fi
# Allow for binary search when inserting v4 leases into queues
AC_ARG_ENABLE(binary_leases,
AS_HELP_STRING([--enable-binary-leases],[enable support for binary insertion of leases (default is no)]))
# binary_leases is off by default.
if test "$enable_binary_leases" = "yes"; then
AC_DEFINE([BINARY_LEASES], [1],
[Define to support binary insertion of leases into queues.])
fi
# Testing section
atf_path="no"
......@@ -697,6 +706,7 @@ Features:
debug: $enable_debug
failover: $enable_failover
execute: $enable_execute
binary-leases: $enable_binary_leases
Developer:
ATF unittests : $atf_path
......
......@@ -3,6 +3,9 @@
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to support binary insertion of leases into queues. */
#undef BINARY_LEASES
/* Define to compile debug-only DHCP software. */
#undef DEBUG
......
......@@ -230,6 +230,42 @@ typedef time_t TIME;
(((x) >> OPTION_HASH_EXP) & \
(OPTION_HASH_PTWO - 1))) % OPTION_HASH_SIZE;
/* Lease queue information. We have two ways of storing leases.
* The original is a linear linked list which is slower but uses
* less memory while the other adds a binary array on top of that
* list to make insertions faster. We define several macros
* based on which is in use to allow the code to be cleaner by
* avoiding #ifdefs.
*
* POOL_DESTROYP is used for debugging purposes
*/
#if !defined (BINARY_LEASES)
#define LEASE_STRUCT struct lease *
#define LEASE_STRUCT_PTR struct lease **
#define LEASE_GET_FIRST(LQ) LQ
#define LEASE_GET_FIRSTP(LQ) *(LQ)
#define LEASE_GET_NEXT(LQ, LEASE) LEASE->next
#define LEASE_GET_NEXTP(LQ, LEASE) LEASE->next
#define LEASE_INSERTP(LQ, LEASE) lease_insert(LQ, LEASE)
#define LEASE_REMOVEP(LQ, LEASE) lease_remove(LQ, LEASE)
#define LEASE_NOT_EMPTY(LQ) LQ
#define LEASE_NOT_EMPTYP(LQ) *LQ
#define POOL_DESTROYP(LQ) lease_remove_all(LQ)
#else
#define LEASE_STRUCT struct leasechain
#define LEASE_STRUCT_PTR struct leasechain *
#define LEASE_GET_FIRST(LQ) lc_get_first_lease(&LQ)
#define LEASE_GET_FIRSTP(LQ) lc_get_first_lease(LQ)
#define LEASE_GET_NEXT(LQ, LEASE) lc_get_next(&LQ, LEASE)
#define LEASE_GET_NEXTP(LQ, LEASE) lc_get_next(LQ, LEASE)
#define LEASE_INSERTP(LQ, LEASE) lc_add_sorted_lease(LQ, LEASE)
#define LEASE_REMOVEP(LQ, LEASE) lc_unlink_lease(LQ, LEASE)
#define LEASE_NOT_EMPTY(LQ) lc_not_empty(&LQ)
#define LEASE_NOT_EMPTYP(LQ) lc_not_empty(LQ)
#define POOL_DESTROYP(LQ) lc_delete_all(LQ)
#endif
enum dhcp_shutdown_state {
shutdown_listeners,
shutdown_omapi_connections,
......@@ -511,10 +547,17 @@ struct on_star {
struct lease {
OMAPI_OBJECT_PREAMBLE;
struct lease *next;
#if defined (BINARY_LEASES)
struct lease *prev;
struct leasechain *lc;
#endif
struct lease *n_uid, *n_hw;
struct iaddr ip_addr;
TIME starts, ends, sort_time;
#if defined (BINARY_LEASES)
long int sort_tiebreaker;
#endif
char *client_hostname;
struct binding_scope *scope;
struct host_decl *host;
......@@ -919,6 +962,18 @@ struct permit {
TIME after; /* date after which this clause applies */
};
#if defined (BINARY_LEASES)
struct leasechain {
struct lease **list; /* lease list */
size_t total; /* max number of elements in this list,
* including free pointers at the end if any */
size_t nelem; /* the number of elements, also the next index to use */
size_t growth; /* the growth factor to use when increase an array
* this is set after parsing the pools and before
* creatin an array. */
};
#endif
struct pool {
OMAPI_OBJECT_PREAMBLE;
struct pool *next;
......@@ -926,12 +981,12 @@ struct pool {
struct shared_network *shared_network;
struct permit *permit_list;
struct permit *prohibit_list;
struct lease *active;
struct lease *expired;
struct lease *free;
struct lease *backup;
struct lease *abandoned;
struct lease *reserved;
LEASE_STRUCT active;
LEASE_STRUCT expired;
LEASE_STRUCT free;
LEASE_STRUCT backup;
LEASE_STRUCT abandoned;
LEASE_STRUCT reserved;
TIME next_event_time;
int lease_count;
int free_leases;
......@@ -3393,6 +3448,14 @@ void hw_hash_add (struct lease *);
void hw_hash_delete (struct lease *);
int write_leases (void);
int write_leases6(void);
#if !defined(BINARY_LEASES)
void lease_insert(struct lease **, struct lease *);
void lease_remove(struct lease **, struct lease *);
#if defined (DEBUG_MEMORY_LEAKAGE) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
void lease_remove_all(struct lease **);
#endif
#endif
int lease_enqueue (struct lease *);
isc_result_t lease_instantiate(const void *, unsigned, void *);
void expire_all_pools (void);
......@@ -3670,6 +3733,20 @@ void mark_phosts_unavailable(void);
void mark_interfaces_unavailable(void);
void report_jumbo_ranges();
#if defined (BINARY_LEASES)
/* leasechain.c */
int lc_not_empty(struct leasechain *lc);
void lc_add_sorted_lease(struct leasechain *lc, struct lease *lp);
void lc_unlink_lease(struct leasechain *lc, struct lease *lp);
struct lease *lc_get_first_lease(struct leasechain *lc);
struct lease *lc_get_next(struct leasechain *lc, struct lease *lp);
void lc_init_growth(struct leasechain *lc, size_t growth);
#if defined (DEBUG_MEMORY_LEAKAGE) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
void lc_delete_all(struct leasechain *lc);
#endif
#endif /* BINARY_LEASES */
#define MAX_ADDRESS_STRING_LEN \
(sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
......
......@@ -111,6 +111,9 @@
/* Define this if you want to debug the host part of the inform processing */
/* #define DEBUG_INFORM_HOST */
/* Define this if you want to debug the binary leases (lease_chain) code */
/* #define DEBUG_BINARY_LEASES */
/* Define this if you want DHCP failover protocol support in the DHCP
server. */
......
......@@ -10,7 +10,7 @@ dist_sysconf_DATA = dhcpd.conf.example
sbin_PROGRAMS = dhcpd
dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c \
dhcpv6.c mdb6.c ldap.c ldap_casa.c
dhcpv6.c mdb6.c ldap.c ldap_casa.c leasechain.c
dhcpd_CFLAGS = $(LDAP_CFLAGS)
dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
......
......@@ -102,7 +102,7 @@ am_dhcpd_OBJECTS = dhcpd-dhcpd.$(OBJEXT) dhcpd-dhcp.$(OBJEXT) \
dhcpd-salloc.$(OBJEXT) dhcpd-ddns.$(OBJEXT) \
dhcpd-dhcpleasequery.$(OBJEXT) dhcpd-dhcpv6.$(OBJEXT) \
dhcpd-mdb6.$(OBJEXT) dhcpd-ldap.$(OBJEXT) \
dhcpd-ldap_casa.$(OBJEXT)
dhcpd-ldap_casa.$(OBJEXT) dhcpd-leasechain.$(OBJEXT)
dhcpd_OBJECTS = $(am_dhcpd_OBJECTS)
dhcpd_DEPENDENCIES = ../common/libdhcp.a ../omapip/libomapi.a \
../dhcpctl/libdhcpctl.a ../bind/lib/libirs.a \
......@@ -357,7 +357,7 @@ AM_CPPFLAGS = -I.. -DLOCALSTATEDIR='"@localstatedir@"'
dist_sysconf_DATA = dhcpd.conf.example
dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c \
dhcpv6.c mdb6.c ldap.c ldap_casa.c
dhcpv6.c mdb6.c ldap.c ldap_casa.c leasechain.c
dhcpd_CFLAGS = $(LDAP_CFLAGS)
dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
......@@ -465,6 +465,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-failover.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-ldap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-ldap_casa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-leasechain.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-mdb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-mdb6.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpd-omapi.Po@am__quote@
......@@ -722,6 +723,20 @@ dhcpd-ldap_casa.obj: ldap_casa.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ldap_casa.c' object='dhcpd-ldap_casa.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dhcpd_CFLAGS) $(CFLAGS) -c -o dhcpd-ldap_casa.obj `if test -f 'ldap_casa.c'; then $(CYGPATH_W) 'ldap_casa.c'; else $(CYGPATH_W) '$(srcdir)/ldap_casa.c'; fi`
dhcpd-leasechain.o: leasechain.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dhcpd_CFLAGS) $(CFLAGS) -MT dhcpd-leasechain.o -MD -MP -MF $(DEPDIR)/dhcpd-leasechain.Tpo -c -o dhcpd-leasechain.o `test -f 'leasechain.c' || echo '$(srcdir)/'`leasechain.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dhcpd-leasechain.Tpo $(DEPDIR)/dhcpd-leasechain.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='leasechain.c' object='dhcpd-leasechain.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dhcpd_CFLAGS) $(CFLAGS) -c -o dhcpd-leasechain.o `test -f 'leasechain.c' || echo '$(srcdir)/'`leasechain.c
dhcpd-leasechain.obj: leasechain.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dhcpd_CFLAGS) $(CFLAGS) -MT dhcpd-leasechain.obj -MD -MP -MF $(DEPDIR)/dhcpd-leasechain.Tpo -c -o dhcpd-leasechain.obj `if test -f 'leasechain.c'; then $(CYGPATH_W) 'leasechain.c'; else $(CYGPATH_W) '$(srcdir)/leasechain.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dhcpd-leasechain.Tpo $(DEPDIR)/dhcpd-leasechain.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='leasechain.c' object='dhcpd-leasechain.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dhcpd_CFLAGS) $(CFLAGS) -c -o dhcpd-leasechain.obj `if test -f 'leasechain.c'; then $(CYGPATH_W) 'leasechain.c'; else $(CYGPATH_W) '$(srcdir)/leasechain.c'; fi`
install-man5: $(man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
......
......@@ -1759,6 +1759,14 @@ void parse_pool_statement (cfile, group, type)
pool_dereference(&lp->pool, MDL);
pool_reference(&lp->pool, pp, MDL);
}
#if defined (BINARY_LEASES)
/* If we are doing binary leases we also need to add the
* addresses in for leasechain allocation.
*/
pp->lease_count += pool->lease_count;
#endif
break;
}
......
......@@ -4548,8 +4548,9 @@ int mockup_lease (struct lease **lp, struct packet *packet,
int allocate_lease (struct lease **lp, struct packet *packet,
struct pool *pool, int *peer_has_leases)
{
struct lease *lease = (struct lease *)0;
struct lease *candl = (struct lease *)0;
struct lease *lease = NULL;
struct lease *candl = NULL;
struct lease *peerl = NULL;
for (; pool ; pool = pool -> next) {
if ((pool -> prohibit_list &&
......@@ -4575,7 +4576,7 @@ int allocate_lease (struct lease **lp, struct packet *packet,
* owned by a failover peer. */
if (pool->failover_peer != NULL) {
if (pool->failover_peer->i_am == primary) {
candl = pool->free;
candl = LEASE_GET_FIRST(pool->free);
/*
* In normal operation, we never want to touch
......@@ -4583,27 +4584,25 @@ int allocate_lease (struct lease **lp, struct packet *packet,
* operation, we need to be able to pick up
* the peer's leases after STOS+MCLT.
*/
if (pool->backup != NULL) {
peerl = LEASE_GET_FIRST(pool->backup);
if (peerl != NULL) {
if (((candl == NULL) ||
(candl->ends >
pool->backup->ends)) &&
lease_mine_to_reallocate(
pool->backup)) {
candl = pool->backup;
(candl->ends > peerl->ends)) &&
lease_mine_to_reallocate(peerl)) {
candl = peerl;
} else {
*peer_has_leases = 1;
}
}
} else {
candl = pool->backup;
candl = LEASE_GET_FIRST(pool->backup);
if (pool->free != NULL) {
peerl = LEASE_GET_FIRST(pool->free);
if (peerl != NULL) {
if (((candl == NULL) ||
(candl->ends >
pool->free->ends)) &&
lease_mine_to_reallocate(
pool->free)) {
candl = pool->free;
(candl->ends > peerl->ends)) &&
lease_mine_to_reallocate(peerl)) {
candl = peerl;
} else {
*peer_has_leases = 1;
}
......@@ -4611,17 +4610,17 @@ int allocate_lease (struct lease **lp, struct packet *packet,
}
/* Try abandoned leases as a last resort. */
if ((candl == NULL) &&
(pool->abandoned != NULL) &&
lease_mine_to_reallocate(pool->abandoned))
candl = pool->abandoned;
peerl = LEASE_GET_FIRST(pool->abandoned);
if ((candl == NULL) && (peerl != NULL) &&
lease_mine_to_reallocate(peerl))
candl = peerl;
} else
#endif
{
if (pool -> free)
candl = pool -> free;
if (LEASE_NOT_EMPTY(pool->free))
candl = LEASE_GET_FIRST(pool->free);
else
candl = pool -> abandoned;
candl = LEASE_GET_FIRST(pool->abandoned);
}
/*
......
......@@ -1117,6 +1117,12 @@ void postconf_initialization (int quiet)
data_string_forget(&db, MDL);
}
#if defined (BINARY_LEASES)
if (local_family == AF_INET) {
log_info("Source compiled to use binary-leases");
}
#endif
/* Don't need the options anymore. */
option_state_dereference(&options, MDL);
}
......
......@@ -3,7 +3,7 @@
Failover protocol support code... */
/*
* Copyright (c) 2004-2014 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
......@@ -1939,18 +1939,33 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
case partner_down:
/* For every expired lease, set a timeout for it to become free. */
for (s = shared_networks; s; s = s -> next) {
for (p = s -> pools; p; p = p -> next) {
if (p -> failover_peer == state) {
for (l = p->expired ; l ; l = l->next) {
for (s = shared_networks; s; s = s->next) {
for (p = s->pools; p; p = p->next) {
#if defined (BINARY_LEASES)
long int tiebreaker = 0;
#endif
if (p->failover_peer == state) {
for (l = LEASE_GET_FIRST(p->expired);
l != NULL;
l = LEASE_GET_NEXT(p->expired, l)) {
l->tsfp = state->me.stos + state->mclt;
l->sort_time = (l->tsfp > l->ends) ?
l->tsfp : l->ends;
#if defined (BINARY_LEASES)
/* If necessary fix up the tiebreaker so the leases
* maintain proper sort order.
*/
l->sort_tiebreaker = tiebreaker;
if (tiebreaker != LONG_MAX)
tiebreaker++;
#endif
}
if (p->expired &&
(p->expired->sort_time < p->next_event_time)) {
p->next_event_time = p->expired->sort_time;
l = LEASE_GET_FIRST(p->expired);
if (l && (l->sort_time < p->next_event_time)) {
p->next_event_time = l->sort_time;
#if defined (DEBUG_FAILOVER_TIMING)
log_info ("add_timeout +%d %s",
(int)(cur_time - p->next_event_time),
......@@ -1967,7 +1982,6 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
}
break;
default:
break;
}
......@@ -2470,14 +2484,15 @@ dhcp_failover_pool_dobalance(dhcp_failover_state_t *state,
{
int lts, total, thresh, hold, panic, pass;
int leases_queued = 0;
struct lease *lp = (struct lease *)0;
struct lease *next = (struct lease *)0;
struct lease *lp = NULL;
struct lease *next = NULL;
struct lease *ltemp = NULL;
struct shared_network *s;
struct pool *p;
binding_state_t peer_lease_state;
/* binding_state_t my_lease_state; */
/* XXX Why is this my_lease_state never used? */
struct lease **lq;
LEASE_STRUCT_PTR lq;
int (*log_func)(const char *, ...);
const char *result, *reqlog;
......@@ -2559,13 +2574,14 @@ dhcp_failover_pool_dobalance(dhcp_failover_state_t *state,
* worth it.
*/
pass = 0;
lease_reference(&lp, *lq, MDL);
lease_reference(&lp, LEASE_GET_FIRSTP(lq), MDL);
while (lp) {
if (next)
lease_dereference(&next, MDL);
if (lp->next)
lease_reference(&next, lp->next, MDL);
ltemp = LEASE_GET_NEXTP(lq, lp);
if (ltemp != NULL)
lease_reference(&next, ltemp, MDL);
/*
* Stop if the pool is 'balanced enough.'
......@@ -2613,7 +2629,7 @@ dhcp_failover_pool_dobalance(dhcp_failover_state_t *state,
lease_reference(&lp, next, MDL);
else if (!pass) {
pass = 1;
lease_reference(&lp, *lq, MDL);
lease_reference(&lp, LEASE_GET_FIRSTP(lq), MDL);
}
}
......@@ -2657,6 +2673,7 @@ dhcp_failover_pool_check(struct pool *pool)
dhcp_failover_state_t *peer;
TIME est1, est2;
struct timeval tv;
struct lease *ltemp;
peer = pool->failover_peer;
......@@ -2673,13 +2690,15 @@ dhcp_failover_pool_check(struct pool *pool)
* lease is a virgin (ends = 0), we wind up sending this against
* the max_balance bounds check.
*/
if(pool->free && pool->free->ends < cur_time)
est1 = cur_time - pool->free->ends;
ltemp = LEASE_GET_FIRST(pool->free);
if(ltemp && ltemp->ends < cur_time)
est1 = cur_time - ltemp->ends;
else
est1 = 0;
if(pool->backup && pool->backup->ends < cur_time)
est2 = cur_time - pool->backup->ends;
ltemp = LEASE_GET_FIRST(pool->backup);
if(ltemp && ltemp->ends < cur_time)
est2 = cur_time - ltemp->ends;
else
est2 = 0;
......@@ -5651,7 +5670,7 @@ isc_result_t dhcp_failover_generate_update_queue (dhcp_failover_state_t *state,
#define ABANDONED_LEASES 3
#define BACKUP_LEASES 4
#define RESERVED_LEASES 5
struct lease **lptr[RESERVED_LEASES+1];
LEASE_STRUCT_PTR lptr[RESERVED_LEASES+1];
/* Loop through each pool in each shared network and call the
expiry routine on the pool. */
......@@ -5668,7 +5687,9 @@ isc_result_t dhcp_failover_generate_update_queue (dhcp_failover_state_t *state,
lptr[RESERVED_LEASES] = &p->reserved;
for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
for (l = *(lptr [i]); l; l = l -> next) {
for (l = LEASE_GET_FIRSTP(lptr[i]);
l != NULL;
l = LEASE_GET_NEXTP(lptr[i], l)) {
if ((l->flags & ON_QUEUE) == 0 &&
(everythingp ||
(l->tstp > l->atsfp) ||
......
/* leasechain.c
Additional support for in-memory database support */
/*
* Copyright (c) 2015 by Internet Systems Consortium, Inc. ("ISC")
*
* 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.
*
* 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.
*
* Internet Systems Consortium, Inc.
* 950 Charter Street
* Redwood City, CA 94063
* <info@isc.org>
* https://www.isc.org/
*
*/
/*! \file server\leasechaing.c
*
* \page leasechain structures overview
*
* A brief description of the leasechain structures
*
* This file provides additional data structures for a leasecain to
* provide faster access to leases on the queues associated with a pool
* than a linear walk. Each pool has a set of queues: active, free, backup,
* expired and abandoned to track leases as they are handed out and returned.
* The original code use a simply linear list for each of those pools but
* this can present performance issues if the pool is large and the lists are
* long.
* This code adds an array on top of the list allowing us to search the list
* in a binary fashion instead of a linear walk.
*
* \verbatim
* leasechain
* +------------+ +-------+-------+-------+-------+
* | lease list |--> | lease | lease | lease | lease |....
* | start | | ptr | ptr | ptr | ptr |
* | end | +-------+-------+-------+-------+
* | max | | |
* +------------+ V V
* +-------+ +-------+
* | lease | | lease |
* | | | |
* | next |->| next |->NULL
* NULL<- | prev |<-| prev |
* +-------+ +-------+
*
* The linked list is maintained in an ordered state. Inserting an entry is
* accomplished by doing a binary search on the array to find the proper place
* in the list and then updating the pointers in the linked list to include the
* new entry. The entry is added into the array by copying the remainder of
* the array to provide space for the new entry.
* Removing an entry is the reverse.
* The arrays for the queues will be pre-allocated but not all of them will be
* large enough to hold all of the leases. If additional space is required the
* array will be grown.