mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
sd-dhcp-server: fix conditions for checking if static address is assigned to another host
Even if a static lease may be configured for a host, another address may be previously assigned to the host. Let's not refuse to assign the static lease to the host even in that case. Fixes an issue reported at https://github.com/systemd/systemd/issues/35781#issuecomment-3369545753.
This commit is contained in:
committed by
Luca Boccassi
parent
85eae6ba35
commit
d19294e92a
@@ -1072,7 +1072,8 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
|
||||
|
||||
/* for now pick a random free address from the pool */
|
||||
if (static_lease) {
|
||||
if (existing_lease != hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(static_lease->address)))
|
||||
sd_dhcp_server_lease *l = hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(static_lease->address));
|
||||
if (l && l != existing_lease)
|
||||
/* The address is already assigned to another host. Refusing. */
|
||||
return 0;
|
||||
|
||||
@@ -1186,7 +1187,8 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
|
||||
/* The client requested an address which is different from the static lease. Refusing. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
if (existing_lease != hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(address)))
|
||||
sd_dhcp_server_lease *l = hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(address));
|
||||
if (l && l != existing_lease)
|
||||
/* The requested address is already assigned to another host. Refusing. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
|
||||
@@ -214,6 +214,45 @@ static void test_message_handler(void) {
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
|
||||
ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_ACK);
|
||||
|
||||
/* add the static lease for the client ID */
|
||||
ASSERT_OK(sd_dhcp_server_stop(server));
|
||||
ASSERT_OK(sd_dhcp_server_set_static_lease(server, &(struct in_addr){ .s_addr = htobe32(INADDR_LOOPBACK + 31) },
|
||||
(uint8_t[7]){ 0x01, 'A', 'B', 'C', 'D', 'E', 'F' }, 7));
|
||||
ASSERT_OK(sd_dhcp_server_start(server));
|
||||
|
||||
/* discover */
|
||||
test.option_type.type = DHCP_DISCOVER;
|
||||
ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_OFFER);
|
||||
|
||||
/* request neither bound nor static address */
|
||||
test.option_type.type = DHCP_REQUEST;
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 29);
|
||||
ASSERT_OK_ZERO(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL));
|
||||
|
||||
/* request the currently assigned address */
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
|
||||
ASSERT_OK_ZERO(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL));
|
||||
|
||||
/* request the new static address */
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 31);
|
||||
ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_ACK);
|
||||
|
||||
/* release the bound static lease */
|
||||
test.message.ciaddr = htobe32(INADDR_LOOPBACK + 31);
|
||||
test.option_type.type = DHCP_RELEASE;
|
||||
ASSERT_OK_ZERO(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL));
|
||||
|
||||
/* drop the static lease for the client ID */
|
||||
ASSERT_OK(sd_dhcp_server_stop(server));
|
||||
ASSERT_OK(sd_dhcp_server_set_static_lease(server, NULL, (uint8_t[7]){ 0x01, 'A', 'B', 'C', 'D', 'E', 'F' }, 7));
|
||||
ASSERT_OK(sd_dhcp_server_start(server));
|
||||
|
||||
/* request a new non-static address */
|
||||
test.message.ciaddr = 0;
|
||||
test.option_type.type = DHCP_REQUEST;
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 29);
|
||||
ASSERT_OK_EQ(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL), DHCP_ACK);
|
||||
|
||||
/* request address reserved for static lease (unmatching client ID) */
|
||||
test.option_client_id.id[6] = 'H';
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 42);
|
||||
|
||||
Reference in New Issue
Block a user