summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@canonical.com>2020-12-08 15:33:29 -0500
committerDan Streetman <ddstreet@canonical.com>2020-12-14 18:19:01 -0500
commit3d75a443ee819c4b2df8bfd8caee5c3ebc76fae3 (patch)
tree86926ac3e51848596064aa8c2c862e1d8d142022
parent0c3c59783b127ec9a1c4860c6509d133cccffe10 (diff)
downloadsystemd-3d75a443ee819c4b2df8bfd8caee5c3ebc76fae3.tar.gz
sd-dhcp-client: add RFC2131 retransmission details
RFC2131, providing the details for dhcpv4, has specific retransmission intervals that it outlines. This adds functions to compute the timeouts as the RFC describes.
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 60e4a93328..0ffc543132 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -29,6 +29,7 @@
#include "sort-util.h"
#include "string-util.h"
#include "strv.h"
+#include "time-util.h"
#include "utf8.h"
#include "web-util.h"
@@ -730,6 +731,37 @@ static void client_stop(sd_dhcp_client *client, int error) {
client_initialize(client);
}
+/* RFC2131 section 4.1:
+ * retransmission delays should include -1 to +1 sec of random 'fuzz'. */
+#define RFC2131_RANDOM_FUZZ \
+ ((int64_t)(random_u64() % (2 * USEC_PER_SEC)) - (int64_t)USEC_PER_SEC)
+
+/* RFC2131 section 4.1:
+ * for retransmission delays, timeout should start at 4s then double
+ * each attempt with max of 64s, with -1 to +1 sec of random 'fuzz' added.
+ * This assumes the first call will be using attempt 1. */
+static usec_t client_compute_request_timeout(usec_t now, uint64_t attempt) {
+ usec_t timeout = (UINT64_C(1) << MIN(attempt + 1, UINT64_C(6))) * USEC_PER_SEC;
+
+ return usec_sub_signed(usec_add(now, timeout), RFC2131_RANDOM_FUZZ);
+}
+
+/* RFC2131 section 4.4.5:
+ * T1 defaults to (0.5 * duration_of_lease).
+ * T2 defaults to (0.875 * duration_of_lease). */
+#define T1_DEFAULT(lifetime) ((lifetime) / 2)
+#define T2_DEFAULT(lifetime) (((lifetime) * 7) / 8)
+
+/* RFC2131 section 4.4.5:
+ * the client SHOULD wait one-half of the remaining time until T2 (in RENEWING state)
+ * and one-half of the remaining lease time (in REBINDING state), down to a minimum
+ * of 60 seconds.
+ * Note that while the default T1/T2 initial times do have random 'fuzz' applied,
+ * the RFC sec 4.4.5 does not mention adding any fuzz to retries. */
+static usec_t client_compute_reacquisition_timeout(usec_t now, usec_t expire) {
+ return MAX(usec_sub_unsigned(expire, now) / 2, 60 * USEC_PER_SEC);
+}
+
static int cmp_uint8(const uint8_t *a, const uint8_t *b) {
return CMP(*a, *b);
}