X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Fentry.c;h=9e9c0dd66393fa312ef02366b6b57de6a4473de7;hb=affc2091e149b08220254a7f700a8be935d0cdde;hp=89f313eb5f6741fa24000a18a1a968afde7ad0e9;hpb=f17d2832301b0f2fcd50fdcc6fec77666178158f;p=catta diff --git a/avahi-core/entry.c b/avahi-core/entry.c index 89f313e..9e9c0dd 100644 --- a/avahi-core/entry.c +++ b/avahi-core/entry.c @@ -23,20 +23,24 @@ #include #endif -#include -#include #include -#include #include #include #include #include #include +#include + +#include +#include +#include + #include #include #include #include +#include #include "internal.h" #include "iface.h" @@ -45,6 +49,27 @@ #include "log.h" #include "util.h" #include "dns-srv-rr.h" +#include "rr-util.h" +#include "domain-util.h" + +static void transport_flags_from_domain(AvahiServer *s, AvahiPublishFlags *flags, const char *domain) { + assert(flags); + assert(domain); + + assert(!((*flags & AVAHI_PUBLISH_USE_MULTICAST) && (*flags & AVAHI_PUBLISH_USE_WIDE_AREA))); + + if (*flags & (AVAHI_PUBLISH_USE_MULTICAST|AVAHI_PUBLISH_USE_WIDE_AREA)) + return; + + if (!s->wide_area_lookup_engine || + !avahi_wide_area_has_servers(s->wide_area_lookup_engine) || + avahi_domain_ends_with(domain, AVAHI_MDNS_SUFFIX_LOCAL) || + avahi_domain_ends_with(domain, AVAHI_MDNS_SUFFIX_ADDR_IPV4) || + avahi_domain_ends_with(domain, AVAHI_MDNS_SUFFIX_ADDR_IPV6)) + *flags |= AVAHI_PUBLISH_USE_MULTICAST; + else + *flags |= AVAHI_PUBLISH_USE_WIDE_AREA; +} void avahi_entry_free(AvahiServer*s, AvahiEntry *e) { AvahiEntry *t; @@ -162,6 +187,7 @@ static AvahiEntry * server_add_internal( assert(s); assert(r); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, s->state != AVAHI_SERVER_FAILURE && s->state != AVAHI_SERVER_INVALID, AVAHI_ERR_BAD_STATE); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, AVAHI_FLAGS_VALID( @@ -170,12 +196,31 @@ static AvahiEntry * server_add_internal( AVAHI_PUBLISH_NO_PROBE| AVAHI_PUBLISH_UNIQUE| AVAHI_PUBLISH_ALLOW_MULTIPLE| - AVAHI_PUBLISH_UPDATE), AVAHI_ERR_INVALID_FLAGS); + AVAHI_PUBLISH_UPDATE| + AVAHI_PUBLISH_USE_WIDE_AREA| + AVAHI_PUBLISH_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, avahi_is_valid_domain_name(r->key->name), AVAHI_ERR_INVALID_HOST_NAME); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, r->ttl != 0, AVAHI_ERR_INVALID_TTL); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, !avahi_key_is_pattern(r->key), AVAHI_ERR_IS_PATTERN); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, avahi_record_is_valid(r), AVAHI_ERR_INVALID_RECORD); - + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, r->key->clazz == AVAHI_DNS_CLASS_IN, AVAHI_ERR_INVALID_DNS_CLASS); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, + (r->key->type != 0) && + (r->key->type != AVAHI_DNS_TYPE_ANY) && + (r->key->type != AVAHI_DNS_TYPE_OPT) && + (r->key->type != AVAHI_DNS_TYPE_TKEY) && + (r->key->type != AVAHI_DNS_TYPE_TSIG) && + (r->key->type != AVAHI_DNS_TYPE_IXFR) && + (r->key->type != AVAHI_DNS_TYPE_AXFR), AVAHI_ERR_INVALID_DNS_TYPE); + + transport_flags_from_domain(s, &flags, r->key->name); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, !s->config.disable_publishing, AVAHI_ERR_NOT_PERMITTED); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, + !g || + (g->state != AVAHI_ENTRY_GROUP_ESTABLISHED && g->state != AVAHI_ENTRY_GROUP_REGISTERING) || + (flags & AVAHI_PUBLISH_UPDATE), AVAHI_ERR_BAD_STATE); + if (flags & AVAHI_PUBLISH_UPDATE) { AvahiRecord *old_record; int is_first = 1; @@ -343,7 +388,7 @@ static AvahiEntry *server_add_ptr_internal( if (!name) name = s->host_name_fqdn; - + if (!(r = avahi_record_new_full(name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR, ttl))) { avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); return NULL; @@ -394,8 +439,14 @@ int avahi_server_add_address( AVAHI_CHECK_VALIDITY(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY(s, AVAHI_PROTO_VALID(protocol) && AVAHI_PROTO_VALID(a->proto), AVAHI_ERR_INVALID_PROTOCOL); - AVAHI_CHECK_VALIDITY(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_REVERSE|AVAHI_PUBLISH_NO_ANNOUNCE|AVAHI_PUBLISH_NO_PROBE|AVAHI_PUBLISH_UPDATE), AVAHI_ERR_INVALID_FLAGS); - AVAHI_CHECK_VALIDITY(s, !name || avahi_is_valid_domain_name(name), AVAHI_ERR_INVALID_HOST_NAME); + AVAHI_CHECK_VALIDITY(s, AVAHI_FLAGS_VALID(flags, + AVAHI_PUBLISH_NO_REVERSE| + AVAHI_PUBLISH_NO_ANNOUNCE| + AVAHI_PUBLISH_NO_PROBE| + AVAHI_PUBLISH_UPDATE| + AVAHI_PUBLISH_USE_WIDE_AREA| + AVAHI_PUBLISH_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY(s, !name || avahi_is_valid_fqdn(name), AVAHI_ERR_INVALID_HOST_NAME); /* Prepare the host naem */ @@ -406,6 +457,9 @@ int avahi_server_add_address( name = n; } + transport_flags_from_domain(s, &flags, name); + AVAHI_CHECK_VALIDITY(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + /* Create the A/AAAA record */ if (a->proto == AVAHI_PROTO_INET) { @@ -440,7 +494,7 @@ int avahi_server_add_address( if (!(flags & AVAHI_PUBLISH_NO_REVERSE)) { char reverse_n[AVAHI_DOMAIN_NAME_MAX]; - avahi_reverse_lookup_name(reverse_n, sizeof(reverse_n), a); + avahi_reverse_lookup_name(a, reverse_n, sizeof(reverse_n)); if (!(reverse = server_add_ptr_internal(s, g, interface, protocol, flags | AVAHI_PUBLISH_UNIQUE, AVAHI_DEFAULT_TTL_HOST_NAME, reverse_n, name))) { ret = avahi_server_errno(s); @@ -528,11 +582,15 @@ static int server_add_service_strlst_nocopy( AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_UPDATE), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, + AVAHI_PUBLISH_NO_COOKIE| + AVAHI_PUBLISH_UPDATE| + AVAHI_PUBLISH_USE_WIDE_AREA| + AVAHI_PUBLISH_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !host || avahi_is_valid_domain_name(host), AVAHI_ERR_INVALID_HOST_NAME); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !host || avahi_is_valid_fqdn(host), AVAHI_ERR_INVALID_HOST_NAME); if (!domain) domain = s->domain_name; @@ -540,6 +598,9 @@ static int server_add_service_strlst_nocopy( if (!host) host = s->host_name_fqdn; + transport_flags_from_domain(s, &flags, domain); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + if (!(h = avahi_normalize_name_strdup(host))) { ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); goto fail; @@ -681,7 +742,10 @@ static int server_update_service_txt_strlst_nocopy( AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, + AVAHI_PUBLISH_NO_COOKIE| + AVAHI_PUBLISH_USE_WIDE_AREA| + AVAHI_PUBLISH_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); @@ -689,6 +753,9 @@ static int server_update_service_txt_strlst_nocopy( if (!domain) domain = s->domain_name; + transport_flags_from_domain(s, &flags, domain); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0) { avahi_server_set_errno(s, ret); goto fail; @@ -767,7 +834,7 @@ int avahi_server_add_service_subtype( AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, 0), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_USE_MULTICAST|AVAHI_PUBLISH_USE_WIDE_AREA), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); @@ -776,6 +843,9 @@ int avahi_server_add_service_subtype( if (!domain) domain = s->domain_name; + transport_flags_from_domain(s, &flags, domain); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + if ((ret = avahi_service_name_join(svc_name, sizeof(svc_name), name, type, domain)) < 0 || (ret = avahi_service_name_join(ptr_name, sizeof(ptr_name), NULL, subtype, domain)) < 0) { avahi_server_set_errno(s, ret); @@ -812,7 +882,7 @@ static void hexstring(char *s, size_t sl, const void *p, size_t pl) { *s = 0; } -static AvahiEntry * server_add_dns_server_name( +static AvahiEntry *server_add_dns_server_name( AvahiServer *s, AvahiSEntryGroup *g, AvahiIfIndex interface, @@ -831,15 +901,18 @@ static AvahiEntry * server_add_dns_server_name( assert(s); assert(name); - AVAHI_CHECK_VALIDITY_RETURN_NULL(s, AVAHI_FLAGS_VALID(flags, 0), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_USE_WIDE_AREA|AVAHI_PUBLISH_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE, AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, port != 0, AVAHI_ERR_INVALID_PORT); - AVAHI_CHECK_VALIDITY_RETURN_NULL(s, avahi_is_valid_domain_name(name), AVAHI_ERR_INVALID_HOST_NAME); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, avahi_is_valid_fqdn(name), AVAHI_ERR_INVALID_HOST_NAME); AVAHI_CHECK_VALIDITY_RETURN_NULL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); if (!domain) domain = s->domain_name; + transport_flags_from_domain(s, &flags, domain); + AVAHI_CHECK_VALIDITY_RETURN_NULL(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + if (!(n = avahi_normalize_name_strdup(name))) { avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY); return NULL; @@ -885,7 +958,7 @@ int avahi_server_add_dns_server_address( AVAHI_CHECK_VALIDITY(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); AVAHI_CHECK_VALIDITY(s, AVAHI_PROTO_VALID(protocol) && AVAHI_PROTO_VALID(address->proto), AVAHI_ERR_INVALID_PROTOCOL); - AVAHI_CHECK_VALIDITY(s, AVAHI_FLAGS_VALID(flags, 0), AVAHI_ERR_INVALID_FLAGS); + AVAHI_CHECK_VALIDITY(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_USE_MULTICAST|AVAHI_PUBLISH_USE_WIDE_AREA), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY(s, type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE, AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY(s, port != 0, AVAHI_ERR_INVALID_PORT); AVAHI_CHECK_VALIDITY(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); @@ -893,6 +966,9 @@ int avahi_server_add_dns_server_address( if (!domain) domain = s->domain_name; + transport_flags_from_domain(s, &flags, domain); + AVAHI_CHECK_VALIDITY(s, flags & AVAHI_PUBLISH_USE_MULTICAST, AVAHI_ERR_NOT_SUPPORTED); + if (address->proto == AVAHI_PROTO_INET) { hexstring(h, sizeof(h), &address->data, sizeof(AvahiIPv4Address)); snprintf(n, sizeof(n), "ip-%s.%s", h, domain); @@ -1010,18 +1086,17 @@ static void entry_group_commit_real(AvahiSEntryGroup *g) { avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_REGISTERING); - if (!g->dead) { - avahi_announce_group(g->server, g); - avahi_s_entry_group_check_probed(g, 0); - } + if (g->dead) + return; + + avahi_announce_group(g->server, g); + avahi_s_entry_group_check_probed(g, 0); } -static void entry_group_register_time_event_callback(AvahiTimeEvent *e, void* userdata) { +static void entry_group_register_time_event_callback(AVAHI_GCC_UNUSED AvahiTimeEvent *e, void* userdata) { AvahiSEntryGroup *g = userdata; assert(g); -/* avahi_log_debug("Holdoff passed, waking up and going on."); */ - avahi_time_event_free(g->register_time_event); g->register_time_event = NULL; @@ -1038,6 +1113,9 @@ int avahi_s_entry_group_commit(AvahiSEntryGroup *g) { if (g->state != AVAHI_ENTRY_GROUP_UNCOMMITED && g->state != AVAHI_ENTRY_GROUP_COLLISION) return avahi_server_set_errno(g->server, AVAHI_ERR_BAD_STATE); + if (avahi_s_entry_group_is_empty(g)) + return avahi_server_set_errno(g->server, AVAHI_ERR_IS_EMPTY); + g->n_register_try++; avahi_timeval_add(&g->register_time, @@ -1048,12 +1126,10 @@ int avahi_s_entry_group_commit(AvahiSEntryGroup *g) { gettimeofday(&now, NULL); if (avahi_timeval_compare(&g->register_time, &now) <= 0) { - /* Holdoff time passed, so let's start probing */ -/* avahi_log_debug("Holdoff passed, directly going on."); */ + /* Holdoff time passed, so let's start probing */ entry_group_commit_real(g); } else { -/* avahi_log_debug("Holdoff not passed, sleeping."); */ /* Holdoff time has not yet passed, so let's wait */ assert(!g->register_time_event);