summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/sd-dhcp6-lease.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-02-06 16:12:10 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-02-14 14:43:45 +0900
commitf4fbea7a0f509c4010605cf12fe30887aea23fe4 (patch)
tree3e1ff3f514121d4de3b355e64fab53da2675bfdb /src/libsystemd-network/sd-dhcp6-lease.c
parent126277aceb389137406eeac7703db1c0a0e355b6 (diff)
downloadsystemd-f4fbea7a0f509c4010605cf12fe30887aea23fe4.tar.gz
sd-dhcp6-lease: unify lease lifetime calculation
Diffstat (limited to 'src/libsystemd-network/sd-dhcp6-lease.c')
-rw-r--r--src/libsystemd-network/sd-dhcp6-lease.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c
index 4cd6d3e352..c2d076d3b9 100644
--- a/src/libsystemd-network/sd-dhcp6-lease.c
+++ b/src/libsystemd-network/sd-dhcp6-lease.c
@@ -24,33 +24,72 @@ int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_
return 0;
}
-int sd_dhcp6_lease_get_server_address(sd_dhcp6_lease *lease, struct in6_addr *ret) {
- assert_return(lease, -EINVAL);
- assert_return(ret, -EINVAL);
+void dhcp6_lease_set_lifetime(sd_dhcp6_lease *lease) {
+ uint32_t t1 = UINT32_MAX, t2 = UINT32_MAX, min_valid_lt = UINT32_MAX;
+ DHCP6Address *a;
- *ret = lease->server_address;
- return 0;
-}
+ assert(lease);
+ assert(lease->ia_na || lease->ia_pd);
-int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
- DHCP6Address *addr;
- uint32_t valid = 0, t;
+ if (lease->ia_na) {
+ t1 = MIN(t1, be32toh(lease->ia_na->header.lifetime_t1));
+ t2 = MIN(t2, be32toh(lease->ia_na->header.lifetime_t2));
- assert(ia);
- assert(expire);
+ LIST_FOREACH(addresses, a, lease->ia_na->addresses)
+ min_valid_lt = MIN(min_valid_lt, be32toh(a->iaaddr.lifetime_valid));
+ }
- LIST_FOREACH(addresses, addr, ia->addresses) {
- t = be32toh(addr->iaaddr.lifetime_valid);
- if (valid < t)
- valid = t;
+ if (lease->ia_pd) {
+ t1 = MIN(t1, be32toh(lease->ia_pd->header.lifetime_t1));
+ t2 = MIN(t2, be32toh(lease->ia_pd->header.lifetime_t2));
+
+ LIST_FOREACH(addresses, a, lease->ia_pd->addresses)
+ min_valid_lt = MIN(min_valid_lt, be32toh(a->iapdprefix.lifetime_valid));
+ }
+
+ if (t2 == 0 || t2 > min_valid_lt) {
+ /* If T2 is zero or longer than the minimum valid lifetime of the addresses or prefixes,
+ * then adjust lifetime with it. */
+ t1 = min_valid_lt / 2;
+ t2 = min_valid_lt / 10 * 8;
}
- t = be32toh(ia->header.lifetime_t2);
- if (t > valid)
- return -EINVAL;
+ assert(t2 <= min_valid_lt);
+ lease->max_retransmit_duration = (min_valid_lt - t2) * USEC_PER_SEC;
+
+ lease->lifetime_t1 = t1 == UINT32_MAX ? USEC_INFINITY : t1 * USEC_PER_SEC;
+ lease->lifetime_t2 = t2 == UINT32_MAX ? USEC_INFINITY : t2 * USEC_PER_SEC;
+}
+
+int dhcp6_lease_get_lifetime(sd_dhcp6_lease *lease, usec_t *ret_t1, usec_t *ret_t2) {
+ assert(lease);
- *expire = valid - t;
+ if (!lease->ia_na && !lease->ia_pd)
+ return -ENODATA;
+ if (ret_t1)
+ *ret_t1 = lease->lifetime_t1;
+ if (ret_t2)
+ *ret_t2 = lease->lifetime_t2;
+ return 0;
+}
+
+int dhcp6_lease_get_max_retransmit_duration(sd_dhcp6_lease *lease, usec_t *ret) {
+ assert(lease);
+
+ if (!lease->ia_na && !lease->ia_pd)
+ return -ENODATA;
+
+ if (ret)
+ *ret = lease->max_retransmit_duration;
+ return 0;
+}
+
+int sd_dhcp6_lease_get_server_address(sd_dhcp6_lease *lease, struct in6_addr *ret) {
+ assert_return(lease, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ *ret = lease->server_address;
return 0;
}