ubus: also allow dumping ipv4/6 as an array
authorJohn Crispin <john@phrozen.org>
Sun, 15 Jan 2023 12:41:44 +0000 (13:41 +0100)
committerJohn Crispin <john@phrozen.org>
Sun, 15 Jan 2023 12:41:44 +0000 (13:41 +0100)
Signed-off-by: John Crispin <john@phrozen.org>
cache.c
cache.h
ubus.c

diff --git a/cache.c b/cache.c
index 9de0fa03cd56d40d2079a2c8b037254bbae9fce4..046e8b91f1828577cc4789f6da0b533254e7f774 100644 (file)
--- a/cache.c
+++ b/cache.c
@@ -382,20 +382,65 @@ void cache_answer(struct interface *iface, struct sockaddr *from, uint8_t *base,
 }
 
 void
-cache_dump_records(struct blob_buf *buf, const char *name, int txt_array)
+cache_dump_records(struct blob_buf *buf, const char *name, int array)
 {
        struct cache_record *r, *last, *next;
        const char *txt;
        char buffer[INET6_ADDRSTRLEN];
+       void *c = NULL;
 
        last = avl_last_element(&records, last, avl);
+       for (r = avl_find_element(&records, name, r, avl); r; r = next) {
+               switch (r->type) {
+               case TYPE_A:
+                       if (!c && array)
+                               c = blobmsg_open_array(buf, "ipv4");
+                       if ((r->rdlength == 4) && inet_ntop(AF_INET, r->rdata, buffer, INET6_ADDRSTRLEN))
+                               blobmsg_add_string(buf, "ipv4", buffer);
+                       break;
+               }
+
+               if (r == last)
+                       break;
+
+               next = avl_next_element(r, avl);
+               if (strcmp(r->record, next->record) != 0)
+                       break;
+       }
+
+       if (c) {
+               blobmsg_close_array(buf, c);
+               c = NULL;
+       }
+
+       for (r = avl_find_element(&records, name, r, avl); r; r = next) {
+               switch (r->type) {
+               case TYPE_AAAA:
+                       if (!c && array)
+                               c = blobmsg_open_array(buf, "ipv6");
+                       if ((r->rdlength == 16) && inet_ntop(AF_INET6, r->rdata, buffer, INET6_ADDRSTRLEN))
+                               blobmsg_add_string(buf, "ipv6", buffer);
+                       break;
+               }
+
+               if (r == last)
+                       break;
+
+               next = avl_next_element(r, avl);
+               if (strcmp(r->record, next->record) != 0)
+                       break;
+       }
+
+       if (c) {
+               blobmsg_close_array(buf, c);
+               c = NULL;
+       }
+
        for (r = avl_find_element(&records, name, r, avl); r; r = next) {
                switch (r->type) {
                case TYPE_TXT:
                        if (r->txt && strlen(r->txt)) {
-                               void *c = NULL;
-
-                               if (txt_array)
+                               if (array)
                                        c = blobmsg_open_array(buf, "txt");
 
                                txt = r->txt;
@@ -403,7 +448,7 @@ cache_dump_records(struct blob_buf *buf, const char *name, int txt_array)
                                        blobmsg_add_string(buf, "txt", txt);
                                        txt = &txt[strlen(txt) + 1];
                                } while (*txt);
-                               if (c)
+                               if (array)
                                        blobmsg_close_array(buf, c);
                        }
                        break;
@@ -412,16 +457,6 @@ cache_dump_records(struct blob_buf *buf, const char *name, int txt_array)
                        if (r->port)
                                blobmsg_add_u32(buf, "port", r->port);
                        break;
-
-               case TYPE_A:
-                       if ((r->rdlength == 4) && inet_ntop(AF_INET, r->rdata, buffer, INET6_ADDRSTRLEN))
-                               blobmsg_add_string(buf, "ipv4", buffer);
-                       break;
-
-               case TYPE_AAAA:
-                       if ((r->rdlength == 16) && inet_ntop(AF_INET6, r->rdata, buffer, INET6_ADDRSTRLEN))
-                               blobmsg_add_string(buf, "ipv6", buffer);
-                       break;
                }
 
                if (r == last)
diff --git a/cache.h b/cache.h
index 44d407abe68af61e1126674faef44a7ce41151ff..8affee6ca6f6f27e1e66bab6fe3b1c9beb42e612 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -58,7 +58,7 @@ 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 txt_array);
+void cache_dump_records(struct blob_buf *buf, const char *name, int array);
 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 ff62e9a6dca44203c0e99df7b32e199e2e0551de..1ff816dcc38af78fcdc44f5a6591042f0a20730f 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -49,13 +49,13 @@ umdns_update(struct ubus_context *ctx, struct ubus_object *obj,
 
 enum {
        BROWSE_SERVICE,
-       BROWSE_TXT_ARRAY,
+       BROWSE_ARRAY,
        BROWSE_MAX
 };
 
 static const struct blobmsg_policy browse_policy[] = {
        [BROWSE_SERVICE]        = { "service", BLOBMSG_TYPE_STRING },
-       [BROWSE_TXT_ARRAY]      = { "txt_array", BLOBMSG_TYPE_BOOL },
+       [BROWSE_ARRAY]          = { "array", BLOBMSG_TYPE_BOOL },
 };
 
 static int
@@ -68,13 +68,13 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
        struct blob_attr *data[BROWSE_MAX];
        void *c1 = NULL, *c2;
        char *service = NULL;
-       int txt_array = 0;
+       int array = 0;
 
        blobmsg_parse(browse_policy, BROWSE_MAX, data, blob_data(msg), blob_len(msg));
        if (data[BROWSE_SERVICE])
                service = blobmsg_get_string(data[BROWSE_SERVICE]);
-       if (data[BROWSE_TXT_ARRAY])
-               txt_array = blobmsg_get_u8(data[BROWSE_TXT_ARRAY]);
+       if (data[BROWSE_ARRAY])
+               array = blobmsg_get_u8(data[BROWSE_ARRAY]);
 
        blob_buf_init(&b, 0);
        avl_for_each_element(&services, s, avl) {
@@ -97,8 +97,8 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
                        *local = '\0';
                c2 = blobmsg_open_table(&b, buffer);
                strncat(buffer, ".local", MAX_NAME_LEN);
-               cache_dump_records(&b, buffer, txt_array);
-               cache_dump_records(&b, s->entry, txt_array);
+               cache_dump_records(&b, buffer, array);
+               cache_dump_records(&b, s->entry, array);
                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)) {