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;
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;
}
}
+ /* 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;
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;
bool reachable;
pthread_mutex_lock(&mesh->mutex);
- reachable = n->status.reachable;
+ reachable = n->status.reachable && !n->status.blacklisted;
if(last_reachable) {
*last_reachable = n->last_reachable;
}
// 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);
// 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;
}
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;
}
n->mtuprobes = 0;
n->status.udp_confirmed = false;
+ if(n->status.reachable) {
+ n->last_unreachable = mesh->loop.now.tv_sec;
+ }
+
/* Graph updates will suppress status updates for blacklisted nodes, so we need to
* manually call the status callback if necessary.
*/
n->status.blacklisted = false;
if(n->status.reachable) {
+ n->last_reachable = mesh->loop.now.tv_sec;
update_node_status(mesh, n);
}