* replace AF_UNSPEC by AVAHI_PROTO_UNSPEC in client-test.c
authorLennart Poettering <lennart@poettering.net>
Tue, 25 Oct 2005 22:20:37 +0000 (22:20 +0000)
committerLennart Poettering <lennart@poettering.net>
Tue, 25 Oct 2005 22:20:37 +0000 (22:20 +0000)
* 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

20 files changed:
avahi-client/client-test.c
avahi-common/address.c
avahi-common/address.h
avahi-common/domain-test.c
avahi-common/domain.c
avahi-common/domain.h
avahi-core/Makefile.am
avahi-core/addr-util.c [new file with mode: 0644]
avahi-core/addr-util.h [new file with mode: 0644]
avahi-core/avahi-test.c
avahi-core/browse.c
avahi-core/domain-util.c [new file with mode: 0644]
avahi-core/domain-util.h [new file with mode: 0644]
avahi-core/rr.c
avahi-core/rr.h
avahi-core/server.c
avahi-core/socket.c
avahi-core/update-test.c
avahi-core/wide-area.c
docs/TODO

index f9913e6..5c9c092 100644 (file)
@@ -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);
index d02d997..56b4058 100644 (file)
@@ -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;
index c383250..95eb392 100644 (file)
@@ -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);
 
index 9926a1f..b765532 100644 (file)
@@ -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"));
index 7d954de..4927086 100644 (file)
 #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];
index 4e3aa55..e5869ce 100644 (file)
@@ -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);
 
index 9516615..cc93265 100644 (file)
@@ -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 (file)
index 0000000..7b9bb03
--- /dev/null
@@ -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 (file)
index 0000000..4134de1
--- /dev/null
@@ -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
index 754988c..51a3a03 100644 (file)
@@ -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);
 
index 5fd3a01..cb2d326 100644 (file)
@@ -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 (file)
index 0000000..d4cc2ad
--- /dev/null
@@ -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 (file)
index 0000000..01233d8
--- /dev/null
@@ -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
index ef1c3d6..e7fac13 100644 (file)
@@ -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;
index 63dc18d..21d6d63 100644 (file)
@@ -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;
index 3edd96e..5cac056 100644 (file)
 #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;
  
index fcc63fa..0487023 100644 (file)
@@ -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;
 
index bd42c75..fbfd51a 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include <assert.h>
+#include <stdlib.h>
 
 #include <avahi-common/error.h>
 #include <avahi-common/watch.h>
index 9dd1e73..d12267a 100644 (file)
@@ -38,6 +38,7 @@
 #include "log.h"
 #include "hashmap.h"
 #include "wide-area.h"
+#include "addr-util.h"
 
 #define CACHE_ENTRIES_MAX 500
 
index 65a606a..757fb82 100644 (file)
--- a/docs/TODO
+++ b/docs/TODO
@@ -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