use hostname from SRV record to look up IP addresses
authorFelix Fietkau <nbd@nbd.name>
Thu, 19 Oct 2023 08:58:04 +0000 (10:58 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 19 Oct 2023 08:58:07 +0000 (10:58 +0200)
On many devices, the main record name contains the long form hostname,
whereas the A/AAAA records are assigned to the hostname indicated in the
SRV record.
This fixes getting IP addresses via browse for many devices

Signed-off-by: Felix Fietkau <nbd@nbd.name>
cache.c
cache.h
ubus.c

diff --git a/cache.c b/cache.c
index 9df051d59072502a6ca5985314fce5a497b7c3c9..83249939d304de87e54378a335def6f9e5d6f45e 100644 (file)
--- a/cache.c
+++ b/cache.c
@@ -382,7 +382,8 @@ void cache_answer(struct interface *iface, struct sockaddr *from, uint8_t *base,
 }
 
 void
-cache_dump_records(struct blob_buf *buf, const char *name, int array)
+cache_dump_records(struct blob_buf *buf, const char *name, int array,
+                  const char **hostname)
 {
        struct cache_record *r, *last, *next;
        const char *txt;
@@ -454,8 +455,11 @@ cache_dump_records(struct blob_buf *buf, const char *name, int array)
                        break;
 
                case TYPE_SRV:
-                       if (r->rdata)
+                       if (r->rdata) {
                                blobmsg_add_string(buf, "host", (char *)r->rdata + sizeof(struct dns_srv_data));
+                               if (hostname)
+                                       *hostname = (char *)r->rdata + sizeof(struct dns_srv_data);
+                       }
                        if (r->port)
                                blobmsg_add_u32(buf, "port", r->port);
                        break;
diff --git a/cache.h b/cache.h
index 8affee6ca6f6f27e1e66bab6fe3b1c9beb42e612..7c81418ce99da7f392f7468917b18921df207fff 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -58,7 +58,8 @@ void cache_answer(struct interface *iface, struct sockaddr *from, uint8_t *base,
                  int blen, char *name, struct dns_answer *a, uint8_t *rdata,
                  int flush);
 int cache_host_is_known(char *record);
-void cache_dump_records(struct blob_buf *buf, const char *name, int array);
+void cache_dump_records(struct blob_buf *buf, const char *name, int array,
+                       const char **hostname);
 void cache_dump_recursive(struct blob_buf *b, const char *name, uint16_t type, struct interface *iface);
 
 #endif
diff --git a/ubus.c b/ubus.c
index cf75cdcf58ab26f4b0a51846d822c11a8dade020..e0a40aa77ae964c1428563d5960c2231161c950f 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -83,6 +83,7 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
 
        blob_buf_init(&b, 0);
        avl_for_each_element(&services, s, avl) {
+               const char *hostname = buffer;
                char *local;
 
                snprintf(buffer, MAX_NAME_LEN, "%s", (const char *) s->avl.key);
@@ -103,9 +104,9 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
                c2 = blobmsg_open_table(&b, buffer);
                strncat(buffer, ".local", MAX_NAME_LEN);
                blobmsg_add_string(&b, "iface", s->iface->name);
+               cache_dump_records(&b, s->entry, array, &hostname);
                if (address)
-                       cache_dump_records(&b, buffer, array);
-               cache_dump_records(&b, s->entry, array);
+                       cache_dump_records(&b, hostname, array, NULL);
                blobmsg_close_table(&b, c2);
                q = avl_next_element(s, avl);
                if (!q || avl_is_last(&services, &s->avl) || strcmp(s->avl.key, q->avl.key)) {
@@ -134,7 +135,7 @@ umdns_hosts(struct ubus_context *ctx, struct ubus_object *obj,
                /* Query each domain just once */
                if (!prev || strcmp(r->record, prev->record)) {
                        c = blobmsg_open_table(&b, r->record);
-                       cache_dump_records(&b, r->record, false);
+                       cache_dump_records(&b, r->record, false, NULL);
                        blobmsg_close_table(&b, c);
                }
                prev = r;