]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-server: store more information in DHCPRequest
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 7 May 2026 02:59:23 +0000 (11:59 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 21 May 2026 19:30:34 +0000 (04:30 +0900)
This makes DHCPRequest stores
- the message type of the received message,
- acquired address,
- found static DHCP lease,

This also moves call of dhcp_request_get_lifetime_timestamp() from
dhcp_server_ack() to dhcp_server_set_lease(), and rename
DHCPRequest.server_id -> .server_address.

No functional change, just refactoring.

src/libsystemd-network/dhcp-server-lease-internal.h
src/libsystemd-network/dhcp-server-request.c
src/libsystemd-network/dhcp-server-request.h
src/libsystemd-network/dhcp-server-send.c
src/libsystemd-network/dhcp-server-send.h
src/libsystemd-network/sd-dhcp-server-lease.c

index 024279ccbd3fa90f7028beb21d44d43a93054bb2..f347837bd847e7432052f97c261c0b2d3468409d 100644 (file)
@@ -28,7 +28,7 @@ extern const struct hash_ops dhcp_server_lease_hash_ops;
 
 int dhcp_server_put_lease(sd_dhcp_server *server, sd_dhcp_server_lease *lease, bool is_static);
 
-int dhcp_server_set_lease(sd_dhcp_server *server, be32_t address, DHCPRequest *req, usec_t expiration);
+int dhcp_server_set_lease(sd_dhcp_server *server, DHCPRequest *req);
 int dhcp_server_cleanup_expired_leases(sd_dhcp_server *server);
 
 sd_dhcp_server_lease* dhcp_server_get_static_lease(sd_dhcp_server *server, const DHCPRequest *req);
index 768677e65e52a34ac500d4d2e506a22acab16cd1..202a8b888cd05f399e5673a90a8aeffa19b535b5 100644 (file)
@@ -112,7 +112,7 @@ static int parse_request(uint8_t code, uint8_t len, const void *option, void *us
                 break;
         case SD_DHCP_OPTION_SERVER_IDENTIFIER:
                 if (len == 4)
-                        memcpy(&req->server_id, option, sizeof(be32_t));
+                        memcpy(&req->server_address, option, sizeof(be32_t));
 
                 break;
         case SD_DHCP_OPTION_CLIENT_IDENTIFIER:
@@ -169,7 +169,7 @@ static int dhcp_server_parse_message(sd_dhcp_server *server, DHCPMessage *messag
         r = dhcp_option_parse(message, length, parse_request, req, &error_message);
         if (r < 0)
                 return r;
-        int type = r;
+        req->type = r;
 
         r = ensure_sane_request(server, req, message);
         if (r < 0)
@@ -177,26 +177,21 @@ static int dhcp_server_parse_message(sd_dhcp_server *server, DHCPMessage *messag
 
         *ret = TAKE_PTR(req);
         *ret_error_message = TAKE_PTR(error_message);
-        return type;
+        return 0;
 }
 
-static int dhcp_server_ack(sd_dhcp_server *server, DHCPRequest *req, be32_t address) {
-        usec_t expiration;
+static int dhcp_server_ack(sd_dhcp_server *server, DHCPRequest *req) {
         int r;
 
         assert(server);
         assert(req);
-        assert(address != 0);
-
-        r = dhcp_request_get_lifetime_timestamp(req, CLOCK_BOOTTIME, &expiration);
-        if (r < 0)
-                return r;
+        assert(req->address != INADDR_ANY);
 
-        r = dhcp_server_set_lease(server, address, req, expiration);
+        r = dhcp_server_set_lease(server, req);
         if (r < 0)
                 return log_dhcp_server_errno(server, r, "Failed to create new lease: %m");
 
-        r = server_send_offer_or_ack(server, req, address, DHCP_ACK);
+        r = server_send_offer_or_ack(server, req, DHCP_ACK);
         if (r < 0)
                 return log_dhcp_server_errno(server, r, "Could not send ACK: %m");
 
@@ -223,8 +218,6 @@ static int dhcp_server_process_discover(sd_dhcp_server *server, DHCPRequest *req
                 /* no pool allocated */
                 return 0;
 
-        be32_t address = INADDR_ANY;
-
         /* for now pick a random free address from the pool */
         if (static_lease) {
                 sd_dhcp_server_lease *l = hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(static_lease->address));
@@ -233,12 +226,13 @@ static int dhcp_server_process_discover(sd_dhcp_server *server, DHCPRequest *req
                         return 0;
 
                 /* Found a matching static lease. */
-                address = static_lease->address;
+                req->static_lease = static_lease;
+                req->address = static_lease->address;
 
         } else if (existing_lease && dhcp_server_address_is_in_pool(server, existing_lease->address))
 
                 /* If we previously assigned an address to the host, then reuse it. */
-                address = existing_lease->address;
+                req->address = existing_lease->address;
 
         else {
                 struct siphash state;
@@ -257,20 +251,20 @@ static int dhcp_server_process_discover(sd_dhcp_server *server, DHCPRequest *req
                 for (unsigned i = 0; i < server->pool_size; i++) {
                         be32_t a = server->subnet | htobe32(server->pool_offset + (hash + i) % server->pool_size);
                         if (dhcp_server_address_available(server, a)) {
-                                address = a;
+                                req->address = a;
                                 break;
                         }
                 }
         }
 
-        if (address == INADDR_ANY)
+        if (req->address == INADDR_ANY)
                 /* no free addresses left */
                 return 0;
 
         if (server->rapid_commit && req->rapid_commit)
-                return dhcp_server_ack(server, req, address);
+                return dhcp_server_ack(server, req);
 
-        r = server_send_offer_or_ack(server, req, address, DHCP_OFFER);
+        r = server_send_offer_or_ack(server, req, DHCP_OFFER);
         if (r < 0)
                 /* this only fails on critical errors */
                 return log_dhcp_server_errno(server, r, "Could not send offer: %m");
@@ -292,12 +286,12 @@ static int dhcp_server_process_request(sd_dhcp_server *server, DHCPRequest *req)
 
         /* see RFC 2131, section 4.3.2 */
 
-        if (req->server_id != 0) {
+        if (req->server_address != INADDR_ANY) {
                 log_dhcp_server(server, "REQUEST (selecting) (0x%x)",
                                 be32toh(req->message->xid));
 
                 /* SELECTING */
-                if (req->server_id != server->address)
+                if (req->server_address != server->address)
                         /* client did not pick us */
                         return 0;
 
@@ -348,13 +342,19 @@ static int dhcp_server_process_request(sd_dhcp_server *server, DHCPRequest *req)
                         /* The requested address is already assigned to another host. Refusing. */
                         return server_send_nak_or_ignore(server, init_reboot, req);
 
+                req->static_lease = static_lease;
+                req->address = address;
+
                 /* Found a static lease for the client ID. */
-                return dhcp_server_ack(server, req, address);
+                return dhcp_server_ack(server, req);
         }
 
-        if (dhcp_server_address_is_in_pool(server, address))
+        if (dhcp_server_address_is_in_pool(server, address)) {
                 /* The requested address is in the pool. */
-                return dhcp_server_ack(server, req, address);
+                req->address = address;
+
+                return dhcp_server_ack(server, req);
+        }
 
         /* Refuse otherwise. */
         return server_send_nak_or_ignore(server, init_reboot, req);
@@ -408,7 +408,6 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
         r = dhcp_server_parse_message(server, message, length, &req, &error_message);
         if (r < 0)
                 return r;
-        int type = r;
 
         dhcp_request_set_timestamp(req, timestamp);
 
@@ -416,7 +415,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
         if (r < 0)
                 return r;
 
-        switch (type) {
+        switch (req->type) {
         case DHCP_DISCOVER:
                 return dhcp_server_process_discover(server, req);
         case DHCP_REQUEST:
index c9ffe2aba8ee8814fd774c5bddeb0af715bd3eb4..e5738978a2ddc2504daa6978a8f6b1cfe0b5e975 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include "sd-dhcp-server-lease.h"
+
 #include "dhcp-client-id-internal.h"
 #include "dhcp-protocol.h"
 #include "ether-addr-util.h"
@@ -16,10 +18,11 @@ typedef struct DHCPRequest {
         triple_timestamp timestamp;
 
         /* options */
+        uint8_t type;
         sd_dhcp_client_id client_id;
         sd_dhcp_client_id client_id_by_header;
         size_t max_optlen;
-        be32_t server_id;
+        be32_t server_address;
         be32_t requested_ip;
         usec_t lifetime;
         const uint8_t *agent_info_option;
@@ -27,6 +30,10 @@ typedef struct DHCPRequest {
         const uint8_t *parameter_request_list;
         size_t parameter_request_list_len;
         bool rapid_commit;
+
+        /* acquired data */
+        sd_dhcp_server_lease *static_lease;
+        be32_t address;
 } DHCPRequest;
 
 int dhcp_request_get_lifetime_timestamp(DHCPRequest *req, clockid_t clock, usec_t *ret);
index 3fd548392da9e9bb955e57d4213710d856741670..9f52ff4cc8df9c2c2d1c053aef1869fff01e68df 100644 (file)
@@ -286,7 +286,6 @@ static int dhcp_server_append_static_hostname(
                 size_t *offset,
                 DHCPRequest *req) {
 
-        sd_dhcp_server_lease *static_lease;
         int r;
 
         assert(server);
@@ -294,11 +293,10 @@ static int dhcp_server_append_static_hostname(
         assert(offset);
         assert(req);
 
-        static_lease = dhcp_server_get_static_lease(server, req);
-        if (!static_lease || !static_lease->hostname)
+        if (!req->static_lease || !req->static_lease->hostname)
                 return 0;
 
-        if (dns_name_is_single_label(static_lease->hostname))
+        if (dns_name_is_single_label(req->static_lease->hostname))
                 /* Option 12 */
                 return dhcp_option_append(
                                 &packet->dhcp,
@@ -306,8 +304,8 @@ static int dhcp_server_append_static_hostname(
                                 offset,
                                 /* overload= */ 0,
                                 SD_DHCP_OPTION_HOST_NAME,
-                                strlen(static_lease->hostname),
-                                static_lease->hostname);
+                                strlen(req->static_lease->hostname),
+                                req->static_lease->hostname);
 
 
         /* Option 81 */
@@ -322,7 +320,7 @@ static int dhcp_server_append_static_hostname(
         buffer[1] = 255;
         buffer[2] = 255;
 
-        r = dns_name_to_wire_format(static_lease->hostname, buffer + 3, sizeof(buffer) - 3, false);
+        r = dns_name_to_wire_format(req->static_lease->hostname, buffer + 3, sizeof(buffer) - 3, false);
         if (r < 0)
                 return log_dhcp_server_errno(server, r, "Failed to encode FQDN for static lease: %m");
         if (r > DHCP_MAX_FQDN_LENGTH)
@@ -350,7 +348,6 @@ static bool dhcp_request_contains(DHCPRequest *req, uint8_t option) {
 int server_send_offer_or_ack(
                 sd_dhcp_server *server,
                 DHCPRequest *req,
-                be32_t address,
                 uint8_t type) {
 
         static const uint8_t option_map[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
@@ -375,7 +372,7 @@ int server_send_offer_or_ack(
         if (r < 0)
                 return r;
 
-        packet->dhcp.yiaddr = address;
+        packet->dhcp.yiaddr = req->address;
         packet->dhcp.siaddr = server->boot_server_address.s_addr;
 
         lease_time = usec_to_be32_sec(req->lifetime);
index 80fd9a6b94fe50d83d9f13388f6a4a40e0e29b75..27801b64ec204fb1f51590ac564b1add391594d7 100644 (file)
@@ -8,7 +8,6 @@
 int server_send_offer_or_ack(
                 sd_dhcp_server *server,
                 DHCPRequest *req,
-                be32_t address,
                 uint8_t type);
 
 int server_send_nak_or_ignore(sd_dhcp_server *server, bool init_reboot, DHCPRequest *req);
index 58b5831e4411922cb9e025d10ca884fec02cd7db..4ab789726407d9ea12908949fd3946a4aef0da2e 100644 (file)
@@ -64,21 +64,25 @@ int dhcp_server_put_lease(sd_dhcp_server *server, sd_dhcp_server_lease *lease, b
         return 0;
 }
 
-int dhcp_server_set_lease(sd_dhcp_server *server, be32_t address, DHCPRequest *req, usec_t expiration) {
+int dhcp_server_set_lease(sd_dhcp_server *server, DHCPRequest *req) {
         _cleanup_(sd_dhcp_server_lease_unrefp) sd_dhcp_server_lease *lease = NULL;
         int r;
 
         assert(server);
-        assert(address != 0);
         assert(req);
-        assert(expiration != 0);
+        assert(req->address != INADDR_ANY);
+
+        usec_t expiration;
+        r = dhcp_request_get_lifetime_timestamp(req, CLOCK_BOOTTIME, &expiration);
+        if (r < 0)
+                return r;
 
         /* If a lease for the host already exists, update it. */
         lease = hashmap_get(server->bound_leases_by_client_id, &req->client_id);
         if (lease) {
-                if (lease->address != address) {
+                if (lease->address != req->address) {
                         hashmap_remove_value(server->bound_leases_by_address, UINT32_TO_PTR(lease->address), lease);
-                        lease->address = address;
+                        lease->address = req->address;
 
                         r = hashmap_ensure_put(&server->bound_leases_by_address, NULL, UINT32_TO_PTR(lease->address), lease);
                         if (r < 0)
@@ -99,7 +103,7 @@ int dhcp_server_set_lease(sd_dhcp_server *server, be32_t address, DHCPRequest *r
 
         *lease = (sd_dhcp_server_lease) {
                 .n_ref = 1,
-                .address = address,
+                .address = req->address,
                 .client_id = req->client_id,
                 .htype = req->message->htype,
                 .gateway = req->message->giaddr,