X-Git-Url: http://git.meshlink.io/?p=meshlink;a=blobdiff_plain;f=src%2Fmeshlink.c;h=fccfecbc404b24e9a9cbfcd67ecce53e221cbeb6;hp=ab3ab7ff9be3d4a2352760d9c56bbc5908f45443;hb=27b37a02bd75e71ed0a95ab201ba15ef4f5cb588;hpb=0d79f476e0311fb36f41c9c6d86744f9d5386fba diff --git a/src/meshlink.c b/src/meshlink.c index ab3ab7ff..fccfecbc 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -577,7 +577,7 @@ static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) { return hostport; } -static bool try_bind(int port) { +static bool try_bind(meshlink_handle_t *mesh, int port) { struct addrinfo *ai = NULL; struct addrinfo hint = { .ai_flags = AI_PASSIVE, @@ -598,16 +598,9 @@ static bool try_bind(int port) { for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) { /* Try to bind to TCP. */ - int tcp_fd = socket(aip->ai_family, SOCK_STREAM, IPPROTO_TCP); + int tcp_fd = setup_tcp_listen_socket(mesh, aip); if(tcp_fd == -1) { - continue; - } - - int result = bind(tcp_fd, aip->ai_addr, aip->ai_addrlen); - closesocket(tcp_fd); - - if(result) { if(errno == EADDRINUSE) { /* If this port is in use for any address family, avoid it. */ success = false; @@ -619,21 +612,16 @@ static bool try_bind(int port) { /* If TCP worked, then we require that UDP works as well. */ - int udp_fd = socket(aip->ai_family, SOCK_DGRAM, IPPROTO_UDP); + int udp_fd = setup_udp_listen_socket(mesh, aip); if(udp_fd == -1) { + closesocket(tcp_fd); success = false; break; } - result = bind(udp_fd, aip->ai_addr, aip->ai_addrlen); + closesocket(tcp_fd); closesocket(udp_fd); - - if(result) { - success = false; - break; - } - success = true; } @@ -645,7 +633,7 @@ int check_port(meshlink_handle_t *mesh) { for(int i = 0; i < 1000; i++) { int port = 0x1000 + prng(mesh, 0x8000); - if(try_bind(port)) { + if(try_bind(mesh, port)) { free(mesh->myport); xasprintf(&mesh->myport, "%d", port); return port; @@ -1173,7 +1161,6 @@ static void *setup_network_in_netns_thread(void *arg) { } bool success = setup_network(mesh); - add_local_addresses(mesh); return success ? arg : NULL; } #endif // HAVE_SETNS @@ -1546,7 +1533,6 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) { #endif // HAVE_SETNS } else { success = setup_network(mesh); - add_local_addresses(mesh); } if(!success) { @@ -1968,22 +1954,12 @@ void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb) pthread_mutex_unlock(&mesh->mutex); } -bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) { +static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) { meshlink_packethdr_t *hdr; - // Validate arguments - if(!mesh || !destination || len >= MAXSIZE - sizeof(*hdr)) { - meshlink_errno = MESHLINK_EINVAL; - return false; - } - - if(!len) { - return true; - } - - if(!data) { + if(len >= MAXSIZE - sizeof(*hdr)) { meshlink_errno = MESHLINK_EINVAL; - return false; + return NULL; } node_t *n = (node_t *)destination; @@ -1991,7 +1967,7 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const if(n->status.blacklisted) { logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name); meshlink_errno = MESHLINK_EBLACKLISTED; - return false; + return NULL; } // Prepare the packet @@ -1999,7 +1975,7 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const if(!packet) { meshlink_errno = MESHLINK_ENOMEM; - return false; + return NULL; } packet->probe = false; @@ -2015,6 +1991,52 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const memcpy(packet->data + sizeof(*hdr), data, len); + return packet; +} + +static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) { + assert(mesh); + assert(destination); + assert(data); + assert(len); + + // Prepare the packet + vpn_packet_t *packet = prepare_packet(mesh, destination, data, len); + + if(!packet) { + return false; + } + + // Send it immediately + route(mesh, mesh->self, packet); + free(packet); + + return true; +} + +bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) { + // Validate arguments + if(!mesh || !destination) { + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + if(!len) { + return true; + } + + if(!data) { + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + // Prepare the packet + vpn_packet_t *packet = prepare_packet(mesh, destination, data, len); + + if(!packet) { + return false; + } + // Queue it if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) { free(packet); @@ -2022,6 +2044,8 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const return false; } + logger(mesh, MESHLINK_DEBUG, "Adding packet of %zu bytes to packet queue", len); + // Notify event loop signal_trigger(&mesh->loop, &mesh->datafromapp); @@ -2031,17 +2055,16 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const 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; - } - - mesh->self->in_packets++; - mesh->self->in_bytes += packet->len; - route(mesh, mesh->self, packet); + logger(mesh, MESHLINK_DEBUG, "Flushing the packet queue"); - free(packet); + 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); + } } ssize_t meshlink_get_pmtu(meshlink_handle_t *mesh, meshlink_node_t *destination) { @@ -2554,7 +2577,7 @@ bool meshlink_set_port(meshlink_handle_t *mesh, int port) { return true; } - if(!try_bind(port)) { + if(!try_bind(mesh, port)) { meshlink_errno = MESHLINK_ENETWORK; return false; } @@ -3531,7 +3554,7 @@ static ssize_t channel_send(struct utcp *utcp, const void *data, size_t len) { } meshlink_handle_t *mesh = n->mesh; - return meshlink_send(mesh, (meshlink_node_t *)n, data, len) ? (ssize_t)len : -1; + return meshlink_send_immediate(mesh, (meshlink_node_t *)n, data, len) ? (ssize_t)len : -1; } void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb) {