summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-08-28 12:17:37 +0200
committerLennart Poettering <lennart@poettering.net>2015-08-28 12:17:37 +0200
commit776d6aac183a1f711b9ebd62558ce914328b03da (patch)
treee8447fb2be457a8aba03fb30396df45c254bc0a5
parent84d449b55215dfe81305d3ee89606fdc17150ad6 (diff)
parent83cedf7ae28925e37931e7e92d22be9c936a1def (diff)
Merge pull request #1067 from teg/dhcp-server
sd-dhcp-server: improve predictability of leases
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h1
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c16
2 files changed, 13 insertions, 4 deletions
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
index 6cc794c937..268210fc50 100644
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ b/src/libsystemd-network/dhcp-server-internal.h
@@ -59,7 +59,6 @@ struct sd_dhcp_server {
be32_t netmask;
be32_t pool_start;
size_t pool_size;
- size_t next_offer;
char *timezone;
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index a46858258b..89b9a4c6be 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -669,6 +669,8 @@ static int get_pool_offset(sd_dhcp_server *server, be32_t requested_ip) {
return be32toh(requested_ip) - be32toh(server->pool_start);
}
+#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) {
_cleanup_dhcp_request_free_ DHCPRequest *req = NULL;
@@ -716,12 +718,20 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
if (existing_lease)
address = existing_lease->address;
else {
+ size_t next_offer;
+
+ /* even with no persistence of leases, we try to offer the same client
+ the same IP address. we do this by using the hash of the client id
+ as the offset into the pool of leases when finding the next free one */
+
+ next_offer = client_id_hash_func(&req->client_id, HASH_KEY.bytes) % server->pool_size;
+
for (i = 0; i < server->pool_size; i++) {
- if (!server->bound_leases[server->next_offer]) {
- address = htobe32(be32toh(server->pool_start) + server->next_offer);
+ if (!server->bound_leases[next_offer]) {
+ address = htobe32(be32toh(server->pool_start) + next_offer);
break;
} else
- server->next_offer = (server->next_offer + 1) % server->pool_size;
+ next_offer = (next_offer + 1) % server->pool_size;
}
}