2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-09-01 14:55:30 +00:00

[master] Delayed-ack now works correctly with failover

Merges in 31474.
This commit is contained in:
Thomas Markwalder
2015-06-15 15:19:42 -04:00
parent 3933e2aa51
commit e422b8c78f
5 changed files with 65 additions and 33 deletions

View File

@@ -54,6 +54,11 @@ by Eric Young (eay@cryptsoft.com).
Changes since 4.3.2
- Delayed-ack now works properly with Failover. Prior to this, bind updates
post startup were being queued but never delivered. Among other things, this
was causing leases to not transition from expired or released to free.
[ISC-Bugs #31474]
- The server now does a better check to see if it can allocate the memory
for large blocks of v4 leases and should provide a slightly better error
message. Note well: the server pre-allocates v4 addresses, if you use

View File

@@ -2313,9 +2313,7 @@ void ack_lease (struct packet *, struct lease *,
unsigned int, TIME, char *, int, struct host_decl *);
void echo_client_id(struct packet*, struct lease*, struct option_state*,
struct option_state*);
void delayed_ack_enqueue(struct lease *);
void commit_leases_readerdry(void *);
void flush_ackqueue(void *);
void dhcp_reply (struct lease *);
int find_lease (struct lease **, struct packet *,
struct shared_network *, int *, int *, struct lease *,
@@ -2953,7 +2951,6 @@ isc_result_t write_named_billing_class(const void *, unsigned, void *);
void write_billing_classes (void);
int write_billing_class (struct class *);
void commit_leases_timeout (void *);
void commit_leases_readerdry(void *);
int commit_leases (void);
int commit_leases_timed (void);
void db_startup (int);

View File

@@ -3,7 +3,7 @@
Persistent database management routines for DHCPD... */
/*
* Copyright (c) 2012-2014 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2012-2015 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
@@ -1017,9 +1017,6 @@ int commit_leases ()
return (0);
}
/* send out all deferred ACKs now */
flush_ackqueue(NULL);
/* If we haven't rewritten the lease database in over an
hour, rewrite it now. (The length of time should probably
be configurable. */

View File

@@ -31,7 +31,6 @@
#include <limits.h>
#include <sys/time.h>
static void commit_leases_ackout(void *foo);
static void maybe_return_agent_options(struct packet *packet,
struct option_state *options);
static int reuse_lease (struct packet* packet, struct lease* new_lease,
@@ -40,6 +39,11 @@ static int reuse_lease (struct packet* packet, struct lease* new_lease,
int outstanding_pings;
#if defined(DELAYED_ACK)
static void delayed_ack_enqueue(struct lease *);
static void delayed_acks_timer(void *);
struct leasequeue *ackqueue_head, *ackqueue_tail;
static struct leasequeue *free_ackqueue;
static struct timeval max_fsync;
@@ -49,6 +53,7 @@ int max_outstanding_acks = DEFAULT_DELAYED_ACK;
int max_ack_delay_secs = DEFAULT_ACK_DELAY_SECS;
int max_ack_delay_usecs = DEFAULT_ACK_DELAY_USECS;
int min_ack_delay_usecs = DEFAULT_MIN_ACK_DELAY_USECS;
#endif
static char dhcp_message [256];
static int site_code_min;
@@ -3368,6 +3373,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
}
}
#if defined(DELAYED_ACK)
/*
* CC: queue single ACK:
* - write the lease (but do not fsync it yet)
@@ -3377,7 +3384,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
* but only up to the max timer value.
*/
void
static void
delayed_ack_enqueue(struct lease *lease)
{
struct leasequeue *q;
@@ -3405,11 +3412,9 @@ delayed_ack_enqueue(struct lease *lease)
outstanding_acks++;
if (outstanding_acks > max_outstanding_acks) {
commit_leases();
/* Reset max_fsync and cancel any pending timeout. */
memset(&max_fsync, 0, sizeof(max_fsync));
cancel_timeout(commit_leases_ackout, NULL);
/* Cancel any pending timeout and call handler directly */
cancel_timeout(delayed_acks_timer, NULL);
delayed_acks_timer(NULL);
} else {
struct timeval next_fsync;
@@ -3440,44 +3445,68 @@ delayed_ack_enqueue(struct lease *lease)
next_fsync.tv_usec = max_fsync.tv_usec;
}
add_timeout(&next_fsync, commit_leases_ackout, NULL,
add_timeout(&next_fsync, delayed_acks_timer, NULL,
(tvref_t) NULL, (tvunref_t) NULL);
}
}
/* Processes any delayed acks:
* Commits the leases and then for each delayed ack:
* - Update the failover peer if we're in failover
* - Send the REPLY to the client
*/
static void
commit_leases_ackout(void *foo)
delayed_acks_timer(void *foo)
{
if (outstanding_acks) {
struct leasequeue *ack, *p;
/* Reset max fsync */
memset(&max_fsync, 0, sizeof(max_fsync));
if (!outstanding_acks) {
/* Nothing to do, so punt, shouldn't happen? */
return;
}
/* Commit the leases first */
commit_leases();
memset(&max_fsync, 0, sizeof(max_fsync));
}
}
/* CC: process the delayed ACK responses:
/* Now process the delayed ACKs
- update failover peer
- send out the ACK packets
- move the queue slots to the free list
*/
void
flush_ackqueue(void *foo)
{
struct leasequeue *ack, *p;
/* process from bottom to retain packet order */
for (ack = ackqueue_tail ; ack ; ack = p) {
p = ack->prev;
#if defined(FAILOVER_PROTOCOL)
/* If we're in failover we need to send any deferred
* bind updates as well as the replies */
if (ack->lease->pool) {
dhcp_failover_state_t *fpeer;
fpeer = ack->lease->pool->failover_peer;
if (fpeer && fpeer->link_to_peer) {
dhcp_failover_send_updates(fpeer);
}
}
#endif
/* dhcp_reply() requires that the reply state still be valid */
if (ack->lease->state == NULL)
log_error("delayed ack for %s has gone stale",
piaddr(ack->lease->ip_addr));
else
else {
dhcp_reply(ack->lease);
}
lease_dereference(&ack->lease, MDL);
ack->next = free_ackqueue;
free_ackqueue = ack;
}
ackqueue_head = NULL;
ackqueue_tail = NULL;
outstanding_acks = 0;
@@ -3500,6 +3529,8 @@ relinquish_ackqueue(void)
}
#endif
#endif /* defined(DELAYED_ACK) */
void dhcp_reply (lease)
struct lease *lease;
{

View File

@@ -1060,6 +1060,7 @@ void postconf_initialization (int quiet)
}
}
#if defined(DELAYED_ACK)
oc = lookup_option(&server_universe, options, SV_DELAYED_ACK);
if (oc &&
evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
@@ -1087,6 +1088,7 @@ void postconf_initialization (int quiet)
data_string_forget(&db, MDL);
}
#endif
oc = lookup_option(&server_universe, options, SV_DONT_USE_FSYNC);
if ((oc != NULL) &&