]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: introduce dhcp6_lease_{get,set}_clientid()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 1 Nov 2021 05:19:16 +0000 (14:19 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 1 Nov 2021 14:13:08 +0000 (23:13 +0900)
src/libsystemd-network/dhcp6-lease-internal.h
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-dhcp6-lease.c

index 88c1c0e9b553f93c873d1ca20c744aa7cc6e7325..4b73e0cfe0555a8b67f10e9c23d7cedb4bb836d2 100644 (file)
@@ -14,6 +14,8 @@
 struct sd_dhcp6_lease {
         unsigned n_ref;
 
+        uint8_t *clientid;
+        size_t clientid_len;
         uint8_t *serverid;
         size_t serverid_len;
         uint8_t preference;
@@ -41,6 +43,8 @@ struct sd_dhcp6_lease {
 int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
 DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia);
 
+int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len);
+int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len);
 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len);
 int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len);
 int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference);
index 6562ebd21c5766b0425f9ff8914ab1d6da6464c7..f8d7367ec3c3ad288e773003e2e252ed62f6e643 100644 (file)
@@ -1134,7 +1134,6 @@ static int client_parse_message(
 
         uint32_t lt_t1 = UINT32_MAX, lt_t2 = UINT32_MAX;
         usec_t irt = IRT_DEFAULT;
-        bool clientid = false;
         int r;
 
         assert(client);
@@ -1154,16 +1153,13 @@ static int client_parse_message(
 
                 switch (optcode) {
                 case SD_DHCP6_OPTION_CLIENTID:
-                        if (clientid)
+                        if (dhcp6_lease_get_clientid(lease, NULL, NULL) >= 0)
                                 return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s contains multiple client IDs",
                                                               dhcp6_message_type_to_string(message->type));
 
-                        if (optlen != client->duid_len ||
-                            memcmp(&client->duid, optval, optlen) != 0)
-                                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s DUID does not match",
-                                                              dhcp6_message_type_to_string(message->type));
-
-                        clientid = true;
+                        r = dhcp6_lease_set_clientid(lease, optval, optlen);
+                        if (r < 0)
+                                return r;
 
                         break;
 
@@ -1308,10 +1304,17 @@ static int client_parse_message(
                 }
         }
 
-        if (!clientid)
+        uint8_t *clientid;
+        size_t clientid_len;
+        if (dhcp6_lease_get_clientid(lease, &clientid, &clientid_len) < 0)
                 return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "%s message does not contain client ID. Ignoring.",
                                               dhcp6_message_type_to_string(message->type));
 
+        if (clientid_len != client->duid_len ||
+            memcmp(clientid, &client->duid, clientid_len) != 0)
+                return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), "The client ID in %s message does not match. Ignoring.",
+                                              dhcp6_message_type_to_string(message->type));
+
         if (client->state != DHCP6_STATE_INFORMATION_REQUEST) {
                 r = dhcp6_lease_get_serverid(lease, NULL, NULL);
                 if (r < 0)
index ba46e09919bc324d70f4fd9c4eb45901bad30e59..22fb77c19e12becf79d91db1ff9f4d3778222a7b 100644 (file)
@@ -71,6 +71,37 @@ DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
         return NULL;
 }
 
+int dhcp6_lease_set_clientid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) {
+        uint8_t *clientid;
+
+        assert_return(lease, -EINVAL);
+        assert_return(id, -EINVAL);
+        assert_return(len > 0, -EINVAL);
+
+        clientid = memdup(id, len);
+        if (!clientid)
+                return -ENOMEM;
+
+        free_and_replace(lease->clientid, clientid);
+        lease->clientid_len = len;
+
+        return 0;
+}
+
+int dhcp6_lease_get_clientid(sd_dhcp6_lease *lease, uint8_t **ret_id, size_t *ret_len) {
+        assert_return(lease, -EINVAL);
+
+        if (!lease->clientid)
+                return -ENODATA;
+
+        if (ret_id)
+                *ret_id = lease->clientid;
+        if (ret_len)
+                *ret_len = lease->clientid_len;
+
+        return 0;
+}
+
 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, size_t len) {
         uint8_t *serverid;
 
@@ -367,6 +398,7 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) {
         if (!lease)
                 return NULL;
 
+        free(lease->clientid);
         free(lease->serverid);
         dhcp6_lease_free_ia(&lease->ia);
         dhcp6_lease_free_ia(&lease->pd);