#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
-
__thread meshlink_errno_t meshlink_errno;
meshlink_log_cb_t global_log_cb;
meshlink_log_level_t global_log_level;
int fd;
};
+#ifdef HAVE_SETNS
static void *socket_in_netns_thread(void *arg) {
struct socket_in_netns_params *params = arg;
if(setns(params->netns, CLONE_NEWNET) == -1) {
meshlink_errno = MESHLINK_EINVAL;
- } else {
- params->fd = socket(params->domain, params->type, params->protocol);
+ return NULL;
}
+ params->fd = socket(params->domain, params->type, params->protocol);
+
return NULL;
}
+#endif // HAVE_SETNS
static int socket_in_netns(int domain, int type, int protocol, int netns) {
if(netns == -1) {
return socket(domain, type, protocol);
}
+#ifdef HAVE_SETNS
struct socket_in_netns_params params = {domain, type, protocol, netns, -1};
pthread_t thr;
}
return params.fd;
+#else
+ return -1;
+#endif // HAVE_SETNS
+
}
// Find out what local address a socket would use if we connect to the given address.
return true;
}
+#ifdef HAVE_SETNS
static void *setup_network_in_netns_thread(void *arg) {
meshlink_handle_t *mesh = arg;
add_local_addresses(mesh);
return success ? arg : NULL;
}
+#endif // HAVE_SETNS
meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
if(!confbase || !*confbase) {
meshlink_handle_t *meshlink_open(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
/* Create a temporary struct on the stack, to avoid allocating and freeing one. */
- meshlink_open_params_t params = {NULL};
+ meshlink_open_params_t params;
+ memset(¶ms, 0, sizeof(params));
params.confbase = (char *)confbase;
params.name = (char *)name;
bool success = false;
if(mesh->netns != -1) {
+#ifdef HAVE_SETNS
pthread_t thr;
if(pthread_create(&thr, NULL, setup_network_in_netns_thread, mesh) == 0) {
void *retval = NULL;
success = pthread_join(thr, &retval) == 0 && retval;
}
+
+#else
+ meshlink_errno = MESHLINK_EINTERNAL;
+ return NULL;
+
+#endif // HAVE_SETNS
} else {
success = setup_network(mesh);
add_local_addresses(mesh);
meshlink_handle_t *mesh = arg;
if(mesh->netns != -1) {
+#ifdef HAVE_SETNS
+
if(setns(mesh->netns, CLONE_NEWNET) != 0) {
return NULL;
}
+
+#else
+ return NULL;
+#endif // HAVE_SETNS
}
pthread_mutex_lock(&(mesh->mesh_mutex));
pthread_mutex_unlock(&(mesh->mesh_mutex));
}
+void meshlink_set_connection_try_cb(meshlink_handle_t *mesh, meshlink_connection_try_cb_t cb) {
+ if(!mesh) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ pthread_mutex_lock(&(mesh->mesh_mutex));
+ mesh->connection_try_cb = cb;
+ pthread_mutex_unlock(&(mesh->mesh_mutex));
+}
+
void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) {
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
return node;
}
+meshlink_submesh_t *meshlink_get_submesh(meshlink_handle_t *mesh, const char *name) {
+ if(!mesh || !name) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return NULL;
+ }
+
+ meshlink_submesh_t *submesh = NULL;
+
+ pthread_mutex_lock(&(mesh->mesh_mutex));
+ submesh = (meshlink_submesh_t *)lookup_submesh(mesh, name);
+ pthread_mutex_unlock(&(mesh->mesh_mutex));
+ return submesh;
+}
+
meshlink_node_t **meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t *nmemb) {
if(!mesh || !nmemb || (*nmemb && !nodes)) {
meshlink_errno = MESHLINK_EINVAL;
}
if(!stat(invname, &st)) {
- if(mesh->invitation_key && deadline < st.st_mtime) {
+ if(mesh->invitation_key && deadline < (time_t)st.st_mtime) {
count++;
} else {
unlink(invname);
done:
pthread_mutex_unlock(&(mesh->mesh_mutex));
- return rval;
+ return rval && meshlink_get_port(mesh) == port;
}
void meshlink_set_invitation_timeout(meshlink_handle_t *mesh, int timeout) {
return channel->c->flags;
}
+size_t meshlink_channel_get_sendq(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+ if(!mesh || !channel) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return -1;
+ }
+
+ return utcp_get_sendq(channel->c);
+}
+
+size_t meshlink_channel_get_recvq(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+ if(!mesh || !channel) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return -1;
+ }
+
+ return utcp_get_recvq(channel->c);
+}
+
void update_node_status(meshlink_handle_t *mesh, node_t *n) {
if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) {
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);