Browse Source

ubus: also allow dumping ipv4/6 as an array

Signed-off-by: John Crispin <john@phrozen.org>
John Crispin 1 year ago
parent
commit
3f86bcf30a
3 changed files with 58 additions and 23 deletions
  1. 50 15
      cache.c
  2. 1 1
      cache.h
  3. 7 7
      ubus.c

+ 50 - 15
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)

+ 1 - 1
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

+ 7 - 7
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)) {