From: Rafał Miłecki <[email protected]>

Whenever we send A(AAA) records, let's also include reverse lookup ones.
This should be extended in the future by adding IPv6.

Signed-off-by: Rafał Miłecki <[email protected]>
---
 announce.c  |  2 +-
 dns.c       | 38 +++++++++++++++++++++++++++++++++++---
 dns.h       |  2 +-
 interface.c |  2 +-
 4 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/announce.c b/announce.c
index 7bbce4a..8d9b080 100644
--- a/announce.c
+++ b/announce.c
@@ -65,7 +65,7 @@ announce_timer(struct uloop_timeout *timeout)
                        /* Fall through */
 
                case STATE_ANNOUNCE:
-                       dns_reply_a(iface, announce_ttl);
+                       dns_reply_domain_name(iface, announce_ttl);
                        service_announce(iface, announce_ttl);
                        uloop_timeout_set(timeout, announce_ttl * 800);
                        break;
diff --git a/dns.c b/dns.c
index de0c21a..e5703aa 100644
--- a/dns.c
+++ b/dns.c
@@ -181,7 +181,7 @@ dns_send_answer(struct interface *iface, const char *answer)
                fprintf(stderr, "failed to send question\n");
 }
 
-void
+static void
 dns_reply_a(struct interface *iface, int ttl)
 {
        struct ifaddrs *ifap, *ifa;
@@ -210,6 +210,38 @@ dns_reply_a(struct interface *iface, int ttl)
        freeifaddrs(ifap);
 }
 
+static void
+dns_reply_rev_lookup(struct interface *iface, int ttl)
+{
+       char name[32];
+       int len;
+
+       if (!iface->v6) {
+               struct in_addr rev_v4_addr;
+
+               /* PTR recored starts with IP with reversed octets order */
+               memcpy(&rev_v4_addr, &iface->v4_addr, sizeof(iface->v4_addr));
+               rev_v4_addr.s_addr = bswap_32(rev_v4_addr.s_addr);
+
+               /* Prepare name with reversed IP & second level domain suffix */
+               inet_ntop(AF_INET, &rev_v4_addr, name, sizeof(name));
+               strcat(name, ".in-addr.arpa");
+
+               dns_init_answer();
+               len = dn_comp(mdns_hostname_local, mdns_buf, sizeof(mdns_buf), 
NULL, NULL);
+               if (len > 0)
+                       dns_add_answer(TYPE_PTR, mdns_buf, len, ttl);
+               dns_send_answer(iface, name);
+       }
+}
+
+void
+dns_reply_domain_name(struct interface *iface, int ttl)
+{
+       dns_reply_a(iface, ttl);
+       dns_reply_rev_lookup(iface, ttl);
+}
+
 static int
 scan_name(const uint8_t *buffer, int len)
 {
@@ -361,8 +393,8 @@ parse_question(struct interface *iface, char *name, struct 
dns_question *q)
        switch (q->type) {
        case TYPE_ANY:
                if (!strcmp(name, mdns_hostname_local)) {
+                       dns_reply_domain_name(iface, announce_ttl);
                        service_reply(iface, NULL, announce_ttl);
-                       dns_reply_a(iface, announce_ttl);
                }
                break;
 
@@ -377,7 +409,7 @@ parse_question(struct interface *iface, char *name, struct 
dns_question *q)
                if (host)
                        *host = '\0';
                if (!strcmp(mdns_hostname, name))
-                       dns_reply_a(iface, announce_ttl);
+                       dns_reply_domain_name(iface, announce_ttl);
                break;
        };
 }
diff --git a/dns.h b/dns.h
index 7f3cbe1..fa532a7 100644
--- a/dns.h
+++ b/dns.h
@@ -77,7 +77,7 @@ void dns_send_question(struct interface *iface, const char 
*question, int type,
 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);
-void dns_reply_a(struct interface *iface, int ttl);
+void dns_reply_domain_name(struct interface *iface, int ttl);
 const char* dns_type_string(uint16_t type);
 void dns_handle_packet(struct interface *iface, struct sockaddr *s, uint16_t 
port, uint8_t *buf, int len);
 
diff --git a/interface.c b/interface.c
index 463335a..4ddddde 100644
--- a/interface.c
+++ b/interface.c
@@ -621,7 +621,7 @@ void interface_shutdown(void)
        vlist_for_each_element(&interfaces, iface, node)
                if (iface->fd.fd > 0 && iface->multicast) {
                        service_announce(iface, 0);
-                       dns_reply_a(iface, 0);
+                       dns_reply_domain_name(iface, 0);
                }
        vlist_for_each_element(&interfaces, iface, node)
                interface_close(iface);
-- 
2.11.0


_______________________________________________
Lede-dev mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/lede-dev

Reply via email to