diff options
| author | Lennart Poettering <lennart@poettering.net> | 2005-10-25 22:20:37 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2005-10-25 22:20:37 +0000 | 
| commit | c3575017e2137ef664e4735bd6f9ff1209653ef3 (patch) | |
| tree | 975af5275fbba0ef9344671adf941f2a60f1968e | |
| parent | d2d2f82263bd1007b847324ec27236097bde1609 (diff) | |
* replace AF_UNSPEC by AVAHI_PROTO_UNSPEC in client-test.c
* remove some functions from the public API in avahi-common/{domain,address}.[ch] and move them into avahi-core/{domain-util,add-util}.[ch]
* properly generate CNAME responses
* add some more comments to server.c
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@871 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
| -rw-r--r-- | avahi-client/client-test.c | 4 | ||||
| -rw-r--r-- | avahi-common/address.c | 47 | ||||
| -rw-r--r-- | avahi-common/address.h | 18 | ||||
| -rw-r--r-- | avahi-common/domain-test.c | 5 | ||||
| -rw-r--r-- | avahi-common/domain.c | 67 | ||||
| -rw-r--r-- | avahi-common/domain.h | 20 | ||||
| -rw-r--r-- | avahi-core/Makefile.am | 7 | ||||
| -rw-r--r-- | avahi-core/addr-util.c | 79 | ||||
| -rw-r--r-- | avahi-core/addr-util.h | 45 | ||||
| -rw-r--r-- | avahi-core/avahi-test.c | 11 | ||||
| -rw-r--r-- | avahi-core/browse.c | 2 | ||||
| -rw-r--r-- | avahi-core/domain-util.c | 101 | ||||
| -rw-r--r-- | avahi-core/domain-util.h | 47 | ||||
| -rw-r--r-- | avahi-core/rr.c | 1 | ||||
| -rw-r--r-- | avahi-core/rr.h | 2 | ||||
| -rw-r--r-- | avahi-core/server.c | 103 | ||||
| -rw-r--r-- | avahi-core/socket.c | 1 | ||||
| -rw-r--r-- | avahi-core/update-test.c | 1 | ||||
| -rw-r--r-- | avahi-core/wide-area.c | 1 | ||||
| -rw-r--r-- | docs/TODO | 5 | 
20 files changed, 369 insertions, 198 deletions
diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c index f9913e6..5c9c092 100644 --- a/avahi-client/client-test.c +++ b/avahi-client/client-test.c @@ -286,7 +286,7 @@ int main (int argc, char *argv[]) {      else          printf ("Successfully created hostname resolver object\n"); -    aar = avahi_address_parse ("224.0.0.251", AF_UNSPEC, aar); +    aar = avahi_address_parse ("224.0.0.251", AVAHI_PROTO_UNSPEC, aar);      if (aar == NULL) {          printf ("failed to create address object\n");      } else { @@ -299,10 +299,8 @@ int main (int argc, char *argv[]) {              printf ("*** success, added address\n");              avahi_entry_group_commit (group2);          } -              } -      avahi_elapse_time(&tv, 8000, 0);      poll_api->timeout_new(poll_api, &tv, test_entry_group_reset, group);      avahi_elapse_time(&tv, 15000, 0); diff --git a/avahi-common/address.c b/avahi-common/address.c index d02d997..56b4058 100644 --- a/avahi-common/address.c +++ b/avahi-common/address.c @@ -34,7 +34,7 @@  #include "address.h"  #include "malloc.h" -size_t avahi_address_get_size(const AvahiAddress *a) { +static size_t address_get_size(const AvahiAddress *a) {      assert(a);      if (a->proto == AVAHI_PROTO_INET) @@ -52,7 +52,7 @@ int avahi_address_cmp(const AvahiAddress *a, const AvahiAddress *b) {      if (a->proto != b->proto)          return -1; -    return memcmp(a->data.data, b->data.data, avahi_address_get_size(a)); +    return memcmp(a->data.data, b->data.data, address_get_size(a));  }  char *avahi_address_snprint(char *s, size_t length, const AvahiAddress *a) { @@ -126,49 +126,6 @@ AvahiAddress *avahi_address_parse(const char *s, AvahiProtocol proto, AvahiAddre      return ret_addr;  } -AvahiAddress *avahi_address_from_sockaddr(const struct sockaddr* sa, AvahiAddress *ret_addr) { -    assert(sa); -    assert(ret_addr); - -    assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); - -    ret_addr->proto = avahi_af_to_proto(sa->sa_family); - -    if (sa->sa_family == AF_INET) -        memcpy(&ret_addr->data.ipv4, &((const struct sockaddr_in*) sa)->sin_addr, sizeof(ret_addr->data.ipv4)); -    else -        memcpy(&ret_addr->data.ipv6, &((const struct sockaddr_in6*) sa)->sin6_addr, sizeof(ret_addr->data.ipv6)); - -    return ret_addr; -} - -uint16_t avahi_port_from_sockaddr(const struct sockaddr* sa) { -    assert(sa); - -    assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); - -    if (sa->sa_family == AF_INET) -        return ntohs(((const struct sockaddr_in*) sa)->sin_port); -    else -        return ntohs(((const struct sockaddr_in6*) sa)->sin6_port); -} - -int avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a) { - -    static const uint8_t ipv4_in_ipv6[] = { -        0x00, 0x00, 0x00, 0x00, -        0x00, 0x00, 0x00, 0x00, -        0xFF, 0xFF, 0xFF, 0xFF -    }; -     -    assert(a); - -    if (a->proto != AVAHI_PROTO_INET6) -        return 0; - -    return memcmp(a->data.ipv6.address, ipv4_in_ipv6, sizeof(ipv4_in_ipv6)) == 0; -} -  int avahi_proto_to_af(AvahiProtocol proto) {      if (proto == AVAHI_PROTO_INET)          return AF_INET; diff --git a/avahi-common/address.h b/avahi-common/address.h index c383250..95eb392 100644 --- a/avahi-common/address.h +++ b/avahi-common/address.h @@ -24,8 +24,8 @@  /** \file address.h Definitions and functions to manipulate IP addresses. */ -#include <sys/socket.h>  #include <inttypes.h> +#include <sys/types.h>  #include <avahi-common/cdecl.h> @@ -65,7 +65,6 @@ typedef struct {      uint32_t address; /**< Address data in network byte order. */  } AvahiIPv4Address; -  /** An IPv6 address */  typedef struct {      uint8_t address[16]; /**< Address data */ @@ -78,13 +77,10 @@ typedef struct {      union {          AvahiIPv6Address ipv6;  /** Address when IPv6 */          AvahiIPv4Address ipv4;  /** Address when IPv4 */ -        uint8_t data[1];         /** Type independant data field */ +        uint8_t data[1];        /** Type independant data field */      } data;  } AvahiAddress; -/** Return the address data size of the specified address. (4 for IPv4, 16 for IPv6) */ -size_t avahi_address_get_size(const AvahiAddress *a); -  /** Compare two addresses. Returns 0 when equal, a negative value when a < b, a positive value when a > b. */  int avahi_address_cmp(const AvahiAddress *a, const AvahiAddress *b); @@ -96,19 +92,9 @@ char *avahi_address_snprint(char *ret_s, size_t length, const AvahiAddress *a);   * family detection. */  AvahiAddress *avahi_address_parse(const char *s, AvahiProtocol af, AvahiAddress *ret_addr); -/** Make an address structture of a sockaddr structure */ -AvahiAddress *avahi_address_from_sockaddr(const struct sockaddr* sa, AvahiAddress *ret_addr); - -/** Return the port number of a sockaddr structure (either IPv4 or IPv6) */ -uint16_t avahi_port_from_sockaddr(const struct sockaddr* sa); -  /** Generate the DNS reverse lookup name for an IPv4 or IPv6 address. */  char* avahi_reverse_lookup_name(char *ret_s, size_t length, const AvahiAddress *a); -/** Check whether the specified IPv6 address is in fact an - * encapsulated IPv4 address, returns 1 if yes, 0 otherwise */ -int avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a); -  /** Map AVAHI_PROTO_xxx constants to Unix AF_xxx constants */  int avahi_proto_to_af(AvahiProtocol proto); diff --git a/avahi-common/domain-test.c b/avahi-common/domain-test.c index 9926a1f..b765532 100644 --- a/avahi-common/domain-test.c +++ b/avahi-common/domain-test.c @@ -37,9 +37,6 @@ int main(int argc, char *argv[]) {      size_t size;      char name[64], type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX]; -    printf("host name: %s\n", s = avahi_get_host_name_strdup()); -    avahi_free(s); -      printf("%s\n", s = avahi_normalize_name_strdup("foo.foo\\046."));      avahi_free(s); @@ -82,8 +79,6 @@ int main(int argc, char *argv[]) {      p = r;      printf("unescaped: <%s>\n", avahi_unescape_label(&p, t, sizeof(t))); -    assert(avahi_domain_ends_with("foo.bar.\\065\\\\\\.aaaa", "\\065\\\\\\.aaaa")); -      assert(avahi_is_valid_service_type_generic("_foo._bar._waldo"));      assert(!avahi_is_valid_service_type_strict("_foo._bar._waldo"));      assert(!avahi_is_valid_service_subtype("_foo._bar._waldo")); diff --git a/avahi-common/domain.c b/avahi-common/domain.c index 7d954de..4927086 100644 --- a/avahi-common/domain.c +++ b/avahi-common/domain.c @@ -37,31 +37,6 @@  #include "malloc.h"  #include "error.h" -char *avahi_get_host_name(char *ret_s, size_t size) { -#ifdef HOST_NAME_MAX -    char t[HOST_NAME_MAX]; -#else -    char t[256]; -#endif -     -    assert(ret_s); -    assert(size > 0); -     -    gethostname(t, sizeof(t)); -    t[sizeof(t)-1] = 0; -     -    return avahi_normalize_name(t, ret_s, size); -} - -char *avahi_get_host_name_strdup(void) { -    char t[AVAHI_DOMAIN_NAME_MAX]; - -    if (!(avahi_get_host_name(t, sizeof(t)))) -        return NULL; - -    return avahi_strdup(t); -} -  /* Read the first label from string *name, unescape "\" and write it to dest */  char *avahi_unescape_label(const char **name, char *dest, size_t size) {      unsigned i = 0; @@ -273,30 +248,6 @@ int avahi_domain_equal(const char *a, const char *b) {      return 1;  } -int avahi_binary_domain_cmp(const char *a, const char *b) { -    assert(a); -    assert(b); - -    if (a == b) -        return 0; - -    for (;;) { -        char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *p; -        int r; - -        p = avahi_unescape_label(&a, ca, sizeof(ca)); -        assert(p); -        p = avahi_unescape_label(&b, cb, sizeof(cb)); -        assert(p); - -        if ((r = strcmp(ca, cb))) -            return r; -         -        if (!*a && !*b) -            return 0; -    } -} -  int avahi_is_valid_service_type_generic(const char *t) {      assert(t); @@ -483,24 +434,6 @@ unsigned avahi_domain_hash(const char *s) {      return hash;  } -int avahi_domain_ends_with(const char *domain, const char *suffix) { -    assert(domain); -    assert(suffix); - -    for (;;) { -        char dummy[AVAHI_LABEL_MAX], *r; - -        if (*domain == 0) -            return 0; -         -        if (avahi_domain_equal(domain, suffix)) -            return 1; - -        r = avahi_unescape_label(&domain, dummy, sizeof(dummy)); -        assert(r); -    }  -} -  int avahi_service_name_join(char *p, size_t size, const char *name, const char *type, const char *domain) {      char escaped_name[AVAHI_LABEL_MAX*4];      char normalized_type[AVAHI_DOMAIN_NAME_MAX]; diff --git a/avahi-common/domain.h b/avahi-common/domain.h index 4e3aa55..e5869ce 100644 --- a/avahi-common/domain.h +++ b/avahi-common/domain.h @@ -44,7 +44,7 @@ AVAHI_C_DECL_BEGIN   * the string brings us to 1014. */  #define AVAHI_DOMAIN_NAME_MAX 1014 -/** Maxium size of an unescaped label */ +/** Maximum size of an unescaped label */  #define AVAHI_LABEL_MAX 64  /** Normalize a domain name into canonical form. This drops trailing @@ -56,18 +56,9 @@ char *avahi_normalize_name(const char *s, char *ret_s, size_t size);   * result! */  char *avahi_normalize_name_strdup(const char *s); -/** Return the local host name. */ -char *avahi_get_host_name(char *ret_s, size_t size);  - -/** Return the local host name. avahi_free() the result! */ -char *avahi_get_host_name_strdup(void); -  /** Return 1 when the specified domain names are equal, 0 otherwise */  int avahi_domain_equal(const char *a, const char *b); -/** Do a binary comparison of to specified domain names, return -1, 0, or 1, depending on the order. */ -int avahi_binary_domain_cmp(const char *a, const char *b); -  /** Read the first label from the textual domain name *name, unescape   * it and write it to dest, *name is changed to point to the next label*/  char *avahi_unescape_label(const char **name, char *dest, size_t size); @@ -75,6 +66,9 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size);  /** Escape the domain name in *src and write it to *ret_name */  char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, size_t *ret_size); +/** Return a pointer to the type section of a subtype i.e. _foo._sub._bar._tcp => _bar._tcp */ +const char *avahi_get_type_from_subtype(const char *t); +  /** Return 1 when the specified string contains a valid generic   * service type (i.e. a series of words starting with "_"), 0   * otherwise */ @@ -88,9 +82,6 @@ int avahi_is_valid_service_type_strict(const char *t);  /** Return 1 when the specified string contains a valid service subtype, 0 otherwise */  int avahi_is_valid_service_subtype(const char *t); -/** Return a pointer to the type section of a subtype i.e. _foo._sub._bar._tcp => _bar._tcp */ -const char *avahi_get_type_from_subtype(const char *t); -  /** Return 1 when the specified string contains a valid domain name, 0 otherwise */  int avahi_is_valid_domain_name(const char *t); @@ -103,9 +94,6 @@ int avahi_is_valid_host_name(const char *t);  /** Return some kind of hash value for the domain, useful for using domains as hash table keys. */  unsigned avahi_domain_hash(const char *name); -/** Returns 1 if the the end labels of domain are eqal to suffix */ -int avahi_domain_ends_with(const char *domain, const char *suffix); -  /** Construct a valid complete service name from a name, a type and a domain */  int avahi_service_name_join(char *p, size_t size, const char *name, const char *type, const char *domain); diff --git a/avahi-core/Makefile.am b/avahi-core/Makefile.am index 9516615..cc93265 100644 --- a/avahi-core/Makefile.am +++ b/avahi-core/Makefile.am @@ -76,7 +76,9 @@ libavahi_core_la_SOURCES = \  	hashmap.c hashmap.h \  	wide-area.c wide-area.h \  	multicast-lookup.c multicast-lookup.h \ -	querier.c querier.h +	querier.c querier.h \ +	addr-util.h addr-util.c \ +	domain-util.h domain-util.c  if HAVE_NETLINK  libavahi_core_la_SOURCES += \ @@ -130,7 +132,8 @@ dns_test_SOURCES = \  	log.c log.h \  	util.c util.h \  	rr.c rr.h \ -	hashmap.c hashmap.h +	hashmap.c hashmap.h \ +	domain-util.c domain-util.h  dns_test_CFLAGS = $(AM_CFLAGS)  dns_test_LDADD = $(AM_LDADD) ../avahi-common/libavahi-common.la diff --git a/avahi-core/addr-util.c b/avahi-core/addr-util.c new file mode 100644 index 0000000..7b9bb03 --- /dev/null +++ b/avahi-core/addr-util.c @@ -0,0 +1,79 @@ +/* $Id$ */ + +/*** +  This file is part of avahi. +  +  avahi is free software; you can redistribute it and/or modify it +  under the terms of the GNU Lesser General Public License as +  published by the Free Software Foundation; either version 2.1 of the +  License, or (at your option) any later version. +  +  avahi is distributed in the hope that it will be useful, but WITHOUT +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General +  Public License for more details. +  +  You should have received a copy of the GNU Lesser General Public +  License along with avahi; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <netinet/in.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <string.h> +#include <assert.h> + +#include "addr-util.h" + +AvahiAddress *avahi_address_from_sockaddr(const struct sockaddr* sa, AvahiAddress *ret_addr) { +    assert(sa); +    assert(ret_addr); + +    assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); + +    ret_addr->proto = avahi_af_to_proto(sa->sa_family); + +    if (sa->sa_family == AF_INET) +        memcpy(&ret_addr->data.ipv4, &((const struct sockaddr_in*) sa)->sin_addr, sizeof(ret_addr->data.ipv4)); +    else +        memcpy(&ret_addr->data.ipv6, &((const struct sockaddr_in6*) sa)->sin6_addr, sizeof(ret_addr->data.ipv6)); + +    return ret_addr; +} + +uint16_t avahi_port_from_sockaddr(const struct sockaddr* sa) { +    assert(sa); + +    assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); + +    if (sa->sa_family == AF_INET) +        return ntohs(((const struct sockaddr_in*) sa)->sin_port); +    else +        return ntohs(((const struct sockaddr_in6*) sa)->sin6_port); +} + +int avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a) { + +    static const uint8_t ipv4_in_ipv6[] = { +        0x00, 0x00, 0x00, 0x00, +        0x00, 0x00, 0x00, 0x00, +        0xFF, 0xFF, 0xFF, 0xFF +    }; +     +    assert(a); + +    if (a->proto != AVAHI_PROTO_INET6) +        return 0; + +    return memcmp(a->data.ipv6.address, ipv4_in_ipv6, sizeof(ipv4_in_ipv6)) == 0; +} + + + diff --git a/avahi-core/addr-util.h b/avahi-core/addr-util.h new file mode 100644 index 0000000..4134de1 --- /dev/null +++ b/avahi-core/addr-util.h @@ -0,0 +1,45 @@ +#ifndef fooaddrutilhfoo +#define fooaddrutilhfoo + +/* $Id$ */ + +/*** +  This file is part of avahi. +  +  avahi is free software; you can redistribute it and/or modify it +  under the terms of the GNU Lesser General Public License as +  published by the Free Software Foundation; either version 2.1 of the +  License, or (at your option) any later version. +  +  avahi is distributed in the hope that it will be useful, but WITHOUT +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General +  Public License for more details. +  +  You should have received a copy of the GNU Lesser General Public +  License along with avahi; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + +#include <inttypes.h> +#include <sys/socket.h> + +#include <avahi-common/cdecl.h> +#include <avahi-common/address.h> + +AVAHI_C_DECL_BEGIN + +/** Make an address structture of a sockaddr structure */ +AvahiAddress *avahi_address_from_sockaddr(const struct sockaddr* sa, AvahiAddress *ret_addr); + +/** Return the port number of a sockaddr structure (either IPv4 or IPv6) */ +uint16_t avahi_port_from_sockaddr(const struct sockaddr* sa); + +/** Check whether the specified IPv6 address is in fact an + * encapsulated IPv4 address, returns 1 if yes, 0 otherwise */ +int avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a); + +AVAHI_C_DECL_END + +#endif diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index 754988c..51a3a03 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -149,6 +149,7 @@ static void remove_entries(void) {  static void create_entries(int new_name) {      AvahiAddress a; +    AvahiRecord *r;      remove_entries(); @@ -185,6 +186,14 @@ static void create_entries(int new_name) {          goto fail;      } +    r = avahi_record_new_full("cname.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME, AVAHI_DEFAULT_TTL); +    r->data.cname.name = avahi_strdup("cocaine.local"); +     +    if (avahi_server_add(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, r) < 0) { +        avahi_log_error("Failed to add CNAME record"); +        goto fail; +    } +      avahi_s_entry_group_commit(group);      return; @@ -345,7 +354,7 @@ int main(int argc, char *argv[]) {      r = avahi_s_record_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, k, 0, record_browser_callback, NULL);      avahi_key_unref(k); -    hnr = avahi_s_host_name_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "cocaine.local", AVAHI_PROTO_UNSPEC, 0, hnr_callback, NULL); +    hnr = avahi_s_host_name_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "cname.local", AVAHI_PROTO_UNSPEC, 0, hnr_callback, NULL);      ar = avahi_s_address_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, avahi_address_parse("192.168.50.1", AVAHI_PROTO_INET, &a), 0, ar_callback, NULL); diff --git a/avahi-core/browse.c b/avahi-core/browse.c index 5fd3a01..cb2d326 100644 --- a/avahi-core/browse.c +++ b/avahi-core/browse.c @@ -35,6 +35,7 @@  #include "browse.h"  #include "log.h"  #include "querier.h" +#include "domain-util.h"  #define AVAHI_LOOKUPS_PER_BROWSER_MAX 15 @@ -278,7 +279,6 @@ static void lookup_multicast_callback(                  lookup_handle_cname(l, interface, protocol, b->flags, r);              else {                  /* It's a normal record, so let's call the user callback */ -                assert(avahi_key_equal(b->key, l->key));                  if (avahi_server_is_record_local(b->server, interface, protocol, r))                      flags |= AVAHI_LOOKUP_RESULT_LOCAL; diff --git a/avahi-core/domain-util.c b/avahi-core/domain-util.c new file mode 100644 index 0000000..d4cc2ad --- /dev/null +++ b/avahi-core/domain-util.c @@ -0,0 +1,101 @@ +/* $Id$ */ + +/*** +  This file is part of avahi. +  +  avahi is free software; you can redistribute it and/or modify it +  under the terms of the GNU Lesser General Public License as +  published by the Free Software Foundation; either version 2.1 of the +  License, or (at your option) any later version. +  +  avahi is distributed in the hope that it will be useful, but WITHOUT +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General +  Public License for more details. +  +  You should have received a copy of the GNU Lesser General Public +  License along with avahi; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <unistd.h> + +#include <avahi-common/malloc.h> + +#include "domain-util.h" + +char *avahi_get_host_name(char *ret_s, size_t size) { +#ifdef HOST_NAME_MAX +    char t[HOST_NAME_MAX]; +#else +    char t[256]; +#endif +     +    assert(ret_s); +    assert(size > 0); +     +    gethostname(t, sizeof(t)); +    t[sizeof(t)-1] = 0; +     +    return avahi_normalize_name(t, ret_s, size); +} + +char *avahi_get_host_name_strdup(void) { +    char t[AVAHI_DOMAIN_NAME_MAX]; + +    if (!(avahi_get_host_name(t, sizeof(t)))) +        return NULL; + +    return avahi_strdup(t); +} + +int avahi_binary_domain_cmp(const char *a, const char *b) { +    assert(a); +    assert(b); + +    if (a == b) +        return 0; + +    for (;;) { +        char ca[AVAHI_LABEL_MAX], cb[AVAHI_LABEL_MAX], *p; +        int r; + +        p = avahi_unescape_label(&a, ca, sizeof(ca)); +        assert(p); +        p = avahi_unescape_label(&b, cb, sizeof(cb)); +        assert(p); + +        if ((r = strcmp(ca, cb))) +            return r; +         +        if (!*a && !*b) +            return 0; +    } +} + +int avahi_domain_ends_with(const char *domain, const char *suffix) { +    assert(domain); +    assert(suffix); + +    for (;;) { +        char dummy[AVAHI_LABEL_MAX], *r; + +        if (*domain == 0) +            return 0; +         +        if (avahi_domain_equal(domain, suffix)) +            return 1; + +        r = avahi_unescape_label(&domain, dummy, sizeof(dummy)); +        assert(r); +    }  +} + diff --git a/avahi-core/domain-util.h b/avahi-core/domain-util.h new file mode 100644 index 0000000..01233d8 --- /dev/null +++ b/avahi-core/domain-util.h @@ -0,0 +1,47 @@ +#ifndef foodomainutilhfoo +#define foodomainutilhfoo + +/* $Id$ */ + +/*** +  This file is part of avahi. +  +  avahi is free software; you can redistribute it and/or modify it +  under the terms of the GNU Lesser General Public License as +  published by the Free Software Foundation; either version 2.1 of the +  License, or (at your option) any later version. +  +  avahi is distributed in the hope that it will be useful, but WITHOUT +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General +  Public License for more details. +  +  You should have received a copy of the GNU Lesser General Public +  License along with avahi; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + +#include <inttypes.h> +#include <sys/types.h> + +#include <avahi-common/cdecl.h> +#include <avahi-common/domain.h> + +AVAHI_C_DECL_BEGIN + +/** Return the local host name. */ +char *avahi_get_host_name(char *ret_s, size_t size);  + +/** Return the local host name. avahi_free() the result! */ +char *avahi_get_host_name_strdup(void); + +/** Do a binary comparison of to specified domain names, return -1, 0, or 1, depending on the order. */ +int avahi_binary_domain_cmp(const char *a, const char *b); + +/** Returns 1 if the the end labels of domain are eqal to suffix */ +int avahi_domain_ends_with(const char *domain, const char *suffix); + +AVAHI_C_DECL_END + +#endif diff --git a/avahi-core/rr.c b/avahi-core/rr.c index ef1c3d6..e7fac13 100644 --- a/avahi-core/rr.c +++ b/avahi-core/rr.c @@ -37,6 +37,7 @@  #include "log.h"  #include "util.h"  #include "hashmap.h" +#include "domain-util.h"  AvahiKey *avahi_key_new(const char *name, uint16_t class, uint16_t type) {      AvahiKey *k; diff --git a/avahi-core/rr.h b/avahi-core/rr.h index 63dc18d..21d6d63 100644 --- a/avahi-core/rr.h +++ b/avahi-core/rr.h @@ -98,7 +98,7 @@ typedef struct  {          struct {              char *name; -        } ptr; /**< Data for PTR an CNAME records */ +        } ptr, ns, cname; /**< Data for PTR, NS and CNAME records */          struct {              char *cpu; diff --git a/avahi-core/server.c b/avahi-core/server.c index 3edd96e..5cac056 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -45,26 +45,38 @@  #include "log.h"  #include "util.h"  #include "dns-srv-rr.h" +#include "addr-util.h" +#include "domain-util.h"  static void enum_aux_records(AvahiServer *s, AvahiInterface *i, const char *name, uint16_t type, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata) { -    AvahiKey *k; -    AvahiEntry *e; -      assert(s);      assert(i);      assert(name);      assert(callback); -    assert(type != AVAHI_DNS_TYPE_ANY); - -    if (!(k = avahi_key_new(name, AVAHI_DNS_CLASS_IN, type))) -        return; /** OOM */ - -    for (e = avahi_hashmap_lookup(s->entries_by_key, k); e; e = e->by_key_next) -        if (!e->dead && avahi_entry_is_registered(s, e, i))  -            callback(s, e->record, e->flags & AVAHI_PUBLISH_UNIQUE, userdata); +    if (type == AVAHI_DNS_TYPE_ANY) { +        AvahiEntry *e; +         +        for (e = s->entries; e; e = e->entries_next) +            if (!e->dead && +                avahi_entry_is_registered(s, e, i) && +                e->record->key->clazz == AVAHI_DNS_CLASS_IN && +                avahi_domain_equal(name, e->record->key->name)) +                callback(s, e->record, e->flags & AVAHI_PUBLISH_UNIQUE, userdata); -    avahi_key_unref(k); +    } else { +        AvahiEntry *e; +        AvahiKey *k; +         +        if (!(k = avahi_key_new(name, AVAHI_DNS_CLASS_IN, type))) +            return; /** OOM */ +         +        for (e = avahi_hashmap_lookup(s->entries_by_key, k); e; e = e->by_key_next) +            if (!e->dead && avahi_entry_is_registered(s, e, i))  +                callback(s, e->record, e->flags & AVAHI_PUBLISH_UNIQUE, userdata); +         +        avahi_key_unref(k); +    }  }  void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, AvahiRecord *r, void (*callback)(AvahiServer *s, AvahiRecord *r, int flush_cache, void* userdata), void* userdata) { @@ -72,6 +84,8 @@ void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, Avahi      assert(i);      assert(r);      assert(callback); + +    /* Call the specified callback far all records referenced by the one specified in *r */      if (r->key->clazz == AVAHI_DNS_CLASS_IN) {          if (r->key->type == AVAHI_DNS_TYPE_PTR) { @@ -80,7 +94,8 @@ void avahi_server_enumerate_aux_records(AvahiServer *s, AvahiInterface *i, Avahi          } else if (r->key->type == AVAHI_DNS_TYPE_SRV) {              enum_aux_records(s, i, r->data.srv.name, AVAHI_DNS_TYPE_A, callback, userdata);              enum_aux_records(s, i, r->data.srv.name, AVAHI_DNS_TYPE_AAAA, callback, userdata); -        } +        } else if (r->key->type == AVAHI_DNS_TYPE_CNAME) +            enum_aux_records(s, i, r->data.cname.name, AVAHI_DNS_TYPE_ANY, callback, userdata);      }  } @@ -93,17 +108,14 @@ void avahi_server_prepare_response(AvahiServer *s, AvahiInterface *i, AvahiEntry  }  void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i, AvahiKey *k, int unicast_response) { -    AvahiEntry *e; -/*     char *txt; */ -          assert(s);      assert(i);      assert(k); -/*     avahi_log_debug("Posting responses matching [%s]", txt = avahi_key_to_string(k)); */ -/*     avahi_free(txt); */ +    /* Push all records that match the specified key to the record list */      if (avahi_key_is_pattern(k)) { +        AvahiEntry *e;          /* Handle ANY query */ @@ -112,6 +124,7 @@ void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i,                  avahi_server_prepare_response(s, i, e, unicast_response, 0);      } else { +        AvahiEntry *e;          /* Handle all other queries */ @@ -119,21 +132,40 @@ void avahi_server_prepare_matching_responses(AvahiServer *s, AvahiInterface *i,              if (!e->dead && avahi_entry_is_registered(s, e, i))                  avahi_server_prepare_response(s, i, e, unicast_response, 0);      } + +    /* Look for CNAME records */ + +    if ((k->clazz == AVAHI_DNS_CLASS_IN || k->clazz == AVAHI_DNS_CLASS_ANY) +        && k->type != AVAHI_DNS_TYPE_CNAME && k->type != AVAHI_DNS_TYPE_ANY) { + +        AvahiKey *cname_key; + +        if (!(cname_key = avahi_key_new(k->name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME))) +            return; +         +        avahi_server_prepare_matching_responses(s, i, cname_key, unicast_response); +        avahi_key_unref(cname_key); +    }  }  static void withdraw_entry(AvahiServer *s, AvahiEntry *e) {      assert(s);      assert(e); + +    /* Withdraw the specified entry, and if is part of an entry group, +     * put that into COLLISION state */ + +    if (e->dead) +        return;      if (e->group) {          AvahiEntry *k; -        for (k = e->group->entries; k; k = k->by_group_next) { +        for (k = e->group->entries; k; k = k->by_group_next)               if (!k->dead) {                  avahi_goodbye_entry(s, k, 0, 1);                  k->dead = 1;              } -        }          e->group->n_probing = 0; @@ -152,24 +184,22 @@ static void withdraw_rrset(AvahiServer *s, AvahiKey *key) {      assert(s);      assert(key); -   for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next) -       if (!e->dead) -           withdraw_entry(s, e); +    /* Withdraw an entry RRSset */ +     +    for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next) +        withdraw_entry(s, e);  }  static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *i) {      AvahiEntry *e, *n; -    char *t;      int ours = 0, won = 0, lost = 0;      assert(s);      assert(record);      assert(i); -    t = avahi_record_to_string(record); - -/*     avahi_log_debug("incoming_probe()");  */ - +    /* Handle incoming probes and check if they conflict our own probes */ +          for (e = avahi_hashmap_lookup(s->entries_by_key, record->key); e; e = n) {          int cmp;          n = e->by_key_next; @@ -192,17 +222,17 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *      }      if (!ours) { - +        char *t = avahi_record_to_string(record); +                  if (won)              avahi_log_debug("Recieved conflicting probe [%s]. Local host won.", t);          else if (lost) {              avahi_log_debug("Recieved conflicting probe [%s]. Local host lost. Withdrawing.", t);              withdraw_rrset(s, record->key); -        }/*  else */ -/*             avahi_log_debug("Not conflicting probe"); */ +        } +         +        avahi_free(t);      } - -    avahi_free(t);  }  static int handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, int unique, const AvahiAddress *a) { @@ -213,9 +243,8 @@ static int handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *recor      assert(i);      assert(record); - -/*     avahi_log_debug("CHECKING FOR CONFLICT: [%s]", t);   */ - +    /* Check whether an incoming record conflicts with one of our own */ +          for (e = avahi_hashmap_lookup(s->entries_by_key, record->key); e; e = n) {          n = e->by_key_next; @@ -286,8 +315,6 @@ static int handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *recor          }      } -/*     avahi_log_debug("ours=%i conflict=%i", ours, conflict); */ -      if (!ours && conflict) {          char *t; diff --git a/avahi-core/socket.c b/avahi-core/socket.c index fcc63fa..0487023 100644 --- a/avahi-core/socket.c +++ b/avahi-core/socket.c @@ -679,7 +679,6 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(int fd, struct sockaddr_in6 *ret_sa,      uint8_t aux[64];      ssize_t l;      int ms; -          struct cmsghdr *cmsg;      int found_ttl = 0, found_iface = 0; diff --git a/avahi-core/update-test.c b/avahi-core/update-test.c index bd42c75..fbfd51a 100644 --- a/avahi-core/update-test.c +++ b/avahi-core/update-test.c @@ -24,6 +24,7 @@  #endif  #include <assert.h> +#include <stdlib.h>  #include <avahi-common/error.h>  #include <avahi-common/watch.h> diff --git a/avahi-core/wide-area.c b/avahi-core/wide-area.c index 9dd1e73..d12267a 100644 --- a/avahi-core/wide-area.c +++ b/avahi-core/wide-area.c @@ -38,6 +38,7 @@  #include "log.h"  #include "hashmap.h"  #include "wide-area.h" +#include "addr-util.h"  #define CACHE_ENTRIES_MAX 500 @@ -1,11 +1,11 @@  for 0.6:  * remove outgoing queries from queue if the browse object they were issued from is destroyed  * add API to allow user to tell the server that some service is not reachable -* generate local CNAME responses  * add support for subtypes in static services  * Add static host configuration like static services [lathiat]  * wrap avahi_server_add_record() via DBUS and in avahi-client [lathiat] -* unify argument oder of functions returning a string in a user   supplied buffer  +* unify argument order of functions returning a string in a user supplied buffer  +* remove irrelevant functions from pubic rr.h API  later:  * add simplification routine for adding services  @@ -96,3 +96,4 @@ done:  * drop partially created created entries on failure  * add error state for server and entry group  * make sure that all limit definitions end with _MAX +* generate local CNAME responses  | 
