Commit a5b21e16 authored by Thomas Markwalder's avatar Thomas Markwalder

[master] Added configuration parameter, ping-cltt-secs (v4 operation only)

    Merges in rt36283.
parent cce04313
......@@ -88,7 +88,13 @@ Consortium. This product includes cryptographic software written
by Eric Young (eay@cryptsoft.com).
Changes since 4.4.1 (New Features)
- none
- A new configuration parameter, ping-cltt-secs (v4 operation only), has
been added to allow the user to specify the number of seconds that must
elapse since CLTT before a ping check is conducted. Prior to this, the
value was hard coded at 60 seconds. Please see the server man pages for
a more detailed discussion.
[ISC-Bugs #36283]
Changes since 4.4.1 (Bug Fixes)
......@@ -100,7 +106,6 @@ by Eric Young (eay@cryptsoft.com).
Changes since 4.4.0 (New Features)
- none
Changes since 4.4.0 (Bug Fixes)
- A delayed-ack value of 0 (the default), now correctly disables the delayed
......
......@@ -815,11 +815,17 @@ struct lease_state {
#define SV_RELEASE_ON_ROAM 95
#define SV_LOCAL_ADDRESS6 96
#define SV_BIND_LOCAL_ADDRESS6 97
#define SV_PING_CLTT_SECS 98
#if !defined (DEFAULT_PING_TIMEOUT)
# define DEFAULT_PING_TIMEOUT 1
#endif
#if !defined (DEFAULT_PING_CLTT_SECS)
# define DEFAULT_PING_CLTT_SECS 60 /* in seconds */
#endif
#if !defined (DEFAULT_DELAYED_ACK)
# define DEFAULT_DELAYED_ACK 0 /* default 0 disables delayed acking */
#endif
......
......@@ -33,9 +33,15 @@
static void maybe_return_agent_options(struct packet *packet,
struct option_state *options);
static int reuse_lease (struct packet* packet, struct lease* new_lease,
struct lease* lease, struct lease_state *state,
int offer);
int offer, int* same_client);
static int do_ping_check(struct packet* packet, struct lease_state* state,
struct lease* lease, TIME original_cltt,
int same_client);
#if defined(DHCPv6) && defined(DHCP4o6)
static int locate_network6(struct packet *packet);
#endif
......@@ -2180,8 +2186,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
TIME default_lease_time;
struct option_cache *oc;
isc_result_t result;
TIME ping_timeout;
TIME lease_cltt;
TIME original_cltt;
struct in_addr from;
TIME remaining_time;
struct iaddr cip;
......@@ -2190,18 +2195,18 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
isc_boolean_t enqueue = ISC_FALSE;
#endif
int use_old_lease = 0;
int same_client = 0;
unsigned i, j;
int s1;
int ignorep;
struct timeval tv;
/* If we're already acking this lease, don't do it again. */
if (lease -> state)
return;
/* Save original cltt for comparison later. */
lease_cltt = lease->cltt;
original_cltt = lease->cltt;
/* If the lease carries a host record, remember it. */
if (hp)
......@@ -3194,7 +3199,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
/* If dhcp-cache-threshold is enabled, see if "lease" can
* be reused. */
use_old_lease = reuse_lease(packet, lt, lease, state, offer);
use_old_lease = reuse_lease(packet, lt, lease, state, offer,
&same_client);
if (use_old_lease == 1) {
commit = 0;
}
......@@ -3560,39 +3566,118 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
/* Hang the packet off the lease state. */
packet_reference (&lease -> state -> packet, packet, MDL);
/* 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) ||
(lease->binding_state == FTS_ABANDONED)) &&
(!(oc = lookup_option (&server_universe, state -> options,
SV_PING_CHECKS)) ||
evaluate_boolean_option_cache (&ignorep, packet, lease,
(struct client_state *)0,
packet -> options,
state -> options,
&lease -> scope, oc, MDL))) {
icmp_echorequest (&lease -> ip_addr);
/* If this is a DHCPOFFER, send a ping (if appropriate) to the
* lease address before actually we send the offer. */
if ((offer == DHCPOFFER) &&
do_ping_check(packet, state, lease, original_cltt, same_client)) {
++outstanding_pings;
} else {
lease->cltt = cur_time;
#if defined(DELAYED_ACK)
if (enqueue)
delayed_ack_enqueue(lease);
else
#endif
dhcp_reply(lease);
}
}
/* Determine whether to use configured or default ping timeout.
/*
* \brief Sends a ping to the lease ip_addr when appropriate
*
* A ping will be sent if all of the following are true:
*
* 1. Ping checks are enabled
* 2. The lease is neither active nor static
* 3. Any of the following is true:
* a. The lease state is ABANDONED
* b. This is the first offer of this lease (CLTT = 0)
* c. The lease is being offered to a client other than its previous
* owner
* d. The lease is being offered to its previous owner and more than
* cltt-secs have elapsed since CLTT of the original lease.
*
* \param packet inbound packet received from the client
* \param state lease options state
* \param lease lease to be offered (if one)
* \param original_cltt CLTT of the original lease
* \param same_client flag indicating if the client to be offered the
* lease is its previous owner
* \return Returns 1 if ping has been sent, 0 otherwise
*/
if ((oc = lookup_option (&server_universe, state -> options,
SV_PING_TIMEOUT)) &&
evaluate_option_cache (&d1, packet, lease, NULL,
packet -> options,
state -> options,
&lease -> scope, oc, MDL)) {
if (d1.len == sizeof (u_int32_t))
ping_timeout = getULong (d1.data);
else
ping_timeout = DEFAULT_PING_TIMEOUT;
int do_ping_check(struct packet* packet, struct lease_state* state,
struct lease* lease, TIME original_cltt,
int same_client) {
TIME ping_timeout = DEFAULT_PING_TIMEOUT;
struct option_cache *oc = NULL;
struct data_string ds;
struct timeval tv;
int ignorep;
data_string_forget (&d1, MDL);
} else
ping_timeout = DEFAULT_PING_TIMEOUT;
// Don't go any further if lease is active or static.
if (lease->binding_state == FTS_ACTIVE || lease->flags & STATIC_LEASE) {
return (0);
}
// If pings aren't enabled, punt.
oc = lookup_option (&server_universe, state -> options, SV_PING_CHECKS);
if (oc &&
!(evaluate_boolean_option_cache (&ignorep, packet, lease,
0, packet->options, state->options,
&lease->scope, oc, MDL))) {
return (0);
}
// If it's not the first time for the same client and not an
// abandoned lease, we need to check the cltt threshold
if (same_client && original_cltt &&
lease->binding_state != FTS_ABANDONED) {
TIME cltt_secs = DEFAULT_PING_CLTT_SECS;
memset(&ds, 0, sizeof(ds));
oc = lookup_option (&server_universe, state->options,
SV_PING_CLTT_SECS);
if (oc &&
(evaluate_option_cache (&ds, packet, lease, 0,
packet->options, state->options,
&lease->scope, oc, MDL))) {
if (ds.len == sizeof (u_int32_t)) {
cltt_secs = getULong (ds.data);
}
data_string_forget (&ds, MDL);
}
// Punt if it is too soon.
if (cur_time - original_cltt < cltt_secs) {
return (0);
}
}
// Send the ping.
icmp_echorequest (&lease->ip_addr);
/* Determine whether to use configured or default ping timeout. */
memset(&ds, 0, sizeof(ds));
oc = lookup_option (&server_universe, state->options, SV_PING_TIMEOUT);
if (oc &&
(evaluate_option_cache (&ds, packet, lease, 0,
packet->options, state->options,
&lease->scope, oc, MDL))) {
if (ds.len == sizeof (u_int32_t)) {
ping_timeout = getULong (ds.data);
}
data_string_forget (&ds, MDL);
}
#ifdef DEBUG
log_debug ("Ping timeout: %ld", (long)ping_timeout);
log_debug ("Pinging:%s, state: %d, same client? %s, "
" orig_cltt %s, elasped: %ld" ,
piaddr(lease->ip_addr),
lease->binding_state,
(same_client ? "y" : "n"),
(original_cltt ? print_time(original_cltt) : "0"),
(original_cltt ? (long)(cur_time - original_cltt) : 0));
#endif
/*
......@@ -3603,21 +3688,12 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
*/
tv.tv_sec = cur_tv.tv_sec + ping_timeout;
tv.tv_usec = cur_tv.tv_usec;
add_timeout (&tv, lease_ping_timeout, lease,
(tvref_t)lease_reference,
add_timeout (&tv, lease_ping_timeout, lease, (tvref_t)lease_reference,
(tvunref_t)lease_dereference);
++outstanding_pings;
} else {
lease->cltt = cur_time;
#if defined(DELAYED_ACK)
if (enqueue)
delayed_ack_enqueue(lease);
else
#endif
dhcp_reply(lease);
}
return (1);
}
#if defined(DELAYED_ACK)
/*
......@@ -5628,7 +5704,10 @@ void use_host_decl_name(struct packet* packet,
* \param packet inbound packet received from the client
* \param new_lease candidate new lease to associate with the client
* \param lease current lease associated with the client
* \param options option state to search and update
* \param lease_state lease state to search and update
* \param offer type of DHCP response we're building
* \param[out] same_client pointer to int, that will be set to 1 if
* the two leases refer to the same client, 0 if not. Must NOT be null.
*
* \return 1 if the lease can be reused.
*/
......@@ -5637,7 +5716,8 @@ reuse_lease (struct packet* packet,
struct lease* new_lease,
struct lease* lease,
struct lease_state *state,
int offer) {
int offer,
int *same_client) {
int reusable = 0;
/* To even consider reuse all of the following must be true:
......@@ -5647,16 +5727,20 @@ reuse_lease (struct packet* packet,
* 4 - the host declaration hasn't changed
* 5 - the uid hasn't changed
* 6 - the hardware address hasn't changed */
if ((lease->cannot_reuse == 0) &&
(lease->binding_state == FTS_ACTIVE) &&
(new_lease->ddns_cb == NULL) &&
(lease->host == new_lease->host) &&
/* Check client equality separately so we can pass the result out. */
*same_client =
(((lease->host == new_lease->host) &&
(lease->uid_len == new_lease->uid_len) &&
(memcmp(lease->uid, new_lease->uid, lease->uid_len) == 0) &&
(memcmp(lease->uid, new_lease->uid, new_lease->uid_len) == 0) &&
(lease->hardware_addr.hlen == new_lease->hardware_addr.hlen) &&
(memcmp(&lease->hardware_addr.hbuf[0],
&new_lease->hardware_addr.hbuf[0],
lease->hardware_addr.hlen) == 0)) {
lease->hardware_addr.hlen) == 0)) ? 1 : 0);
if ((lease->cannot_reuse == 0) &&
(lease->binding_state == FTS_ACTIVE) &&
(new_lease->ddns_cb == NULL) && *same_client) {
int thresh = DEFAULT_CACHE_THRESHOLD;
struct option_cache* oc = NULL;
struct data_string d1;
......
......@@ -3027,6 +3027,36 @@ checking - if its value is false, no ping check is done.
.RE
.PP
The
.I ping-cltt-secs
statement
.RS 0.25i
.PP
.B ping-cltt-secs
.I seconds\fR\fB;\fR
.PP
The server will conduct a ping check if all the following conditions are true:
.PP
1. Ping checking is enabled.
.PP
2. The server is responding to a DISCOVER.
.PP
3. The lease to be offered is neither static nor active (i.e. still a valid
lease).
.PP
4. And any of the following are true:
a. This will be the first offer of this lease (CLTT is 0).
b. The lease is being offered to a client other than its previous owner
c. The lease is being offered to its previous owner and more than
\fBping-cltt-secs\fR have elapsed since CLTT of the original lease.
d. The lease was abandoned and the server is attempting to reclaim it.
.PP
The \fBping-cltt-secs\fR statement allows the user to specify the amount of
time that must elaspe after CLTT before a ping check will be conducted.
The default value is sixty seconds.
.RE
.PP
The
.I ping-timeout
statement
.RS 0.25i
......
......@@ -291,6 +291,7 @@ static struct option server_options[] = {
{ "release-on-roam", "f", &server_universe, SV_RELEASE_ON_ROAM, 1 },
{ "local-address6", "6", &server_universe, SV_LOCAL_ADDRESS6, 1 },
{ "bind-local-address6", "f", &server_universe, SV_BIND_LOCAL_ADDRESS6, 1 },
{ "ping-cltt-secs", "T", &server_universe, SV_PING_CLTT_SECS, 1 },
{ NULL, NULL, NULL, 0, 0 }
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment