]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Use blocking ADNS requests for most other hostname resolving.
[meshlink] / src / meshlink.c
index 38ef57508b7e13540644bdababfc27f2d1042602..cdf9b17dcd94fe1d77d31a4102b539cf4049f02e 100644 (file)
 #include "system.h"
 #include <pthread.h>
 
+#include "adns.h"
 #include "crypto.h"
 #include "ecdsagen.h"
 #include "logger.h"
 #include "meshlink_internal.h"
+#include "net.h"
 #include "netutl.h"
 #include "node.h"
 #include "submesh.h"
@@ -171,6 +173,7 @@ static bool getlocaladdr(char *destaddr, sockaddr_t *sa, socklen_t *salen, int n
                .ai_family = AF_UNSPEC,
                .ai_socktype = SOCK_DGRAM,
                .ai_protocol = IPPROTO_UDP,
+               .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV,
        };
 
        if(getaddrinfo(destaddr, "80", &hint, &rai) || !rai) {
@@ -254,7 +257,7 @@ char *meshlink_get_external_address_for_family(meshlink_handle_t *mesh, int fami
        }
 
        logger(mesh, MESHLINK_DEBUG, "Trying to discover externally visible hostname...\n");
-       struct addrinfo *ai = str2addrinfo(host, port ? port : "80", SOCK_STREAM);
+       struct addrinfo *ai = adns_blocking_request(mesh, xstrdup(host), xstrdup(port ? port : "80"), 5);
        char line[256];
        char *hostname = NULL;
 
@@ -498,15 +501,9 @@ static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) {
                }
 
                // Convert what we have to a sockaddr
-               struct addrinfo *ai_in, *ai_out;
-               struct addrinfo hint = {
-                       .ai_family = AF_UNSPEC,
-                       .ai_flags = AI_NUMERICSERV,
-                       .ai_socktype = SOCK_STREAM,
-               };
-               int err = getaddrinfo(hostname[i], port[i], &hint, &ai_in);
-
-               if(err || !ai_in) {
+               struct addrinfo *ai_in = adns_blocking_request(mesh, xstrdup(hostname[i]), xstrdup(port[i]), 5);
+
+               if(!ai_in) {
                        continue;
                }
 
@@ -515,44 +512,8 @@ static char *get_my_hostname(meshlink_handle_t *mesh, uint32_t flags) {
                        node_add_recent_address(mesh, mesh->self, (sockaddr_t *)aip->ai_addr);
                }
 
-               if(flags & MESHLINK_INVITE_NUMERIC) {
-                       // We don't need to do any further conversion
-                       freeaddrinfo(ai_in);
-                       continue;
-               }
-
-               // Convert it to a hostname
-               char resolved_host[NI_MAXHOST];
-               char resolved_port[NI_MAXSERV];
-               err = getnameinfo(ai_in->ai_addr, ai_in->ai_addrlen, resolved_host, sizeof resolved_host, resolved_port, sizeof resolved_port, NI_NUMERICSERV);
-
-               if(err || !is_valid_hostname(resolved_host)) {
-                       freeaddrinfo(ai_in);
-                       continue;
-               }
-
-               // Convert the hostname back to a sockaddr
-               hint.ai_family = ai_in->ai_family;
-               err = getaddrinfo(resolved_host, resolved_port, &hint, &ai_out);
-
-               if(err || !ai_out) {
-                       freeaddrinfo(ai_in);
-                       continue;
-               }
-
-               // Check if it's still the same sockaddr
-               if(ai_in->ai_addrlen != ai_out->ai_addrlen || memcmp(ai_in->ai_addr, ai_out->ai_addr, ai_in->ai_addrlen)) {
-                       freeaddrinfo(ai_in);
-                       freeaddrinfo(ai_out);
-                       continue;
-               }
-
-               // Yes: replace the hostname with the resolved one
-               free(hostname[i]);
-               hostname[i] = xstrdup(resolved_host);
-
                freeaddrinfo(ai_in);
-               freeaddrinfo(ai_out);
+               continue;
        }
 
        // Remove duplicates again, since IPv4 and IPv6 addresses might map to the same hostname
@@ -1456,6 +1417,7 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
        mesh->submeshes = NULL;
        mesh->log_cb = global_log_cb;
        mesh->log_level = global_log_level;
