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 *,
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);
#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,
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;
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;
}
}
+#if defined(DELAYED_ACK)
+
/*
* CC: queue single ACK:
* - write the lease (but do not fsync it yet)
* but only up to the max timer value.
*/
-void
+static void
delayed_ack_enqueue(struct lease *lease)
{
struct leasequeue *q;
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;
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) {
- commit_leases();
+ struct leasequeue *ack, *p;
+
+ /* Reset max fsync */
+ memset(&max_fsync, 0, sizeof(max_fsync));
- memset(&max_fsync, 0, sizeof(max_fsync));
+ if (!outstanding_acks) {
+ /* Nothing to do, so punt, shouldn't happen? */
+ return;
}
-}
-/* CC: process the delayed ACK responses:
- - send out the ACK packets
- - move the queue slots to the free list
- */
-void
-flush_ackqueue(void *foo)
-{
- struct leasequeue *ack, *p;
+ /* Commit the leases first */
+ commit_leases();
+
+ /* Now process the delayed ACKs
+ - update failover peer
+ - send out the ACK packets
+ - move the queue slots to the free list
+ */
+
/* 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;
}
#endif
+#endif /* defined(DELAYED_ACK) */
+
void dhcp_reply (lease)
struct lease *lease;
{