summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELNOTES6
-rw-r--r--includes/dhcpd.h6
-rw-r--r--server/dhcp.c8
-rw-r--r--server/dhcpd.c15
-rw-r--r--server/dhcpd.conf.531
-rw-r--r--server/mdb.c40
-rw-r--r--server/stables.c1
7 files changed, 88 insertions, 19 deletions
diff --git a/RELNOTES b/RELNOTES
index 3d051312..352dd7f6 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -92,6 +92,12 @@ by Eric Young (eay@cryptsoft.com).
are issues while cleaning up the A or AAAA records.
[ISC-Bugs #23954]
+- Added global configuration parameter, abandon-lease-time, which determines
+ the amount of time a lease remains abandoned. The default is 84600 seconds.
+ Additionaly, the server now conducts a ping check (if ping checks are
+ enabled) prior to offering an abandoned lease to client.
+ [ISC-Bugs #41815]
+
Changes since 4.3.4b1
- None
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index d1497928..261714dc 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -798,6 +798,7 @@ struct lease_state {
#define SV_SERVER_ID_CHECK 86
#define SV_PREFIX_LEN_MODE 87
#define SV_DHCPV6_SET_TEE_TIMES 88
+#define SV_ABANDON_LEASE_TIME 89
#if !defined (DEFAULT_PING_TIMEOUT)
# define DEFAULT_PING_TIMEOUT 1
@@ -846,6 +847,10 @@ struct lease_state {
# define MIN_LEASE_WRITE 15
#endif
+#if !defined (DEFAULT_ABANDON_LEASE_TIME)
+# define DEFAULT_ABANDON_LEASE_TIME 86400
+#endif
+
#define PLM_IGNORE 0
#define PLM_PREFER 1
#define PLM_EXACT 2
@@ -2069,6 +2074,7 @@ extern int server_id_check;
extern int prefix_length_mode;
extern int authoring_byte_order;
extern int lease_id_format;
+extern u_int32_t abandon_lease_time;
extern const char *path_dhcpd_conf;
extern const char *path_dhcpd_db;
diff --git a/server/dhcp.c b/server/dhcp.c
index a823a4e8..55a67bfb 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -3490,7 +3490,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
/* If this is a DHCPOFFER, ping the lease address before actually
sending the offer. */
if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
- ((cur_time - lease_cltt) > 60) &&
+ (((cur_time - lease_cltt) > 60) ||
+ (lease->binding_state == FTS_ABANDONED)) &&
(!(oc = lookup_option (&server_universe, state -> options,
SV_PING_CHECKS)) ||
evaluate_boolean_option_cache (&ignorep, packet, lease,
@@ -4871,8 +4872,11 @@ int allocate_lease (struct lease **lp, struct packet *packet,
* "no free leases" error when the last lease has been
* offered, but it's not exactly broken either.
*/
- if (!candl || (candl -> ends > cur_time))
+ if (!candl ||
+ (candl->binding_state != FTS_ABANDONED &&
+ (candl->ends > cur_time))) {
continue;
+ }
if (!lease) {
lease = candl;
diff --git a/server/dhcpd.c b/server/dhcpd.c
index a42d7591..43642823 100644
--- a/server/dhcpd.c
+++ b/server/dhcpd.c
@@ -78,6 +78,7 @@ int prefix_length_mode = PLM_EXACT;
int authoring_byte_order = 0; /* 0 = not set */
int lease_id_format = TOKEN_OCTAL; /* octal by default */
+u_int32_t abandon_lease_time = DEFAULT_ABANDON_LEASE_TIME;
const char *path_dhcpd_conf = _PATH_DHCPD_CONF;
const char *path_dhcpd_db = _PATH_DHCPD_DB;
@@ -1241,6 +1242,20 @@ void postconf_initialization (int quiet)
data_string_forget(&db, MDL);
}
+ // Set global abandon-lease-time option.
+ oc = lookup_option (&server_universe, options, SV_ABANDON_LEASE_TIME);
+ if ((oc != NULL) &&
+ evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
+ &global_scope, oc, MDL)) {
+ if (db.len == sizeof (u_int32_t)) {
+ abandon_lease_time = getULong (db.data);
+ } else {
+ log_fatal("invalid abandon-lease-time");
+ }
+
+ data_string_forget (&db, MDL);
+ }
+
#if defined (BINARY_LEASES)
if (local_family == AF_INET) {
log_info("Source compiled to use binary-leases");
diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
index 9c99676d..a053ef14 100644
--- a/server/dhcpd.conf.5
+++ b/server/dhcpd.conf.5
@@ -405,7 +405,8 @@ the lease as in use.
If a response is received to an ICMP Echo request, the DHCP server
assumes that there is a configuration error - the IP address is in use
by some host on the network that is not a DHCP client. It marks the
-address as abandoned, and will not assign it to clients.
+address as abandoned, and will not assign it to clients. The lease will
+remain abandoned for a minimum of abandon-lease-time seconds.
.PP
If a DHCP client tries to get an IP address, but none are available,
but there are abandoned IP addresses, then the DHCP server will
@@ -1882,6 +1883,27 @@ min-lease-time allows for a gradual change.
e.g. 4 2007/08/24 11:14:32 -7200
.SH REFERENCE: PARAMETERS
The
+.I abandon-lease-time
+statement
+.RS 0.25i
+.PP
+.B adandon-lease-time \fItime\fR\fB;\fR
+.PP
+.I Time
+should be the maximum amount of time (in seconds) that an abandoned IPv4 lease
+remains unavailable for assignment to a client. Abandoned leases will only be
+offered to clients if there are no free leases. If not defined, the default
+abandon lease time is 86400 seconds (24 hours). Note the abandoned lease time
+for a given lease is preserved across server restarts. The parameter may only
+be set at the global scope and is evaluated only once during server startup.
+.PP
+Values less than sixty seconds are not recommended as this is below the ping
+check threshold and can cause leases once abandoned but since returned to the
+free state to not be pinged before being offered. If the requested time is
+larger than 0x7FFFFFFF - 1 or the sum of the current time plus the abandoned time isgreater than 0x7FFFFFFF it is treated as infinite.
+.RE
+.PP
+The
.I adaptive-lease-time-threshold
statement
.RS 0.25i
@@ -2802,7 +2824,12 @@ address to a client, it first sends an ICMP Echo request (a \fIping\fR)
to the address being assigned. It waits for a second, and if no
ICMP Echo response has been heard, it assigns the address. If a
response \fIis\fR heard, the lease is abandoned, and the server does
-not respond to the client.
+not respond to the client. The lease will remain abandoned for a minimum
+of abandon-lease-time seconds.
+.PP
+If a there are no free addressses but there are abandoned IP addresses, the
+DHCP server will attempt to reclaim an abandoned IP address regardless of the
+value of abandon-lease-time.
.PP
This \fIping check\fR introduces a default one-second delay in responding
to DHCPDISCOVER messages, which can be a problem for some clients. The
diff --git a/server/mdb.c b/server/mdb.c
index 48947c51..6af6b631 100644
--- a/server/mdb.c
+++ b/server/mdb.c
@@ -1808,30 +1808,40 @@ void abandon_lease (lease, message)
struct lease *lease;
const char *message;
{
- struct lease *lt = (struct lease *)0;
+ struct lease *lt = NULL;
#if defined (NSUPDATE)
(void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
#endif
- if (!lease_copy (&lt, lease, MDL))
+ if (!lease_copy(&lt, lease, MDL)) {
return;
+ }
- if (lt->scope)
+ if (lt->scope) {
binding_scope_dereference(&lt->scope, MDL);
+ }
- lt -> ends = cur_time; /* XXX */
- lt -> next_binding_state = FTS_ABANDONED;
+ /* Calculate the abandone expiry time. If it wraps,
+ * use the maximum expiry time. */
+ lt->ends = cur_time + abandon_lease_time;
+ if (lt->ends < cur_time || lt->ends > MAX_TIME) {
+ lt->ends = MAX_TIME;
+ }
- log_error ("Abandoning IP address %s: %s",
- piaddr (lease -> ip_addr), message);
- lt -> hardware_addr.hlen = 0;
- if (lt -> uid && lt -> uid != lt -> uid_buf)
- dfree (lt -> uid, MDL);
- lt -> uid = (unsigned char *)0;
- lt -> uid_len = 0;
- lt -> uid_max = 0;
- supersede_lease (lease, lt, 1, 1, 1, 0);
- lease_dereference (&lt, MDL);
+ lt->next_binding_state = FTS_ABANDONED;
+
+ log_error ("Abandoning IP address %s: %s", piaddr(lease->ip_addr),
+ message);
+ lt->hardware_addr.hlen = 0;
+ if (lt->uid && lt->uid != lt->uid_buf) {
+ dfree(lt->uid, MDL);
+ }
+
+ lt->uid = NULL;
+ lt->uid_len = 0;
+ lt->uid_max = 0;
+ supersede_lease(lease, lt, 1, 1, 1, 0);
+ lease_dereference(&lt, MDL);
}
#if 0
diff --git a/server/stables.c b/server/stables.c
index 3a83acbe..445ef0fd 100644
--- a/server/stables.c
+++ b/server/stables.c
@@ -276,6 +276,7 @@ static struct option server_options[] = {
{ "server-id-check", "f", &server_universe, SV_SERVER_ID_CHECK, 1 },
{ "prefix-length-mode", "Nprefix_length_modes.", &server_universe, SV_PREFIX_LEN_MODE, 1 },
{ "dhcpv6-set-tee-times", "f", &server_universe, SV_DHCPV6_SET_TEE_TIMES, 1 },
+ { "abandon-lease-time", "T", &server_universe, SV_ABANDON_LEASE_TIME, 1 },
{ NULL, NULL, NULL, 0, 0 }
};