From 6d1e112ec8f6dd6c1f594b028e2d0e0052d9d12f Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 2 Sep 2014 15:23:57 +0200 Subject: [PATCH] propagate unicast bit Signed-off-by: John Crispin --- announce.c | 2 +- cache.c | 4 ++-- dns.c | 10 ++++++++-- dns.h | 4 ++-- interface.c | 13 ++++++++++--- interface.h | 1 + 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/announce.c b/announce.c index 481523c..10389b8 100644 --- a/announce.c +++ b/announce.c @@ -46,7 +46,7 @@ announce_timer(struct uloop_timeout *timeout) case STATE_PROBE1: case STATE_PROBE2: case STATE_PROBE3: - dns_send_question(iface, mdns_hostname_local, TYPE_ANY); + dns_send_question(iface, mdns_hostname_local, TYPE_ANY, 0); uloop_timeout_set(timeout, 250); iface->announce_state++; break; diff --git a/cache.c b/cache.c index c78a3b7..6240e2f 100644 --- a/cache.c +++ b/cache.c @@ -120,7 +120,7 @@ cache_scan(void) vlist_for_each_element(&interfaces, iface, node) avl_for_each_element(&entries, s, avl) - dns_send_question(iface, s->entry, TYPE_PTR); + dns_send_question(iface, s->entry, TYPE_PTR, 1); } static struct cache_entry* @@ -154,7 +154,7 @@ cache_entry(struct interface *iface, char *entry, int hlen, int ttl) avl_insert(&entries, &s->avl); if (!hlen) - dns_send_question(iface, entry, TYPE_PTR); + dns_send_question(iface, entry, TYPE_PTR, !iface->multicast); return s; } diff --git a/dns.c b/dns.c index 961c2d0..4f82849 100644 --- a/dns.c +++ b/dns.c @@ -66,7 +66,7 @@ dns_type_string(uint16_t type) } void -dns_send_question(struct interface *iface, const char *question, int type) +dns_send_question(struct interface *iface, const char *question, int type, int unicast) { static struct dns_header h; static struct dns_question q; @@ -86,7 +86,7 @@ dns_send_question(struct interface *iface, const char *question, int type) int len; h.questions = cpu_to_be16(1); - q.class = cpu_to_be16(1); + q.class = cpu_to_be16(((unicast) ? (CLASS_UNICAST) : (0)) | 1); q.type = cpu_to_be16(type); len = dn_comp(question, (void *) name_buffer, sizeof(name_buffer), NULL, NULL); @@ -95,6 +95,9 @@ dns_send_question(struct interface *iface, const char *question, int type) iov[1].iov_len = len; + if (unicast == iface->multicast) + iface = iface->peer; + if (interface_send_packet(iface, iov, ARRAY_SIZE(iov)) < 0) fprintf(stderr, "failed to send question\n"); else @@ -320,6 +323,9 @@ parse_question(struct interface *iface, char *name, struct dns_question *q) { char *host; + if ((q->class & CLASS_UNICAST) && iface->multicast) + iface = iface->peer; + DBG(1, "Q -> %s %s\n", dns_type_string(q->type), name); switch (q->type) { diff --git a/dns.h b/dns.h index 492b2e8..92f4c08 100644 --- a/dns.h +++ b/dns.h @@ -32,7 +32,7 @@ #define MCAST_ADDR6 "ff02::fb" #define MCAST_PORT 5353 -#define CLASS_FLUSH 0x8000 +#define CLASS_UNICAST 0x8000 #define CLASS_IN 0x0001 #define MAX_NAME_LEN 8096 @@ -70,7 +70,7 @@ struct dns_question { struct interface; extern int cfg_proto; -void dns_send_question(struct interface *iface, const char *question, int type); +void dns_send_question(struct interface *iface, const char *question, int type, int unicast); void dns_init_answer(void); void dns_add_answer(int type, const uint8_t *rdata, uint16_t rdlength, int ttl); void dns_send_answer(struct interface *iface, const char *answer); diff --git a/interface.c b/interface.c index dc65415..c84bacb 100644 --- a/interface.c +++ b/interface.c @@ -363,8 +363,9 @@ reconnect_socket4(struct uloop_timeout *timeout) } uloop_fd_add(&iface->fd, ULOOP_READ); - dns_send_question(iface, "_services._dns-sd._udp.local", TYPE_PTR); - announce_init(iface); + dns_send_question(iface, "_services._dns-sd._udp.local", TYPE_PTR, 1); + if (iface->multicast) + announce_init(iface); return; @@ -405,7 +406,7 @@ reconnect_socket6(struct uloop_timeout *timeout) } uloop_fd_add(&iface->fd, ULOOP_READ); - dns_send_question(iface, "_services._dns-sd._udp.local", TYPE_PTR); + dns_send_question(iface, "_services._dns-sd._udp.local", TYPE_PTR, 1); announce_init(iface); return; @@ -506,6 +507,9 @@ int interface_add(const char *name) memcpy(&unicast->v4_addr, &sa->sin_addr, sizeof(unicast->v4_addr)); inet_ntop(AF_INET, &sa->sin_addr, unicast->v4_addrs, sizeof(unicast->v4_addrs)); + + v4->peer = unicast; + unicast->peer = v4; } if (ifa->ifa_addr->sa_family == AF_INET6 && !v6) { @@ -531,6 +535,9 @@ int interface_add(const char *name) memcpy(&unicast->v6_addr, &sa6->sin6_addr, sizeof(unicast->v6_addr)); inet_ntop(AF_INET6, &sa6->sin6_addr, unicast->v6_addrs, sizeof(unicast->v6_addrs)); + + v6->peer = unicast; + unicast->peer = v6; } } diff --git a/interface.h b/interface.h index 2f7aea4..545369d 100644 --- a/interface.h +++ b/interface.h @@ -27,6 +27,7 @@ extern struct vlist_tree interfaces; struct interface { struct vlist_node node; + struct interface *peer; const char *name; char *id; -- 2.25.1