diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-02-06 16:12:10 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-02-14 14:43:45 +0900 |
commit | f4fbea7a0f509c4010605cf12fe30887aea23fe4 (patch) | |
tree | 3e1ff3f514121d4de3b355e64fab53da2675bfdb /src/libsystemd-network/sd-dhcp6-lease.c | |
parent | 126277aceb389137406eeac7703db1c0a0e355b6 (diff) | |
download | systemd-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.c | 77 |
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; } |