summaryrefslogtreecommitdiff
path: root/src/libsystemd-network
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-10-04 00:22:41 +0200
committerTom Gundersen <teg@jklm.no>2015-10-05 18:22:10 +0200
commitb826ab586c9e0a9c0d438a75c28cf3a8ab485929 (patch)
tree198d9f30b924468fc7d7dbf5fe9f05ce73809269 /src/libsystemd-network
parent57217c8f2a2dea07b41ecf05000172ce77a90466 (diff)
hashmap: refactor hash_func
All our hash functions are based on siphash24(), factor out siphash_init() and siphash24_finalize() and pass the siphash state to the hash functions rather than the hash key. This simplifies the hash functions, and in particular makes composition simpler as calling siphash24_compress() repeatedly on separate chunks of input has the same effect as first concatenating the input and then calling siphash23_compress() on the result.
Diffstat (limited to 'src/libsystemd-network')
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h2
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c13
-rw-r--r--src/libsystemd-network/sd-lldp.c9
-rw-r--r--src/libsystemd-network/test-dhcp-server.c14
4 files changed, 21 insertions, 17 deletions
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
index 5dc3c7aa26..3b88b93d9a 100644
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ b/src/libsystemd-network/dhcp-server-internal.h
@@ -96,5 +96,5 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
DHCPRequest *req, DHCPPacket *packet,
int type, size_t optoffset);
-unsigned long client_id_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
+void client_id_hash_func(const void *p, struct siphash *state);
int client_id_compare_func(const void *_a, const void *_b);
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 1f167485e3..4ea5a29e5c 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -110,18 +110,14 @@ sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) {
return server;
}
-unsigned long client_id_hash_func(const void *p,
- const uint8_t hash_key[HASH_KEY_SIZE]) {
- uint64_t u;
+void client_id_hash_func(const void *p, struct siphash *state) {
const DHCPClientId *id = p;
assert(id);
assert(id->length);
assert(id->data);
- siphash24((uint8_t*) &u, id->data, id->length, hash_key);
-
- return (unsigned long) u;
+ siphash24_compress(id->data, id->length, state);
}
int client_id_compare_func(const void *_a, const void *_b) {
@@ -743,13 +739,16 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
if (existing_lease)
address = existing_lease->address;
else {
+ struct siphash state;
uint32_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;
+ siphash_init(&state, HASH_KEY.bytes);
+ client_id_hash_func(&req->client_id, &state);
+ next_offer = siphash24_finalize(&state) % server->pool_size;
for (i = 0; i < server->pool_size; i++) {
if (!server->bound_leases[next_offer]) {
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
index 17512884f5..b9bf4d3c00 100644
--- a/src/libsystemd-network/sd-lldp.c
+++ b/src/libsystemd-network/sd-lldp.c
@@ -68,16 +68,13 @@ struct sd_lldp {
lldp_agent_statistics statistics;
};
-static unsigned long chassis_id_hash_func(const void *p,
- const uint8_t hash_key[HASH_KEY_SIZE]) {
- uint64_t u;
+static void chassis_id_hash_func(const void *p, struct siphash *state) {
const lldp_chassis_id *id = p;
assert(id);
+ assert(id->data);
- siphash24((uint8_t *) &u, id->data, id->length, hash_key);
-
- return (unsigned long) u;
+ siphash24_compress(id->data, id->length, state);
}
static int chassis_id_compare_func(const void *_a, const void *_b) {
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
index 7d8a1f6bd9..01205efc18 100644
--- a/src/libsystemd-network/test-dhcp-server.c
+++ b/src/libsystemd-network/test-dhcp-server.c
@@ -198,6 +198,14 @@ static void test_message_handler(void) {
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
}
+static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZE]) {
+ struct siphash state;
+
+ siphash_init(&state, key);
+ client_id_hash_func(id, &state);
+ return siphash24_finalize(&state);
+}
+
static void test_client_id_hash(void) {
DHCPClientId a = {
.length = 4,
@@ -213,18 +221,18 @@ static void test_client_id_hash(void) {
b.data = (uint8_t*)strdup("abcd");
assert_se(client_id_compare_func(&a, &b) == 0);
- assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
+ assert_se(client_id_hash_helper(&a, hash_key) == client_id_hash_helper(&b, hash_key));
a.length = 3;
assert_se(client_id_compare_func(&a, &b) != 0);
a.length = 4;
assert_se(client_id_compare_func(&a, &b) == 0);
- assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
+ assert_se(client_id_hash_helper(&a, hash_key) == client_id_hash_helper(&b, hash_key));
b.length = 3;
assert_se(client_id_compare_func(&a, &b) != 0);
b.length = 4;
assert_se(client_id_compare_func(&a, &b) == 0);
- assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
+ assert_se(client_id_hash_helper(&a, hash_key) == client_id_hash_helper(&b, hash_key));
free(b.data);
b.data = (uint8_t*)strdup("abce");