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:
5
RELNOTES
5
RELNOTES
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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. */
|
||||
|
@@ -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;
|
||||
{
|
||||
|
@@ -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) &&
|
||||
|
Reference in New Issue
Block a user