]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp6: read OPTION_INFORMATION_REFRESH_TIME option
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 6 Sep 2019 18:29:46 +0000 (03:29 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 15 Sep 2019 20:36:57 +0000 (05:36 +0900)
Fixes #13460.

src/libsystemd-network/sd-dhcp6-client.c
src/systemd/sd-dhcp6-client.h

index d7a5349c70126559e3286fa4b6934841b0aea9a5..7dab776b7295d2dc63faf0ed192fbd3e90980782 100644 (file)
@@ -29,6 +29,9 @@
 
 #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
 
+#define IRT_DEFAULT 1 * USEC_PER_DAY
+#define IRT_MINIMUM 600 * USEC_PER_SEC
+
 /* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
 enum {
         DHCP6_REQUEST_IA_NA                     = 1,
@@ -71,6 +74,8 @@ struct sd_dhcp6_client {
         void *userdata;
         struct duid duid;
         size_t duid_len;
+        usec_t information_request_time_usec;
+        usec_t information_refresh_time_usec;
 };
 
 static const uint16_t default_req_opts[] = {
@@ -820,6 +825,7 @@ static int client_parse_message(
         uint32_t lt_t1 = ~0, lt_t2 = ~0;
         bool clientid = false;
         size_t pos = 0;
+        usec_t irt = IRT_DEFAULT;
         int r;
 
         assert(client);
@@ -994,6 +1000,10 @@ static int client_parse_message(
                                 return r;
 
                         break;
+
+                case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
+                        irt = be32toh(*(be32_t *) optval) * USEC_PER_SEC;
+                        break;
                 }
 
                 pos += offsetof(DHCP6Option, data) + optlen;
@@ -1025,6 +1035,8 @@ static int client_parse_message(
                 }
         }
 
+        client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM);
+
         return 0;
 }
 
@@ -1425,8 +1437,15 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
                 client->fd = r;
         }
 
-        if (client->information_request)
+        if (client->information_request) {
+                usec_t t = now(CLOCK_MONOTONIC);
+
+                if (t < usec_add(client->information_request_time_usec, client->information_refresh_time_usec))
+                        return 0;
+
+                client->information_request_time_usec = t;
                 state = DHCP6_STATE_INFORMATION_REQUEST;
+        }
 
         log_dhcp6_client(client, "Started in %s mode",
                          client->information_request? "Information request":
index 43d38f5c7da66bb618699cf28b294be921d5f2de..3aac3f14fe30f1a6e5007d1a15e3bf1b0cafd758 100644 (file)
@@ -66,6 +66,7 @@ enum {
         SD_DHCP6_OPTION_IA_PD_PREFIX               = 26,  /* RFC 3633, prefix delegation */
 
         SD_DHCP6_OPTION_SNTP_SERVERS               = 31,  /* RFC 4075, deprecated */
+        SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME   = 32,  /* RFC 8415, sec. 21.23 */
 
         /* option code 35 is unassigned */