use leaetime as base for T1 and T2 upper bound
[project/odhcpd.git] / src / dhcpv6-ia.c
index 5e34b5c..181973d 100644 (file)
@@ -718,8 +718,14 @@ static size_t append_reply(uint8_t *buf, size_t buflen, uint16_t status,
                datalen += sizeof(stat);
        } else {
                if (a) {
-                       uint32_t pref = 3600;
-                       uint32_t valid = 3600;
+                       uint32_t leasetime = iface->dhcpv4_leasetime;
+                       if (leasetime == 0)
+                               leasetime = 3600;
+                       else if (leasetime < 60)
+                               leasetime = 60;
+
+                       uint32_t pref = leasetime;
+                       uint32_t valid = leasetime;
 
                        struct odhcpd_ipaddr *addrs = (a->managed) ? a->managed : iface->ia_addr;
                        size_t addrlen = (a->managed) ? (size_t)a->managed_size : iface->ia_addr_len;
@@ -933,6 +939,8 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
        char hostname[256];
        size_t hostname_len = 0;
        bool class_oro = false;
+       bool notonlink = false;
+
        dhcpv6_for_each_option(start, end, otype, olen, odata) {
                if (otype == DHCPV6_OPT_CLIENTID) {
                        clid_data = odata;
@@ -1184,6 +1192,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                        // Send NOTONLINK for CONFIRM with addr present so that clients restart connection
                        status = DHCPV6_STATUS_NOTONLINK;
                        ia_response_len = append_reply(buf, buflen, status, ia, a, iface, true);
+                       notonlink = true;
                }
 
                buf += ia_response_len;
@@ -1191,13 +1200,14 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
                response_len += ia_response_len;
        }
 
-       if (hdr->msg_type == DHCPV6_MSG_RELEASE && response_len + 6 < buflen) {
+       if ((hdr->msg_type == DHCPV6_MSG_RELEASE || hdr->msg_type == DHCPV6_MSG_DECLINE || notonlink) &&
+                       response_len + 6 < buflen) {
                buf[0] = 0;
                buf[1] = DHCPV6_OPT_STATUS;
                buf[2] = 0;
                buf[3] = 2;
                buf[4] = 0;
-               buf[5] = DHCPV6_STATUS_OK;
+               buf[5] = (notonlink) ? DHCPV6_STATUS_NOTONLINK : DHCPV6_STATUS_OK;
                response_len += 6;
        }