send unsolicitated answers when a new service appears
authorJohn Crispin <blogic@openwrt.org>
Fri, 29 Aug 2014 07:01:31 +0000 (09:01 +0200)
committerJohn Crispin <blogic@openwrt.org>
Fri, 29 Aug 2014 07:01:31 +0000 (09:01 +0200)
Signed-off-by: John Crispin <blogic@openwrt.org>
main.c
service.c
service.h
ubus.c

diff --git a/main.c b/main.c
index f559c199cea40fb7a888e81c748145abc6e60941..93db2e5c0398dbcb5a5b270fa0377c7eb2d6f54f 100644 (file)
--- a/main.c
+++ b/main.c
@@ -77,7 +77,7 @@ main(int argc, char **argv)
        if (cache_init())
                return -1;
 
-       service_init();
+       service_init(0);
 
        ubus_startup();
        uloop_run();
index 01a55b6d8b4d7ca80cbb76e74cf928c5fe51a126..610cac5b7a792890634e6f451475842873b55bec 100644 (file)
--- a/service.c
+++ b/service.c
@@ -67,6 +67,7 @@ static struct blob_buf b;
 static VLIST_TREE(services, avl_strcmp, service_update, false, false);
 static char *sdudp =  "_services._dns-sd._udp.local";
 static char *sdtcp =  "_services._dns-sd._tcp.local";
+static int service_init_announce;
 
 static const char *
 service_name(const char *domain)
@@ -148,12 +149,12 @@ service_reply_a(struct interface *iface, int type, int ttl)
 }
 
 static void
-service_reply_single(struct interface *iface, struct service *s, const char *match, int ttl)
+service_reply_single(struct interface *iface, struct service *s, const char *match, int ttl, int force)
 {
        const char *host = service_name(s->service);
        char *service = strstr(host, "._");
 
-       if (!s->active || !service || !service_timeout(s))
+       if (!force && (!s->active || !service || !service_timeout(s)))
                return;
 
        service++;
@@ -178,7 +179,7 @@ service_reply(struct interface *iface, const char *match, int ttl)
        struct service *s;
 
        vlist_for_each_element(&services, s, node)
-               service_reply_single(iface, s, match, ttl);
+               service_reply_single(iface, s, match, ttl, 0);
 
        if (match)
                return;
@@ -227,15 +228,20 @@ service_update(struct vlist_tree *tree, struct vlist_node *node_new,
        struct interface *iface;
        struct service *s;
 
-       if (!node_old)
+       if (!node_old) {
+               s = container_of(node_new, struct service, node);
+               if (service_init_announce)
+                       vlist_for_each_element(&interfaces, iface, node) {
+                               s->t = 0;
+                               service_reply_single(iface, s, NULL, announce_ttl, 1);
+                       }
                return;
+       }
 
        s = container_of(node_old, struct service, node);
-
-       if (!node_new)
+       if (!node_new && service_init_announce)
                vlist_for_each_element(&interfaces, iface, node)
-                       service_reply_single(iface, s, NULL, 0);
-
+                       service_reply_single(iface, s, NULL, 0, 1);
        free(s);
 }
 
@@ -302,8 +308,10 @@ service_load(char *path)
 }
 
 void
-service_init(void)
+service_init(int announce)
 {
+       service_init_announce = announce;
+
        get_hostname();
 
        vlist_update(&services);
index cc49abe23424d4f58ec8d907a7ed37f028523244..e17c8607ee2697caf3df3f346ef248ae5c0dbaee 100644 (file)
--- a/service.h
+++ b/service.h
@@ -14,7 +14,7 @@
 #ifndef _SERVICE_H__
 #define _SERVICE_H__
 
-extern void service_init(void);
+extern void service_init(int announce);
 extern void service_cleanup(void);
 extern void service_announce(struct interface *iface);
 extern void service_announce_services(struct interface *iface, const char *service);
diff --git a/ubus.c b/ubus.c
index c5c8e04032a9bc6fb3e1fc37cc5aca14edcfe282..b9bb9ee229bca52745fbc4029bbfd136471e10dc 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -34,7 +34,7 @@ mdns_reload(struct ubus_context *ctx, struct ubus_object *obj,
                struct ubus_request_data *req, const char *method,
                struct blob_attr *msg)
 {
-       service_init();
+       service_init(1);
        return 0;
 }