]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: sort requesting options
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 1 Apr 2022 16:13:24 +0000 (01:13 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 3 Apr 2022 10:23:03 +0000 (19:23 +0900)
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/test-dhcp6-client.c

index e3e18b58269f4d763afd269471f97d64af685be1..04e5f2aaf3078a1611268703970b6a325c8ec5b2 100644 (file)
 #include "io-util.h"
 #include "random-util.h"
 #include "socket-util.h"
+#include "sort-util.h"
 #include "strv.h"
 #include "web-util.h"
 
+/* Keep the list sorted. */
 static const uint16_t default_req_opts[] = {
-        SD_DHCP6_OPTION_DNS_SERVERS,
-        SD_DHCP6_OPTION_DOMAIN_LIST,
-        SD_DHCP6_OPTION_NTP_SERVER,
-        SD_DHCP6_OPTION_SNTP_SERVERS,
+        SD_DHCP6_OPTION_DNS_SERVERS,  /* 23 */
+        SD_DHCP6_OPTION_DOMAIN_LIST,  /* 24 */
+        SD_DHCP6_OPTION_SNTP_SERVERS, /* 31 */
+        SD_DHCP6_OPTION_NTP_SERVER,   /* 56 */
 };
 
 #define DHCP6_CLIENT_DONT_DESTROY(client) \
@@ -371,8 +373,12 @@ int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enable
         return 0;
 }
 
+static int be16_compare_func(const be16_t *a, const be16_t *b) {
+        return CMP(be16toh(*a), be16toh(*b));
+}
+
 int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) {
-        size_t t;
+        be16_t opt;
 
         assert_return(client, -EINVAL);
         assert_return(!sd_dhcp6_client_is_running(client), -EBUSY);
@@ -380,15 +386,17 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
         if (!dhcp6_option_can_request(option))
                 return -EINVAL;
 
-        for (t = 0; t < client->n_req_opts; t++)
-                if (client->req_opts[t] == htobe16(option))
-                        return -EEXIST;
+        opt = htobe16(option);
+        if (typesafe_bsearch(&opt, client->req_opts, client->n_req_opts, be16_compare_func))
+                return -EEXIST;
 
         if (!GREEDY_REALLOC(client->req_opts, client->n_req_opts + 1))
                 return -ENOMEM;
 
-        client->req_opts[client->n_req_opts++] = htobe16(option);
+        client->req_opts[client->n_req_opts++] = opt;
 
+        /* Sort immediately to make the above binary search will work for the next time. */
+        typesafe_qsort(client->req_opts, client->n_req_opts, be16_compare_func);
         return 0;
 }
 
index 8278a3875abc7a5bb50e190f8f861968360e67d4..c4e5bd0e5a9c4672764c5239409792f6dcf797b6 100644 (file)
@@ -453,8 +453,8 @@ static const uint8_t msg_information_request[] = {
         0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x08,
         0x00, SD_DHCP6_OPTION_DNS_SERVERS,
         0x00, SD_DHCP6_OPTION_DOMAIN_LIST,
-        0x00, SD_DHCP6_OPTION_NTP_SERVER,
         0x00, SD_DHCP6_OPTION_SNTP_SERVERS,
+        0x00, SD_DHCP6_OPTION_NTP_SERVER,
         /* Client ID */
         0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
         CLIENT_ID_BYTES,
@@ -493,8 +493,8 @@ static const uint8_t msg_solicit[] = {
         0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x08,
         0x00, SD_DHCP6_OPTION_DNS_SERVERS,
         0x00, SD_DHCP6_OPTION_DOMAIN_LIST,
-        0x00, SD_DHCP6_OPTION_NTP_SERVER,
         0x00, SD_DHCP6_OPTION_SNTP_SERVERS,
+        0x00, SD_DHCP6_OPTION_NTP_SERVER,
         /* Client ID */
         0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
         CLIENT_ID_BYTES,
@@ -556,8 +556,8 @@ static const uint8_t msg_request[] = {
         0x00, SD_DHCP6_OPTION_ORO, 0x00, 0x08,
         0x00, SD_DHCP6_OPTION_DNS_SERVERS,
         0x00, SD_DHCP6_OPTION_DOMAIN_LIST,
-        0x00, SD_DHCP6_OPTION_NTP_SERVER,
         0x00, SD_DHCP6_OPTION_SNTP_SERVERS,
+        0x00, SD_DHCP6_OPTION_NTP_SERVER,
         /* Client ID */
         0x00, SD_DHCP6_OPTION_CLIENTID, 0x00, 0x0e,
         CLIENT_ID_BYTES,