+       mesh->packet = xmalloc(sizeof(vpn_packet_t));
 
        randomize(&mesh->prng_state, sizeof(mesh->prng_state));
 
@@ -1671,6 +1633,7 @@ bool meshlink_start(meshlink_handle_t *mesh) {
        }
 
        init_outgoings(mesh);
+       init_adns(mesh);
 
        // Start the main thread
 
@@ -1741,6 +1704,7 @@ void meshlink_stop(meshlink_handle_t *mesh) {
                }
        }
 
+       exit_adns(mesh);
        exit_outgoings(mesh);
 
        // Ensure we are considered unreachable
@@ -1805,6 +1769,7 @@ void meshlink_close(meshlink_handle_t *mesh) {
        free(mesh->confbase);
        free(mesh->config_key);
        free(mesh->external_address_url);
+       free(mesh->packet);
        ecdsa_free(mesh->private_key);
 
        if(mesh->invitation_addresses) {
@@ -1962,12 +1927,12 @@ void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb)
        pthread_mutex_unlock(&mesh->mutex);
 }
 
-static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
+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;
 
        if(len >= MAXSIZE - sizeof(*hdr)) {
                meshlink_errno = MESHLINK_EINVAL;
-               return NULL;
+               return false;
        }
 
        node_t *n = (node_t *)destination;
@@ -1975,17 +1940,10 @@ static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *de
        if(n->status.blacklisted) {
                logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name);
                meshlink_errno = MESHLINK_EBLACKLISTED;
-               return NULL;
+               return false;
        }
 
        // Prepare the packet
-       vpn_packet_t *packet = malloc(sizeof(*packet));
-
-       if(!packet) {
-               meshlink_errno = MESHLINK_ENOMEM;
-               return NULL;
-       }
-
        packet->probe = false;
        packet->tcp = false;
        packet->len = len + sizeof(*hdr);
@@ -1999,7 +1957,7 @@ static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *de
 
        memcpy(packet->data + sizeof(*hdr), data, len);
 
-       return packet;
+       return true;
 }
 
 static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
@@ -2009,15 +1967,12 @@ static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *de
        assert(len);
 
        // Prepare the packet
-       vpn_packet_t *packet = prepare_packet(mesh, destination, data, len);
-
-       if(!packet) {
+       if(!prepare_packet(mesh, destination, data, len, mesh->packet)) {
                return false;
        }
 
        // Send it immediately
-       route(mesh, mesh->self, packet);
-       free(packet);
+       route(mesh, mesh->self, mesh->packet);
 
        return true;
 }
@@ -2039,12 +1994,17 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const
        }
 
        // Prepare the packet
-       vpn_packet_t *packet = prepare_packet(mesh, destination, data, len);
+       vpn_packet_t *packet = malloc(sizeof(*packet));
 
        if(!packet) {
+               meshlink_errno = MESHLINK_ENOMEM;
                return false;
        }
 
+       if(!prepare_packet(mesh, destination, data, len, packet)) {
+               free(packet);
+       }
+
        // Queue it
        if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) {
                free(packet);
@@ -2894,7 +2854,7 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) {
                }
 
                // Connect to the meshlink daemon mentioned in the URL.
-               struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM);
+               struct addrinfo *ai = adns_blocking_request(mesh, xstrdup(address), xstrdup(port), 5);
 
                if(ai) {
                        for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
@@ -4164,6 +4124,15 @@ void meshlink_set_external_address_discovery_url(struct meshlink_handle *mesh, c
        pthread_mutex_unlock(&mesh->mutex);
 }
 
+void meshlink_set_scheduling_granularity(struct meshlink_handle *mesh, long granularity) {
+       if(!mesh || granularity < 0) {
+               meshlink_errno = EINVAL;
+               return;
+       }
+
+       utcp_set_clock_granularity(granularity);
+}
+
 void handle_network_change(meshlink_handle_t *mesh, bool online) {
        (void)online;
 
@@ -4191,6 +4160,7 @@ void call_error_cb(meshlink_handle_t *mesh, meshlink_errno_t meshlink_errno) {
 
 static void __attribute__((constructor)) meshlink_init(void) {
        crypto_init();
+       utcp_set_clock_granularity(10000);
 }
 
 static void __attribute__((destructor)) meshlink_exit(void) {