X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=5b01ad2c1fda7b12abb823baa9c80da391177fb7;hb=3fe7713c4f9d16f192271bc4fa8a2ffda6bb28fd;hp=0fbcf1535379810fd2295d4d28287a87b1beb774;hpb=eeb8f3502fdf25704ce2d234732509cad32e8bff;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 0fbcf153..5b01ad2c 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -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; @@ -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; }