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;
/* 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);
}
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);
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';