Dynamically create and destroy sockets without fixed binds

This commit is contained in:
Matthias Schiffer 2012-11-01 15:11:40 +01:00
parent 86df5dbefe
commit cb98cbc593
8 changed files with 132 additions and 68 deletions

View file

@ -434,7 +434,6 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
} }
static void count_peers(fastd_context *ctx, fastd_config *conf) { static void count_peers(fastd_context *ctx, fastd_config *conf) {
conf->n_peers = 0;
conf->n_floating = 0; conf->n_floating = 0;
conf->n_v4 = 0; conf->n_v4 = 0;
conf->n_v6 = 0; conf->n_v6 = 0;
@ -444,8 +443,6 @@ static void count_peers(fastd_context *ctx, fastd_config *conf) {
fastd_peer_config *peer; fastd_peer_config *peer;
for (peer = conf->peers; peer; peer = peer->next) { for (peer = conf->peers; peer; peer = peer->next) {
conf->n_peers++;
switch (peer->address.sa.sa_family) { switch (peer->address.sa.sa_family) {
case AF_UNSPEC: case AF_UNSPEC:
if (peer->hostname) if (peer->hostname)

View file

@ -256,6 +256,21 @@ static void bind_sockets(fastd_context *ctx) {
} }
} }
fastd_socket* fastd_socket_open(fastd_context *ctx, int af) {
const fastd_bind_address any_address = { .addr.sa.sa_family = af };
int fd = bind_socket(ctx, &any_address, true);
if (fd < 0)
return NULL;
fastd_socket *sock = malloc(sizeof(fastd_socket));
sock->fd = fd;
sock->addr = NULL;
return sock;
}
static void init_tuntap(fastd_context *ctx) { static void init_tuntap(fastd_context *ctx) {
struct ifreq ifr; struct ifreq ifr;
@ -309,19 +324,10 @@ static void close_tuntap(fastd_context *ctx) {
free(ctx->ifname); free(ctx->ifname);
} }
static void close_socket(fastd_context *ctx, fastd_socket *sock) {
if (sock->fd >= 0) {
if(close(sock->fd))
pr_error_errno(ctx, "closing socket: close");
sock->fd = -2;
}
}
static void close_sockets(fastd_context *ctx) { static void close_sockets(fastd_context *ctx) {
unsigned i; unsigned i;
for (i = 0; i < ctx->n_socks; i++) for (i = 0; i < ctx->n_socks; i++)
close_socket(ctx, &ctx->socks[i]); fastd_socket_close(ctx, &ctx->socks[i]);
free(ctx->socks); free(ctx->socks);
} }
@ -555,8 +561,10 @@ static void init_peers(fastd_context *ctx) {
for (peer_conf = ctx->conf->peers; peer_conf; peer_conf = peer_conf->next) { for (peer_conf = ctx->conf->peers; peer_conf; peer_conf = peer_conf->next) {
ctx->conf->protocol->peer_configure(ctx, peer_conf); ctx->conf->protocol->peer_configure(ctx, peer_conf);
if (peer_conf->enabled) if (peer_conf->enabled) {
fastd_peer_add(ctx, peer_conf); fastd_peer_add(ctx, peer_conf);
ctx->n_peers++;
}
} }
} }
@ -574,7 +582,10 @@ static inline void update_time(fastd_context *ctx) {
} }
static inline void send_handshake(fastd_context *ctx, fastd_peer *peer) { static inline void send_handshake(fastd_context *ctx, fastd_peer *peer) {
if (peer->address.sa.sa_family && peer->sock) { if (!fastd_peer_is_established(peer))
fastd_peer_reset_socket(ctx, peer);
if (peer->sock) {
if (timespec_diff(&ctx->now, &peer->last_handshake) < ctx->conf->min_handshake_interval*1000 if (timespec_diff(&ctx->now, &peer->last_handshake) < ctx->conf->min_handshake_interval*1000
&& fastd_peer_address_equal(&peer->address, &peer->last_handshake_address)) { && fastd_peer_address_equal(&peer->address, &peer->last_handshake_address)) {
pr_debug(ctx, "not sending a handshake to %P as we sent one a short time ago", peer); pr_debug(ctx, "not sending a handshake to %P as we sent one a short time ago", peer);
@ -663,7 +674,7 @@ static void handle_tun(fastd_context *ctx) {
} }
} }
static void handle_socket(fastd_context *ctx, const fastd_socket *sock) { static void handle_socket(fastd_context *ctx, fastd_socket *sock) {
size_t max_len = PACKET_TYPE_LEN + methods_max_packet_size(ctx); size_t max_len = PACKET_TYPE_LEN + methods_max_packet_size(ctx);
fastd_buffer buffer = fastd_buffer_alloc(max_len, methods_min_decrypt_head_space(ctx), methods_min_decrypt_tail_space(ctx)); fastd_buffer buffer = fastd_buffer_alloc(max_len, methods_min_decrypt_head_space(ctx), methods_min_decrypt_tail_space(ctx));
uint8_t *packet_type; uint8_t *packet_type;
@ -752,17 +763,6 @@ static void handle_resolv_returns(fastd_context *ctx) {
peer->last_resolve_return = ctx->now; peer->last_resolve_return = ctx->now;
if (fastd_peer_claim_address(ctx, peer, NULL, &resolve_return.addr)) { if (fastd_peer_claim_address(ctx, peer, NULL, &resolve_return.addr)) {
if (!peer->sock) {
switch(resolve_return.addr.sa.sa_family) {
case AF_INET:
peer->sock = ctx->sock_default_v4;
break;
case AF_INET6:
peer->sock = ctx->sock_default_v6;
}
}
send_handshake(ctx, peer); send_handshake(ctx, peer);
} }
else { else {
@ -781,28 +781,44 @@ static inline void handle_socket_error(fastd_context *ctx, fastd_socket *sock) {
else else
pr_warn(ctx, "socket bind %I lost", &sock->addr->addr); pr_warn(ctx, "socket bind %I lost", &sock->addr->addr);
close_socket(ctx, sock); fastd_socket_close(ctx, sock);
} }
static void handle_input(fastd_context *ctx) { static void handle_input(fastd_context *ctx) {
struct pollfd fds[ctx->n_socks + 2]; const size_t n_fds = 2 + ctx->n_socks + ctx->n_peers;
struct pollfd fds[n_fds];
fds[0].fd = ctx->tunfd; fds[0].fd = ctx->tunfd;
fds[0].events = POLLIN; fds[0].events = POLLIN;
fds[1].fd = ctx->resolverfd; fds[1].fd = ctx->resolverfd;
fds[1].events = POLLIN; fds[1].events = POLLIN;
unsigned i; unsigned i;
for (i = 0; i < ctx->n_socks; i++) { for (i = 2; i < ctx->n_socks+2; i++) {
fds[i+2].fd = ctx->socks[i].fd; fds[i].fd = ctx->socks[i-2].fd;
fds[i+2].events = POLLIN; fds[i].events = POLLIN;
} }
fastd_peer *peer;
for (peer = ctx->peers; peer; peer = peer->next) {
if (peer->sock && fastd_peer_is_socket_dynamic(peer))
fds[i].fd = peer->sock->fd;
else
fds[i].fd = -1;
fds[i].events = POLLIN;
i++;
}
if (i != n_fds)
exit_bug(ctx, "fd count mismatch");
int timeout = fastd_task_timeout(ctx); int timeout = fastd_task_timeout(ctx);
if (timeout < 0 || timeout > 60000) if (timeout < 0 || timeout > 60000)
timeout = 60000; /* call maintenance at least once a minute */ timeout = 60000; /* call maintenance at least once a minute */
int ret = poll(fds, ctx->n_socks + 2, timeout); int ret = poll(fds, n_fds, timeout);
if (ret < 0) { if (ret < 0) {
if (errno == EINTR) if (errno == EINTR)
return; return;
@ -817,15 +833,24 @@ static void handle_input(fastd_context *ctx) {
if (fds[1].revents & POLLIN) if (fds[1].revents & POLLIN)
handle_resolv_returns(ctx); handle_resolv_returns(ctx);
for (i = 0; i < ctx->n_socks; i++) { for (i = 2; i < ctx->n_socks+2; i++) {
if (fds[i+2].revents & (POLLERR|POLLHUP|POLLNVAL)) { if (fds[i].revents & (POLLERR|POLLHUP|POLLNVAL))
handle_socket_error(ctx, &ctx->socks[i]); handle_socket_error(ctx, &ctx->socks[i-2]);
continue; else if (fds[i].revents & POLLIN)
} handle_socket(ctx, &ctx->socks[i-2]);
if (fds[i+2].revents & POLLIN)
handle_socket(ctx, &ctx->socks[i]);
} }
for (peer = ctx->peers; peer; peer = peer->next) {
if (fds[i].revents & (POLLERR|POLLHUP|POLLNVAL))
fastd_peer_reset_socket(ctx, peer);
else if (fds[i].revents & POLLIN)
handle_socket(ctx, peer->sock);
i++;
}
if (i != n_fds)
exit_bug(ctx, "fd count mismatch");
} }
static void cleanup_peers(fastd_context *ctx) { static void cleanup_peers(fastd_context *ctx) {

View file

@ -73,7 +73,7 @@ struct _fastd_protocol {
void (*peer_configure)(fastd_context *ctx, fastd_peer_config *peer_conf); void (*peer_configure)(fastd_context *ctx, fastd_peer_config *peer_conf);
void (*handshake_init)(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf); void (*handshake_init)(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf);
void (*handshake_handle)(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, const fastd_handshake *handshake, const fastd_method *method); void (*handshake_handle)(fastd_context *ctx, fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, const fastd_handshake *handshake, const fastd_method *method);
void (*handle_recv)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); void (*handle_recv)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
void (*send)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); void (*send)(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
@ -189,7 +189,6 @@ struct _fastd_config {
fastd_string_stack *peer_dirs; fastd_string_stack *peer_dirs;
fastd_peer_config *peers; fastd_peer_config *peers;
unsigned n_peers;
unsigned n_floating; unsigned n_floating;
unsigned n_v4; unsigned n_v4;
unsigned n_v6; unsigned n_v6;
@ -228,6 +227,7 @@ struct _fastd_context {
struct timespec now; struct timespec now;
unsigned n_peers;
fastd_peer *peers; fastd_peer *peers;
fastd_queue task_queue; fastd_queue task_queue;
@ -268,6 +268,8 @@ void fastd_send(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_a
void fastd_send_handshake(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, fastd_buffer buffer); void fastd_send_handshake(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, fastd_buffer buffer);
void fastd_handle_receive(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer); void fastd_handle_receive(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer);
fastd_socket* fastd_socket_open(fastd_context *ctx, int af);
void fastd_resolve_peer(fastd_context *ctx, fastd_peer *peer); void fastd_resolve_peer(fastd_context *ctx, fastd_peer *peer);
int fastd_vsnprintf(const fastd_context *ctx, char *buffer, size_t size, const char *format, va_list ap); int fastd_vsnprintf(const fastd_context *ctx, char *buffer, size_t size, const char *format, va_list ap);
@ -394,6 +396,15 @@ static inline void fastd_string_stack_free(fastd_string_stack *str) {
} }
} }
static inline void fastd_socket_close(fastd_context *ctx, fastd_socket *sock) {
if (sock->fd >= 0) {
if(close(sock->fd))
pr_error_errno(ctx, "closing socket: close");
sock->fd = -2;
}
}
static inline bool timespec_after(const struct timespec *tp1, const struct timespec *tp2) { static inline bool timespec_after(const struct timespec *tp1, const struct timespec *tp2) {
return (tp1->tv_sec > tp2->tv_sec || return (tp1->tv_sec > tp2->tv_sec ||
(tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec)); (tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec));

View file

@ -180,7 +180,7 @@ static fastd_string_stack* parse_string_list(uint8_t *data, size_t len) {
return ret; return ret;
} }
void fastd_handshake_handle(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, fastd_buffer buffer) { void fastd_handshake_handle(fastd_context *ctx, fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, fastd_buffer buffer) {
if (buffer.len < sizeof(fastd_packet)) { if (buffer.len < sizeof(fastd_packet)) {
pr_warn(ctx, "received a short handshake from %I", address); pr_warn(ctx, "received a short handshake from %I", address);
goto end_free; goto end_free;

View file

@ -71,7 +71,7 @@ struct _fastd_handshake {
fastd_buffer fastd_handshake_new_init(fastd_context *ctx, size_t tail_space); fastd_buffer fastd_handshake_new_init(fastd_context *ctx, size_t tail_space);
fastd_buffer fastd_handshake_new_reply(fastd_context *ctx, const fastd_handshake *handshake, const fastd_method *method, size_t tail_space); fastd_buffer fastd_handshake_new_reply(fastd_context *ctx, const fastd_handshake *handshake, const fastd_method *method, size_t tail_space);
void fastd_handshake_handle(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, fastd_buffer buffer); void fastd_handshake_handle(fastd_context *ctx, fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, fastd_buffer buffer);
static inline void fastd_handshake_add(fastd_context *ctx, fastd_buffer *buffer, fastd_handshake_record_type type, size_t len, const void *data) { static inline void fastd_handshake_add(fastd_context *ctx, fastd_buffer *buffer, fastd_handshake_record_type type, size_t len, const void *data) {

View file

@ -146,10 +146,46 @@ static void on_disestablish(fastd_context *ctx, fastd_peer *peer) {
free(cwd); free(cwd);
} }
static inline void reset_peer(fastd_context *ctx, fastd_peer *peer) { static inline void free_socket(fastd_context *ctx, fastd_peer *peer) {
if (peer->sock) {
if (fastd_peer_is_socket_dynamic(peer)) {
fastd_socket_close(ctx, peer->sock);
free(peer->sock);
}
peer->sock = NULL;
}
}
void fastd_peer_reset_socket(fastd_context *ctx, fastd_peer *peer) {
if (!fastd_peer_is_socket_dynamic(peer))
return;
pr_debug(ctx, "resetting socket for peer %P", peer);
free_socket(ctx, peer);
switch (peer->address.sa.sa_family) {
case AF_INET:
if (ctx->sock_default_v4)
peer->sock = ctx->sock_default_v4;
else
peer->sock = fastd_socket_open(ctx, AF_INET);
break;
case AF_INET6:
if (ctx->sock_default_v6)
peer->sock = ctx->sock_default_v6;
else
peer->sock = fastd_socket_open(ctx, AF_INET6);
}
}
static void reset_peer(fastd_context *ctx, fastd_peer *peer) {
if (peer->established) if (peer->established)
on_disestablish(ctx, peer); on_disestablish(ctx, peer);
free_socket(ctx, peer);
ctx->conf->protocol->reset_peer_state(ctx, peer); ctx->conf->protocol->reset_peer_state(ctx, peer);
int i, deleted = 0; int i, deleted = 0;
@ -167,7 +203,7 @@ static inline void reset_peer(fastd_context *ctx, fastd_peer *peer) {
fastd_task_delete_peer(ctx, peer); fastd_task_delete_peer(ctx, peer);
} }
static inline void setup_peer(fastd_context *ctx, fastd_peer *peer) { static void setup_peer(fastd_context *ctx, fastd_peer *peer) {
if (peer->config->hostname) if (peer->config->hostname)
peer->address.sa.sa_family = AF_UNSPEC; peer->address.sa.sa_family = AF_UNSPEC;
else else
@ -175,19 +211,6 @@ static inline void setup_peer(fastd_context *ctx, fastd_peer *peer) {
peer->established = false; peer->established = false;
switch (peer->address.sa.sa_family) {
case AF_INET:
peer->sock = ctx->sock_default_v4;
break;
case AF_INET6:
peer->sock = ctx->sock_default_v6;
break;
default:
peer->sock = NULL;
}
peer->last_resolve = (struct timespec){0, 0}; peer->last_resolve = (struct timespec){0, 0};
peer->last_resolve_return = (struct timespec){0, 0}; peer->last_resolve_return = (struct timespec){0, 0};
peer->seen = (struct timespec){0, 0}; peer->seen = (struct timespec){0, 0};
@ -292,7 +315,7 @@ bool fastd_peer_address_equal(const fastd_peer_address *addr1, const fastd_peer_
return true; return true;
} }
bool fastd_peer_claim_address(fastd_context *ctx, fastd_peer *new_peer, const fastd_socket *sock, const fastd_peer_address *addr) { bool fastd_peer_claim_address(fastd_context *ctx, fastd_peer *new_peer, fastd_socket *sock, const fastd_peer_address *addr) {
if (addr->sa.sa_family != AF_UNSPEC) { if (addr->sa.sa_family != AF_UNSPEC) {
fastd_peer *peer; fastd_peer *peer;
for (peer = ctx->peers; peer; peer = peer->next) { for (peer = ctx->peers; peer; peer = peer->next) {
@ -316,8 +339,10 @@ bool fastd_peer_claim_address(fastd_context *ctx, fastd_peer *new_peer, const fa
} }
new_peer->address = *addr; new_peer->address = *addr;
if (sock) if (sock && sock->addr && sock != new_peer->sock) {
free_socket(ctx, new_peer);
new_peer->sock = sock; new_peer->sock = sock;
}
return true; return true;
} }
@ -358,6 +383,7 @@ fastd_peer* fastd_peer_add(fastd_context *ctx, fastd_peer_config *peer_conf) {
peer->config = peer_conf; peer->config = peer_conf;
peer->protocol_state = NULL; peer->protocol_state = NULL;
peer->sock = NULL;
setup_peer(ctx, peer); setup_peer(ctx, peer);
pr_verbose(ctx, "adding peer %P", peer); pr_verbose(ctx, "adding peer %P", peer);

View file

@ -35,7 +35,7 @@ struct _fastd_peer {
const fastd_peer_config *config; const fastd_peer_config *config;
const fastd_socket *sock; fastd_socket *sock;
fastd_peer_address address; fastd_peer_address address;
bool established; bool established;
@ -88,7 +88,8 @@ void fastd_peer_reset(fastd_context *ctx, fastd_peer *peer);
void fastd_peer_delete(fastd_context *ctx, fastd_peer *peer); void fastd_peer_delete(fastd_context *ctx, fastd_peer *peer);
fastd_peer* fastd_peer_add(fastd_context *ctx, fastd_peer_config *conf); fastd_peer* fastd_peer_add(fastd_context *ctx, fastd_peer_config *conf);
void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer); void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer);
bool fastd_peer_claim_address(fastd_context *ctx, fastd_peer *peer, const fastd_socket *sock, const fastd_peer_address *addr); bool fastd_peer_claim_address(fastd_context *ctx, fastd_peer *peer, fastd_socket *sock, const fastd_peer_address *addr);
void fastd_peer_reset_socket(fastd_context *ctx, fastd_peer *peer);
const fastd_eth_addr* fastd_get_source_address(const fastd_context *ctx, fastd_buffer buffer); const fastd_eth_addr* fastd_get_source_address(const fastd_context *ctx, fastd_buffer buffer);
const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buffer buffer); const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buffer buffer);
@ -119,6 +120,10 @@ static inline void fastd_peer_seen(fastd_context *ctx, fastd_peer *peer) {
peer->seen = ctx->now; peer->seen = ctx->now;
} }
static inline bool fastd_peer_is_socket_dynamic(const fastd_peer *peer) {
return (!peer->sock || !peer->sock->addr);
}
static inline bool fastd_eth_addr_is_unicast(const fastd_eth_addr *addr) { static inline bool fastd_eth_addr_is_unicast(const fastd_eth_addr *addr) {
return ((addr->data[0] & 1) == 0); return ((addr->data[0] & 1) == 0);
} }

View file

@ -305,7 +305,7 @@ static void respond_handshake(fastd_context *ctx, const fastd_socket *sock, cons
fastd_send_handshake(ctx, sock, address, buffer); fastd_send_handshake(ctx, sock, address, buffer);
} }
static bool establish(fastd_context *ctx, fastd_peer *peer, const fastd_method *method, const fastd_socket *sock, const fastd_peer_address *address, bool initiator, static bool establish(fastd_context *ctx, fastd_peer *peer, const fastd_method *method, fastd_socket *sock, const fastd_peer_address *address, bool initiator,
const ecc_public_key_256 *A, const ecc_public_key_256 *B, const ecc_public_key_256 *X, const ecc_public_key_256 *A, const ecc_public_key_256 *B, const ecc_public_key_256 *X,
const ecc_public_key_256 *Y, const ecc_public_key_256 *sigma, uint64_t serial) { const ecc_public_key_256 *Y, const ecc_public_key_256 *sigma, uint64_t serial) {
uint8_t hashinput[5*PUBLICKEYBYTES]; uint8_t hashinput[5*PUBLICKEYBYTES];
@ -362,7 +362,7 @@ static bool establish(fastd_context *ctx, fastd_peer *peer, const fastd_method *
return true; return true;
} }
static void finish_handshake(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, fastd_peer *peer, const handshake_key *handshake_key, const ecc_public_key_256 *peer_handshake_key, static void finish_handshake(fastd_context *ctx, fastd_socket *sock, const fastd_peer_address *address, fastd_peer *peer, const handshake_key *handshake_key, const ecc_public_key_256 *peer_handshake_key,
const fastd_handshake *handshake, const fastd_method *method) { const fastd_handshake *handshake, const fastd_method *method) {
pr_debug(ctx, "finishing handshake with %P[%I]...", peer, address); pr_debug(ctx, "finishing handshake with %P[%I]...", peer, address);
@ -433,7 +433,7 @@ static void finish_handshake(fastd_context *ctx, const fastd_socket *sock, const
fastd_send_handshake(ctx, sock, address, buffer); fastd_send_handshake(ctx, sock, address, buffer);
} }
static void handle_finish_handshake(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, fastd_peer *peer, const handshake_key *handshake_key, const ecc_public_key_256 *peer_handshake_key, static void handle_finish_handshake(fastd_context *ctx, fastd_socket *sock, const fastd_peer_address *address, fastd_peer *peer, const handshake_key *handshake_key, const ecc_public_key_256 *peer_handshake_key,
const fastd_handshake *handshake, const fastd_method *method) { const fastd_handshake *handshake, const fastd_method *method) {
pr_debug(ctx, "handling handshake finish with %P[%I]...", peer, address); pr_debug(ctx, "handling handshake finish with %P[%I]...", peer, address);
@ -522,7 +522,7 @@ static inline bool has_field(const fastd_handshake *handshake, uint8_t type, siz
return (handshake->records[type].length == length); return (handshake->records[type].length == length);
} }
static void protocol_handshake_handle(fastd_context *ctx, const fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, const fastd_handshake *handshake, const fastd_method *method) { static void protocol_handshake_handle(fastd_context *ctx, fastd_socket *sock, const fastd_peer_address *address, const fastd_peer_config *peer_conf, const fastd_handshake *handshake, const fastd_method *method) {
handshake_key *handshake_key; handshake_key *handshake_key;
char *peer_version_name = NULL; char *peer_version_name = NULL;