summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohd Husaam Mehdi2024-02-05 14:56:24 +0000
committerJohn Crispin2024-12-11 14:06:53 +0000
commit453773429dcfb4af4e939ac7d7b454d78bbc44dc (patch)
treeba8d34733e395bea308a4685fd86f9d66fc62d07
parent0b50c29101b3e8e2095c42df43eddf0181f885fb (diff)
downloadmdnsd-453773429dcfb4af4e939ac7d7b454d78bbc44dc.tar.gz
display announced services in ubus call umdns browse
This commit adds logic to display details of services announced by umdns. Signed-off-by: Mohd Husaam <husaam.mehdi@iopsys.eu> (minor changes to the original PR) Signed-off-by: John Crispin <john@phrozen.org>
-rw-r--r--service.c36
-rw-r--r--service.h19
-rw-r--r--ubus.c78
3 files changed, 105 insertions, 28 deletions
diff --git a/service.c b/service.c
index b693b31..21bdc7b 100644
--- a/service.c
+++ b/service.c
@@ -22,9 +22,7 @@
#include <time.h>
#include <libubus.h>
-#include <libubox/vlist.h>
#include <libubox/uloop.h>
-#include <libubox/avl-cmp.h>
#include <libubox/blobmsg_json.h>
#include "ubus.h"
@@ -43,20 +41,6 @@ enum {
__SERVICE_MAX,
};
-struct service {
- struct vlist_node node;
-
- time_t t;
-
- const char *id;
- const char *instance;
- const char *service;
- const uint8_t *txt;
- int txt_len;
- int port;
- int active;
-};
-
static const struct blobmsg_policy service_policy[__SERVICE_MAX] = {
[SERVICE_INSTANCE] = { .name = "instance", .type = BLOBMSG_TYPE_STRING },
[SERVICE_SERVICE] = { .name = "service", .type = BLOBMSG_TYPE_STRING },
@@ -66,15 +50,11 @@ static const struct blobmsg_policy service_policy[__SERVICE_MAX] = {
};
static void
-service_update(struct vlist_tree *tree, struct vlist_node *node_new,
- struct vlist_node *node_old);
-
-static void
hostname_update(struct vlist_tree *tree, struct vlist_node *node_new,
struct vlist_node *node_old);
static struct blob_buf b;
-static VLIST_TREE(services, avl_strcmp, service_update, false, false);
+VLIST_TREE(announced_services, avl_strcmp, service_update, false, false);
VLIST_TREE(hostnames, avl_strcmp, hostname_update, false, false);
static int service_init_announce;
@@ -168,7 +148,7 @@ service_reply(struct interface *iface, struct sockaddr *to, const char *instance
{
struct service *s;
- vlist_for_each_element(&services, s, node) {
+ vlist_for_each_element(&announced_services, s, node) {
if (instance && strcmp(s->instance, instance))
continue;
if (service_domain && strcmp(s->service, service_domain))
@@ -182,7 +162,7 @@ service_announce_services(struct interface *iface, struct sockaddr *to, int ttl)
{
struct service *s;
- vlist_for_each_element(&services, s, node) {
+ vlist_for_each_element(&announced_services, s, node) {
s->t = 0;
if (ttl) {
dns_init_answer();
@@ -193,7 +173,7 @@ service_announce_services(struct interface *iface, struct sockaddr *to, int ttl)
}
}
-static void
+void
service_update(struct vlist_tree *tree, struct vlist_node *node_new,
struct vlist_node *node_old)
{
@@ -315,7 +295,7 @@ service_load_blob(struct blob_attr *b)
d_txt += len;
}
- vlist_add(&services, &s->node, s->id);
+ vlist_add(&announced_services, &s->node, s->id);
}
static void
@@ -348,7 +328,7 @@ service_init_cb(struct ubus_request *req, int type, struct blob_attr *msg)
get_hostname();
- vlist_update(&services);
+ vlist_update(&announced_services);
vlist_update(&hostnames);
service_load("/etc/umdns/*");
@@ -393,7 +373,7 @@ service_init_cb(struct ubus_request *req, int type, struct blob_attr *msg)
}
}
}
- vlist_flush(&services);
+ vlist_flush(&announced_services);
vlist_flush(&hostnames);
}
@@ -409,6 +389,6 @@ service_init(int announce)
void
service_cleanup(void)
{
- vlist_flush(&services);
+ vlist_flush(&announced_services);
blob_buf_free(&b);
}
diff --git a/service.h b/service.h
index 9dea1f6..ea2a6ed 100644
--- a/service.h
+++ b/service.h
@@ -14,16 +14,35 @@
#ifndef _SERVICE_H__
#define _SERVICE_H__
+#include <libubox/vlist.h>
+#include <libubox/avl-cmp.h>
+
+struct service {
+ struct vlist_node node;
+
+ time_t t;
+
+ const char *id;
+ const char *instance;
+ const char *service;
+ const uint8_t *txt;
+ int txt_len;
+ int port;
+ int active;
+};
+
struct hostname {
struct vlist_node node;
const char *hostname;
};
extern struct vlist_tree hostnames;
+extern struct vlist_tree announced_services;
extern void service_init(int announce);
extern void service_cleanup(void);
extern void service_reply(struct interface *iface, struct sockaddr *to, const char *instance, const char *service_domain, int ttl);
extern void service_announce_services(struct interface *iface, struct sockaddr *to, int ttl);
+extern void service_update(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old);
#endif
diff --git a/ubus.c b/ubus.c
index 6991278..3dbaeaa 100644
--- a/ubus.c
+++ b/ubus.c
@@ -15,6 +15,7 @@
#include <arpa/inet.h>
#include <stdio.h>
+#include <ctype.h>
#include <libubus.h>
#include <libubox/vlist.h>
@@ -48,6 +49,80 @@ umdns_update(struct ubus_context *ctx, struct ubus_object *obj,
return 0;
}
+static int
+umdns_announcements(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct service *s;
+ void *c1 = NULL, *c2 = NULL;
+
+ blob_buf_init(&b, 0);
+ vlist_for_each_element(&announced_services, s, node) {
+ // is something there?
+ if (!s->id || !strlen(s->id))
+ continue;
+
+ if (!s->service || !strlen(s->service))
+ continue;
+
+ if (!s->port)
+ continue;
+
+ if (!c1) {
+ c1 = blobmsg_open_table(&b, (const char *) s->service);
+ }
+
+ c2 = blobmsg_open_table(&b, s->id);
+
+ blobmsg_add_u32(&b, "port", s->port);
+
+ // check if there are any text entries
+ if (s->txt_len) {
+ void *c_txt = NULL;
+ int i;
+
+ // this string will hold text records
+ char *txt_str = (char *) calloc(s->txt_len, sizeof(char));
+
+ // we get some weird characters like \u000b, so get don't copy them
+ for (i=0; i<s->txt_len; i++) {
+ if ((ispunct(s->txt[i])) || (isalnum(s->txt[i])))
+ txt_str[i] = (char) s->txt[i];
+ else
+ txt_str[i] = ' ';
+ }
+
+ txt_str[s->txt_len] = '\0';
+
+ // a table of txt json objects
+ c_txt = blobmsg_open_array(&b, "txt");
+
+ // split based on space and add each token to output
+ char *pch = NULL, *pchr = NULL;
+
+ for (pch = strtok_r(txt_str, " ", &pchr); pch != NULL; pch = strtok_r(NULL, " ", &pchr)) {
+ // add it to array
+ blobmsg_add_string(&b, "txt", pch);
+ }
+
+ // close the array
+ blobmsg_close_array(&b, c_txt);
+
+ // free the calloced memory
+ free(txt_str);
+ }
+
+ blobmsg_close_table(&b, c2);
+ blobmsg_close_table(&b, c1);
+ c1 = NULL;
+ }
+
+ ubus_send_reply(ctx, req, b.head);
+
+ return UBUS_STATUS_OK;
+}
+
enum {
BROWSE_SERVICE,
BROWSE_ARRAY,
@@ -83,6 +158,7 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
address = blobmsg_get_bool(data[BROWSE_ADDRESS]);
blob_buf_init(&b, 0);
+
avl_for_each_element(&services, s, avl) {
const char *hostname = buffer;
char *local;
@@ -116,6 +192,7 @@ umdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
c1 = NULL;
}
}
+
ubus_send_reply(ctx, req, b.head);
return UBUS_STATUS_OK;
@@ -270,6 +347,7 @@ static const struct ubus_method umdns_methods[] = {
UBUS_METHOD("query", umdns_query, query_policy),
UBUS_METHOD("fetch", umdns_query, query_policy),
UBUS_METHOD("browse", umdns_browse, browse_policy),
+ UBUS_METHOD_NOARG("announcements", umdns_announcements),
UBUS_METHOD_NOARG("update", umdns_update),
UBUS_METHOD("hosts", umdns_hosts, hosts_policy),
UBUS_METHOD_NOARG("reload", umdns_reload),