process to start up even if the resolv.conf file has problems.
[ISC-Bugs #35989]
+- Add theshold logging functionality. Two new options,
+ log-threshold-low and log-threshold-high, indicate to the
+ server if and when it should log an error message as addresses
+ in a pool are used.
+ [ISC-Bugs #34487]
+
Changes since 4.3.0rc1
- None
return 1;
}
+/*
+ * Look for the option and dig out the value assoicated with it.
+ * Currently this is used for 1 byte integers, it maybe expanded
+ * in the future to handle other integers at which point it will
+ * need a size argument.
+ */
+int get_option_int (result, universe, packet, lease, client_state,
+ in_options, cfg_options, options, scope, code, file, line)
+ int *result;
+ struct universe *universe;
+ struct packet *packet;
+ struct lease *lease;
+ struct client_state *client_state;
+ struct option_state *in_options;
+ struct option_state *cfg_options;
+ struct option_state *options;
+ struct binding_scope **scope;
+ unsigned code;
+ const char *file;
+ int line;
+{
+ struct option_cache *oc;
+ struct data_string d1;
+ int rcode = 0;
+
+ /* basic sanity checks */
+ if ((options == NULL) || (universe->lookup_func == NULL))
+ return (0);
+
+ /* find the option cache */
+ oc = ((*universe->lookup_func)(universe, options, code));
+ if (!oc)
+ return (0);
+
+ /* if there is a value get it into the string */
+ memset(&d1, 0, sizeof(d1));
+ if (!evaluate_option_cache(&d1, packet, lease, client_state,
+ in_options, cfg_options, scope, oc,
+ file, line))
+ return (0);
+
+ /* If the length matches extract the value for the return */
+ if (d1.len == 1) {
+ *result = d1.data[0];
+ rcode = 1;
+ }
+ data_string_forget(&d1, MDL);
+
+ return (rcode);
+}
+
void set_option (universe, options, option, op)
struct universe *universe;
struct option_state *options;
if HAVE_ATF
-ATF_TESTS += alloc_unittest dns_unittest
+ATF_TESTS += alloc_unittest dns_unittest misc_unittest
alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c
alloc_unittest_LDADD = $(ATF_LDFLAGS)
../../omapip/libomapi.a ../../bind/lib/libirs.a \
../../bind/lib/libdns.a ../../bind/lib/libisccfg.a ../../bind/lib/libisc.a
+misc_unittest_SOURCES = misc_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
+misc_unittest_LDADD = $(ATF_LDFLAGS)
+misc_unittest_LDADD += ../libdhcp.a \
+ ../../omapip/libomapi.a ../../bind/lib/libirs.a \
+ ../../bind/lib/libdns.a ../../bind/lib/libisccfg.a ../../bind/lib/libisc.a
+
check: $(ATF_TESTS)
atf-run | atf-report
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@HAVE_ATF_TRUE@am__append_1 = alloc_unittest dns_unittest
+@HAVE_ATF_TRUE@am__append_1 = alloc_unittest dns_unittest misc_unittest
check_PROGRAMS = $(am__EXEEXT_2)
subdir = common/tests
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
@HAVE_ATF_TRUE@am__EXEEXT_1 = alloc_unittest$(EXEEXT) \
-@HAVE_ATF_TRUE@ dns_unittest$(EXEEXT)
+@HAVE_ATF_TRUE@ dns_unittest$(EXEEXT) misc_unittest$(EXEEXT)
am__EXEEXT_2 = $(am__EXEEXT_1)
am__alloc_unittest_SOURCES_DIST = test_alloc.c \
$(top_srcdir)/tests/t_api_dhcp.c
@HAVE_ATF_TRUE@ ../../bind/lib/libirs.a ../../bind/lib/libdns.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libisccfg.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libisc.a
+am__misc_unittest_SOURCES_DIST = misc_unittest.c \
+ $(top_srcdir)/tests/t_api_dhcp.c
+@HAVE_ATF_TRUE@am_misc_unittest_OBJECTS = misc_unittest.$(OBJEXT) \
+@HAVE_ATF_TRUE@ t_api_dhcp.$(OBJEXT)
+misc_unittest_OBJECTS = $(am_misc_unittest_OBJECTS)
+@HAVE_ATF_TRUE@misc_unittest_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+@HAVE_ATF_TRUE@ ../libdhcp.a ../../omapip/libomapi.a \
+@HAVE_ATF_TRUE@ ../../bind/lib/libirs.a ../../bind/lib/libdns.a \
+@HAVE_ATF_TRUE@ ../../bind/lib/libisccfg.a \
+@HAVE_ATF_TRUE@ ../../bind/lib/libisc.a
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(alloc_unittest_SOURCES) $(dns_unittest_SOURCES)
+SOURCES = $(alloc_unittest_SOURCES) $(dns_unittest_SOURCES) \
+ $(misc_unittest_SOURCES)
DIST_SOURCES = $(am__alloc_unittest_SOURCES_DIST) \
- $(am__dns_unittest_SOURCES_DIST)
+ $(am__dns_unittest_SOURCES_DIST) \
+ $(am__misc_unittest_SOURCES_DIST)
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
@HAVE_ATF_TRUE@ ../../bind/lib/libdns.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libisccfg.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libisc.a
+@HAVE_ATF_TRUE@misc_unittest_SOURCES = misc_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
+@HAVE_ATF_TRUE@misc_unittest_LDADD = $(ATF_LDFLAGS) ../libdhcp.a \
+@HAVE_ATF_TRUE@ ../../omapip/libomapi.a ../../bind/lib/libirs.a \
+@HAVE_ATF_TRUE@ ../../bind/lib/libdns.a \
+@HAVE_ATF_TRUE@ ../../bind/lib/libisccfg.a \
+@HAVE_ATF_TRUE@ ../../bind/lib/libisc.a
all: all-recursive
.SUFFIXES:
@rm -f dns_unittest$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(dns_unittest_OBJECTS) $(dns_unittest_LDADD) $(LIBS)
+misc_unittest$(EXEEXT): $(misc_unittest_OBJECTS) $(misc_unittest_DEPENDENCIES) $(EXTRA_misc_unittest_DEPENDENCIES)
+ @rm -f misc_unittest$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(misc_unittest_OBJECTS) $(misc_unittest_LDADD) $(LIBS)
+
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_api_dhcp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_alloc.Po@am__quote@
--- /dev/null
+/*
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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.
+ */
+
+#include <config.h>
+#include <atf-c.h>
+#include "dhcpd.h"
+
+struct basic_test {
+ int count;
+ int used_0;
+ int used_25;
+ int used_50;
+ int used_75;
+ int used_100;
+};
+
+struct basic_test basic_values[] =
+ {{ 0, 0, 0, 0, 0, 0},
+ { 10, 0, 2, 5, 7, 10},
+ { 20, 0, 5, 10, 15, 20},
+ { 50, 0, 12, 25, 37, 50},
+ { 100, 0, 25, 50, 75, 100},
+ { 1000, 0, 250, 500, 750, 1000},
+ { 10000, 0, 2500, 5000, 7500, 10000},
+ { 100000, 0, 25000, 50000, 75000, 100000},
+ { 1000000, 0, 250000, 500000, 750000, 1000000},
+ { 10000000, 0, 2500000, 5000000, 7500000, 10000000},
+ { 100000000, 0, 25000000, 50000000, 75000000, 100000000},
+ {1000000000, 0, 250000000, 500000000, 750000000, 1000000000},
+ {2000000000, 0, 500000000, 1000000000, 1500000000, 2000000000},
+ {-1, 0, 0, 0, 0, 0}};
+
+ATF_TC(find_percent_basic);
+
+ATF_TC_HEAD(find_percent_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify basic percent calculation.");
+}
+
+/* This test does a simple check to see if we get the right value
+ * given a count and a percnetage of that count
+ */
+ATF_TC_BODY(find_percent_basic, tc)
+{
+ struct basic_test *basic_value;
+ int used;
+
+ for (basic_value = &basic_values[0];
+ basic_value->count != -1;
+ basic_value++) {
+ used = FIND_PERCENT(basic_value->count, 0);
+ if (used != basic_value->used_0) {
+ atf_tc_fail("Wrong value for 0 - count: %d, used %d",
+ basic_value->count, used);
+ }
+
+ used = FIND_PERCENT(basic_value->count, 25);
+ if (used != basic_value->used_25) {
+ atf_tc_fail("Wrong value for 25 - count: %d, used %d",
+ basic_value->count, used);
+ }
+
+ used = FIND_PERCENT(basic_value->count, 50);
+ if (used != basic_value->used_50) {
+ atf_tc_fail("Wrong value for 50 - count: %d, used %d",
+ basic_value->count, used);
+ }
+
+ used = FIND_PERCENT(basic_value->count, 75);
+ if (used != basic_value->used_75) {
+ atf_tc_fail("Wrong value for 75 - count: %d, used %d",
+ basic_value->count, used);
+ }
+
+ used = FIND_PERCENT(basic_value->count, 100);
+ if (used != basic_value->used_100) {
+ atf_tc_fail("Wrong value for 100 - count: %d, used %d",
+ basic_value->count, used);
+ }
+ }
+ return;
+}
+
+ATF_TC(find_percent_adv);
+
+ATF_TC_HEAD(find_percent_adv, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify advanced percent calculation.");
+}
+
+/* This test tries some more complicated items, such as using the macro
+ * in a function or passing expressions into macro
+ */
+ATF_TC_BODY(find_percent_adv, tc)
+{
+ if (FIND_PERCENT(10*10, 10) != 10) {
+ atf_tc_fail("Wrong value for adv 1");
+ }
+
+ if (FIND_PERCENT(20*20, 80) != 320) {
+ atf_tc_fail("Wrong value for adv 2");
+ }
+
+ if (FIND_PERCENT(1000000*1000, 50) != 500000000) {
+ atf_tc_fail("Wrong value for adv 3");
+ }
+
+ if (FIND_PERCENT(100+100, 10) != 20) {
+ atf_tc_fail("Wrong value for adv 4");
+ }
+
+ if (FIND_PERCENT(1000+2000, 90) != 2700) {
+ atf_tc_fail("Wrong value for adv 5");
+ }
+
+ if (FIND_PERCENT(10000 - 8000, 70) != 1400) {
+ atf_tc_fail("Wrong value for adv 6");
+ }
+
+ if (FIND_PERCENT(2000000000 / 1000, 25) != 500000) {
+ atf_tc_fail("Wrong value for adv 7");
+ }
+
+ if (FIND_PERCENT(10*10, 10)/2 != 5) {
+ atf_tc_fail("Wrong value for adv 8");
+ }
+
+ if (FIND_PERCENT(100*10, 50) * 2 != 1000) {
+ atf_tc_fail("Wrong value for adv 9");
+ }
+
+ if (FIND_PERCENT(100*10, 50) * 2 > 1000) {
+ atf_tc_fail("Wrong value for adv 10");
+ }
+
+ if (FIND_PERCENT(100+100, 20) * 2 < 60) {
+ atf_tc_fail("Wrong value for adv 11");
+ }
+
+ return;
+}
+
+
+/* This macro defines main() method that will call specified
+ test cases. tp and simple_test_case names can be whatever you want
+ as long as it is a valid variable identifier. */
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, find_percent_basic);
+ ATF_TP_ADD_TC(tp, find_percent_adv);
+
+ return (atf_no_error());
+}
#define SV_DDNS_LOCAL_ADDRESS4 80
#define SV_DDNS_LOCAL_ADDRESS6 81
#define SV_IGNORE_CLIENT_UIDS 82
+#define SV_LOG_THRESHOLD_LOW 83
+#define SV_LOG_THRESHOLD_HIGH 84
#if !defined (DEFAULT_PING_TIMEOUT)
# define DEFAULT_PING_TIMEOUT 1
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *failover_peer;
#endif
+ int logged; /* already logged a message */
+ int low_threshold; /* low threshold to restart logging */
};
struct shared_network {
struct ipv6_pool **ipv6_pools; /* NULL-terminated array */
int last_ipv6_pool; /* offset of last IPv6 pool
used to issue a lease */
+ int num_total; /* Total number of elements in the pond */
+ int num_active; /* Number of elements in the pond in use */
+ int logged; /* already logged a message */
+ int low_threshold; /* low threshold to restart logging */
};
/* Flags and state for dhcp_ddns_cb_t */
struct option_state *, struct option_state *,
struct option_state *, struct binding_scope **, unsigned,
const char *, int);
+int get_option_int (int *, struct universe *,
+ struct packet *, struct lease *, struct client_state *,
+ struct option_state *, struct option_state *,
+ struct option_state *, struct binding_scope **, unsigned,
+ const char *, int);
void set_option (struct universe *, struct option_state *,
struct option_cache *, enum statement_op);
struct option_cache *lookup_option (struct universe *,
#define MAX_ADDRESS_STRING_LEN \
(sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
+
+/* Find the percentage of count. We need to try two different
+ * ways to avoid rounding mistakes.
+ */
+#define FIND_PERCENT(count, percent) \
+ ((count) > (INT_MAX / 100) ? \
+ ((count) / 100) * (percent) : ((count) * (percent)) / 100)
+
+
*/
ipv6_pool_reference(&pond->ipv6_pools[num_pools], pool, MDL);
pond->ipv6_pools[num_pools+1] = NULL;
+ /* Update the number of elements in the pond. Conveniently
+ * we have the total size of the block in bits and the amount
+ * we would allocate per element in units. For an address units
+ * will always be 128, for a prefix it will be something else.
+ */
+ pond->num_total += 1 << (units - bits);
}
/*!
}
+void check_pool_threshold (packet, lease, state)
+ struct packet *packet;
+ struct lease *lease;
+ struct lease_state *state;
+
+{
+
+ struct pool *pool = lease->pool;
+ int used, count, high_threshold, poolhigh = 0, poollow = 0;
+ char *shared_name = "no name";
+
+ if (pool == NULL)
+ return;
+
+ /* get a pointer to the name if we have one */
+ if ((pool->shared_network != NULL) &&
+ (pool->shared_network->name != NULL)) {
+ shared_name = pool->shared_network->name;
+ }
+
+ count = pool->lease_count;
+ used = count - (pool->free_leases + pool->backup_leases);
+
+ /* The logged flag indicates if we have already crossed the high
+ * threshold and emitted a log message. If it is set we check to
+ * see if we have re-crossed the low threshold and need to reset
+ * things. When we cross the high threshold we determine what
+ * the low threshold is and save it into the low_threshold value.
+ * When we cross that threshold we reset the logged flag and
+ * the low_threshold to 0 which allows the high threshold message
+ * to be emitted once again.
+ * if we haven't recrossed the boundry we don't need to do anything.
+ */
+ if (pool->logged !=0) {
+ if (used <= pool->low_threshold) {
+ pool->low_threshold = 0;
+ pool->logged = 0;
+ log_error("Pool threshold reset - shared subnet: %s; "
+ "address: %s; low threshold %d/%d.",
+ shared_name, piaddr(lease->ip_addr),
+ used, count);
+ }
+ return;
+ }
+
+ /* find the high threshold */
+ if (get_option_int(&poolhigh, &server_universe, packet, lease, NULL,
+ packet->options, state->options, state->options,
+ &lease->scope, SV_LOG_THRESHOLD_HIGH, MDL) == 0) {
+ /* no threshold bail out */
+ return;
+ }
+
+ /* We do have a threshold for this pool, see if its valid */
+ if ((poolhigh <= 0) || (poolhigh > 100)) {
+ /* not valid */
+ return;
+ }
+
+ /* we have a valid value, have we exceeded it */
+ high_threshold = FIND_PERCENT(count, poolhigh);
+ if (used < high_threshold) {
+ /* nope, no more to do */
+ return;
+ }
+
+ /* we've exceeded it, output a message */
+ log_error("Pool threshold exceeded - shared subnet: %s; "
+ "address: %s; high threshold %d%% %d/%d.",
+ shared_name, piaddr(lease->ip_addr),
+ poolhigh, used, count);
+
+ /* handle the low threshold now, if we don't
+ * have a valid one we default to 0. */
+ if ((get_option_int(&poollow, &server_universe, packet, lease, NULL,
+ packet->options, state->options, state->options,
+ &lease->scope, SV_LOG_THRESHOLD_LOW, MDL) == 0) ||
+ (poollow > 100)) {
+ poollow = 0;
+ }
+
+ /*
+ * If the low theshold is higher than the high threshold we continue to log
+ * If it isn't then we set the flag saying we already logged and determine
+ * what the reset threshold is.
+ */
+ if (poollow < poolhigh) {
+ pool->logged = 1;
+ pool->low_threshold = FIND_PERCENT(count, poollow);
+ }
+}
+
void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
struct packet *packet;
struct lease *lease;
data_string_forget(&d1, MDL);
}
+
+ /*
+ * If this is an ack check to see if we have used enough of
+ * the pool to want to log a message
+ */
+ if (offer == DHCPACK)
+ check_pool_threshold(packet, lease, state);
+
/* a client requests an address which is not yet active*/
if (lease->pool && lease->pool->valid_from &&
cur_time < lease->pool->valid_from) {
b) extend lease only up to the expiration date, but not
below min-lease-time
Setting min-lease-time is essential for this to work!
- The value of min-lease-time determines the lenght
+ The value of min-lease-time determines the length
of the transition window:
A client renewing a second before the deadline will
get a min-lease-time lease. Since the current ip might not
.RE
.PP
The
+.I log-threshold-high
+and
+.I log-threshold-low
+statements
+.RS 0.25i
+.PP
+.B log-threshold-high \fIpercentage\fB;\fR
+.PP
+.B log-threshold-low \fIpercentage\fB;\fR
+.PP
+The \fIlog-threshold-low\fR and \fIlog-threshold-high\fR statements
+are used to control when a message is output about pool usage. The
+value for both of them is the percentage of the pool in use. If the
+high threshold is 0 or has not been specified, no messages will be
+produced. If a high threshold is given, a message is output once the
+pool usage passes that level. After that, no more messages will be
+output until the pool usage falls below the low threshold. If the low
+threshold is not given, it default to a value of zero.
+.PP
+A special case occurs when the low threshold is set to be higer than
+the high threshold. In this case, a message will be generated each time
+a lease is acknowledged when the pool usage is above the high threshold.
+.RE
+.PP
+The
.I max-lease-time
statement
.RS 0.25i
return ret_val;
}
+void check_pool6_threshold(struct reply_state *reply,
+ struct iasubopt *lease)
+{
+ struct ipv6_pond *pond;
+ int used, count, high_threshold, poolhigh = 0, poollow = 0;
+ char *shared_name = "no name";
+ char tmp_addr[INET6_ADDRSTRLEN];
+
+ if ((lease->ipv6_pool == NULL) || (lease->ipv6_pool->ipv6_pond == NULL))
+ return;
+ pond = lease->ipv6_pool->ipv6_pond;
+
+ count = pond->num_total;
+ used = pond->num_active;
+
+ /* The logged flag indicates if we have already crossed the high
+ * threshold and emitted a log message. If it is set we check to
+ * see if we have re-crossed the low threshold and need to reset
+ * things. When we cross the high threshold we determine what
+ * the low threshold is and save it into the low_threshold value.
+ * When we cross that threshold we reset the logged flag and
+ * the low_threshold to 0 which allows the high threshold message
+ * to be emitted once again.
+ * if we haven't recrossed the boundry we don't need to do anything.
+ */
+ if (pond->logged !=0) {
+ if (used <= pond->low_threshold) {
+ pond->low_threshold = 0;
+ pond->logged = 0;
+ log_error("Pool threshold reset - shared subnet: %s; "
+ "address: %s; low threshold %d/%d.",
+ shared_name,
+ inet_ntop(AF_INET6, &lease->addr,
+ tmp_addr, sizeof(tmp_addr)),
+ used, count);
+ }
+ return;
+ }
+
+ /* find the high threshold */
+ if (get_option_int(&poolhigh, &server_universe, reply->packet, NULL,
+ NULL, reply->packet->options, reply->opt_state,
+ reply->opt_state, &lease->scope,
+ SV_LOG_THRESHOLD_HIGH, MDL) == 0) {
+ /* no threshold bail out */
+ return;
+ }
+
+ /* We do have a threshold for this pool, see if its valid */
+ if ((poolhigh <= 0) || (poolhigh > 100)) {
+ /* not valid */
+ return;
+ }
+
+ /* we have a valid value, have we exceeded it */
+ high_threshold = FIND_PERCENT(count, poolhigh);
+ if (used < high_threshold) {
+ /* nope, no more to do */
+ return;
+ }
+
+ /* we've exceeded it, output a message */
+ if ((pond->shared_network != NULL) &&
+ (pond->shared_network->name != NULL)) {
+ shared_name = pond->shared_network->name;
+ }
+ log_error("Pool threshold exceeded - shared subnet: %s; "
+ "address: %s; high threshold %d%% %d/%d.",
+ shared_name,
+ inet_ntop(AF_INET6, &lease->addr, tmp_addr, sizeof(tmp_addr)),
+ poolhigh, used, count);
+
+ /* handle the low threshold now, if we don't
+ * have one we default to 0. */
+ if ((get_option_int(&poollow, &server_universe, reply->packet, NULL,
+ NULL, reply->packet->options, reply->opt_state,
+ reply->opt_state, &lease->scope,
+ SV_LOG_THRESHOLD_LOW, MDL) == 0) ||
+ (poollow > 100)) {
+ poollow = 0;
+ }
+
+ /*
+ * If the low theshold is higher than the high threshold we continue to log
+ * If it isn't then we set the flag saying we already logged and determine
+ * what the reset threshold is.
+ */
+ if (poollow < poolhigh) {
+ pond->logged = 1;
+ pond->low_threshold = FIND_PERCENT(count, poollow);
+ }
+}
+
/*
* We have a set of operations we do to set up the reply packet, which
* is the same for many message types.
tmp, NULL, reply->opt_state);
}
#endif
+ /* Do our threshold check. */
+ check_pool6_threshold(reply, tmp);
}
/* Remove any old ia from the hash. */
tmp, NULL, reply->opt_state);
}
#endif
+ /* Do our threshold check. */
+ check_pool6_threshold(reply, tmp);
}
/* Remove any old ia from the hash. */
executable_statement_dereference
(&tmp->on_star.on_commit, MDL);
}
+
+ /* Do our threshold check. */
+ check_pool6_threshold(reply, tmp);
}
/* Remove any old ia from the hash. */
*/
isc_heap_delete(pool->active_timeouts, test_iasubopt->heap_index);
pool->num_active--;
+ if (pool->ipv6_pond)
+ pool->ipv6_pond->num_active--;
iasubopt_hash_delete(pool->leases, &test_iasubopt->addr,
sizeof(test_iasubopt->addr), MDL);
isc_heap_delete(pool->active_timeouts,
test_iasubopt->heap_index);
pool->num_active--;
+ if (pool->ipv6_pond)
+ pool->ipv6_pond->num_active--;
} else {
isc_heap_delete(pool->inactive_timeouts,
test_iasubopt->heap_index);
sizeof(tmp_iasubopt->addr), lease, MDL);
insert_result = isc_heap_insert(pool->active_timeouts,
tmp_iasubopt);
- if (insert_result == ISC_R_SUCCESS)
+ if (insert_result == ISC_R_SUCCESS) {
pool->num_active++;
+ if (pool->ipv6_pond)
+ pool->ipv6_pond->num_active++;
+ }
+
} else {
tmp_iasubopt->soft_lifetime_end_time = valid_lifetime_end_time;
insert_result = isc_heap_insert(pool->inactive_timeouts,
pool->num_active++;
pool->num_inactive--;
lease->state = FTS_ACTIVE;
+ if (pool->ipv6_pond)
+ pool->ipv6_pond->num_active++;
}
return insert_result;
}
lease->state = state;
pool->num_active--;
pool->num_inactive++;
+ if (pool->ipv6_pond)
+ pool->ipv6_pond->num_active--;
}
return insert_result;
}
{ "ddns-local-address4", "I", &server_universe, 80, 1 },
{ "ddns-local-address6", "6", &server_universe, 81, 1 },
{ "ignore-client-uids", "f", &server_universe, 82, 1 },
+ { "log-threshold-low", "B", &server_universe, 83, 1 },
+ { "log-threshold-high", "B", &server_universe, 84, 1 },
{ NULL, NULL, NULL, 0, 0 }
};