summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network/sd-dhcp-server.c
diff options
context:
space:
mode:
authorToke Høiland-Jørgensen <toke@redhat.com>2021-10-28 22:36:51 +0200
committerToke Høiland-Jørgensen <toke@redhat.com>2021-10-29 15:29:05 +0200
commitd635a7f9e4c58c5578f4fe2989bb799325067232 (patch)
tree20b6163f1e455f6a229407a91684468e7a6f990b /src/libsystemd-network/sd-dhcp-server.c
parentMerge pull request #20321 from bluca/state_dir_symlink (diff)
downloadsystemd-d635a7f9e4c58c5578f4fe2989bb799325067232.tar.xz
systemd-d635a7f9e4c58c5578f4fe2989bb799325067232.zip
sd-dhcp-server: clear out expired leases when processing requests
The DHCP server configuration supports setting a maximum lease time, but old leases are never actually cleared out if the client doesn't send a RELEASE. This causes the pool to run out of addresses on networks where clients just disappear, which is a fairly common occurrence on wireless networks. Fix this by cleaning up expired leases before processing client requests, so addresses can be reused for new clients.
Diffstat (limited to '')
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 45ac70b461..39ac5e86fa 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -854,6 +854,27 @@ static int prepare_new_lease(
return 0;
}
+static int dhcp_server_cleanup_expired_leases(sd_dhcp_server *server) {
+ DHCPLease *lease;
+ usec_t time_now;
+ int r;
+
+ assert(server);
+
+ r = sd_event_now(server->event, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0)
+ return r;
+
+ HASHMAP_FOREACH(lease, server->bound_leases_by_client_id) {
+ if (lease->expiration < time_now) {
+ log_dhcp_server(server, "CLEAN (0x%x)", be32toh(lease->address));
+ dhcp_lease_free(lease);
+ }
+ }
+
+ return 0;
+}
+
#define HASH_KEY SD_ID128_MAKE(0d,1d,fe,bd,f1,24,bd,b3,47,f1,dd,6e,73,21,93,30)
int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, size_t length) {
@@ -883,6 +904,10 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
/* this only fails on critical errors */
return r;
+ r = dhcp_server_cleanup_expired_leases(server);
+ if (r < 0)
+ return r;
+
existing_lease = hashmap_get(server->bound_leases_by_client_id, &req->client_id);
static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id);