From: Mohd Husaam Mehdi Date: Mon, 5 Feb 2024 14:56:24 +0000 (+0530) Subject: display announced services in ubus call umdns browse X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=453773429dcfb4af4e939ac7d7b454d78bbc44dc;p=project%2Fmdnsd.git 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 (minor changes to the original PR) Signed-off-by: John Crispin --- diff --git a/service.c b/service.c index b693b31..21bdc7b 100644 --- a/service.c +++ b/service.c @@ -22,9 +22,7 @@ #include #include -#include #include -#include #include #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 }, @@ -65,16 +49,12 @@ static const struct blobmsg_policy service_policy[__SERVICE_MAX] = { [SERVICE_HOSTNAME] = { .name = "hostname", .type = BLOBMSG_TYPE_STRING }, }; -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 +#include + +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 #include +#include #include #include @@ -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; itxt_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),