From 9962a048634c590db23a00db1d01daada779844c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 24 Jun 2005 19:02:51 +0000 Subject: [PATCH] * implement new source address check mechanisms * introduce new types AvahiIfIndex and AvahiProtocol to abstract underlying OS structures a bit * document string list, address and other stuff * implement qclass = ANY queries * don't make use of UTF8 collation as RFC mandates git-svn-id: file:///home/lennart/svn/public/avahi/trunk@144 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/address.c | 14 ++--- avahi-common/address.h | 52 ++++++++++++++++--- avahi-common/rr.c | 23 +++++---- avahi-common/rr.h | 1 + avahi-common/strlst.c | 4 +- avahi-common/strlst.h | 44 ++++++++++++++-- avahi-common/util.c | 41 +++------------ avahi-core/avahi-test.c | 26 +++++----- avahi-core/core.h | 89 ++++++++++++++++---------------- avahi-core/iface.c | 93 ++++++++++++++++++++++++++-------- avahi-core/iface.h | 14 +++-- avahi-core/resolve-address.c | 6 +-- avahi-core/resolve-host-name.c | 12 ++--- avahi-core/resolve-service.c | 14 ++--- avahi-core/server.c | 78 +++++++++++++++++----------- avahi-core/socket.c | 24 +++++---- avahi-core/socket.h | 6 ++- avahi-daemon/avahi.conf | 2 +- 18 files changed, 337 insertions(+), 206 deletions(-) diff --git a/avahi-common/address.c b/avahi-common/address.c index 3e6fc97..b982a2c 100644 --- a/avahi-common/address.c +++ b/avahi-common/address.c @@ -33,9 +33,9 @@ guint avahi_address_get_size(const AvahiAddress *a) { g_assert(a); - if (a->family == AF_INET) + if (a->family == AVAHI_PROTO_INET) return 4; - else if (a->family == AF_INET6) + else if (a->family == AVAHI_PROTO_INET6) return 16; return 0; @@ -111,18 +111,18 @@ gchar *avahi_reverse_lookup_name_ipv6_int(const AvahiIPv6Address *a) { return reverse_lookup_name_ipv6(a, "ip6.int"); } -AvahiAddress *avahi_address_parse(const char *s, guchar family, AvahiAddress *ret_addr) { +AvahiAddress *avahi_address_parse(const gchar *s, AvahiProtocol family, AvahiAddress *ret_addr) { g_assert(ret_addr); g_assert(s); - if (family == AF_UNSPEC) { + if (family == AVAHI_PROTO_UNSPEC) { if (inet_pton(AF_INET, s, ret_addr->data.data) <= 0) { if (inet_pton(AF_INET6, s, ret_addr->data.data) <= 0) return NULL; else - ret_addr->family = AF_INET6; + ret_addr->family = AVAHI_PROTO_INET6; } else - ret_addr->family = AF_INET; + ret_addr->family = AVAHI_PROTO_INET; } else { if (inet_pton(family, s, ret_addr->data.data) <= 0) return NULL; @@ -168,7 +168,7 @@ gboolean avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a) { g_assert(a); - if (a->family != AF_INET6) + if (a->family != AVAHI_PROTO_INET6) return FALSE; return memcmp(a->data.ipv6.address, ipv4_in_ipv6, sizeof(ipv4_in_ipv6)) == 0; diff --git a/avahi-common/address.h b/avahi-common/address.h index 22cb74b..4b5fb27 100644 --- a/avahi-common/address.h +++ b/avahi-common/address.h @@ -25,38 +25,76 @@ #include #include +/** Protocol family specification, takes the values AVAHI_INET, AVAHI_INET6, AVAHI_UNSPEC */ +typedef guchar AvahiProtocol; + +/** Numeric network interface index. Takes OS dependent values and the special constant AVAHI_IF_UNSPEC */ +typedef gint AvahiIfIndex; + +/** Values for AvahiProtocol */ +enum { + AVAHI_PROTO_INET = AF_INET, /**< IPv4 */ + AVAHI_PROTO_INET6 = AF_INET6, /**< IPv6 */ + AVAHI_PROTO_UNSPEC = AF_UNSPEC /**< Unspecified/all protocol(s) */ +}; + +/** Special values for AvahiIfIndex */ +enum { + AVAHI_IF_UNSPEC = -1 /**< Unspecifed/all interfaces */ +}; + +/** An IPv4 address */ typedef struct { - guint32 address; + guint32 address; /**< Address data in network byte order. */ } AvahiIPv4Address; +/** An IPv6 address */ typedef struct { - guint8 address[16]; + guint8 address[16]; /**< Address data */ } AvahiIPv6Address; +/** Protocol (address family) independant address structure */ typedef struct { - guchar family; + AvahiProtocol family; /**< Address family */ union { - AvahiIPv6Address ipv6; - AvahiIPv4Address ipv4; - guint8 data[1]; + AvahiIPv6Address ipv6; /** Address when IPv6 */ + AvahiIPv4Address ipv4; /** Address when IPv4 */ + guint8 data[1]; /** Type independant data field */ } data; } AvahiAddress; +/** Return the address data size of the specified address. (4 for IPv4, 16 for IPv6) */ guint 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. */ gint avahi_address_cmp(const AvahiAddress *a, const AvahiAddress *b); +/** Convert the specified address *a to a human readable character string */ gchar *avahi_address_snprint(char *ret_s, guint length, const AvahiAddress *a); -AvahiAddress *avahi_address_parse(const char *s, guchar family, AvahiAddress *ret_addr); +/** Convert the specifeid human readable character string to an + * address structure. Set af to AVAHI_UNSPEC for automatic address + * 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) */ guint16 avahi_port_from_sockaddr(const struct sockaddr* sa); +/** Generate the DNS reverse lookup name for an IPv4 address. g_free() the result! */ gchar* avahi_reverse_lookup_name_ipv4(const AvahiIPv4Address *a); + +/** Generate the modern DNS reverse lookup name for an IPv6 address, ending in ipv6.arpa. g_free() the result! */ gchar* avahi_reverse_lookup_name_ipv6_arpa(const AvahiIPv6Address *a); + +/** Generate the historic DNS reverse lookup name for an IPv6 address, ending in ipv6.int. g_free() the result! */ gchar* avahi_reverse_lookup_name_ipv6_int(const AvahiIPv6Address *a); +/** Check whether the specified IPv6 address is in fact an + * encapsulated IPv4 address */ gboolean avahi_address_is_ipv4_in_ipv6(const AvahiAddress *a); #endif diff --git a/avahi-common/rr.c b/avahi-common/rr.c index 7e974c4..13160fc 100644 --- a/avahi-common/rr.c +++ b/avahi-common/rr.c @@ -148,11 +148,15 @@ void avahi_record_unref(AvahiRecord *r) { const gchar *avahi_dns_class_to_string(guint16 class) { if (class & AVAHI_DNS_CACHE_FLUSH) return "FLUSH"; - - if (class == AVAHI_DNS_CLASS_IN) - return "IN"; - return NULL; + switch (class) { + case AVAHI_DNS_CLASS_IN: + return "IN"; + case AVAHI_DNS_CLASS_ANY: + return "ANY"; + default: + return NULL; + } } const gchar *avahi_dns_type_to_string(guint16 type) { @@ -266,16 +270,17 @@ gboolean avahi_key_pattern_match(const AvahiKey *pattern, const AvahiKey *k) { return avahi_domain_equal(pattern->name, k->name) && (pattern->type == k->type || pattern->type == AVAHI_DNS_TYPE_ANY) && - pattern->class == k->class; + (pattern->class == k->class || pattern->type == AVAHI_DNS_CLASS_ANY); } gboolean avahi_key_is_pattern(const AvahiKey *k) { g_assert(k); - return k->type == AVAHI_DNS_TYPE_ANY; + return + k->type == AVAHI_DNS_TYPE_ANY || + k->class == AVAHI_DNS_CLASS_ANY; } - guint avahi_key_hash(const AvahiKey *k) { g_assert(k); @@ -313,8 +318,8 @@ static gboolean rdata_equal(const AvahiRecord *a, const AvahiRecord *b) { case AVAHI_DNS_TYPE_HINFO: return - !g_utf8_collate(a->data.hinfo.cpu, b->data.hinfo.cpu) && - !g_utf8_collate(a->data.hinfo.os, b->data.hinfo.os); + !strcmp(a->data.hinfo.cpu, b->data.hinfo.cpu) && + !strcmp(a->data.hinfo.os, b->data.hinfo.os); case AVAHI_DNS_TYPE_TXT: return avahi_string_list_equal(a->data.txt.string_list, b->data.txt.string_list); diff --git a/avahi-common/rr.h b/avahi-common/rr.h index 404cc21..da0b285 100644 --- a/avahi-common/rr.h +++ b/avahi-common/rr.h @@ -43,6 +43,7 @@ enum { enum { AVAHI_DNS_CLASS_IN = 0x01, + AVAHI_DNS_CLASS_ANY = 0xFF, AVAHI_DNS_CACHE_FLUSH = 0x8000, AVAHI_DNS_UNICAST_RESPONSE = 0x8000 }; diff --git a/avahi-common/strlst.c b/avahi-common/strlst.c index 866618f..0853414 100644 --- a/avahi-common/strlst.c +++ b/avahi-common/strlst.c @@ -176,7 +176,7 @@ guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size) return used; } -gboolean avahi_string_list_equal(AvahiStringList *a, AvahiStringList *b) { +gboolean avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b) { for (;;) { if (!a && !b) @@ -235,7 +235,7 @@ AvahiStringList *avahi_string_list_new_va(va_list va) { return avahi_string_list_add_many_va(NULL, va); } -AvahiStringList *avahi_string_list_copy(AvahiStringList *l) { +AvahiStringList *avahi_string_list_copy(const AvahiStringList *l) { AvahiStringList *r = NULL; for (; l; l = l->next) diff --git a/avahi-common/strlst.h b/avahi-common/strlst.h index 80dfc2c..4fde8eb 100644 --- a/avahi-common/strlst.h +++ b/avahi-common/strlst.h @@ -24,30 +24,64 @@ #include +/** Linked list of strings that can contain any number of binary + * characters, include NUL bytes. An empty list is created by + * assigning a NULL to a pointer to AvahiStringList. The string list + * is stored in reverse order, so that appending to the string list is + * effectively a prepending to the linked list. This object is used + * primarily for storing DNS TXT record data. */ typedef struct AvahiStringList { - struct AvahiStringList *next; - guint size; - guint8 text[1]; + struct AvahiStringList *next; /**< Pointe to the next linked list element */ + guint size; /**< Size of text[] */ + guint8 text[1]; /**< Character data */ } AvahiStringList; +/** Create a new string list by taking a variable list of NUL + * terminated strings. The strings are copied using g_strdup(). The + * argument list must be terminated by a NULL pointer. */ AvahiStringList *avahi_string_list_new(const gchar *txt, ...); + +/** Same as avahi_string_list_new() but pass a va_list structure */ AvahiStringList *avahi_string_list_new_va(va_list va); +/** Free a string list */ void avahi_string_list_free(AvahiStringList *l); +/** Append a NUL terminated string to the specified string list. The + * passed string is copied using g_strdup(). Returns the new list + * start. */ AvahiStringList *avahi_string_list_add(AvahiStringList *l, const gchar *text); + +/** Append am arbitrary length byte string to the list. Returns the + * new list start. */ AvahiStringList *avahi_string_list_add_arbitrary(AvahiStringList *l, const guint8 *text, guint size); + +/** Same as avahi_string_list_add(), but takes a variable number of + * NUL terminated strings. The argument list must be terminated by a + * NULL pointer. Returns the new list start. */ AvahiStringList *avahi_string_list_add_many(AvahiStringList *r, ...); + +/** Same as avahi_string_list_add_many(), but use a va_list + * structure. Returns the new list start. */ AvahiStringList *avahi_string_list_add_many_va(AvahiStringList *r, va_list va); +/** Convert the string list object to a single character string, + * seperated by spaces and enclosed in "". g_free() the result! This + * function doesn't work well with string that contain NUL bytes. */ gchar* avahi_string_list_to_string(AvahiStringList *l); +/** Serialize the string list object in a way that is compatible with + * the storing of DNS TXT records. Strings longer than 255 bytes are truncated. */ guint avahi_string_list_serialize(AvahiStringList *l, gpointer data, guint size); + +/** Inverse of avahi_string_list_serialize() */ AvahiStringList *avahi_string_list_parse(gconstpointer data, guint size); -gboolean avahi_string_list_equal(AvahiStringList *a, AvahiStringList *b); +/** Compare to string lists */ +gboolean avahi_string_list_equal(const AvahiStringList *a, const AvahiStringList *b); -AvahiStringList *avahi_string_list_copy(AvahiStringList *l); +/** Copy a string list */ +AvahiStringList *avahi_string_list_copy(const AvahiStringList *l); #endif diff --git a/avahi-common/util.c b/avahi-common/util.c index a41475a..baf5527 100644 --- a/avahi-common/util.c +++ b/avahi-common/util.c @@ -79,25 +79,18 @@ static gchar *unescape_uneeded(const gchar *src, gchar *ret_dest, size_t size) { gchar *avahi_normalize_name(const gchar *s) { gchar tmp[256]; - gchar *n, *t; guint l; g_assert(s); unescape_uneeded(s, tmp, sizeof(tmp)); - n = g_utf8_normalize(tmp, -1, G_NORMALIZE_DEFAULT); - - if ((l = strlen(n)) == 0) { - g_free(n); + if ((l = strlen(tmp)) == 0) return g_strdup("."); - } - if (n[l-1] == '.') - return n; + if (tmp[l-1] == '.') + return g_strdup(tmp); - t = g_strdup_printf("%s.", n); - g_free(n); - return t; + return g_strdup_printf("%s.", tmp); } gint avahi_timeval_compare(const GTimeVal *a, const GTimeVal *b) { @@ -280,22 +273,6 @@ gchar *avahi_escape_label(const guint8* src, guint src_length, gchar **ret_name, return r; } -static gint utf8_strcasecmp(const gchar *a, const gchar *b) { - gchar *ta, *tb; - gint r; - - g_assert(a); - g_assert(b); - - ta = g_utf8_casefold(a, -1); - tb = g_utf8_casefold(b, -1); - r = g_utf8_collate(ta, tb); - g_free(ta); - g_free(tb); - - return r; -} - gboolean avahi_domain_equal(const gchar *a, const gchar *b) { g_assert(a); g_assert(b); @@ -314,7 +291,7 @@ gboolean avahi_domain_equal(const gchar *a, const gchar *b) { else if ((pa && !pb) || (!pa && pb)) return FALSE; - if (utf8_strcasecmp(pa, pb)) + if (g_ascii_strcasecmp(pa, pb)) return FALSE; } @@ -385,7 +362,7 @@ guint avahi_domain_hash(const gchar *s) { guint hash = 0; for (;;) { - gchar c[65], *n, *m; + gchar c[65], *m; if (!avahi_unescape_label(&s, c, sizeof(c))) return hash; @@ -393,13 +370,9 @@ guint avahi_domain_hash(const gchar *s) { if (!c[0]) continue; - n = g_utf8_normalize(c, -1, G_NORMALIZE_DEFAULT); - m = g_utf8_strdown(n, -1); - + m = g_ascii_strdown(c, -1); hash += g_str_hash(m); - g_free(m); - g_free(n); } } diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index 908212c..9bd4e2c 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -52,7 +52,7 @@ static void record_browser_callback(AvahiRecordBrowser *r, gint interface, gucha g_assert(r); g_assert(record); g_assert(interface > 0); - g_assert(protocol != AF_UNSPEC); + g_assert(protocol != AVAHI_PROTO_UNSPEC); avahi_log_debug("SUBSCRIPTION: record [%s] on %i.%i is %s", t = avahi_record_to_string(record), interface, protocol, event == AVAHI_BROWSER_NEW ? "new" : "remove"); @@ -115,22 +115,22 @@ static void create_entries(gboolean new_name) { service_name = n; } - if (avahi_server_add_service(server, group, 0, AF_UNSPEC, "_http._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) { + if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) { avahi_log_error("Failed to add HTTP service"); goto fail; } - if (avahi_server_add_service(server, group, 0, AF_UNSPEC, "_ftp._tcp", service_name, NULL, NULL, 21, "foo", NULL) < 0) { + if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ftp._tcp", service_name, NULL, NULL, 21, "foo", NULL) < 0) { avahi_log_error("Failed to add FTP service"); goto fail; } - if (avahi_server_add_service(server, group, 0, AF_UNSPEC, "_webdav._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) { + if (avahi_server_add_service(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_webdav._tcp", service_name, NULL, NULL, 80, "foo", NULL) < 0) { avahi_log_error("Failed to add WEBDAV service"); goto fail; } - if (avahi_server_add_dns_server_address(server, group, 0, AF_UNSPEC, NULL, AVAHI_DNS_SERVER_RESOLVE, avahi_address_parse("192.168.50.1", AF_UNSPEC, &a), 53) < 0) { + if (avahi_server_add_dns_server_address(server, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DNS_SERVER_RESOLVE, avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &a), 53) < 0) { avahi_log_error("Failed to add new DNS Server address"); goto fail; } @@ -218,22 +218,22 @@ int main(int argc, char *argv[]) { avahi_server_config_free(&config); k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR); - r = avahi_record_browser_new(server, -1, AF_UNSPEC, k, record_browser_callback, NULL); + r = avahi_record_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, k, record_browser_callback, NULL); avahi_key_unref(k); - hnr = avahi_host_name_resolver_new(server, -1, AF_UNSPEC, "codes-CompUTER.local", AF_UNSPEC, hnr_callback, NULL); + hnr = avahi_host_name_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "codes-CompUTER.local", AVAHI_PROTO_UNSPEC, hnr_callback, NULL); - ar = avahi_address_resolver_new(server, -1, AF_UNSPEC, avahi_address_parse("192.168.50.15", AF_INET, &a), ar_callback, NULL); + ar = avahi_address_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, avahi_address_parse("192.168.50.15", AVAHI_PROTO_INET, &a), ar_callback, NULL); - db = avahi_domain_browser_new(server, -1, AF_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, db_callback, NULL); + db = avahi_domain_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, db_callback, NULL); - stb = avahi_service_type_browser_new(server, -1, AF_UNSPEC, NULL, stb_callback, NULL); + stb = avahi_service_type_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, stb_callback, NULL); - sb = avahi_service_browser_new(server, -1, AF_UNSPEC, "_http._tcp", NULL, sb_callback, NULL); + sb = avahi_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, sb_callback, NULL); - sr = avahi_service_resolver_new(server, -1, AF_UNSPEC, "Ecstasy HTTP", "_http._tcp", "local", AF_UNSPEC, sr_callback, NULL); + sr = avahi_service_resolver_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "Ecstasy HTTP", "_http._tcp", "local", AVAHI_PROTO_UNSPEC, sr_callback, NULL); - dsb = avahi_dns_server_browser_new(server, -1, AF_UNSPEC, "local", AVAHI_DNS_SERVER_RESOLVE, AF_UNSPEC, dsb_callback, NULL); + dsb = avahi_dns_server_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "local", AVAHI_DNS_SERVER_RESOLVE, AVAHI_PROTO_UNSPEC, dsb_callback, NULL); loop = g_main_loop_new(NULL, FALSE); diff --git a/avahi-core/core.h b/avahi-core/core.h index 74f5cf4..e0b5b5c 100644 --- a/avahi-core/core.h +++ b/avahi-core/core.h @@ -80,7 +80,7 @@ typedef struct AvahiServerConfig { gboolean publish_addresses; /**< Register A, AAAA and PTR records for all local IP addresses */ gboolean publish_workstation; /**< Register a _workstation._tcp service */ gboolean publish_domain; /**< Announce the local domain for browsing */ - gboolean check_response_ttl; /**< If enabled the server ignores all incoming responses with IP TTL != 255 */ + gboolean check_response_ttl; /**< If enabled the server ignores all incoming responses with IP TTL != 255. Newer versions of the RFC do no longer contain this check, so it is disabled by default. */ gboolean use_iff_running; /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */ gboolean enable_reflector; /**< Reflect incoming mDNS traffic to all local networks. This allows mDNS based network browsing beyond ethernet borders */ gboolean reflect_ipv; /**< if enable_reflector is TRUE, enable/disable reflecting between IPv4 and IPv6 */ @@ -186,19 +186,20 @@ void avahi_entry_group_set_data(AvahiEntryGroup *g, gpointer userdata); /** Return the opaque user data pointer currently set for the entry group object */ gpointer avahi_entry_group_get_data(AvahiEntryGroup *g); +/** Add a new resource record to the server. Returns 0 on success, negative otherwise. */ gint avahi_server_add( - AvahiServer *s, - AvahiEntryGroup *g, - gint interface, - guchar protocol, - AvahiEntryFlags flags, - AvahiRecord *r); + AvahiServer *s, /**< The server object to add this record to */ + AvahiEntryGroup *g, /**< An entry group object if this new record shall be attached to one, or NULL. If you plan to remove the record sometime later you a required to pass an entry group object here. */ + AvahiIfIndex interface, /**< A numeric index of a network interface to attach this record to, or AVAHI_IF_UNSPEC to attach this record to all interfaces */ + AvahiProtocol protocol, /**< A protocol family to attach this record to. One of the AVAHI_PROTO_xxx constants. Use AVAHI_PROTO_UNSPEC to make this record available on all protocols (wich means on both IPv4 and IPv6). */ + AvahiEntryFlags flags, /**< Special flags for this record */ + AvahiRecord *r /**< The record to add. This function increases the reference counter of this object. */ ); gint avahi_server_add_ptr( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, AvahiEntryFlags flags, const gchar *name, const gchar *dest); @@ -206,8 +207,8 @@ gint avahi_server_add_ptr( gint avahi_server_add_address( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, AvahiEntryFlags flags, const gchar *name, AvahiAddress *a); @@ -215,8 +216,8 @@ gint avahi_server_add_address( gint avahi_server_add_text( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, AvahiEntryFlags flags, const gchar *name, ... /* text records, terminated by NULL */); @@ -224,8 +225,8 @@ gint avahi_server_add_text( gint avahi_server_add_text_va( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, AvahiEntryFlags flags, const gchar *name, va_list va); @@ -233,8 +234,8 @@ gint avahi_server_add_text_va( gint avahi_server_add_text_strlst( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, AvahiEntryFlags flags, const gchar *name, AvahiStringList *strlst); @@ -242,20 +243,20 @@ gint avahi_server_add_text_strlst( gint avahi_server_add_service( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, const gchar *type, const gchar *name, const gchar *domain, const gchar *host, guint16 port, - ... /* text records, terminated by NULL */); + ... /**< text records, terminated by NULL */); gint avahi_server_add_service_va( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, const gchar *type, const gchar *name, const gchar *domain, @@ -266,8 +267,8 @@ gint avahi_server_add_service_va( gint avahi_server_add_service_strlst( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, const gchar *type, const gchar *name, const gchar *domain, @@ -287,8 +288,8 @@ typedef enum { gint avahi_server_add_dns_server_address( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, const gchar *domain, AvahiDNSServerType type, const AvahiAddress *address, @@ -300,8 +301,8 @@ resolvable via mDNS */ gint avahi_server_add_dns_server_name( AvahiServer *s, AvahiEntryGroup *g, - gint interface, - guchar protocol, + AvahiIfIndex interface, + AvahiProtocol protocol, const gchar *domain, AvahiDNSServerType type, const gchar *name, @@ -319,18 +320,18 @@ typedef enum { typedef struct AvahiRecordBrowser AvahiRecordBrowser; -typedef void (*AvahiRecordBrowserCallback)(AvahiRecordBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata); -AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata); +typedef void (*AvahiRecordBrowserCallback)(AvahiRecordBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata); +AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata); void avahi_record_browser_free(AvahiRecordBrowser *b); typedef struct AvahiHostNameResolver AvahiHostNameResolver; -typedef void (*AvahiHostNameResolverCallback)(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata); -AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback calback, gpointer userdata); +typedef void (*AvahiHostNameResolverCallback)(AvahiHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata); +AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *host_name, AvahiProtocol aprotocol, AvahiHostNameResolverCallback calback, gpointer userdata); void avahi_host_name_resolver_free(AvahiHostNameResolver *r); typedef struct AvahiAddressResolver AvahiAddressResolver; -typedef void (*AvahiAddressResolverCallback)(AvahiAddressResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const AvahiAddress *a, const gchar *host_name, gpointer userdata); -AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback calback, gpointer userdata); +typedef void (*AvahiAddressResolverCallback)(AvahiAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *a, const gchar *host_name, gpointer userdata); +AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const AvahiAddress *address, AvahiAddressResolverCallback calback, gpointer userdata); void avahi_address_resolver_free(AvahiAddressResolver *r); /** The type of domain to browse for */ @@ -343,23 +344,23 @@ typedef enum { } AvahiDomainBrowserType; typedef struct AvahiDomainBrowser AvahiDomainBrowser; -typedef void (*AvahiDomainBrowserCallback)(AvahiDomainBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata); -AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata); +typedef void (*AvahiDomainBrowserCallback)(AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata); +AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata); void avahi_domain_browser_free(AvahiDomainBrowser *b); typedef struct AvahiServiceTypeBrowser AvahiServiceTypeBrowser; -typedef void (*AvahiServiceTypeBrowserCallback)(AvahiServiceTypeBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *type, const gchar *domain, gpointer userdata); -AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiServiceTypeBrowserCallback callback, gpointer userdata); +typedef void (*AvahiServiceTypeBrowserCallback)(AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *type, const gchar *domain, gpointer userdata); +AvahiServiceTypeBrowser *avahi_service_type_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiServiceTypeBrowserCallback callback, gpointer userdata); void avahi_service_type_browser_free(AvahiServiceTypeBrowser *b); typedef struct AvahiServiceBrowser AvahiServiceBrowser; -typedef void (*AvahiServiceBrowserCallback)(AvahiServiceBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *name, const gchar *type, const gchar *domain, gpointer userdata); -AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *service_type, const gchar *domain, AvahiServiceBrowserCallback callback, gpointer userdata); +typedef void (*AvahiServiceBrowserCallback)(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *name, const gchar *type, const gchar *domain, gpointer userdata); +AvahiServiceBrowser *avahi_service_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *service_type, const gchar *domain, AvahiServiceBrowserCallback callback, gpointer userdata); void avahi_service_browser_free(AvahiServiceBrowser *b); typedef struct AvahiServiceResolver AvahiServiceResolver; -typedef void (*AvahiServiceResolverCallback)(AvahiServiceResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *name, const gchar *type, const gchar *domain, const gchar *host_name, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata); -AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *name, const gchar *type, const gchar *domain, guchar aprotocol, AvahiServiceResolverCallback calback, gpointer userdata); +typedef void (*AvahiServiceResolverCallback)(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *name, const gchar *type, const gchar *domain, const gchar *host_name, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata); +AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *name, const gchar *type, const gchar *domain, AvahiProtocol aprotocol, AvahiServiceResolverCallback calback, gpointer userdata); void avahi_service_resolver_free(AvahiServiceResolver *r); @@ -367,8 +368,8 @@ void avahi_service_resolver_free(AvahiServiceResolver *r); * conventional unicast DNS servers which may be used to resolve * conventional domain names */ typedef struct AvahiDNSServerBrowser AvahiDNSServerBrowser; -typedef void (*AvahiDNSServerBrowserCallback)(AvahiDNSServerBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, guint16 port, gpointer userdata); -AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDNSServerType type, guchar aprotocol, AvahiDNSServerBrowserCallback callback, gpointer userdata); +typedef void (*AvahiDNSServerBrowserCallback)(AvahiDNSServerBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, guint16 port, gpointer userdata); +AvahiDNSServerBrowser *avahi_dns_server_browser_new(AvahiServer *server, AvahiIfIndex interface, AvahiProtocol protocol, const gchar *domain, AvahiDNSServerType type, AvahiProtocol aprotocol, AvahiDNSServerBrowserCallback callback, gpointer userdata); void avahi_dns_server_browser_free(AvahiDNSServerBrowser *b); #endif diff --git a/avahi-core/iface.c b/avahi-core/iface.c index 60419df..fb491c9 100644 --- a/avahi-core/iface.c +++ b/avahi-core/iface.c @@ -102,7 +102,7 @@ static void update_hw_interface_rr(AvahiInterfaceMonitor *m, AvahiHwInterface *h g_free(t); hw->entry_group = avahi_entry_group_new(m->server, avahi_host_rr_entry_group_callback, NULL); - if (avahi_server_add_service(m->server, hw->entry_group, hw->index, AF_UNSPEC, "_workstation._tcp", name, NULL, NULL, 9, NULL) < 0) { + if (avahi_server_add_service(m->server, hw->entry_group, hw->index, AVAHI_PROTO_UNSPEC, "_workstation._tcp", name, NULL, NULL, 9, NULL) < 0) { avahi_log_warn(__FILE__": avahi_server_add_service() failed."); avahi_entry_group_free(hw->entry_group); hw->entry_group = NULL; @@ -210,12 +210,12 @@ static int netlink_list_items(AvahiNetlink *nl, guint16 type, guint *ret_seq) { return avahi_netlink_send(nl, n, ret_seq); } -static void new_interface(AvahiInterfaceMonitor *m, AvahiHwInterface *hw, guchar protocol) { +static void new_interface(AvahiInterfaceMonitor *m, AvahiHwInterface *hw, AvahiProtocol protocol) { AvahiInterface *i; g_assert(m); g_assert(hw); - g_assert(protocol != AF_UNSPEC); + g_assert(protocol != AVAHI_PROTO_UNSPEC); i = g_new(AvahiInterface, 1); i->monitor = m; @@ -246,9 +246,9 @@ static void check_interface_relevant(AvahiInterfaceMonitor *m, AvahiInterface *i if (b && !i->announcing) { avahi_log_debug("New relevant interface %s.%i (#%i)", i->hardware->name, i->protocol, i->hardware->index); - if (i->protocol == AF_INET) + if (i->protocol == AVAHI_PROTO_INET) avahi_mdns_mcast_join_ipv4(i->hardware->index, m->server->fd_ipv4); - if (i->protocol == AF_INET6) + if (i->protocol == AVAHI_PROTO_INET6) avahi_mdns_mcast_join_ipv6(i->hardware->index, m->server->fd_ipv6); i->announcing = TRUE; @@ -257,9 +257,9 @@ static void check_interface_relevant(AvahiInterfaceMonitor *m, AvahiInterface *i } else if (!b && i->announcing) { avahi_log_debug("Interface %s.%i no longer relevant", i->hardware->name, i->protocol); - if (i->protocol == AF_INET) + if (i->protocol == AVAHI_PROTO_INET) avahi_mdns_mcast_leave_ipv4(i->hardware->index, m->server->fd_ipv4); - if (i->protocol == AF_INET6) + if (i->protocol == AVAHI_PROTO_INET6) avahi_mdns_mcast_leave_ipv6(i->hardware->index, m->server->fd_ipv6); avahi_goodbye_interface(m->server, i, FALSE); @@ -314,9 +314,9 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) { g_hash_table_insert(m->hash_table, &hw->index, hw); if (m->server->fd_ipv4 >= 0) - new_interface(m, hw, AF_INET); + new_interface(m, hw, AVAHI_PROTO_INET); if (m->server->fd_ipv6 >= 0) - new_interface(m, hw, AF_INET6); + new_interface(m, hw, AVAHI_PROTO_INET6); } hw->flags = ifinfomsg->ifi_flags; @@ -377,7 +377,7 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) { AvahiAddress raddr; gboolean raddr_valid = FALSE; - if (ifaddrmsg->ifa_family != AF_INET && ifaddrmsg->ifa_family != AF_INET6) + if (ifaddrmsg->ifa_family != AVAHI_PROTO_INET && ifaddrmsg->ifa_family != AVAHI_PROTO_INET6) return; if (!(i = (AvahiInterface*) avahi_interface_monitor_get_interface(m, ifaddrmsg->ifa_index, ifaddrmsg->ifa_family))) @@ -392,15 +392,15 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) { switch(a->rta_type) { case IFA_ADDRESS: - if ((raddr.family == AF_INET6 && RTA_PAYLOAD(a) != 16) || - (raddr.family == AF_INET && RTA_PAYLOAD(a) != 4)) + if ((raddr.family == AVAHI_PROTO_INET6 && RTA_PAYLOAD(a) != 16) || + (raddr.family == AVAHI_PROTO_INET && RTA_PAYLOAD(a) != 4)) return; memcpy(raddr.data.data, RTA_DATA(a), RTA_PAYLOAD(a)); raddr_valid = TRUE; break; - + default: ; } @@ -426,6 +426,7 @@ static void callback(AvahiNetlink *nl, struct nlmsghdr *n, gpointer userdata) { addr->flags = ifaddrmsg->ifa_flags; addr->scope = ifaddrmsg->ifa_scope; + addr->prefix_len = ifaddrmsg->ifa_prefixlen; update_address_rr(m, addr, FALSE); check_interface_relevant(m, i); @@ -516,13 +517,13 @@ void avahi_interface_monitor_free(AvahiInterfaceMonitor *m) { } -AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, gint index, guchar protocol) { +AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, AvahiIfIndex index, AvahiProtocol protocol) { AvahiHwInterface *hw; AvahiInterface *i; g_assert(m); g_assert(index > 0); - g_assert(protocol != AF_UNSPEC); + g_assert(protocol != AVAHI_PROTO_UNSPEC); if (!(hw = avahi_interface_monitor_get_hw_interface(m, index))) return NULL; @@ -534,7 +535,7 @@ AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, return NULL; } -AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor *m, gint index) { +AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor *m, AvahiIfIndex index) { g_assert(m); g_assert(index > 0); @@ -557,9 +558,9 @@ void avahi_interface_send_packet_unicast(AvahiInterface *i, AvahiDnsPacket *p, c /* else */ /* avahi_log_debug("multicast sending on '%s.%i'", i->hardware->name, i->protocol); */ - if (i->protocol == AF_INET && i->monitor->server->fd_ipv4 >= 0) + if (i->protocol == AVAHI_PROTO_INET && i->monitor->server->fd_ipv4 >= 0) avahi_send_dns_packet_ipv4(i->monitor->server->fd_ipv4, i->hardware->index, p, a ? &a->data.ipv4 : NULL, port); - else if (i->protocol == AF_INET6 && i->monitor->server->fd_ipv6 >= 0) + else if (i->protocol == AVAHI_PROTO_INET6 && i->monitor->server->fd_ipv6 >= 0) avahi_send_dns_packet_ipv6(i->monitor->server->fd_ipv6, i->hardware->index, p, a ? &a->data.ipv6 : NULL, port); } @@ -650,24 +651,24 @@ gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a) { } -gboolean avahi_interface_match(AvahiInterface *i, gint index, guchar protocol) { +gboolean avahi_interface_match(AvahiInterface *i, AvahiIfIndex index, AvahiProtocol protocol) { g_assert(i); if (index > 0 && index != i->hardware->index) return FALSE; - if (protocol != AF_UNSPEC && protocol != i->protocol) + if (protocol != AVAHI_PROTO_UNSPEC && protocol != i->protocol) return FALSE; return TRUE; } -void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint interface, guchar protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata) { +void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, AvahiIfIndex interface, AvahiProtocol protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata) { g_assert(m); g_assert(callback); if (interface > 0) { - if (protocol != AF_UNSPEC) { + if (protocol != AVAHI_PROTO_UNSPEC) { AvahiInterface *i; if ((i = avahi_interface_monitor_get_interface(m, interface, protocol))) @@ -714,3 +715,51 @@ gboolean avahi_address_is_local(AvahiInterfaceMonitor *m, const AvahiAddress *a) return FALSE; } + +gboolean avahi_interface_address_on_link(AvahiInterface *i, const AvahiAddress *a) { + AvahiInterfaceAddress *ia; + + g_assert(i); + g_assert(a); + + if (a->family != i->protocol) + return FALSE; + + for (ia = i->addresses; ia; ia = ia->address_next) { + + if (a->family == AVAHI_PROTO_INET) { + guint32 m; + + m = ~(((guint32) -1) >> ia->prefix_len); + + if ((g_ntohl(a->data.ipv4.address) & m) == (g_ntohl(ia->address.data.ipv4.address) & m)) + return TRUE; + } else { + guint i; + guchar pl; + g_assert(a->family == AVAHI_PROTO_INET6); + + pl = ia->prefix_len; + + for (i = 0; i < 16; i++) { + guint8 m; + + if (pl == 0) + return TRUE; + + if (pl >= 8) { + m = 0xFF; + pl -= 8; + } else { + m = ~(0xFF >> pl); + pl = 0; + } + + if ((a->data.ipv6.address[i] & m) != (ia->address.data.ipv6.address[i] & m)) + break; + } + } + } + + return FALSE; +} diff --git a/avahi-core/iface.h b/avahi-core/iface.h index 1372e6f..486207e 100644 --- a/avahi-core/iface.h +++ b/avahi-core/iface.h @@ -64,7 +64,7 @@ struct AvahiHwInterface { AvahiInterfaceMonitor *monitor; gchar *name; - gint index; + AvahiIfIndex index; guint flags; guint mtu; @@ -82,7 +82,7 @@ struct AvahiInterface { AvahiInterfaceMonitor *monitor; AvahiHwInterface *hardware; - guchar protocol; + AvahiProtocol protocol; gboolean announcing; AvahiCache *cache; @@ -100,6 +100,7 @@ struct AvahiInterfaceAddress { guchar flags; guchar scope; + guchar prefix_len; AvahiAddress address; AvahiEntryGroup *entry_group; @@ -111,7 +112,7 @@ void avahi_interface_monitor_free(AvahiInterfaceMonitor *m); void avahi_interface_monitor_sync(AvahiInterfaceMonitor *m); -AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, gint index, guchar protocol); +AvahiInterface* avahi_interface_monitor_get_interface(AvahiInterfaceMonitor *m, AvahiIfIndex index, AvahiProtocol protocol); AvahiHwInterface* avahi_interface_monitor_get_hw_interface(AvahiInterfaceMonitor *m, gint index); void avahi_interface_send_packet(AvahiInterface *i, AvahiDnsPacket *p); @@ -126,14 +127,17 @@ void avahi_dump_caches(AvahiInterfaceMonitor *m, FILE *f); gboolean avahi_interface_relevant(AvahiInterface *i); gboolean avahi_interface_address_relevant(AvahiInterfaceAddress *a); -gboolean avahi_interface_match(AvahiInterface *i, gint index, guchar protocol); +gboolean avahi_interface_match(AvahiInterface *i, AvahiIfIndex index, AvahiProtocol protocol); typedef void (*AvahiInterfaceMonitorWalkCallback)(AvahiInterfaceMonitor *m, AvahiInterface *i, gpointer userdata); -void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, gint index, guchar protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata); +void avahi_interface_monitor_walk(AvahiInterfaceMonitor *m, AvahiIfIndex index, AvahiProtocol protocol, AvahiInterfaceMonitorWalkCallback callback, gpointer userdata); void avahi_update_host_rrs(AvahiInterfaceMonitor *m, gboolean remove); gboolean avahi_address_is_local(AvahiInterfaceMonitor *m, const AvahiAddress *a); +gboolean avahi_interface_address_on_link(AvahiInterface *i, const AvahiAddress *a); + + #endif diff --git a/avahi-core/resolve-address.c b/avahi-core/resolve-address.c index 07cbef4..a4ed594 100644 --- a/avahi-core/resolve-address.c +++ b/avahi-core/resolve-address.c @@ -75,7 +75,7 @@ static void time_event_callback(AvahiTimeEvent *e, void *userdata) { g_assert(e); g_assert(r); - finish(r, -1, AF_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL); + finish(r, -1, AVAHI_PROTO_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL); } AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback callback, gpointer userdata) { @@ -88,7 +88,7 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint inter g_assert(address); g_assert(callback); - g_assert(address->family == AF_INET || address->family == AF_INET6); + g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6); r = g_new(AvahiAddressResolver, 1); r->server = server; @@ -101,7 +101,7 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint inter AVAHI_LLIST_PREPEND(AvahiAddressResolver, resolver, server->address_resolvers, r); - if (address->family == AF_INET) + if (address->family == AVAHI_PROTO_INET) n = avahi_reverse_lookup_name_ipv4(&address->data.ipv4); else n = avahi_reverse_lookup_name_ipv6_arpa(&address->data.ipv6); diff --git a/avahi-core/resolve-host-name.c b/avahi-core/resolve-host-name.c index c10119a..fadfc85 100644 --- a/avahi-core/resolve-host-name.c +++ b/avahi-core/resolve-host-name.c @@ -64,12 +64,12 @@ static void finish(AvahiHostNameResolver *r, gint interface, guchar protocol, Av if (record) { switch (record->key->type) { case AVAHI_DNS_TYPE_A: - a.family = AF_INET; + a.family = AVAHI_PROTO_INET; a.data.ipv4 = record->data.a.address; break; case AVAHI_DNS_TYPE_AAAA: - a.family = AF_INET6; + a.family = AVAHI_PROTO_INET6; a.data.ipv6 = record->data.aaaa.address; break; @@ -101,7 +101,7 @@ static void time_event_callback(AvahiTimeEvent *e, void *userdata) { g_assert(e); g_assert(r); - finish(r, -1, AF_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL); + finish(r, -1, AVAHI_PROTO_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL); } AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback callback, gpointer userdata) { @@ -113,7 +113,7 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint in g_assert(host_name); g_assert(callback); - g_assert(aprotocol == AF_UNSPEC || aprotocol == AF_INET || aprotocol == AF_INET6); + g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6); r = g_new(AvahiHostNameResolver, 1); r->server = server; @@ -128,13 +128,13 @@ AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint in AVAHI_LLIST_PREPEND(AvahiHostNameResolver, resolver, server->host_name_resolvers, r); - if (aprotocol == AF_INET || aprotocol == AF_UNSPEC) { + if (aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_UNSPEC) { k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A); r->record_browser_a = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); } - if (aprotocol == AF_INET6 || aprotocol == AF_UNSPEC) { + if (aprotocol == AVAHI_PROTO_INET6 || aprotocol == AVAHI_PROTO_UNSPEC) { k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA); r->record_browser_aaaa = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r); avahi_key_unref(k); diff --git a/avahi-core/resolve-service.c b/avahi-core/resolve-service.c index deb4cdb..8fe9fd2 100644 --- a/avahi-core/resolve-service.c +++ b/avahi-core/resolve-service.c @@ -94,12 +94,12 @@ static void finish(AvahiServiceResolver *r, AvahiResolverEvent event) { switch (r->address_record->key->type) { case AVAHI_DNS_TYPE_A: - a.family = AF_INET; + a.family = AVAHI_PROTO_INET; a.data.ipv4 = r->address_record->data.a.address; break; case AVAHI_DNS_TYPE_AAAA: - a.family = AF_INET6; + a.family = AVAHI_PROTO_INET6; a.data.ipv6 = r->address_record->data.aaaa.address; break; @@ -134,13 +134,13 @@ static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, gucha if (r->interface > 0 && interface != r->interface) return; - if (r->protocol != AF_UNSPEC && protocol != r->protocol) + if (r->protocol != AVAHI_PROTO_UNSPEC && protocol != r->protocol) return; if (r->interface <= 0) r->interface = interface; - if (r->protocol == AF_UNSPEC) + if (r->protocol == AVAHI_PROTO_UNSPEC) r->protocol = protocol; switch (record->key->type) { @@ -150,13 +150,13 @@ static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, gucha g_assert(!r->record_browser_a && !r->record_browser_aaaa); - if (r->address_protocol == AF_INET || r->address_protocol == AF_UNSPEC) { + if (r->address_protocol == AVAHI_PROTO_INET || r->address_protocol == AVAHI_PROTO_UNSPEC) { AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A); r->record_browser_a = avahi_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r); avahi_key_unref(k); } - if (r->address_protocol == AF_INET6 || r->address_protocol == AF_UNSPEC) { + if (r->address_protocol == AVAHI_PROTO_INET6 || r->address_protocol == AVAHI_PROTO_UNSPEC) { AvahiKey *k = avahi_key_new(r->srv_record->data.srv.name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA); r->record_browser_aaaa = avahi_record_browser_new(r->server, r->interface, r->protocol, k, record_browser_callback, r); avahi_key_unref(k); @@ -204,7 +204,7 @@ AvahiServiceResolver *avahi_service_resolver_new(AvahiServer *server, gint inter g_assert(type); g_assert(callback); - g_assert(aprotocol == AF_UNSPEC || aprotocol == AF_INET || aprotocol == AF_INET6); + g_assert(aprotocol == AVAHI_PROTO_UNSPEC || aprotocol == AVAHI_PROTO_INET || aprotocol == AVAHI_PROTO_INET6); r = g_new(AvahiServiceResolver, 1); r->server = server; diff --git a/avahi-core/server.c b/avahi-core/server.c index 0e92e27..19badd1 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -600,7 +600,7 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac goto fail; } - if (record->key->type != AVAHI_DNS_TYPE_ANY) { + if (!avahi_key_is_pattern(record->key)) { reflect_probe(s, i, record); incoming_probe(s, record, i); } @@ -638,7 +638,7 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter break; } - if (record->key->type != AVAHI_DNS_TYPE_ANY) { + if (!avahi_key_is_pattern(record->key)) { /* avahi_log_debug("Handling response: %s", txt = avahi_record_to_string(record)); */ /* g_free(txt); */ @@ -788,9 +788,9 @@ static void reflect_legacy_unicast_query_packet(AvahiServer *s, AvahiDnsPacket * j != i && (s->config.reflect_ipv || j->protocol == i->protocol)) { - if (j->protocol == AF_INET && s->fd_legacy_unicast_ipv4 >= 0) { + if (j->protocol == AVAHI_PROTO_INET && s->fd_legacy_unicast_ipv4 >= 0) { avahi_send_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, j->hardware->index, p, NULL, 0); - } else if (j->protocol == AF_INET6 && s->fd_legacy_unicast_ipv6 >= 0) + } else if (j->protocol == AVAHI_PROTO_INET6 && s->fd_legacy_unicast_ipv6 >= 0) avahi_send_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, j->hardware->index, p, NULL, 0); } @@ -835,7 +835,15 @@ static gboolean originates_from_local_legacy_unicast_socket(AvahiServer *s, cons return FALSE; } -static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, gint iface, gint ttl) { +static gboolean is_mdns_mcast_address(const AvahiAddress *a) { + AvahiAddress b; + g_assert(a); + + avahi_address_parse(a->family == AVAHI_PROTO_INET ? AVAHI_IPV4_MCAST_GROUP : AVAHI_IPV6_MCAST_GROUP, a->family, &b); + return avahi_address_cmp(a, &b) == 0; +} + +static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, AvahiAddress *dest, AvahiIfIndex iface, gint ttl) { AvahiInterface *i; AvahiAddress a; guint16 port; @@ -843,6 +851,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock g_assert(s); g_assert(p); g_assert(sa); + g_assert(dest); g_assert(iface > 0); if (!(i = avahi_interface_monitor_get_interface(s->monitor, iface, sa->sa_family)) || @@ -896,18 +905,22 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock /* avahi_log_debug("Handled query"); */ } else { - if (port != AVAHI_MDNS_PORT) { avahi_log_warn("Recieved repsonse with invalid source port %u on interface '%s.%i'", port, i->hardware->name, i->protocol); return; } - if (ttl != 255) { + if (ttl != 255 && s->config.check_response_ttl) { avahi_log_warn("Recieved response with invalid TTL %u on interface '%s.%i'.", ttl, i->hardware->name, i->protocol); - if (s->config.check_response_ttl) - return; + return; } + if (!is_mdns_mcast_address(dest) && + !avahi_interface_address_on_link(i, &a)) { + avahi_log_warn("Recivied non-local response on interface '%s.%i'.", i->hardware->name, i->protocol); + return; + } + if (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_QDCOUNT) != 0 || avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT) == 0 || avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT) != 0) { @@ -920,7 +933,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock } } -static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, gint iface, gint ttl) { +static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, AvahiIfIndex iface, gint ttl) { AvahiInterface *i, *j; AvahiAddress a; guint16 port; @@ -973,6 +986,7 @@ static void dispatch_legacy_unicast_packet(AvahiServer *s, AvahiDnsPacket *p, co static void work(AvahiServer *s) { struct sockaddr_in6 sa6; struct sockaddr_in sa; + AvahiAddress dest; AvahiDnsPacket *p; gint iface = 0; guint8 ttl; @@ -980,28 +994,32 @@ static void work(AvahiServer *s) { g_assert(s); if (s->fd_ipv4 >= 0 && (s->pollfd_ipv4.revents & G_IO_IN)) { - if ((p = avahi_recv_dns_packet_ipv4(s->fd_ipv4, &sa, &iface, &ttl))) { - dispatch_packet(s, p, (struct sockaddr*) &sa, iface, ttl); + dest.family = AVAHI_PROTO_INET; + if ((p = avahi_recv_dns_packet_ipv4(s->fd_ipv4, &sa, &dest.data.ipv4, &iface, &ttl))) { + dispatch_packet(s, p, (struct sockaddr*) &sa, &dest, iface, ttl); avahi_dns_packet_free(p); } } if (s->fd_ipv6 >= 0 && (s->pollfd_ipv6.revents & G_IO_IN)) { - if ((p = avahi_recv_dns_packet_ipv6(s->fd_ipv6, &sa6, &iface, &ttl))) { - dispatch_packet(s, p, (struct sockaddr*) &sa6, iface, ttl); + dest.family = AVAHI_PROTO_INET6; + if ((p = avahi_recv_dns_packet_ipv6(s->fd_ipv6, &sa6, &dest.data.ipv6, &iface, &ttl))) { + dispatch_packet(s, p, (struct sockaddr*) &sa6, &dest, iface, ttl); avahi_dns_packet_free(p); } } if (s->fd_legacy_unicast_ipv4 >= 0 && (s->pollfd_legacy_unicast_ipv4.revents & G_IO_IN)) { - if ((p = avahi_recv_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, &sa, &iface, &ttl))) { + dest.family = AVAHI_PROTO_INET; + if ((p = avahi_recv_dns_packet_ipv4(s->fd_legacy_unicast_ipv4, &sa, &dest.data.ipv4, &iface, &ttl))) { dispatch_legacy_unicast_packet(s, p, (struct sockaddr*) &sa, iface, ttl); avahi_dns_packet_free(p); } } if (s->fd_legacy_unicast_ipv6 >= 0 && (s->pollfd_legacy_unicast_ipv6.revents & G_IO_IN)) { - if ((p = avahi_recv_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, &sa6, &iface, &ttl))) { + dest.family = AVAHI_PROTO_INET6; + if ((p = avahi_recv_dns_packet_ipv6(s->fd_legacy_unicast_ipv6, &sa6, &dest.data.ipv6, &iface, &ttl))) { dispatch_legacy_unicast_packet(s, p, (struct sockaddr*) &sa6, iface, ttl); avahi_dns_packet_free(p); } @@ -1126,7 +1144,7 @@ static void register_hinfo(AvahiServer *s) { uname(&utsname); r->data.hinfo.cpu = g_strdup(g_strup(utsname.machine)); r->data.hinfo.os = g_strdup(g_strup(utsname.sysname)); - avahi_server_add(s, s->hinfo_entry_group, 0, AF_UNSPEC, AVAHI_ENTRY_UNIQUE, r); + avahi_server_add(s, s->hinfo_entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_ENTRY_UNIQUE, r); avahi_record_unref(r); avahi_entry_group_commit(s->hinfo_entry_group); @@ -1137,11 +1155,11 @@ static void register_localhost(AvahiServer *s) { g_assert(s); /* Add localhost entries */ - avahi_address_parse("127.0.0.1", AF_INET, &a); - avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "localhost", &a); + avahi_address_parse("127.0.0.1", AVAHI_PROTO_INET, &a); + avahi_server_add_address(s, NULL, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "localhost", &a); - avahi_address_parse("::1", AF_INET6, &a); - avahi_server_add_address(s, NULL, 0, AF_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a); + avahi_address_parse("::1", AVAHI_PROTO_INET6, &a); + avahi_server_add_address(s, NULL, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_ENTRY_NOPROBE|AVAHI_ENTRY_NOANNOUNCE, "ip6-localhost", &a); } static void register_browse_domain(AvahiServer *s) { @@ -1151,7 +1169,7 @@ static void register_browse_domain(AvahiServer *s) { return; s->browse_domain_entry_group = avahi_entry_group_new(s, NULL, NULL); - avahi_server_add_ptr(s, s->browse_domain_entry_group, 0, AF_UNSPEC, 0, "b._dns-sd._udp.local", s->domain_name); + avahi_server_add_ptr(s, s->browse_domain_entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "b._dns-sd._udp.local", s->domain_name); avahi_entry_group_commit(s->browse_domain_entry_group); } @@ -1429,8 +1447,8 @@ static gint check_record_conflict(AvahiServer *s, gint interface, guchar protoco if (interface <= 0 || e->interface <= 0 || e->interface == interface || - protocol == AF_UNSPEC || - e->protocol == AF_UNSPEC || + protocol == AVAHI_PROTO_UNSPEC || + e->protocol == AVAHI_PROTO_UNSPEC || e->protocol == protocol) return -1; @@ -1449,10 +1467,12 @@ gint avahi_server_add( AvahiRecord *r) { AvahiEntry *e, *t; + g_assert(s); g_assert(r); - g_assert(r->key->type != AVAHI_DNS_TYPE_ANY); + if (avahi_key_is_pattern(r->key)) + return -1; if (check_record_conflict(s, interface, protocol, r, flags) < 0) return -1; @@ -1559,7 +1579,7 @@ gint avahi_server_add_address( name = name ? (n = avahi_normalize_name(name)) : s->host_name_fqdn; - if (a->family == AF_INET) { + if (a->family == AVAHI_PROTO_INET) { gchar *reverse; AvahiRecord *r; @@ -1809,9 +1829,9 @@ gint avahi_server_add_dns_server_address( g_assert(s); g_assert(address); g_assert(type == AVAHI_DNS_SERVER_UPDATE || type == AVAHI_DNS_SERVER_RESOLVE); - g_assert(address->family == AF_INET || address->family == AF_INET6); + g_assert(address->family == AVAHI_PROTO_INET || address->family == AVAHI_PROTO_INET6); - if (address->family == AF_INET) { + if (address->family == AVAHI_PROTO_INET) { hexstring(n+2, sizeof(n)-2, &address->data, 4); r = avahi_record_new_full(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A); r->data.a.address = address->data.ipv4; @@ -2019,7 +2039,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) { c->use_ipv4 = TRUE; c->host_name = NULL; c->domain_name = NULL; - c->check_response_ttl = TRUE; + c->check_response_ttl = FALSE; c->publish_hinfo = TRUE; c->publish_addresses = TRUE; c->publish_workstation = TRUE; diff --git a/avahi-core/socket.c b/avahi-core/socket.c index b635dca..1b1f2fd 100644 --- a/avahi-core/socket.c +++ b/avahi-core/socket.c @@ -48,7 +48,7 @@ static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) { ret_sa->sin_family = AF_INET; ret_sa->sin_port = htons(AVAHI_MDNS_PORT); - inet_pton(AF_INET, "224.0.0.251", &ret_sa->sin_addr); + inet_pton(AF_INET, AVAHI_IPV4_MCAST_GROUP, &ret_sa->sin_addr); } static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) { @@ -59,7 +59,7 @@ static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) { ret_sa->sin6_family = AF_INET6; ret_sa->sin6_port = htons(AVAHI_MDNS_PORT); - inet_pton(AF_INET6, "ff02::fb", &ret_sa->sin6_addr); + inet_pton(AF_INET6, AVAHI_IPV6_MCAST_GROUP, &ret_sa->sin6_addr); } static void ipv4_address_to_sockaddr(struct sockaddr_in *ret_sa, const AvahiIPv4Address *a, guint16 port) { @@ -399,7 +399,7 @@ gint avahi_send_dns_packet_ipv4(gint fd, gint interface, AvahiDnsPacket *p, cons msg.msg_controllen = sizeof(cmsg_data); msg.msg_flags = 0; - return sendmsg_loop(fd, &msg, MSG_DONTROUTE); + return sendmsg_loop(fd, &msg, 0 /*MSG_DONTROUTE*/); } gint avahi_send_dns_packet_ipv6(gint fd, gint interface, AvahiDnsPacket *p, const AvahiIPv6Address *a, guint16 port) { @@ -441,10 +441,10 @@ gint avahi_send_dns_packet_ipv6(gint fd, gint interface, AvahiDnsPacket *p, cons msg.msg_controllen = sizeof(cmsg_data); msg.msg_flags = 0; - return sendmsg_loop(fd, &msg, MSG_DONTROUTE); + return sendmsg_loop(fd, &msg, 0 /*MSG_DONTROUTE*/); } -AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, gint *ret_iface, guint8* ret_ttl) { +AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, AvahiIPv4Address *ret_dest_address, gint *ret_iface, guint8* ret_ttl) { AvahiDnsPacket *p= NULL; struct msghdr msg; struct iovec io; @@ -456,6 +456,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, g_assert(fd >= 0); g_assert(ret_sa); + g_assert(ret_dest_address); g_assert(ret_iface); g_assert(ret_ttl); @@ -487,8 +488,6 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, /* Linux 2.4 behaves very strangely sometimes! */ avahi_hexdump(AVAHI_DNS_PACKET_DATA(p), l); - - goto fail; } @@ -510,7 +509,9 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, *ret_ttl = (uint8_t) (*(int *) CMSG_DATA(cmsg)); found_ttl = TRUE; } else if (cmsg->cmsg_type == IP_PKTINFO) { - *ret_iface = (gint) ((struct in_pktinfo*) CMSG_DATA(cmsg))->ipi_ifindex; + struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg); + *ret_iface = (gint) i->ipi_ifindex; + ret_dest_address->address = i->ipi_addr.s_addr; found_iface = TRUE; } } @@ -530,7 +531,7 @@ fail: return NULL; } -AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, gint *ret_iface, guint8* ret_ttl) { +AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, AvahiIPv6Address *ret_dest_address, gint *ret_iface, guint8* ret_ttl) { AvahiDnsPacket *p = NULL; struct msghdr msg; struct iovec io; @@ -543,6 +544,7 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, g_assert(fd >= 0); g_assert(ret_sa); + g_assert(ret_dest_address); g_assert(ret_iface); g_assert(ret_ttl); @@ -581,7 +583,9 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, } if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { - *ret_iface = ((struct in6_pktinfo*) CMSG_DATA(cmsg))->ipi6_ifindex; + struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg); + *ret_iface = i->ipi6_ifindex; + memcpy(ret_dest_address->address, i->ipi6_addr.s6_addr, 16); found_iface = TRUE; } } diff --git a/avahi-core/socket.h b/avahi-core/socket.h index 03eafb0..dc0bbdd 100644 --- a/avahi-core/socket.h +++ b/avahi-core/socket.h @@ -27,6 +27,8 @@ #include "dns.h" #define AVAHI_MDNS_PORT 5353 +#define AVAHI_IPV4_MCAST_GROUP "224.0.0.251" +#define AVAHI_IPV6_MCAST_GROUP "ff02::fb" gint avahi_open_socket_ipv4(void); gint avahi_open_socket_ipv6(void); @@ -37,8 +39,8 @@ gint avahi_open_legacy_unicast_socket_ipv6(void); gint avahi_send_dns_packet_ipv4(gint fd, gint iface, AvahiDnsPacket *p, const AvahiIPv4Address *a, guint16 port); gint avahi_send_dns_packet_ipv6(gint fd, gint iface, AvahiDnsPacket *p, const AvahiIPv6Address *a, guint16 port); -AvahiDnsPacket *avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in*ret_sa, gint *ret_iface, guint8 *ret_ttl); -AvahiDnsPacket *avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6*ret_sa, gint *ret_iface, guint8 *ret_ttl); +AvahiDnsPacket *avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in*ret_sa, AvahiIPv4Address *ret_dest_address, gint *ret_iface, guint8 *ret_ttl); +AvahiDnsPacket *avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6*ret_sa, AvahiIPv6Address *ret_dest_address, gint *ret_iface, guint8 *ret_ttl); int avahi_mdns_mcast_join_ipv4(int index, int fd); int avahi_mdns_mcast_join_ipv6(int index, int fd); diff --git a/avahi-daemon/avahi.conf b/avahi-daemon/avahi.conf index 82f5326..fc47ecf 100644 --- a/avahi-daemon/avahi.conf +++ b/avahi-daemon/avahi.conf @@ -3,7 +3,7 @@ #domain-name=local use-ipv4=yes use-ipv6=no -check-response-ttl=yes +check-response-ttl=no use-iff-running=yes enable-dbus=yes -- 2.39.5