X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=56da2a045452acf8004b0d0a04cbf1e7e2810ceb;hb=c4deb6c20dceb73c0ac6baa2eb901434584e6191;hp=a8f8c928876b034fb169a4c92821faebd851226f;hpb=4b6c01b1d5383b1a7417244a31ad4652aab2d5db;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index a8f8c928..56da2a04 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -344,6 +344,52 @@ static bool is_localaddr(sockaddr_t *sa) { } } +#ifdef HAVE_GETIFADDRS +struct getifaddrs_in_netns_params { + struct ifaddrs **ifa; + int netns; +}; + +#ifdef HAVE_SETNS +static void *getifaddrs_in_netns_thread(void *arg) { + struct getifaddrs_in_netns_params *params = arg; + + if(setns(params->netns, CLONE_NEWNET) == -1) { + meshlink_errno = MESHLINK_EINVAL; + return NULL; + } + + if(getifaddrs(params->ifa) != 0) { + *params->ifa = NULL; + } + + return NULL; +} +#endif // HAVE_SETNS + +static int getifaddrs_in_netns(struct ifaddrs **ifa, int netns) { + if(netns == -1) { + return getifaddrs(ifa); + } + +#ifdef HAVE_SETNS + struct getifaddrs_in_netns_params params = {ifa, netns}; + pthread_t thr; + + if(pthread_create(&thr, NULL, getifaddrs_in_netns_thread, ¶ms) == 0) { + if(pthread_join(thr, NULL) != 0) { + abort(); + } + } + + return *params.ifa ? 0 : -1; +#else + return -1; +#endif // HAVE_SETNS + +} +#endif + char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) { (void)mesh; @@ -361,12 +407,12 @@ char *meshlink_get_local_address_for_family(meshlink_handle_t *mesh, int family) if(!success) { struct ifaddrs *ifa = NULL; - getifaddrs(&ifa); + getifaddrs_in_netns(&ifa, mesh->netns); for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) { sockaddr_t *sa = (sockaddr_t *)ifap->ifa_addr; - if(sa->sa.sa_family != family) { + if(!sa || sa->sa.sa_family != family) { continue; } @@ -783,7 +829,7 @@ static bool finalize_join(join_state_t *state, const void *buf, uint16_t len) { } /* Ensure the configuration directory metadata is on disk */ - if(!config_sync(mesh, "current") || !sync_path(mesh->confbase)) { + if(!config_sync(mesh, "current") || (mesh->confbase && !sync_path(mesh->confbase))) { return false; } @@ -1667,6 +1713,11 @@ bool meshlink_start(meshlink_handle_t *mesh) { return false; } + // Reset node connection timers + for splay_each(node_t, n, mesh->nodes) { + n->last_connect_try = 0; + } + // TODO: open listening sockets first //Check that a valid name is set @@ -2532,11 +2583,7 @@ bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *no char *canonical_address; - if(port) { - xasprintf(&canonical_address, "%s %s", address, port); - } else { - canonical_address = xstrdup(address); - } + xasprintf(&canonical_address, "%s %s", address, port ? port : mesh->myport); if(pthread_mutex_lock(&mesh->mutex) != 0) { abort(); @@ -2556,6 +2603,30 @@ bool meshlink_set_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *no return config_sync(mesh, "current"); } +bool meshlink_clear_canonical_address(meshlink_handle_t *mesh, meshlink_node_t *node) { + if(!mesh || !node) { + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + node_t *n = (node_t *)node; + free(n->canonical_address); + n->canonical_address = NULL; + + if(!node_write_config(mesh, n)) { + pthread_mutex_unlock(&mesh->mutex); + return false; + } + + pthread_mutex_unlock(&mesh->mutex); + + return config_sync(mesh, "current"); +} + bool meshlink_add_invitation_address(struct meshlink_handle *mesh, const char *address, const char *port) { if(!mesh || !address) { meshlink_errno = MESHLINK_EINVAL; @@ -3575,7 +3646,12 @@ static bool channel_pre_accept(struct utcp *utcp, uint16_t port) { (void)port; node_t *n = utcp->priv; meshlink_handle_t *mesh = n->mesh; - return mesh->channel_accept_cb; + + if(mesh->channel_accept_cb && mesh->channel_listen_cb) { + return mesh->channel_listen_cb(mesh, (meshlink_node_t *)n, port); + } else { + return mesh->channel_accept_cb; + } } /* Finish one AIO buffer, return true if the channel is still open. */ @@ -3880,6 +3956,21 @@ void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *c pthread_mutex_unlock(&mesh->mutex); } +void meshlink_set_channel_listen_cb(meshlink_handle_t *mesh, meshlink_channel_listen_cb_t cb) { + if(!mesh) { + meshlink_errno = MESHLINK_EINVAL; + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + mesh->channel_listen_cb = cb; + + pthread_mutex_unlock(&mesh->mutex); +} + void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) { if(!mesh) { meshlink_errno = MESHLINK_EINVAL; @@ -4420,7 +4511,20 @@ void meshlink_set_dev_class_maxtimeout(struct meshlink_handle *mesh, dev_class_t pthread_mutex_unlock(&mesh->mutex); } -extern void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool inviter_commits_first) { +void meshlink_reset_timers(struct meshlink_handle *mesh) { + if(!mesh) { + return; + } + + if(pthread_mutex_lock(&mesh->mutex) != 0) { + abort(); + } + + handle_network_change(mesh, true); + pthread_mutex_unlock(&mesh->mutex); +} + +void meshlink_set_inviter_commits_first(struct meshlink_handle *mesh, bool inviter_commits_first) { if(!mesh) { meshlink_errno = EINVAL; return;