]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Fall back to getifaddrs() to get an interface address if there is no default route.
[meshlink] / src / meshlink.c
index 0bec2f8aaf831c2cfd663f36fb7c0f97a7155633..5b01ad2c1fda7b12abb823baa9c80da391177fb7 100644 (file)
@@ -287,6 +287,21 @@ char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int fami
        return hostname;
 }
 
+static bool is_localaddr(sockaddr_t *sa) {
+       switch(sa->sa.sa_family) {
+       case AF_INET:
+               return *(uint8_t *)(&sa->in.sin_addr.s_addr) == 127;
+
+       case AF_INET6: {
+               uint16_t first = sa->in6.sin6_addr.s6_addr[0] << 8 | sa->in6.sin6_addr.s6_addr[1];
+               return first == 0 || (first & 0xffc0) == 0xfe80;
+       }
+
+       default:
+               return false;
+       }
+}
+
 char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) {
        (void)mesh;
 
@@ -300,6 +315,34 @@ char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family)
                success = getlocaladdrname("2606:2800:220:1:248:1893:25c8:1946", localaddr, sizeof(localaddr), mesh->netns);
        }
 
+#ifdef HAVE_GETIFADDRS
+
+       if(!success) {
+               struct ifaddrs *ifa = NULL;
+               getifaddrs(&ifa);
+
+               for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
+                       sockaddr_t *sa = (sockaddr_t *)ifap->ifa_addr;
+
+                       if(sa->sa.sa_family != family) {
+                               continue;
+                       }
+
+                       if(is_localaddr(sa)) {
+                               continue;
+                       }
+
+                       if(!getnameinfo(&sa->sa, SALEN(sa->sa), localaddr, sizeof(localaddr), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) {
+                               success = true;
+                               break;
+                       }
+               }
+
+               freeifaddrs(ifa);
+       }
+
+#endif
+
        if(!success) {
                meshlink_errno = MESHLINK_ENETWORK;
                return NULL;
@@ -668,6 +711,10 @@ static bool finalize_join(meshlink_handle_t *mesh, const void *buf, uint16_t len
                        }
                }
 
+               /* Clear the reachability times, since we ourself have never seen these nodes yet */
+               n->last_reachable = 0;
+               n->last_unreachable = 0;
+
                if(!node_write_config(mesh, n)) {
                        free_node(n);
                        return false;
@@ -720,7 +767,7 @@ static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint
                return finalize_join(mesh, msg, len);
 
        case 1:
-               logger(mesh, MESHLINK_DEBUG, "Invitation succesfully accepted.\n");
+               logger(mesh, MESHLINK_DEBUG, "Invitation successfully accepted.\n");
                shutdown(mesh->sock, SHUT_RDWR);
                mesh->success = true;
                break;
@@ -2428,7 +2475,7 @@ char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, c
        }
 
        // Ensure no other nodes know about this name
-       if(meshlink_get_node(mesh, name)) {
+       if(lookup_node(mesh, name)) {
                logger(mesh, MESHLINK_ERROR, "A node with name %s is already known!\n", name);
                meshlink_errno = MESHLINK_EEXIST;
                pthread_mutex_unlock(&mesh->mutex);
@@ -2454,7 +2501,7 @@ char *meshlink_invite_ex(meshlink_handle_t *mesh, meshlink_submesh_t *submesh, c
        // If we changed our own host config file, write it out now
        if(mesh->self->status.dirty) {
                if(!node_write_config(mesh, mesh->self)) {
-                       logger(mesh, MESHLINK_ERROR, "Could not write our own host conifg file!\n");
+                       logger(mesh, MESHLINK_ERROR, "Could not write our own host config file!\n");
                        pthread_mutex_unlock(&mesh->mutex);
                        return NULL;
                }
@@ -2919,7 +2966,11 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
                        break;
                }
 
-               if(!config_write(mesh, "current", n->name, &config, mesh->config_key)) {
+               /* Clear the reachability times, since we ourself have never seen these nodes yet */
+               n->last_reachable = 0;
+               n->last_unreachable = 0;
+
+               if(!node_write_config(mesh, n)) {
                        free_node(n);
                        return false;
                }