X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Fserver.c;h=c74628757e24854e78dfd1e1d72b2cdb0fb54424;hb=5867849876e19996fd05a0d4917cb739904519c1;hp=66cc70592699286d40120494f45b44263729989e;hpb=b30495599b156ac933d091bb0cc1ed669c7887b5;p=catta diff --git a/avahi-core/server.c b/avahi-core/server.c index 66cc705..c746287 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -813,7 +814,7 @@ static void reflect_legacy_unicast_query_packet(AvahiServer *s, AvahiDnsPacket * assert(i); assert(a); assert(port > 0); - assert(i->protocol == a->family); + assert(i->protocol == a->proto); if (!s->config.enable_reflector) return; @@ -901,7 +902,7 @@ static int is_mdns_mcast_address(const AvahiAddress *a) { AvahiAddress b; assert(a); - avahi_address_parse(a->family == AVAHI_PROTO_INET ? AVAHI_IPV4_MCAST_GROUP : AVAHI_IPV6_MCAST_GROUP, a->family, &b); + avahi_address_parse(a->proto == AVAHI_PROTO_INET ? AVAHI_IPV4_MCAST_GROUP : AVAHI_IPV6_MCAST_GROUP, a->proto, &b); return avahi_address_cmp(a, &b) == 0; } @@ -929,7 +930,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock assert(dest); assert(iface > 0); - if (!(i = avahi_interface_monitor_get_interface(s->monitor, iface, sa->sa_family)) || + if (!(i = avahi_interface_monitor_get_interface(s->monitor, iface, avahi_af_to_proto(sa->sa_family))) || !avahi_interface_relevant(i)) { avahi_log_warn("Recieved packet from invalid interface."); return; @@ -1023,7 +1024,7 @@ static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, co assert(sa); assert(iface > 0); - if (!(i = avahi_interface_monitor_get_interface(s->monitor, iface, sa->sa_family)) || + if (!(i = avahi_interface_monitor_get_interface(s->monitor, iface, avahi_af_to_proto(sa->sa_family))) || !avahi_interface_relevant(i)) { avahi_log_warn("Recieved packet from invalid interface."); return; @@ -1048,7 +1049,7 @@ static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, co return; } - if (!(j = avahi_interface_monitor_get_interface(s->monitor, slot->interface, slot->address.family)) || + if (!(j = avahi_interface_monitor_get_interface(s->monitor, slot->interface, slot->address.proto)) || !avahi_interface_relevant(j)) return; @@ -1077,27 +1078,27 @@ static void socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events, void *us if (events & AVAHI_WATCH_IN) { if (fd == s->fd_ipv4) { - dest.family = AVAHI_PROTO_INET; + dest.proto = AVAHI_PROTO_INET; if ((p = avahi_recv_dns_packet_ipv4(s->fd_ipv4, &sa, &dest.data.ipv4, &iface, &ttl))) { dispatch_packet(s, p, (struct sockaddr*) &sa, &dest, iface, ttl); avahi_dns_packet_free(p); } } else if (fd == s->fd_ipv6) { - dest.family = AVAHI_PROTO_INET6; + dest.proto = AVAHI_PROTO_INET6; if ((p = avahi_recv_dns_packet_ipv6(s->fd_ipv6, &sa6, &dest.data.ipv6, &iface, &ttl))) { dispatch_packet(s, p, (struct sockaddr*) &sa6, &dest, iface, ttl); avahi_dns_packet_free(p); } } else if (fd == s->fd_legacy_unicast_ipv4) { - dest.family = AVAHI_PROTO_INET; + dest.proto = AVAHI_PROTO_INET; if ((p = avahi_recv_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, &sa, &dest.data.ipv4, &iface, &ttl))) { dispatch_legacy_unicast_packet(s, p, (struct sockaddr*) &sa, iface, ttl); avahi_dns_packet_free(p); } } else if (fd == s->fd_legacy_unicast_ipv6) { - dest.family = AVAHI_PROTO_INET6; + dest.proto = AVAHI_PROTO_INET6; if ((p = avahi_recv_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, &sa6, &dest.data.ipv6, &iface, &ttl))) { dispatch_legacy_unicast_packet(s, p, (struct sockaddr*) &sa6, iface, ttl); @@ -1411,6 +1412,10 @@ AvahiServer *avahi_server_new(const AvahiPoll *poll_api, const AvahiServerConfig s->legacy_unicast_reflect_slots = NULL; s->legacy_unicast_reflect_id = 0; + + do { + s->local_service_cookie = (uint32_t) rand() * (uint32_t) rand(); + } while (s->local_service_cookie == AVAHI_SERVICE_COOKIE_INVALID); /* Get host name */ s->host_name = s->config.host_name ? avahi_normalize_name(s->config.host_name) : avahi_get_host_name(); @@ -1681,7 +1686,7 @@ int avahi_server_add_address( goto fail; } - if (a->family == AVAHI_PROTO_INET) { + if (a->proto == AVAHI_PROTO_INET) { char *reverse; AvahiRecord *r; @@ -1709,7 +1714,7 @@ int avahi_server_add_address( char *reverse; AvahiRecord *r; - assert(a->family == AVAHI_PROTO_INET6); + assert(a->proto == AVAHI_PROTO_INET6); if (!(r = avahi_record_new_full(name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA, AVAHI_DEFAULT_TTL_HOST_NAME))) { ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); @@ -1849,6 +1854,22 @@ static void escape_service_name(char *d, size_t size, const char *s) { *(d++) = 0; } +static AvahiStringList *add_magic_cookie( + AvahiServer *s, + AvahiStringList *strlst) { + + assert(s); + + if (!s->config.add_service_cookie) + return strlst; + + if (avahi_string_list_find(strlst, AVAHI_SERVICE_COOKIE)) + /* This string list already contains a magic cookie */ + return strlst; + + return avahi_string_list_add_printf(strlst, AVAHI_SERVICE_COOKIE"=%u", s->local_service_cookie); +} + static int server_add_service_strlst_nocopy( AvahiServer *s, AvahiSEntryGroup *g, @@ -1919,6 +1940,8 @@ static int server_add_service_strlst_nocopy( if (ret < 0) goto fail; + strlst = add_magic_cookie(s, strlst); + ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst); strlst = NULL; @@ -2041,7 +2064,7 @@ int avahi_server_add_dns_server_address( assert(s); assert(address); assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE); - assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6); + assert(address->proto == AVAHI_PROTO_INET || address->proto == AVAHI_PROTO_INET6); if (port == 0) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PORT); @@ -2049,7 +2072,7 @@ int avahi_server_add_dns_server_address( if (domain && !avahi_is_valid_domain_name(domain)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); - if (address->family == AVAHI_PROTO_INET) { + if (address->proto == AVAHI_PROTO_INET) { hexstring(n+3, sizeof(n)-3, &address->data, 4); r = avahi_record_new_full(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, AVAHI_DEFAULT_TTL_HOST_NAME); r->data.a.address = address->data.ipv4; @@ -2389,6 +2412,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) { c->use_iff_running = 0; c->enable_reflector = 0; c->reflect_ipv = 0; + c->add_service_cookie = 1; return c; } @@ -2435,3 +2459,74 @@ int avahi_server_set_errno(AvahiServer *s, int error) { return s->error = error; } +uint32_t avahi_server_get_local_service_cookie(AvahiServer *s) { + assert(s); + + return s->local_service_cookie; +} + +int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char*domain) { + AvahiKey *key = NULL; + char *d, *t; + char ename[64], n[256]; + int ret; + AvahiEntry *e; + + assert(s); + assert(name); + assert(type); + assert(domain); + + if (!avahi_is_valid_service_name(name)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME); + + if (!avahi_is_valid_service_type(type)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE); + + if (domain && !avahi_is_valid_domain_name(domain)) + return avahi_server_set_errno(s, AVAHI_ERR_INVALID_DOMAIN_NAME); + + escape_service_name(ename, sizeof(ename), name); + + if (!(d = avahi_normalize_name(domain)) || + !(t = avahi_normalize_name(type))) { + ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); + goto fail; + } + snprintf(n, sizeof(n), "%s.%s.%s", ename, t, d); + + if (!(key = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV))) { + ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); + goto fail; + } + + ret = 0; + + for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next) { + + if ((e->interface == interface || e->interface <= 0 || interface <= 0) && + (e->protocol == protocol || e->protocol == AVAHI_PROTO_UNSPEC || protocol == AVAHI_PROTO_UNSPEC)) { + ret = 1; + break; + } + } + + avahi_key_unref(key); + + avahi_free(d); + avahi_free(t); + + return ret; + +fail: + if (d) + avahi_free(d); + + if (t) + avahi_free(t); + + if (key) + avahi_key_unref(key); + + return ret; +}