sd-dhcp-server: check address conflict more carefully
- Even if we found a matching static lease, check if there is no conflicting lease. - Accept an address request that is different from the previous one. - Also return NAK if the server address is requested.
This commit is contained in:
@@ -1050,10 +1050,19 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
|
||||
return 0;
|
||||
|
||||
/* for now pick a random free address from the pool */
|
||||
if (static_lease)
|
||||
if (static_lease) {
|
||||
if (existing_lease != hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(static_lease->address)))
|
||||
/* The address is already assigned to another host. Refusing. */
|
||||
return 0;
|
||||
|
||||
/* Found a matching static lease. */
|
||||
address = static_lease->address;
|
||||
else if (existing_lease)
|
||||
|
||||
} else if (existing_lease && address_is_in_pool(server, existing_lease->address))
|
||||
|
||||
/* If we previously assigned an address to the host, then reuse it. */
|
||||
address = existing_lease->address;
|
||||
|
||||
else {
|
||||
struct siphash state;
|
||||
uint64_t hash;
|
||||
@@ -1151,30 +1160,24 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
|
||||
/* Silently ignore Rapid Commit option in REQUEST message. */
|
||||
req->rapid_commit = false;
|
||||
|
||||
/* disallow our own address */
|
||||
if (address == server->address)
|
||||
return 0;
|
||||
|
||||
if (static_lease) {
|
||||
/* Found a static lease for the client ID. */
|
||||
|
||||
if (static_lease->address != address)
|
||||
/* The client requested an address which is different from the static lease. Refuse. */
|
||||
/* 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)))
|
||||
/* The requested address is already assigned to another host. Refusing. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
/* Found a static lease for the client ID. */
|
||||
return server_ack_request(server, req, address);
|
||||
}
|
||||
|
||||
if (address_is_in_pool(server, address)) {
|
||||
if (address_is_in_pool(server, address))
|
||||
/* The requested address is in the pool. */
|
||||
|
||||
if (existing_lease && existing_lease->address != address)
|
||||
/* We previously assigned an address, but the client requested another one. Refuse. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
return server_ack_request(server, req, address);
|
||||
}
|
||||
|
||||
/* Refuse otherwise. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ static void test_message_handler(void) {
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == 0);
|
||||
test.option_server_id.address = htobe32(INADDR_LOOPBACK);
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 4);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == 0);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
|
||||
@@ -200,7 +200,7 @@ static void test_message_handler(void) {
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == 0);
|
||||
assert_se(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';
|
||||
|
||||
Reference in New Issue
Block a user