propagate unicast bit
authorJohn Crispin <blogic@openwrt.org>
Tue, 2 Sep 2014 13:23:57 +0000 (15:23 +0200)
committerJohn Crispin <blogic@openwrt.org>
Tue, 2 Sep 2014 14:28:55 +0000 (16:28 +0200)
Signed-off-by: John Crispin <blogic@openwrt.org>
announce.c
cache.c
dns.c
dns.h
interface.c
interface.h

index 481523c12a9a426ca773f6317b5d5fdd4224917e..10389b8c662e3ac07deeaf7d5f66509084fb64d1 100644 (file)
@@ -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 c78a3b7a9b438118b369c68c3102fd62cad0b9ee..6240e2f2c8ee80a9fe7751853cd3ef61c6022d11 100644 (file)
--- 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 961c2d0a2fded8459f23adde7432ca05b14c4202..4f82849ef6f64e44c17a3ae5df7a6bc8f9818a19 100644 (file)
--- 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 492b2e8875546df57bbc6236d504183b8c3844c7..92f4c08a05815a82f2552cc4bc77b49f86c9b8dd 100644 (file)
--- 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);
index dc654158eb2bab53cfcc74e5e109af1789eee97b..c84bacbdc26b5fabbed610e6cc83d70a8e3abbcd 100644 (file)
@@ -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;
                }
        }
 
index 2f7aea4c5e69e93331dd79aaebd44b54bc4fe5b2..545369da431b3c89e05a66a0bf5d907530717012 100644 (file)
@@ -27,6 +27,7 @@ extern struct vlist_tree interfaces;
 
 struct interface {
        struct vlist_node node;
+       struct interface *peer;
 
        const char *name;
        char *id;