X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=e59170a9f220b50f992e0b07be376923f8ac1018;hb=cfb5273b8e1e5ab7dadb1e05ed7294fcb394e5e8;hp=956651155fbe09bffde83dd0ddde1ef47c0aa229;hpb=103be3a74f3b08ec7f5d06d2c7453496b42ae6c1;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 95665115..e59170a9 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -48,8 +48,6 @@ typedef struct { #define MSG_NOSIGNAL 0 #endif -static pthread_mutex_t global_mutex; - __thread meshlink_errno_t meshlink_errno; meshlink_log_cb_t global_log_cb; meshlink_log_level_t global_log_level; @@ -1012,7 +1010,10 @@ void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, me } bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) { - if(!mesh || !destination) { + meshlink_packethdr_t *hdr; + + // Validate arguments + if(!mesh || !destination || len >= MAXSIZE - sizeof *hdr) { meshlink_errno = MESHLINK_EINVAL; return false; } @@ -1025,59 +1026,45 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const return false; } - pthread_mutex_lock(&(mesh->mesh_mutex)); + // Prepare the packet + vpn_packet_t *packet = malloc(sizeof *packet); + if(!packet) { + meshlink_errno = MESHLINK_ENOMEM; + return false; + } - //add packet to the queue - outpacketqueue_t *packet_in_queue = xzalloc(sizeof *packet_in_queue); - packet_in_queue->destination=destination; - packet_in_queue->data=data; - packet_in_queue->len=len; - if(!meshlink_queue_push(&mesh->outpacketqueue, packet_in_queue)) { - free(packet_in_queue); - pthread_mutex_unlock(&(mesh->mesh_mutex)); + packet->probe = false; + packet->tcp = false; + packet->len = len + sizeof *hdr; + + hdr = (meshlink_packethdr_t *)packet->data; + memset(hdr, 0, sizeof *hdr); + memcpy(hdr->destination, destination->name, sizeof hdr->destination); + memcpy(hdr->source, mesh->self->name, sizeof hdr->source); + + memcpy(packet->data + sizeof *hdr, data, len); + + // Queue it + if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) { + free(packet); + meshlink_errno = MESHLINK_ENOMEM; return false; } - //notify event loop + // Notify event loop signal_trigger(&(mesh->loop),&(mesh->datafromapp)); - pthread_mutex_unlock(&(mesh->mesh_mutex)); return true; } -void meshlink_send_from_queue(event_loop_t* el,meshlink_handle_t *mesh) { - pthread_mutex_lock(&(mesh->mesh_mutex)); - - vpn_packet_t packet; - meshlink_packethdr_t *hdr = (meshlink_packethdr_t *)packet.data; - - outpacketqueue_t* p = meshlink_queue_pop(&mesh->outpacketqueue); - if(!p) - { - pthread_mutex_unlock(&(mesh->mesh_mutex)); - return; - } - - if (sizeof(meshlink_packethdr_t) + p->len > MAXSIZE) { - pthread_mutex_unlock(&(mesh->mesh_mutex)); - //log something +void meshlink_send_from_queue(event_loop_t *loop, meshlink_handle_t *mesh) { + vpn_packet_t *packet = meshlink_queue_pop(&mesh->outpacketqueue); + if(!packet) return; - } - packet.probe = false; - memset(hdr, 0, sizeof *hdr); - memcpy(hdr->destination, p->destination->name, sizeof hdr->destination); - memcpy(hdr->source, mesh->self->name, sizeof hdr->source); - - packet.len = sizeof *hdr + p->len; - memcpy(packet.data + sizeof *hdr, p->data, p->len); - - mesh->self->in_packets++; - mesh->self->in_bytes += packet.len; - route(mesh, mesh->self, &packet); - - pthread_mutex_unlock(&(mesh->mesh_mutex)); - return ; + mesh->self->in_packets++; + mesh->self->in_bytes += packet->len; + route(mesh, mesh->self, packet); } ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) { @@ -1714,7 +1701,7 @@ char *meshlink_export(meshlink_handle_t *mesh) { fclose(f); buf[len - 1] = 0; - pthread_mutex_lock(&(mesh->mesh_mutex)); + pthread_mutex_unlock(&(mesh->mesh_mutex)); return buf; } @@ -1836,7 +1823,10 @@ void meshlink_hint_address(meshlink_handle_t *mesh, meshlink_node_t *node, const if(host && port) { xasprintf(&str, "%s %s", host, port); - append_config_file(mesh, node->name, "Address", str); + if ( (strncmp ("fe80",host,4) != 0) && ( strncmp("127.",host,4) != 0 ) && ( strcmp("localhost",host) !=0 ) ) + append_config_file(mesh, node->name, "Address", str); + else + logger(mesh, MESHLINK_DEBUG, "Not adding Link Local IPv6 Address to config\n"); } free(str); @@ -1913,6 +1903,76 @@ meshlink_edge_t **meshlink_get_all_edges_state(meshlink_handle_t *mesh, meshlink return result; } +static bool channel_pre_accept(struct utcp *utcp, uint16_t port) { + //TODO: implement + return false; +} + +static void channel_accept(struct utcp_connection *utcp_connection, uint16_t port) { + //TODO: implement +} + +static int channel_recv(struct utcp_connection *connection, const void *data, size_t len) { + meshlink_channel_t *channel = connection->priv; + node_t *n = channel->node; + meshlink_handle_t *mesh = n->mesh; + if(!channel->receive_cb) + return -1; + else { + channel->receive_cb(mesh, channel, data, len); + return 0; + } +} + +static int channel_send(struct utcp *utcp, const void *data, size_t len) { + node_t *n = utcp->priv; + meshlink_handle_t *mesh = n->mesh; + return meshlink_send(mesh, (meshlink_node_t *)n, data, len) ? len : -1; +} + +void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) { + mesh->channel_accept_cb = cb; +} + +void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb) { + channel->receive_cb = cb; +} + +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) { + node_t *n = (node_t *)node; + if(!n->utcp) { + n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n); + if(!n->utcp) + return NULL; + } + meshlink_channel_t *channel = xzalloc(sizeof *channel); + channel->node = n; + channel->receive_cb = cb; + channel->c = utcp_connect(n->utcp, port, channel_recv, channel); + if(!channel->c) { + free(channel); + return NULL; + } + return channel; +} + +void meshlink_channel_shutdown(meshlink_handle_t *mesh, meshlink_channel_t *channel, int direction) { + utcp_shutdown(channel->c, direction); +} + +void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel) { + utcp_close(channel->c); + free(channel); +} + +ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) { + // TODO: locking. + // Ideally we want to put the data into the UTCP connection's send buffer. + // Then, preferrably only if there is room in the receiver window, + // kick the meshlink thread to go send packets. + return utcp_send(channel->c, data, len); +} + static void __attribute__((constructor)) meshlink_init(void) { crypto_init(); }