]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Fix a potential segfault when closing a stopped meshlink handle.
[meshlink] / src / meshlink.c
index 84f6e29cf725897deb9b52e78460dbf5a0e8609a..1de54e916dab53abaa5f85a3db8739783fa3d3f1 100644 (file)
@@ -56,64 +56,12 @@ meshlink_log_level_t global_log_level;
 //TODO: this can go away completely
 const var_t variables[] = {
        /* Server configuration */
-       {"AddressFamily", VAR_SERVER},
-       {"AutoConnect", VAR_SERVER | VAR_SAFE},
-       {"BindToAddress", VAR_SERVER | VAR_MULTIPLE},
-       {"BindToInterface", VAR_SERVER},
-       {"Broadcast", VAR_SERVER | VAR_SAFE},
        {"ConnectTo", VAR_SERVER | VAR_MULTIPLE | VAR_SAFE},
-       {"DecrementTTL", VAR_SERVER},
-       {"Device", VAR_SERVER},
-       {"DeviceType", VAR_SERVER},
-       {"DirectOnly", VAR_SERVER},
-       {"ECDSAPrivateKeyFile", VAR_SERVER},
-       {"ExperimentalProtocol", VAR_SERVER},
-       {"Forwarding", VAR_SERVER},
-       {"GraphDumpFile", VAR_SERVER | VAR_OBSOLETE},
-       {"Hostnames", VAR_SERVER},
-       {"IffOneQueue", VAR_SERVER},
-       {"Interface", VAR_SERVER},
-       {"KeyExpire", VAR_SERVER},
-       {"ListenAddress", VAR_SERVER | VAR_MULTIPLE},
-       {"LocalDiscovery", VAR_SERVER},
-       {"MACExpire", VAR_SERVER},
-       {"MaxConnectionBurst", VAR_SERVER},
-       {"MaxOutputBufferSize", VAR_SERVER},
-       {"MaxTimeout", VAR_SERVER},
-       {"Mode", VAR_SERVER | VAR_SAFE},
        {"Name", VAR_SERVER},
-       {"PingInterval", VAR_SERVER},
-       {"PingTimeout", VAR_SERVER},
-       {"PriorityInheritance", VAR_SERVER},
-       {"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
-       {"PrivateKeyFile", VAR_SERVER},
-       {"ProcessPriority", VAR_SERVER},
-       {"Proxy", VAR_SERVER},
-       {"ReplayWindow", VAR_SERVER},
-       {"ScriptsExtension", VAR_SERVER},
-       {"ScriptsInterpreter", VAR_SERVER},
-       {"StrictSubnets", VAR_SERVER},
-       {"TunnelServer", VAR_SERVER},
-       {"VDEGroup", VAR_SERVER},
-       {"VDEPort", VAR_SERVER},
        /* Host configuration */
        {"Address", VAR_HOST | VAR_MULTIPLE},
-       {"Cipher", VAR_SERVER | VAR_HOST},
-       {"ClampMSS", VAR_SERVER | VAR_HOST},
-       {"Compression", VAR_SERVER | VAR_HOST},
-       {"Digest", VAR_SERVER | VAR_HOST},
        {"ECDSAPublicKey", VAR_HOST},
-       {"ECDSAPublicKeyFile", VAR_SERVER | VAR_HOST},
-       {"IndirectData", VAR_SERVER | VAR_HOST},
-       {"MACLength", VAR_SERVER | VAR_HOST},
-       {"PMTU", VAR_SERVER | VAR_HOST},
-       {"PMTUDiscovery", VAR_SERVER | VAR_HOST},
        {"Port", VAR_HOST},
-       {"PublicKey", VAR_HOST | VAR_OBSOLETE},
-       {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
-       {"Subnet", VAR_HOST | VAR_MULTIPLE | VAR_SAFE},
-       {"TCPOnly", VAR_SERVER | VAR_HOST},
-       {"Weight", VAR_HOST | VAR_SAFE},
        {NULL, 0}
 };
 
@@ -388,7 +336,7 @@ static char *get_my_hostname(meshlink_handle_t *mesh) {
                return NULL;
        }
 
-       if(!strcmp(hostname[0], hostname[1])) {
+       if(hostname[0] && hostname[1] && !strcmp(hostname[0], hostname[1])) {
                free(hostname[1]);
                hostname[1] = NULL;
        }
@@ -619,7 +567,7 @@ static bool finalize_join(meshlink_handle_t *mesh) {
                        continue;
                }
 
-               // Check the list of known variables //TODO: most variables will not be available in meshlink, only name and key will be absolutely necessary
+               // Check the list of known variables
                bool found = false;
                int i;
 
@@ -1050,6 +998,7 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const c
        mesh->confbase = xstrdup(confbase);
        mesh->appname = xstrdup(appname);
        mesh->devclass = devclass;
+       mesh->discovery = true;
 
        if(usingname) {
                mesh->name = xstrdup(name);
@@ -1178,6 +1127,7 @@ bool meshlink_start(meshlink_handle_t *mesh) {
                logger(mesh, MESHLINK_DEBUG, "Could not start thread: %s\n", strerror(errno));
                memset(&mesh->thread, 0, sizeof(mesh)->thread);
                meshlink_errno = MESHLINK_EINTERNAL;
+               event_loop_stop(&mesh->loop);
                pthread_mutex_unlock(&(mesh->mesh_mutex));
                return false;
        }
@@ -1210,18 +1160,28 @@ void meshlink_stop(meshlink_handle_t *mesh) {
        event_loop_stop(&mesh->loop);
 
        // Send ourselves a UDP packet to kick the event loop
-       listen_socket_t *s = &mesh->listen_socket[0];
+       for(int i = 0; i < mesh->listen_sockets; i++) {
+               sockaddr_t sa;
+               socklen_t salen = sizeof(sa.sa);
 
-       if(sendto(s->udp.fd, "", 1, MSG_NOSIGNAL, &s->sa.sa, SALEN(s->sa.sa)) == -1) {
-               logger(mesh, MESHLINK_ERROR, "Could not send a UDP packet to ourself");
+               if(getsockname(mesh->listen_socket[i].udp.fd, &sa.sa, &salen) == -1) {
+                       logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "getsockname", sockstrerror(sockerrno));
+                       continue;
+               }
+
+               if(sendto(mesh->listen_socket[i].udp.fd, "", 1, MSG_NOSIGNAL, &sa.sa, salen) == -1) {
+                       logger(mesh, MESHLINK_ERROR, "Could not send a UDP packet to ourself: %s", sockstrerror(sockerrno));
+               }
        }
 
-       // Wait for the main thread to finish
-       pthread_mutex_unlock(&(mesh->mesh_mutex));
-       pthread_join(mesh->thread, NULL);
-       pthread_mutex_lock(&(mesh->mesh_mutex));
+       if(mesh->threadstarted) {
+               // Wait for the main thread to finish
+               pthread_mutex_unlock(&(mesh->mesh_mutex));
+               pthread_join(mesh->thread, NULL);
+               pthread_mutex_lock(&(mesh->mesh_mutex));
 
-       mesh->threadstarted = false;
+               mesh->threadstarted = false;
+       }
 
        // Close all metaconnections
        if(mesh->connections) {
@@ -1235,10 +1195,9 @@ void meshlink_stop(meshlink_handle_t *mesh) {
 
        if(mesh->outgoings) {
                list_delete_list(mesh->outgoings);
+               mesh->outgoings = NULL;
        }
 
-       mesh->outgoings = NULL;
-
        pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
@@ -1915,8 +1874,6 @@ char *meshlink_invite(meshlink_handle_t *mesh, const char *name) {
 
        // Fill in the details.
        fprintf(f, "Name = %s\n", name);
-       //if(netname)
-       //      fprintf(f, "NetName = %s\n", netname);
        fprintf(f, "ConnectTo = %s\n", mesh->self->name);
 
        // Copy Broadcast and Mode
@@ -2441,6 +2398,11 @@ static void channel_accept(struct utcp_connection *utcp_connection, uint16_t por
 
 static ssize_t channel_send(struct utcp *utcp, const void *data, size_t len) {
        node_t *n = utcp->priv;
+
+       if(n->status.destroyed) {
+               return -1;
+       }
+
        meshlink_handle_t *mesh = n->mesh;
        return meshlink_send(mesh, (meshlink_node_t *)n, data, len) ? (ssize_t)len : -1;
 }