+static void free_dhcpv6_assignment(struct dhcpv6_assignment *c)
+{
+ if (c->managed_sock.fd.registered) {
+ ustream_free(&c->managed_sock.stream);
+ close(c->managed_sock.fd.fd);
+ }
+
+ if (c->head.next)
+ list_del(&c->head);
+
+ free(c->managed);
+ free(c->hostname);
+ free(c);
+}
+
+static inline bool valid_prefix_length(const struct dhcpv6_assignment *a, const uint8_t prefix_length)
+{
+ return (a->managed_size || a->length > prefix_length);
+}
+
+static inline bool valid_addr(const struct odhcpd_ipaddr *addr, time_t now)
+{
+ return (addr->prefix <= 96 && addr->preferred > (uint32_t)now);
+}
+
+static size_t elect_addr(const struct odhcpd_ipaddr *addrs, const size_t addrlen)
+{
+ size_t i, m;
+
+ for (i = 0, m = 0; i < addrlen; ++i) {
+ if (addrs[i].preferred > addrs[m].preferred ||
+ (addrs[i].preferred == addrs[m].preferred &&
+ memcmp(&addrs[i].addr, &addrs[m].addr, 16) > 0))
+ m = i;
+ }
+
+ return m;
+}