+ if (addr4.n_addr) {
+ size_t addr_size = addr4.n_addr * sizeof(*addr4.v4);
+ void *addr_dup = malloc(addr_size);
+
+ memcpy(addr_dup, addr4.v4, addr_size);
+ __interface_add(name, SOCK_UC_IPV4, &addr4);
+ addr4.v4 = addr_dup;
+ __interface_add(name, SOCK_MC_IPV4, &addr4);
+ }
+
+ if (addr6.n_addr) {
+ size_t addr_size = addr6.n_addr * sizeof(*addr6.v6);
+ void *addr_dup = malloc(addr_size);
+
+ memcpy(addr_dup, addr6.v6, addr_size);
+ __interface_add(name, SOCK_UC_IPV6, &addr6);
+ addr6.v6 = addr_dup;
+ __interface_add(name, SOCK_MC_IPV6, &addr6);
+ }
+
+ return !addr4.n_addr && !addr6.n_addr;
+}
+
+void interface_shutdown(void)
+{
+ struct interface *iface;
+
+ vlist_for_each_element(&interfaces, iface, node)
+ if (interface_multicast(iface)) {
+ dns_reply_a(iface, NULL, 0, NULL);
+ dns_reply_a_additional(iface, NULL, 0);
+ service_announce_services(iface, NULL, 0);
+ }
+
+ for (size_t i = 0; i < ARRAY_SIZE(ufd); i++) {
+ uloop_fd_delete(&ufd[i]);
+ close(ufd[i].fd);
+ ufd[i].fd = -1;
+ }
+}
+
+struct interface *interface_get(const char *name, enum umdns_socket_type type)
+{
+ char id_buf[32];
+ snprintf(id_buf, sizeof(id_buf), "%d_%s", type, name);
+ struct interface *iface = vlist_find(&interfaces, id_buf, iface, node);
+ return iface;