config: use correct defaults if interface is not in UCI
[project/odhcpd.git] / src / dhcpv6-ia.c
index 159017f..844dfd3 100644 (file)
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <poll.h>
 #include <alloca.h>
 #include <resolv.h>
 #include <limits.h>
@@ -279,7 +280,7 @@ void dhcpv6_write_statefile(void)
                                                        md5_hash(c->hostname, strlen(c->hostname), &md5);
                                                }
 
-                                               l += snprintf(leasebuf + l, sizeof(leasebuf) - l, "%s/%hhu ", ipbuf,
+                                               l += snprintf(leasebuf + l, sizeof(leasebuf) - l, "%s/%d ", ipbuf,
                                                                (c->managed_size) ? addrs[i].prefix : c->length);
                                        }
                                        leasebuf[l - 1] = '\n';
@@ -428,6 +429,8 @@ static void managed_handle_pd_data(struct ustream *s, _unused int bytes_new)
 
        if (first && c->managed_size == 0)
                free_dhcpv6_assignment(c);
+       else if (first)
+               c->valid_until = now + 150;
 }
 
 
@@ -460,7 +463,16 @@ static bool assign_pd(struct interface *iface, struct dhcpv6_assignment *assign)
                                        iaidbuf, assign->iaid, assign->length);
                        ustream_write_pending(&assign->managed_sock.stream);
                        assign->managed_size = -1;
+                       assign->valid_until = odhcpd_time() + 15;
                        list_add(&assign->head, &iface->ia_assignments);
+
+                       // Wait initial period of up to 250ms for immediate assignment
+                       struct pollfd pfd = { .fd = fd, .events = POLLIN };
+                       poll(&pfd, 1, 250);
+                       managed_handle_pd_data(&assign->managed_sock.stream, 0);
+
+                       if (fcntl(fd, F_GETFL) >= 0 && assign->managed_size > 0)
+                               return true;
                }
 
                return false;
@@ -1130,7 +1142,7 @@ ssize_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface,
 
                        // Was only a solicitation: mark binding for removal
                        if (assigned && hdr->msg_type == DHCPV6_MSG_SOLICIT) {
-                               a->valid_until = now + 15;
+                               a->valid_until = 0;
                        } else if (assigned && hdr->msg_type == DHCPV6_MSG_REQUEST) {
                                if (hostname_len > 0) {
                                        a->hostname = realloc(a->hostname, hostname_len + 1);