summaryrefslogtreecommitdiffhomepage
path: root/src/dhcpv4.c
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2017-09-12 10:31:13 +0200
committerHans Dedecker <dedeckeh@gmail.com>2017-09-13 15:34:22 +0200
commit47fe122d19c0485ec398b19d223bbaa2f45b32d3 (patch)
tree0fce40ad465ae07dbc8577e9efafa96e6fd38794 /src/dhcpv4.c
parent028ab85da8ef40af43aeb48129ffa32c98503336 (diff)
dhcpv4: rework lease expire handling logic
Don't rely on incoming DHCPv4 messages to trigger the lease expire detection logic but rather use a periodic timer which checks every second if a lease is expired Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
Diffstat (limited to 'src/dhcpv4.c')
-rw-r--r--src/dhcpv4.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/dhcpv4.c b/src/dhcpv4.c
index 12e6336..9e862ca 100644
--- a/src/dhcpv4.c
+++ b/src/dhcpv4.c
@@ -37,6 +37,7 @@
static int setup_dhcpv4_addresses(struct interface *iface);
static void update_static_assignments(struct interface *iface);
+static void valid_until_cb(struct uloop_timeout *event);
static void free_dhcpv4_assignment(struct dhcpv4_assignment *a);
static void dhcpv4_fr_start(struct dhcpv4_assignment *a);
static void dhcpv4_fr_stop(struct dhcpv4_assignment *a);
@@ -46,6 +47,8 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
enum dhcpv4_msg msg, const uint8_t *mac, struct in_addr reqaddr,
uint32_t *leasetime, const char *hostname, const size_t hostname_len,
const bool accept_fr_nonce, bool *incl_fr_opt, uint32_t *fr_serverid);
+
+static struct uloop_timeout valid_until_timeout = {.cb = valid_until_cb};
static uint32_t serial = 0;
struct odhcpd_ref_ip {
@@ -57,6 +60,7 @@ struct odhcpd_ref_ip {
/* Create socket and register events */
int init_dhcpv4(void)
{
+ uloop_timeout_set(&valid_until_timeout, 1000);
return 0;
}
@@ -323,6 +327,23 @@ static bool leases_require_fr(struct interface *iface, struct odhcpd_ipaddr *add
return fr_ip ? true : false;
}
+static void valid_until_cb(struct uloop_timeout *event)
+{
+ time_t now = odhcpd_time();
+ struct interface *iface;
+ list_for_each_entry(iface, &interfaces, head) {
+ if (iface->dhcpv4 != MODE_SERVER || iface->dhcpv4_assignments.next == NULL)
+ continue;
+
+ struct dhcpv4_assignment *a, *n;
+ list_for_each_entry_safe(a, n, &iface->dhcpv4_assignments, head) {
+ if (!INFINITE_VALID(a->valid_until) && a->valid_until < now)
+ free_dhcpv4_assignment(a);
+ }
+ }
+ uloop_timeout_set(event, 1000);
+}
+
void dhcpv4_addr_update(struct interface *iface)
{
if (iface->dhcpv4 == MODE_DISABLED)
@@ -910,14 +931,13 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
struct dhcpv4_assignment *lease = NULL;
time_t now = odhcpd_time();
- struct dhcpv4_assignment *c, *n, *a = NULL;
- list_for_each_entry_safe(c, n, &iface->dhcpv4_assignments, head) {
+ struct dhcpv4_assignment *c, *a = NULL;
+ list_for_each_entry(c, &iface->dhcpv4_assignments, head) {
if (!memcmp(c->hwaddr, mac, 6)) {
a = c;
if (c->addr == reqaddr.s_addr)
break;
- } else if (!INFINITE_VALID(c->valid_until) && c->valid_until < now)
- free_dhcpv4_assignment(c);
+ }
}
if (a && (a->flags & OAF_BOUND) && a->fr_ip) {