#include <net/if.h>
#include <stdio.h>
+#include <avahi-common/error.h>
#include <avahi-common/malloc.h>
#include "iface.h"
assert(m);
assert(a);
- if (avahi_interface_address_relevant(a) &&
+ if (a->interface->announcing &&
+ m->list == LIST_DONE &&
+ avahi_interface_address_relevant(a) &&
!remove_rrs &&
m->server->config.publish_addresses &&
(m->server->state == AVAHI_SERVER_RUNNING ||
return;
if (avahi_s_entry_group_is_empty(a->entry_group)) {
+ char t[64];
+ avahi_address_snprint(t, sizeof(t), &a->address);
+
+ avahi_log_info("Registering new address %s on %s.", t, a->interface->hardware->name);
if (avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, a->interface->protocol, 0, NULL, &a->address) < 0) {
avahi_log_warn(__FILE__": avahi_server_add_address() failed: %s", avahi_strerror(m->server->error));
/* Clear the entry group */
if (a->entry_group && !avahi_s_entry_group_is_empty(a->entry_group)) {
+ char t[64];
+ avahi_address_snprint(t, sizeof(t), &a->address);
if (avahi_s_entry_group_get_state(a->entry_group) == AVAHI_ENTRY_GROUP_REGISTERING)
avahi_server_decrease_host_rr_pending(m->server);
+
+ avahi_log_info("Withdrawing address %s on %s.", t, a->interface->hardware->name);
avahi_s_entry_group_reset(a->entry_group);
}
for (i = hw->interfaces; i; i = i->by_hardware_next)
update_interface_rr(m, i, remove_rrs);
- if (!remove_rrs &&
+ if (m->list == LIST_DONE &&
+ !remove_rrs &&
m->server->config.publish_workstation &&
(m->server->state == AVAHI_SERVER_RUNNING ||
m->server->state == AVAHI_SERVER_REGISTERING)) {
b = avahi_interface_relevant(i);
- if (b && !i->announcing) {
- avahi_log_debug("New relevant interface %s.%i (#%i)", i->hardware->name, i->protocol, i->hardware->index);
+ if (m->list == LIST_DONE && b && !i->announcing) {
+ avahi_log_info("New relevant interface %s.%i.", i->hardware->name, i->protocol);
if (i->protocol == AVAHI_PROTO_INET)
avahi_mdns_mcast_join_ipv4(m->server->fd_ipv4, i->hardware->index);
avahi_announce_interface(m->server, i);
avahi_browser_new_interface(m->server, i);
} else if (!b && i->announcing) {
- avahi_log_debug("Interface %s.%i no longer relevant", i->hardware->name, i->protocol);
+ avahi_log_info("Interface %s.%i no longer relevant.", i->hardware->name, i->protocol);
if (i->protocol == AVAHI_PROTO_INET)
avahi_mdns_mcast_leave_ipv4(m->server->fd_ipv4, i->hardware->index);
check_interface_relevant(m, i);
}
+static void check_all_interfaces_relevant(AvahiInterfaceMonitor *m) {
+ AvahiInterface *i;
+ assert(m);
+
+ for (i = m->interfaces; i; i = i->interface_next)
+ check_interface_relevant(m, i);
+}
+
static void netlink_callback(AvahiNetlink *nl, struct nlmsghdr *n, void* userdata) {
AvahiInterfaceMonitor *m = userdata;
a = RTA_NEXT(a, l);
}
- update_hw_interface_rr(m, hw, 0);
check_hw_interface_relevant(m, hw);
+ update_hw_interface_rr(m, hw, 0);
} else if (n->nlmsg_type == RTM_DELLINK) {
struct ifinfomsg *ifinfomsg = NLMSG_DATA(n);
if (!(hw = avahi_interface_monitor_get_hw_interface(m, (AvahiIfIndex) ifinfomsg->ifi_index)))
return;
- update_hw_interface_rr(m, hw, 1);
free_hw_interface(m, hw, 0);
} else if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
addr->flags = ifaddrmsg->ifa_flags;
addr->scope = ifaddrmsg->ifa_scope;
addr->prefix_len = ifaddrmsg->ifa_prefixlen;
-
- update_address_rr(m, addr, 0);
} else {
AvahiInterfaceAddress *addr;
if (!(addr = get_address(m, i, &raddr)))
return;
- update_address_rr(m, addr, 1);
free_address(m, addr);
}
check_interface_relevant(m, i);
+ update_interface_rr(m, i, 0);
} else if (n->nlmsg_type == NLMSG_DONE) {
if (m->list == LIST_IFACE) {
- m->list = LIST_DONE;
- if (netlink_list_items(m->netlink, RTM_GETADDR, &m->query_addr_seq) < 0)
+ if (netlink_list_items(m->netlink, RTM_GETADDR, &m->query_addr_seq) < 0) {
avahi_log_warn("NETLINK: Failed to list addrs: %s", strerror(errno));
- else
+ m->list = LIST_DONE;
+ } else
m->list = LIST_ADDR;
- } else {
+
+ } else
+ /* We're through */
m->list = LIST_DONE;
- avahi_log_debug("Network interface enumeration completed");
+
+ if (m->list == LIST_DONE) {
+ check_all_interfaces_relevant(m);
+ avahi_update_host_rrs(m, 0);
+ avahi_log_info("Network interface enumeration completed.");
}
} else if (n->nlmsg_type == NLMSG_ERROR && (n->nlmsg_seq == m->query_link_seq || n->nlmsg_seq == m->query_addr_seq)) {
relevant_address;
}
-int avahi_interface_address_relevant(AvahiInterfaceAddress *a) {
+int avahi_interface_address_relevant(AvahiInterfaceAddress *a) {
+ AvahiInterfaceAddress *b;
assert(a);
- return a->scope == RT_SCOPE_UNIVERSE;
-}
+ /* Publish public IP addresses */
+ if (a->scope == RT_SCOPE_UNIVERSE ||
+ a->scope == RT_SCOPE_SITE)
+ return 1;
+ if (a->scope == RT_SCOPE_LINK) {
+
+ /* Publish link local IP addresses if they are the only ones on the link */
+ for (b = a->interface->addresses; b; b = b->address_next) {
+ if (b == a)
+ continue;
+
+ if (b->scope == RT_SCOPE_UNIVERSE ||
+ b->scope == RT_SCOPE_SITE)
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
int avahi_interface_match(AvahiInterface *i, AvahiIfIndex idx, AvahiProtocol protocol) {
assert(i);
return 0;
}
+
+int avahi_interface_has_address(AvahiInterfaceMonitor *m, AvahiIfIndex iface, const AvahiAddress *a) {
+ AvahiInterface *i;
+ AvahiInterfaceAddress *j;
+
+ assert(m);
+ assert(iface != AVAHI_IF_UNSPEC);
+ assert(a);
+
+ if (!(i = avahi_interface_monitor_get_interface(m, iface, a->family)))
+ return 0;
+
+ for (j = i->addresses; j; j = j->address_next)
+ if (avahi_address_cmp(a, &j->address) == 0)
+ return 1;
+
+ return 0;
+}