From cb3c06a02eea17999c4fd577d35be7c9d1745a91 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Fri, 29 Oct 2021 12:24:33 +0200 Subject: [PATCH] sd-dhcp-server: fix address availability checks The checks for finding a new available address in the pool were broken in two ways: not using UINT32_TO_PTR() on hashmap lookups resulted in false negatives, and the check wasn't skipping the server address if that was part of the pool. Move the check for available addresses to a small helper function and fix both issues, and also add a check to the REQUEST code for the server address. --- src/libsystemd-network/sd-dhcp-server.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 39ac5e86fa2..604c34fe155 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -875,6 +875,17 @@ static int dhcp_server_cleanup_expired_leases(sd_dhcp_server *server) { 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) { @@ -943,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; } @@ -1021,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)); -- 2.47.3