]> git.meshlink.io Git - meshlink/blobdiff - src/discovery.c
Remove disconnect code from autoconnect because it makes the mesh flapping
[meshlink] / src / discovery.c
index e196825ac5d378f94359897d384a3f20a0282962..fa4e13c3435ec928e5c2e626e111344509032803 100644 (file)
@@ -2,12 +2,14 @@
 #include "meshlink_internal.h"
 #include "discovery.h"
 #include "sockaddr.h"
+#include "logger.h"
 
 #include <pthread.h>
 
 #include <avahi-core/core.h>
 #include <avahi-core/lookup.h>
 #include <avahi-core/publish.h>
+#include <avahi-core/log.h>
 #include <avahi-common/simple-watch.h>
 #include <avahi-common/malloc.h>
 #include <avahi-common/alternative.h>
@@ -30,6 +32,8 @@ static void discovery_entry_group_callback(AvahiServer *server, AvahiSEntryGroup
     assert(mesh->avahi_server != NULL);
     assert(mesh->avahi_poll != NULL);
 
+    pthread_mutex_lock(&(mesh->mesh_mutex));
+
     /* Called whenever the entry group state changes */
     switch(state)
     {
@@ -53,6 +57,8 @@ static void discovery_entry_group_callback(AvahiServer *server, AvahiSEntryGroup
         case AVAHI_ENTRY_GROUP_REGISTERING:
             ;
     }
+
+    pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
 
@@ -69,6 +75,8 @@ static void discovery_create_services(meshlink_handle_t *mesh)
     assert(mesh->avahi_servicetype != NULL);
     assert(mesh->self != NULL);
 
+    pthread_mutex_lock(&(mesh->mesh_mutex));
+
     logger(mesh, MESHLINK_DEBUG, "Adding service\n");
 
     /* Ifthis is the first time we're called, let's create a new entry group */
@@ -119,6 +127,8 @@ fail:
 done:
     if(txt_name)
         { free(txt_name); }
+
+    pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
 static void discovery_server_callback(AvahiServer *server, AvahiServerState state, void * userdata)
@@ -127,6 +137,8 @@ static void discovery_server_callback(AvahiServer *server, AvahiServerState stat
 
     // asserts
     assert(mesh != NULL);
+    
+    pthread_mutex_lock(&(mesh->mesh_mutex));
 
     switch(state)
     {
@@ -161,7 +173,6 @@ static void discovery_server_callback(AvahiServer *server, AvahiServerState stat
                 {
                     logger(mesh, MESHLINK_ERROR, "Avahi failed to set new host name: %s\n", avahi_strerror(result));
                     avahi_simple_poll_quit(mesh->avahi_poll);
-                    return;
                 }
             }
             break;
@@ -194,6 +205,8 @@ static void discovery_server_callback(AvahiServer *server, AvahiServerState stat
         case AVAHI_SERVER_INVALID:
             break;
     }
+
+    pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
 static void discovery_resolve_callback(AvahiSServiceResolver *resolver, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata)
@@ -205,6 +218,8 @@ static void discovery_resolve_callback(AvahiSServiceResolver *resolver, AvahiIfI
     assert(mesh != NULL);
     assert(mesh->avahi_server != NULL);
 
+    pthread_mutex_lock(&(mesh->mesh_mutex));
+
     /* Called whenever a service has been resolved successfully or timed out */
     switch(event)
     {
@@ -280,7 +295,7 @@ static void discovery_resolve_callback(AvahiSServiceResolver *resolver, AvahiIfI
                                 case AVAHI_PROTO_INET:
                                     {
                                         naddress.in.sin_family = AF_INET;
-                                        naddress.in.sin_port = port;
+                                        naddress.in.sin_port = htons(port);
                                         naddress.in.sin_addr.s_addr = address->data.ipv4.address;
                                     }
                                     break;
@@ -288,7 +303,7 @@ static void discovery_resolve_callback(AvahiSServiceResolver *resolver, AvahiIfI
                                 case AVAHI_PROTO_INET6:
                                     {
                                         naddress.in6.sin6_family = AF_INET6;
-                                        naddress.in6.sin6_port = port;
+                                        naddress.in6.sin6_port = htons(port);
                                         memcpy(naddress.in6.sin6_addr.s6_addr, address->data.ipv6.address, sizeof(naddress.in6.sin6_addr.s6_addr));
                                     }
                                     break;
@@ -326,6 +341,8 @@ static void discovery_resolve_callback(AvahiSServiceResolver *resolver, AvahiIfI
     }
 
     avahi_s_service_resolver_free(resolver);
+
+    pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
 static void discovery_browse_callback(AvahiSServiceBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata)
@@ -337,6 +354,8 @@ static void discovery_browse_callback(AvahiSServiceBrowser *browser, AvahiIfInde
     assert(mesh->avahi_server != NULL);
     assert(mesh->avahi_poll != NULL);
 
+    pthread_mutex_lock(&(mesh->mesh_mutex));
+
     /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
     switch (event)
     {
@@ -345,7 +364,7 @@ static void discovery_browse_callback(AvahiSServiceBrowser *browser, AvahiIfInde
                 logger(mesh, MESHLINK_ERROR, "(Browser) %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
                 avahi_simple_poll_quit(mesh->avahi_poll);
             }
-            return;
+            break;
 
         case AVAHI_BROWSER_NEW:
             {
@@ -384,6 +403,8 @@ static void discovery_browse_callback(AvahiSServiceBrowser *browser, AvahiIfInde
             }
             break;
     }
+    
+    pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
 static void *discovery_loop(void *userdata)
@@ -399,6 +420,33 @@ static void *discovery_loop(void *userdata)
     return NULL;
 }
 
+static void discovery_log_cb(AvahiLogLevel level, const char *txt)
+{
+    meshlink_log_level_t mlevel = MESHLINK_CRITICAL;
+
+    switch(level)
+    {
+    case AVAHI_LOG_ERROR:
+        mlevel = MESHLINK_ERROR;
+        break;
+
+    case AVAHI_LOG_WARN:
+        mlevel = MESHLINK_WARNING;
+        break;
+
+    case AVAHI_LOG_NOTICE:
+    case AVAHI_LOG_INFO:
+        mlevel = MESHLINK_INFO;
+        break;
+
+    case AVAHI_LOG_DEBUG:
+        mlevel = MESHLINK_DEBUG;
+        break;
+    }
+
+    logger(NULL, mlevel, "%s\n", txt);
+}
+
 bool discovery_start(meshlink_handle_t *mesh)
 {
     logger(mesh, MESHLINK_DEBUG, "discovery_start called\n");
@@ -411,6 +459,9 @@ bool discovery_start(meshlink_handle_t *mesh)
     assert(mesh->discovery_threadstarted == false);
     assert(mesh->avahi_servicetype == NULL);
 
+    // handle avahi logs
+    avahi_set_log_function(discovery_log_cb);
+    
     // create service type string
     size_t servicetype_strlen = sizeof(MESHLINK_MDNS_SERVICE_TYPE) + strlen(mesh->appname) + 1;
     mesh->avahi_servicetype = malloc(servicetype_strlen);
@@ -535,6 +586,13 @@ void discovery_stop(meshlink_handle_t *mesh)
         mesh->avahi_browser = NULL;
     }
 
+    if(mesh->avahi_group)
+    {
+        avahi_s_entry_group_reset(mesh->avahi_group);
+        avahi_s_entry_group_free(mesh->avahi_group);
+        mesh->avahi_group = NULL;
+    }
+
     if(mesh->avahi_server != NULL)
     {
         avahi_server_free(mesh->avahi_server);