int check_port(meshlink_handle_t *mesh) {
for(int i = 0; i < 1000; i++) {
- int port = 0x1000 + prng(mesh, 0x8000);
+ int port = 0x1000 + prng(mesh, 0x7000);
if(try_bind(mesh, port)) {
free(mesh->myport);
abort();
}
+ if(mesh->thread_status_cb) {
+ mesh->thread_status_cb(mesh, true);
+ }
+
logger(mesh, MESHLINK_DEBUG, "Starting main_loop...\n");
pthread_cond_broadcast(&mesh->cond);
main_loop(mesh);
logger(mesh, MESHLINK_DEBUG, "main_loop returned.\n");
+ if(mesh->thread_status_cb) {
+ mesh->thread_status_cb(mesh, false);
+ }
+
pthread_mutex_unlock(&mesh->mutex);
// Stop discovery
}
void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_receive_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_receive_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_connection_try_cb(meshlink_handle_t *mesh, meshlink_connection_try_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_connection_try_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_connection_try_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_node_status_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_node_status_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_node_pmtu_cb(meshlink_handle_t *mesh, meshlink_node_pmtu_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_node_pmtu_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_node_pmtu_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_node_duplicate_cb(meshlink_handle_t *mesh, meshlink_node_duplicate_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_node_duplicate_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_node_duplicate_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_log_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_log_cb(%p)", (void *)(intptr_t)cb);
if(mesh) {
if(pthread_mutex_lock(&mesh->mutex) != 0) {
}
void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_error_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_error_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_blacklisted_cb(struct meshlink_handle *mesh, meshlink_blacklisted_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_blacklisted_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_blacklisted_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
pthread_mutex_unlock(&mesh->mutex);
}
+void meshlink_set_thread_status_cb(struct meshlink_handle *mesh, meshlink_thread_status_cb_t cb) {
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_thread_status_cb(%p)", (void *)(intptr_t)cb);
+
+ if(!mesh) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ if(pthread_mutex_lock(&mesh->mutex) != 0) {
+ abort();
+ }
+
+ mesh->thread_status_cb = cb;
+ pthread_mutex_unlock(&mesh->mutex);
+}
+
static bool prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len, vpn_packet_t *packet) {
meshlink_packethdr_t *hdr;
for(vpn_packet_t *packet; (packet = meshlink_queue_pop(&mesh->outpacketqueue));) {
logger(mesh, MESHLINK_DEBUG, "Removing packet of %d bytes from packet queue", packet->len);
- mesh->self->in_packets++;
- mesh->self->in_bytes += packet->len;
route(mesh, mesh->self, packet);
free(packet);
}
return devclass;
}
+bool meshlink_get_node_tiny(meshlink_handle_t *mesh, meshlink_node_t *node) {
+ if(!mesh || !node) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return -1;
+ }
+
+ bool tiny;
+
+ if(pthread_mutex_lock(&mesh->mutex) != 0) {
+ abort();
+ }
+
+ tiny = ((node_t *)node)->status.tiny;
+
+ pthread_mutex_unlock(&mesh->mutex);
+
+ return tiny;
+}
+
bool meshlink_get_node_blacklisted(meshlink_handle_t *mesh, meshlink_node_t *node) {
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_receive_cb(%p, %p)", (void *)channel, (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_receive_cb(%p, %p)", (void *)channel, (void *)(intptr_t)cb);
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;
channel->receive_cb = cb;
}
-static void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
+void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
(void)mesh;
node_t *n = (node_t *)source;
}
void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_poll_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_poll_cb(%p, %p)", (void *)channel, (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_poll_cb(%p, %p)", (void *)channel, (void *)(intptr_t)cb);
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_channel_listen_cb(meshlink_handle_t *mesh, meshlink_channel_listen_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_listen_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_listen_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_accept_cb(%p)", (void *)cb);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_set_channel_accept_cb(%p)", (void *)(intptr_t)cb);
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
}
mesh->channel_accept_cb = cb;
- mesh->receive_cb = channel_receive;
for splay_each(node_t, n, mesh->nodes) {
if(!n->utcp && n != mesh->self) {
}
meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_channel_open_ex(%s, %u, %p, %p, %zu, %u)", node ? node->name : "(null)", port, (void *)cb, data, len, flags);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_channel_open_ex(%s, %u, %p, %p, %zu, %u)", node ? node->name : "(null)", port, (void *)(intptr_t)cb, data, len, flags);
if(data && len) {
abort(); // TODO: handle non-NULL data
n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
utcp_set_mtu(n->utcp, n->mtu - sizeof(meshlink_packethdr_t));
utcp_set_retransmit_cb(n->utcp, channel_retransmit);
- mesh->receive_cb = channel_receive;
if(!n->utcp) {
meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
}
meshlink_channel_t *meshlink_channel_open(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_channel_open_ex(%s, %u, %p, %p, %zu)", node ? node->name : "(null)", port, (void *)cb, data, len);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_channel_open_ex(%s, %u, %p, %p, %zu)", node ? node->name : "(null)", port, (void *)(intptr_t)cb, data, len);
return meshlink_channel_open_ex(mesh, node, port, cb, data, len, MESHLINK_CHANNEL_TCP);
}
}
bool meshlink_channel_aio_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, meshlink_aio_cb_t cb, void *priv) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_send(%p, %p, %zu, %p, %p)", (void *)channel, data, len, (void *)cb, priv);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_send(%p, %p, %zu, %p, %p)", (void *)channel, data, len, (void *)(intptr_t)cb, priv);
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;
/* Ensure the poll callback is set, and call it right now to push data if possible */
utcp_set_poll_cb(channel->c, channel_poll);
- size_t todo = MIN(len, utcp_get_rcvbuf_free(channel->c));
+ size_t todo = MIN(len, utcp_get_sndbuf_free(channel->c));
if(todo) {
channel_poll(channel->c, todo);
}
bool meshlink_channel_aio_fd_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, int fd, size_t len, meshlink_aio_fd_cb_t cb, void *priv) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_fd_send(%p, %d, %zu, %p, %p)", (void *)channel, fd, len, (void *)cb, priv);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_fd_send(%p, %d, %zu, %p, %p)", (void *)channel, fd, len, (void *)(intptr_t)cb, priv);
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;
/* Ensure the poll callback is set, and call it right now to push data if possible */
utcp_set_poll_cb(channel->c, channel_poll);
- size_t left = utcp_get_rcvbuf_free(channel->c);
+ size_t left = utcp_get_sndbuf_free(channel->c);
if(left) {
channel_poll(channel->c, left);
}
bool meshlink_channel_aio_receive(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, meshlink_aio_cb_t cb, void *priv) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_receive(%p, %p, %zu, %p, %p)", (void *)channel, data, len, (void *)cb, priv);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_receive(%p, %p, %zu, %p, %p)", (void *)channel, data, len, (void *)(intptr_t)cb, priv);
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;
}
bool meshlink_channel_aio_fd_receive(meshlink_handle_t *mesh, meshlink_channel_t *channel, int fd, size_t len, meshlink_aio_fd_cb_t cb, void *priv) {
- logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_fd_receive(%p, %d, %zu, %p, %p)", (void *)channel, fd, len, (void *)cb, priv);
+ logger(mesh, MESHLINK_DEBUG, "meshlink_channel_aio_fd_receive(%p, %d, %zu, %p, %p)", (void *)channel, fd, len, (void *)(intptr_t)cb, priv);
if(!mesh || !channel) {
meshlink_errno = MESHLINK_EINVAL;