diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-04-16 05:23:12 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-04-16 05:23:12 +0200 |
commit | 96ec41768b5937e5cf0cd83bf815d365d12d1f93 (patch) | |
tree | c56fb1c45db75c32b156b5ceee8758334df69c12 | |
parent | 037c58ae51a61064d7bb5022715546509328d83f (diff) | |
download | fastd-96ec41768b5937e5cf0cd83bf815d365d12d1f93.tar fastd-96ec41768b5937e5cf0cd83bf815d365d12d1f93.zip |
Add support for peers specified by hostnames
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/config.l | 5 | ||||
-rw-r--r-- | src/config.y | 61 | ||||
-rw-r--r-- | src/fastd.c | 76 | ||||
-rw-r--r-- | src/fastd.h | 26 | ||||
-rw-r--r-- | src/peer.c | 22 | ||||
-rw-r--r-- | src/peer.h | 9 | ||||
-rw-r--r-- | src/printf.c | 3 | ||||
-rw-r--r-- | src/resolve.c | 123 | ||||
-rw-r--r-- | src/types.h | 4 |
11 files changed, 291 insertions, 47 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c33c10c..c50ec05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,12 @@ set(CMAKE_MODULE_PATH ${FASTD_SOURCE_DIR}) find_package(BISON 2.5 REQUIRED) find_package(FLEX REQUIRED) +set(CMAKE_THREAD_PREFER_PTHREAD TRUE) +find_package(Threads) +if(NOT CMAKE_USE_PTHREADS_INIT) + MESSAGE(FATAL_ERROR "No pthread support found.") +endif(NOT CMAKE_USE_PTHREADS_INIT) + find_package(UECC REQUIRED) find_package(NaCl REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a700c4c..84f25fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,12 +17,13 @@ add_executable(fastd printf.c queue.c random.c + resolve.c task.c protocol_ec25519_fhmqvc.c ${FLEX_fastd_config_lex_OUTPUTS} ${BISON_fastd_config_parse_OUTPUTS} ${METHODS} ) -target_link_libraries(fastd rt ${UECC_LIBRARY} ${NACL_LIBRARY}) +target_link_libraries(fastd rt ${CMAKE_THREAD_LIBS_INIT} ${UECC_LIBRARY} ${NACL_LIBRARY}) install(TARGETS fastd RUNTIME DESTINATION sbin) diff --git a/src/config.l b/src/config.l index f20116c..c05f0e1 100644 --- a/src/config.l +++ b/src/config.l @@ -61,7 +61,9 @@ mode { UPDATE_LOCATION; return TOK_MODE; } protocol { UPDATE_LOCATION; return TOK_PROTOCOL; } method { UPDATE_LOCATION; return TOK_METHOD; } peer { UPDATE_LOCATION; return TOK_PEER; } -address { UPDATE_LOCATION; return TOK_ADDRESS; } +remote { UPDATE_LOCATION; return TOK_REMOTE; } +ipv4 { UPDATE_LOCATION; return TOK_IPV4; } +ipv6 { UPDATE_LOCATION; return TOK_IPV6; } secret { UPDATE_LOCATION; return TOK_SECRET; } key { UPDATE_LOCATION; return TOK_KEY; } include { UPDATE_LOCATION; return TOK_INCLUDE; } @@ -87,6 +89,7 @@ debug { UPDATE_LOCATION; return TOK_DEBUG; } peer-to-peer { UPDATE_LOCATION; return TOK_PEER_TO_PEER; } yes { UPDATE_LOCATION; return TOK_YES; } no { UPDATE_LOCATION; return TOK_NO; } +port { UPDATE_LOCATION; return TOK_PORT; } [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} { UPDATE_LOCATION; diff --git a/src/config.y b/src/config.y index b1d68e0..5ef30b6 100644 --- a/src/config.y +++ b/src/config.y @@ -38,7 +38,6 @@ #include <fastd.h> #include <arpa/inet.h> - #include <unistd.h> } %union { @@ -63,7 +62,9 @@ %token TOK_PROTOCOL %token TOK_METHOD %token TOK_PEER -%token TOK_ADDRESS +%token TOK_REMOTE +%token TOK_IPV4 +%token TOK_IPV6 %token TOK_SECRET %token TOK_KEY %token TOK_INCLUDE @@ -89,6 +90,7 @@ %token TOK_PEER_TO_PEER %token TOK_YES %token TOK_NO +%token TOK_PORT %token <addr> TOK_ADDR %token <addr6> TOK_ADDR6 @@ -96,9 +98,11 @@ %code { #include <config.h> - #include <stdint.h> #include <peer.h> + #include <stdint.h> + #include <unistd.h> + void fastd_config_error(YYLTYPE *loc, fastd_context *ctx, fastd_config *conf, const char *filename, int depth, char *s); } @@ -109,6 +113,7 @@ %type <boolean> boolean %type <num> maybe_port %type <str> maybe_as +%type <num> maybe_af %% start: START_CONFIG config @@ -153,18 +158,18 @@ interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1->str); } bind: TOK_ADDR maybe_port { conf->bind_addr_in.sin_family = AF_INET; conf->bind_addr_in.sin_addr = $1; - conf->bind_addr_in.sin_port = $2; + conf->bind_addr_in.sin_port = htons($2); } | TOK_ADDR6 maybe_port { conf->bind_addr_in6.sin6_family = AF_INET6; conf->bind_addr_in6.sin6_addr = $1; - conf->bind_addr_in6.sin6_port = $2; + conf->bind_addr_in6.sin6_port = htons($2); } | TOK_ANY maybe_port { conf->bind_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); - conf->bind_addr_in.sin_port = $2; + conf->bind_addr_in.sin_port = htons($2); conf->bind_addr_in6.sin6_addr = in6addr_any; - conf->bind_addr_in6.sin6_port = $2; + conf->bind_addr_in6.sin6_port = htons($2); } ; @@ -221,7 +226,7 @@ on_establish: TOK_STRING { } ; -on_disestablish: TOK_STRING { +on_disestablish: TOK_STRING { free(conf->on_disestablish); free(conf->on_disestablish_dir); @@ -240,20 +245,33 @@ peer_conf: peer_conf peer_statement | ; -peer_statement: TOK_ADDRESS peer_address ';' +peer_statement: TOK_REMOTE peer_remote ';' | TOK_KEY peer_key ';' | TOK_INCLUDE peer_include ';' ; -peer_address: TOK_ADDR ':' port { +peer_remote: TOK_ADDR port { + free(conf->peers->hostname); + conf->peers->hostname = NULL; + conf->peers->address.in.sin_family = AF_INET; conf->peers->address.in.sin_addr = $1; - conf->peers->address.in.sin_port = $3; + conf->peers->address.in.sin_port = htons($2); } - | TOK_ADDR6 ':' port { + | TOK_ADDR6 port { + free(conf->peers->hostname); + conf->peers->hostname = NULL; + conf->peers->address.in6.sin6_family = AF_INET6; conf->peers->address.in6.sin6_addr = $1; - conf->peers->address.in6.sin6_port = $3; + conf->peers->address.in6.sin6_port = htons($2); + } + | maybe_af TOK_STRING port { + free(conf->peers->hostname); + + conf->peers->hostname = strdup($2->str); + conf->peers->address.sa.sa_family = $1; + conf->peers->address.in.sin_port = htons($3); } ; @@ -292,7 +310,7 @@ maybe_string: TOK_STRING | { $$ = NULL; } ; -maybe_port: ':' port { $$ = $2; } +maybe_port: port { $$ = $1; } | { $$ = 0; } ; @@ -300,16 +318,25 @@ maybe_as: TOK_AS TOK_STRING { $$ = $2; } | { $$ = NULL; } ; +maybe_af: TOK_IPV4 { $$ = AF_INET; } + | TOK_IPV6 { $$ = AF_INET6; } + | { $$ = AF_UNSPEC; } + ; + boolean: TOK_YES { $$ = true; } | TOK_NO { $$ = false; } ; -port: TOK_INTEGER { - if ($1 < 0 || $1 > 65635) { +colon_or_port: ':' + | TOK_PORT + ; + +port: colon_or_port TOK_INTEGER { + if ($2 < 0 || $2 > 65635) { fastd_config_error(&@$, ctx, conf, filename, depth, "invalid port"); YYERROR; } - $$ = htons($1); + $$ = $2; } ; %% diff --git a/src/fastd.c b/src/fastd.c index 71d0a04..695edaa 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -42,8 +42,8 @@ #include <unistd.h> -static bool sighup = false; -static bool terminate = false; +static volatile bool sighup = false; +static volatile bool terminate = false; static void on_sighup(int signo) { @@ -54,6 +54,13 @@ static void on_terminate(int signo) { terminate = true; } +static void on_sigusr1(int signo, siginfo_t *siginfo, void *context) { + fastd_resolve_return *ret = siginfo->si_value.sival_ptr; + + ret->next = ret->ctx->resolve_returns; + ret->ctx->resolve_returns = ret; +} + static void init_signals(fastd_context *ctx) { struct sigaction action; @@ -72,6 +79,11 @@ static void init_signals(fastd_context *ctx) { exit_errno(ctx, "sigaction"); if(sigaction(SIGINT, &action, NULL)) exit_errno(ctx, "sigaction"); + + action.sa_flags = SA_SIGINFO; + action.sa_sigaction = on_sigusr1; + if(sigaction(SIGUSR1, &action, NULL)) + exit_errno(ctx, "sigaction"); } static void init_tuntap(fastd_context *ctx) { @@ -111,7 +123,7 @@ static void init_tuntap(fastd_context *ctx) { static void close_tuntap(fastd_context *ctx) { if(close(ctx->tunfd)) - warn_errno(ctx, "closing tun/tap: close"); + pr_warn_errno(ctx, "closing tun/tap: close"); free(ctx->ifname); } @@ -154,7 +166,7 @@ static void init_sockets(fastd_context *ctx) { if ((ctx->sock6fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { if (ctx->sockfd >= 0) - warn_errno(ctx, "socket"); + pr_warn_errno(ctx, "socket"); else exit_errno(ctx, "socket"); } @@ -177,12 +189,12 @@ static void init_sockets(fastd_context *ctx) { static void close_sockets(fastd_context *ctx) { if (ctx->sockfd >= 0) { if(close(ctx->sockfd)) - warn_errno(ctx, "closing IPv4 socket: close"); + pr_warn_errno(ctx, "closing IPv4 socket: close"); } if (ctx->sock6fd >= 0) { if(close(ctx->sock6fd)) - warn_errno(ctx, "closing IPv6 socket: close"); + pr_warn_errno(ctx, "closing IPv6 socket: close"); } } @@ -238,7 +250,7 @@ void fastd_handle_receive(fastd_context *ctx, fastd_peer *peer, fastd_buffer buf } if (write(ctx->tunfd, buffer.data, buffer.len) < 0) - warn_errno(ctx, "write"); + pr_warn_errno(ctx, "write"); if (ctx->conf->mode == MODE_TAP && ctx->conf->peer_to_peer) { const fastd_eth_addr *dest_addr = fastd_get_dest_address(ctx, buffer); @@ -354,18 +366,25 @@ static void update_time(fastd_context *ctx) { clock_gettime(CLOCK_MONOTONIC, &ctx->now); } +static void send_handshake(fastd_context *ctx, fastd_peer *peer) { + pr_debug(ctx, "sending handshake to %P...", peer); + ctx->conf->protocol->handshake_init(ctx, peer); + + if (fastd_peer_is_established(peer)) + fastd_task_schedule_handshake(ctx, peer, fastd_rand(ctx, 10000, 20000)); + else + fastd_task_schedule_handshake(ctx, peer, 20000); +} + static void handle_tasks(fastd_context *ctx) { fastd_task *task; while ((task = fastd_task_get(ctx)) != NULL) { switch (task->type) { case TASK_HANDSHAKE: - pr_debug(ctx, "sending handshake to %P...", task->peer); - ctx->conf->protocol->handshake_init(ctx, task->peer); - - if (fastd_peer_is_established(task->peer)) - fastd_task_schedule_handshake(ctx, task->peer, fastd_rand(ctx, 10000, 20000)); + if (task->peer->state == STATE_RESOLVE) + fastd_resolve_peer_handshake(ctx, task->peer); else - fastd_task_schedule_handshake(ctx, task->peer, 20000); + send_handshake(ctx, task->peer); break; case TASK_KEEPALIVE: @@ -554,6 +573,35 @@ static void handle_input(fastd_context *ctx) { handle_socket(ctx, ctx->sock6fd); } +static void handle_resolv_returns(fastd_context *ctx) { + while (ctx->resolve_returns) { + fastd_peer *peer; + for (peer = ctx->peers; peer; peer = peer->next) { + if (peer->state != STATE_RESOLVE) + continue; + + if (!strequal(peer->config->hostname, ctx->resolve_returns->hostname)) + continue; + + if (peer->config->address.sa.sa_family != AF_UNSPEC && + peer->config->address.sa.sa_family != ctx->resolve_returns->addr.sa.sa_family) + continue; + + if (peer->config->address.in.sin_port != htons(ctx->resolve_returns->port)) + continue; + + peer->address = ctx->resolve_returns->addr; + send_handshake(ctx, peer); + break; + } + + fastd_resolve_return *next = ctx->resolve_returns->next; + free(ctx->resolve_returns->hostname); + free(ctx->resolve_returns); + ctx->resolve_returns = next; + } +} + static void cleanup_peers(fastd_context *ctx) { fastd_peer *peer, *next; @@ -611,6 +659,8 @@ int main(int argc, char *argv[]) { sighup = false; fastd_reconfigure(&ctx, &conf); } + + handle_resolv_returns(&ctx); } on_down(&ctx); diff --git a/src/fastd.h b/src/fastd.h index 102c2c4..c778b19 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -91,6 +91,24 @@ struct _fastd_method { bool (*decrypt)(fastd_context *ctx, fastd_method_session_state *session, fastd_buffer *out, fastd_buffer in); }; +union _fastd_peer_address { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +}; + +struct _fastd_resolve_return { + fastd_resolve_return *next; + + fastd_context *ctx; + + char *hostname; + sa_family_t af; + uint16_t port; + + fastd_peer_address addr; +}; + struct _fastd_config { fastd_loglevel loglevel; @@ -156,6 +174,8 @@ struct _fastd_context { fastd_peer_eth_addr *eth_addr; unsigned int randseed; + + fastd_resolve_return *resolve_returns; }; struct _fastd_string_stack { @@ -163,10 +183,13 @@ struct _fastd_string_stack { char str[]; }; + void fastd_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); void fastd_send_handshake(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); void fastd_handle_receive(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); +void fastd_resolve_peer_handshake(fastd_context *ctx, fastd_peer *peer); + void fastd_printf(const fastd_context *ctx, const char *format, ...); void fastd_read_peer_dir(fastd_context *ctx, fastd_config *conf, const char *dir); @@ -216,7 +239,8 @@ static inline int fastd_rand(fastd_context *ctx, int min, int max) { #define pr_verbose(ctx, args...) pr_log(ctx, LOG_VERBOSE, "Verbose: ", args) #define pr_debug(ctx, args...) pr_log(ctx, LOG_DEBUG, "DEBUG: ", args) -#define warn_errno(ctx, message) pr_warn(ctx, "%s: %s", message, strerror(errno)) +#define pr_warn_errno(ctx, message) pr_warn(ctx, "%s: %s", message, strerror(errno)) +#define pr_error_errno(ctx, message) pr_warn(ctx, "%s: %s", message, strerror(errno)) #define exit_fatal(ctx, args...) do { pr_fatal(ctx, args); abort(); } while(0) #define exit_bug(ctx, message) exit_fatal(ctx, "BUG: %s", message) #define exit_error(ctx, args...) do { pr_error(ctx, args); exit(1); } while(0) @@ -174,12 +174,16 @@ static inline void reset_peer(fastd_context *ctx, fastd_peer *peer) { } static inline void setup_peer(fastd_context *ctx, fastd_peer *peer) { - if (fastd_peer_is_temporary(peer)) { - exit_fatal(ctx, "tried to setup temporary peer"); - } + if (peer->config->hostname) + peer->address.sa.sa_family = AF_UNSPEC; + else + peer->address = peer->config->address; + + if (peer->config->hostname) + peer->state = STATE_RESOLVE; + else + peer->state = STATE_WAIT; - peer->address = peer->config->address; - peer->state = STATE_WAIT; peer->seen = (struct timespec){0, 0}; if (!fastd_peer_is_floating(peer)) @@ -205,6 +209,7 @@ fastd_peer_config* fastd_peer_config_new(fastd_context *ctx, fastd_config *conf) fastd_peer_config *peer = malloc(sizeof(fastd_peer_config)); peer->enabled = true; + peer->hostname = NULL; memset(&peer->address, 0, sizeof(fastd_peer_address)); peer->config_source_dir = NULL; @@ -221,6 +226,7 @@ fastd_peer_config* fastd_peer_config_new(fastd_context *ctx, fastd_config *conf) void fastd_peer_config_free(fastd_peer_config *peer) { free(peer->name); + free(peer->hostname); free(peer->key); free(peer->protocol_config); free(peer); @@ -270,6 +276,9 @@ bool fastd_peer_config_equal(const fastd_peer_config *peer1, const fastd_peer_co if (peer1->enabled != peer2->enabled) return false; + if (!strequal(peer1->hostname, peer2->hostname)) + return false; + if (!fastd_peer_addr_equal(&peer1->address, &peer2->address)) return false; @@ -311,8 +320,6 @@ fastd_peer* fastd_peer_add(fastd_context *ctx, fastd_peer_config *peer_conf) { fastd_peer *peer = add_peer(ctx); peer->config = peer_conf; - peer->state = STATE_WAIT; - setup_peer(ctx, peer); pr_debug(ctx, "adding peer %P", peer); @@ -369,6 +376,7 @@ fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *per void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer) { switch(peer->state) { + case STATE_RESOLVE: case STATE_WAIT: peer->state = STATE_ESTABLISHED; on_establish(ctx, peer); @@ -30,12 +30,6 @@ #include "fastd.h" -union _fastd_peer_address { - struct sockaddr sa; - struct sockaddr_in in; - struct sockaddr_in6 in6; -}; - struct _fastd_peer { fastd_peer *next; @@ -59,6 +53,7 @@ struct _fastd_peer_config { bool enabled; char *name; + char *hostname; fastd_peer_address address; char *key; @@ -89,7 +84,7 @@ const fastd_eth_addr* fastd_get_source_address(const fastd_context *ctx, fastd_b const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buffer buffer); static inline bool fastd_peer_config_is_floating(const fastd_peer_config *config) { - return (config->address.sa.sa_family == AF_UNSPEC); + return (config->hostname == NULL && config->address.sa.sa_family == AF_UNSPEC); } static inline bool fastd_peer_is_floating(const fastd_peer *peer) { diff --git a/src/printf.c b/src/printf.c index 7c922c5..c32ebf9 100644 --- a/src/printf.c +++ b/src/printf.c @@ -43,6 +43,9 @@ static void print_peer_str(const fastd_context *ctx, const fastd_peer *peer) { if (peer->config && peer->config->name) { fprintf(stderr, "%c%s%c", pl, peer->config->name, pr); } + else if (peer->config && peer->config->hostname) { + fprintf(stderr, "%c\"%s\"%c", pl, peer->config->hostname, pr); + } else { switch (peer->address.sa.sa_family) { case AF_UNSPEC: diff --git a/src/resolve.c b/src/resolve.c new file mode 100644 index 0000000..1fbb1bf --- /dev/null +++ b/src/resolve.c @@ -0,0 +1,123 @@ +/* + Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net> + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#define _GNU_SOURCE + +#include "fastd.h" +#include "peer.h" + +#include <netdb.h> +#include <pthread.h> +#include <signal.h> + + +typedef struct _resolv_arg { + fastd_context *ctx; + pthread_t master_thread; + char *hostname; + sa_family_t af; + uint16_t port; +} resolv_arg; + + +static void* fastd_resolve_peer_handshake_do(void *varg) { + resolv_arg *arg = varg; + + struct addrinfo hints; + struct addrinfo *res = NULL; + int gai_ret; + bool error = false; + + char portstr[6]; + snprintf(portstr, 6, "%u", arg->port); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = arg->af; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG; +#ifdef AI_IDN + hints.ai_flags |= AI_IDN; +#endif + + gai_ret = getaddrinfo(arg->hostname, portstr, &hints, &res); + + if (gai_ret) { + pr_debug(arg->ctx, "Resolving host `%s' failed: %s", arg->hostname, gai_strerror(gai_ret)); + error = true; + } + else if (res->ai_addrlen > sizeof(fastd_peer_address)) { + pr_warn(arg->ctx, "Resolving host `%s': unsupported address returned", arg->hostname); + error = true; + } + + fastd_resolve_return *ret = malloc(sizeof(fastd_resolve_return)); + + ret->ctx = arg->ctx; + + ret->hostname = arg->hostname; + ret->af = arg->af; + ret->port = arg->port; + + if (!error) { + pr_debug(arg->ctx, "Resolved host `%s' successfully", arg->hostname); + memcpy(&ret->addr, res->ai_addr, res->ai_addrlen); + } + else { + ret->addr.sa.sa_family = AF_UNSPEC; + } + + union sigval sigval; + sigval.sival_ptr = ret; + if (pthread_sigqueue(arg->master_thread, SIGUSR1, sigval)) + exit_errno(arg->ctx, "pthread_sigqueue"); + + freeaddrinfo(res); + free(arg); + + return NULL; +} + +void fastd_resolve_peer_handshake(fastd_context *ctx, fastd_peer *peer) { + pr_debug(ctx, "Resolving host `%s' for peer %P...", peer->config->hostname, peer); + + resolv_arg *arg = malloc(sizeof(resolv_arg)); + + arg->ctx = ctx; + arg->master_thread = pthread_self(); + arg->hostname = strdup(peer->config->hostname); + arg->af = peer->config->address.sa.sa_family; + arg->port = ntohs(peer->config->address.in.sin_port); + + pthread_t thread; + if (pthread_create(&thread, NULL, fastd_resolve_peer_handshake_do, arg) != 0) { + pr_error_errno(ctx, "unable to create resolver thread"); + free(arg->hostname); + free(arg); + } + + pthread_detach(thread); +} diff --git a/src/types.h b/src/types.h index 3808b32..c48cf59 100644 --- a/src/types.h +++ b/src/types.h @@ -48,6 +48,7 @@ typedef enum _fastd_mode { } fastd_mode; typedef enum _fastd_peer_state { + STATE_RESOLVE, STATE_WAIT, STATE_TEMP, STATE_ESTABLISHED, @@ -72,6 +73,9 @@ typedef struct _fastd_handshake fastd_handshake; typedef struct _fastd_string_stack fastd_string_stack; +typedef struct _fastd_resolve_return fastd_resolve_return; + + /* May be defined by the protocol/method however it likes */ typedef struct _fastd_protocol_config fastd_protocol_config; typedef struct _fastd_protocol_peer_config fastd_protocol_peer_config; |