static int check_port(meshlink_handle_t *mesh) {
for(int i = 0; i < 1000; i++) {
- int port = 0x1000 + (rand() & 0x7fff);
+ int port = 0x1000 + prng(mesh, 0x8000);
if(try_bind(port)) {
free(mesh->myport);
mesh->log_cb = global_log_cb;
mesh->log_level = global_log_level;
+ randomize(&mesh->prng_state, sizeof(mesh->prng_state));
+
memcpy(mesh->dev_class_traits, default_class_traits, sizeof(default_class_traits));
if(usingname) {
free(mesh->confbase);
free(mesh->config_key);
ecdsa_free(mesh->private_key);
- pthread_mutex_destroy(&(mesh->mesh_mutex));
main_config_unlock(mesh);
+ pthread_mutex_unlock(&mesh->mesh_mutex);
+ pthread_mutex_destroy(&mesh->mesh_mutex);
+
memset(mesh, 0, sizeof(*mesh));
free(mesh);
}
}
+void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) {
+ if(!mesh) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ pthread_mutex_lock(&(mesh->mesh_mutex));
+ mesh->error_cb = cb;
+ pthread_mutex_unlock(&(mesh->mesh_mutex));
+}
+
bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
meshlink_packethdr_t *hdr;
return true;
}
-void meshlink_send_from_queue(event_loop_t *loop, meshlink_handle_t *mesh) {
+void meshlink_send_from_queue(event_loop_t *loop, void *data) {
(void)loop;
+ meshlink_handle_t *mesh = data;
vpn_packet_t *packet = meshlink_queue_pop(&mesh->outpacketqueue);
if(!packet) {
return utcp_get_recvq(channel->c);
}
+void meshlink_set_node_channel_timeout(meshlink_handle_t *mesh, meshlink_node_t *node, int timeout) {
+ if(!mesh || !node) {
+ meshlink_errno = MESHLINK_EINVAL;
+ return;
+ }
+
+ node_t *n = (node_t *)node;
+
+ pthread_mutex_lock(&mesh->mesh_mutex);
+
+ if(!n->utcp) {
+ n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
+ }
+
+ utcp_set_user_timeout(n->utcp, timeout);
+
+ pthread_mutex_unlock(&mesh->mesh_mutex);
+}
+
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);
retry(mesh);
}
+void call_error_cb(meshlink_handle_t *mesh, meshlink_errno_t meshlink_errno) {
+ // We should only call the callback function if we are in the background thread.
+ if(!mesh->error_cb) {
+ return;
+ }
+
+ if(!mesh->threadstarted) {
+ return;
+ }
+
+ if(mesh->thread == pthread_self()) {
+ mesh->error_cb(mesh, meshlink_errno);
+ }
+}
+
+
static void __attribute__((constructor)) meshlink_init(void) {
crypto_init();
- unsigned int seed;
- randomize(&seed, sizeof(seed));
- srand(seed);
}
static void __attribute__((destructor)) meshlink_exit(void) {