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 {
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);
#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)
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) {
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;
/** \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>
uint32_t address; /**< Address data in network byte order. */
} AvahiIPv4Address;
-
/** An IPv6 address */
typedef struct {
uint8_t address[16]; /**< Address data */
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);
* 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);
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);
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"));
#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;
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);
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];
* 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
* 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);
/** 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 */
/** 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);
/** 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);
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 += \
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
--- /dev/null
+/* $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;
+}
+
+
+
--- /dev/null
+#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
static void create_entries(int new_name) {
AvahiAddress a;
+ AvahiRecord *r;
remove_entries();
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;
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);
#include "browse.h"
#include "log.h"
#include "querier.h"
+#include "domain-util.h"
#define AVAHI_LOOKUPS_PER_BROWSER_MAX 15
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;
--- /dev/null
+/* $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);
+ }
+}
+
--- /dev/null
+#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
#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;
struct {
char *name;
- } ptr; /**< Data for PTR an CNAME records */
+ } ptr, ns, cname; /**< Data for PTR, NS and CNAME records */
struct {
char *cpu;
#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) {
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) {
} 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);
}
}
}
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 */
avahi_server_prepare_response(s, i, e, unicast_response, 0);
} else {
+ AvahiEntry *e;
/* Handle all other queries */
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;
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;
}
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) {
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;
}
}
-/* avahi_log_debug("ours=%i conflict=%i", ours, conflict); */
-
if (!ours && conflict) {
char *t;
uint8_t aux[64];
ssize_t l;
int ms;
-
struct cmsghdr *cmsg;
int found_ttl = 0, found_iface = 0;
#endif
#include <assert.h>
+#include <stdlib.h>
#include <avahi-common/error.h>
#include <avahi-common/watch.h>
#include "log.h"
#include "hashmap.h"
#include "wide-area.h"
+#include "addr-util.h"
#define CACHE_ENTRIES_MAX 500
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
* 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