diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-10-29 21:13:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-29 21:13:40 +0200 |
commit | 6db9b300667d008a933e819b5689400a20fd3617 (patch) | |
tree | fd12d77a5a10cb35d92afefc82eee41dd2759470 /src/libsystemd-network | |
parent | Merge pull request #21180 from yuwata/libsystemd-network-cleanups (diff) | |
parent | sd-dhcp-server: fix address availability checks (diff) | |
download | systemd-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.c | 43 |
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)); |