From 53818faa72ac501f593edfc454b35d1fd4bfb318 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 8 Apr 2020 00:50:51 +0200 Subject: [PATCH] Add asynchronous DNS lookups for outgoing connections. --- src/net.h | 1 + src/net_socket.c | 69 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/net.h b/src/net.h index 38727c28..5ea2ae3e 100644 --- a/src/net.h +++ b/src/net.h @@ -63,6 +63,7 @@ typedef struct outgoing_t { struct node_t *node; enum { OUTGOING_START, + OUTGOING_CANONICAL_RESOLVE, OUTGOING_CANONICAL, OUTGOING_RECENT, OUTGOING_KNOWN, diff --git a/src/net_socket.c b/src/net_socket.c index 30ff0169..8b293d5d 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -19,6 +19,7 @@ #include "system.h" +#include "adns.h" #include "conf.h" #include "connection.h" #include "list.h" @@ -240,25 +241,26 @@ static void free_known_addresses(struct addrinfo *ai) { } } -static struct addrinfo *get_canonical_address(node_t *n) { - if(!n->canonical_address) { - return false; - } - - char *address = xstrdup(n->canonical_address); - char *port = strchr(address, ' '); +static void canonical_resolve_cb(meshlink_handle_t *mesh, char *host, char *serv, void *data, struct addrinfo *ai, int err) { + (void)serv; + (void)err; + node_t *n = data; + + free(host); + free(serv); + + for list_each(outgoing_t, outgoing, mesh->outgoings) { + if(outgoing->node == n) { + if(outgoing->state == OUTGOING_CANONICAL_RESOLVE) { + outgoing->ai = ai; + outgoing->aip = NULL; + outgoing->state = OUTGOING_CANONICAL; + do_outgoing_connection(mesh, outgoing); + } - if(!port) { - free(address); - return false; + return; + } } - - *port++ = 0; - - struct addrinfo *ai = str2addrinfo(address, port, SOCK_STREAM); - free(address); - - return ai; } static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgoing) { @@ -268,12 +270,32 @@ static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgo if(outgoing->state == OUTGOING_START) { start = true; - outgoing->state = OUTGOING_CANONICAL; + outgoing->state = OUTGOING_CANONICAL_RESOLVE; + } + + if(outgoing->state == OUTGOING_CANONICAL_RESOLVE) { + node_t *n = outgoing->node; + + if(n->canonical_address) { + char *address = xstrdup(n->canonical_address); + char *port = strchr(address, ' '); + + if(port) { + *port++ = 0; + port = xstrdup(port); + } else { + port = xstrdup(mesh->myport); + } + + adns_queue(mesh, address, port, canonical_resolve_cb, outgoing->node, 2); + return false; + } else { + outgoing->state = OUTGOING_RECENT; + } } if(outgoing->state == OUTGOING_CANONICAL) { if(!outgoing->aip) { - outgoing->ai = get_canonical_address(outgoing->node); outgoing->aip = outgoing->ai; } else { outgoing->aip = outgoing->aip->ai_next; @@ -283,7 +305,10 @@ static bool get_next_outgoing_address(meshlink_handle_t *mesh, outgoing_t *outgo return true; } - freeaddrinfo(outgoing->ai); + if(outgoing->ai) { + freeaddrinfo(outgoing->ai); + } + outgoing->ai = NULL; outgoing->aip = NULL; outgoing->state = OUTGOING_RECENT; @@ -336,7 +361,9 @@ void do_outgoing_connection(meshlink_handle_t *mesh, outgoing_t *outgoing) { begin: if(!get_next_outgoing_address(mesh, outgoing)) { - if(outgoing->state == OUTGOING_NO_KNOWN_ADDRESSES) { + if(outgoing->state == OUTGOING_CANONICAL_RESOLVE) { + /* We are waiting for a callback from the ADNS thread */ + } else if(outgoing->state == OUTGOING_NO_KNOWN_ADDRESSES) { logger(mesh, MESHLINK_ERROR, "No known addresses for %s", outgoing->node->name); } else { logger(mesh, MESHLINK_ERROR, "Could not set up a meta connection to %s", outgoing->node->name); -- 2.39.5