summaryrefslogtreecommitdiffstats
path: root/src/libsystemd-network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-10-29 21:13:40 +0200
committerGitHub <noreply@github.com>2021-10-29 21:13:40 +0200
commit6db9b300667d008a933e819b5689400a20fd3617 (patch)
treefd12d77a5a10cb35d92afefc82eee41dd2759470 /src/libsystemd-network
parentMerge pull request #21180 from yuwata/libsystemd-network-cleanups (diff)
parentsd-dhcp-server: fix address availability checks (diff)
downloadsystemd-6db9b300667d008a933e819b5689400a20fd3617.tar.xz
systemd-6db9b300667d008a933e819b5689400a20fd3617.zip
Merge pull request #21175 from tohojo/dhcp-server-expire
sd-dhcp-server: clear out expired leases when finding new address
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 45ac70b461..604c34fe15 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -854,6 +854,38 @@ 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;
+}
+
+static bool address_available(sd_dhcp_server *server, be32_t address) {
+ assert(server);
+
+ if (hashmap_contains(server->bound_leases_by_address, UINT32_TO_PTR(address)) ||
+ hashmap_contains(server->static_leases_by_address, UINT32_TO_PTR(address)) ||
+ address == server->address)
+ return false;
+
+ return true;
+}
+
#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 +915,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);
@@ -918,8 +954,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
be32_t tmp_address;
tmp_address = server->subnet | htobe32(server->pool_offset + (hash + i) % server->pool_size);
- if (!hashmap_contains(server->bound_leases_by_address, &tmp_address) &&
- !hashmap_contains(server->static_leases_by_address, &tmp_address)) {
+ if (address_available(server, tmp_address)) {
address = tmp_address;
break;
}
@@ -996,6 +1031,10 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
address = req->message->ciaddr;
}
+ /* disallow our own address */
+ if (address == server->address)
+ return 0;
+
pool_offset = get_pool_offset(server, address);
existing_lease_by_address = hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(address));