summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-07-24 13:54:35 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-07-24 13:54:35 +0200
commit01196a23874f5e826b0fd3641aac6b85ede32fa5 (patch)
treeedd2c24cbddbe56a0b3a0d3beea01abe6256fac6
parent0b8d807bf675189fd496b6313283d58f917368d9 (diff)
downloadfastd-01196a23874f5e826b0fd3641aac6b85ede32fa5.tar
fastd-01196a23874f5e826b0fd3641aac6b85ede32fa5.zip
Don't let resolves delay handshakes
-rw-r--r--src/fastd.c69
-rw-r--r--src/peer.c42
-rw-r--r--src/peer.h1
-rw-r--r--src/resolve.c20
-rw-r--r--src/types.h2
5 files changed, 68 insertions, 66 deletions
diff --git a/src/fastd.c b/src/fastd.c
index 13c28ba..6cfa442 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -793,28 +793,27 @@ static inline void schedule_handshake(fastd_context_t *ctx, fastd_peer_t *peer)
}
static void send_handshake(fastd_context_t *ctx, fastd_peer_t *peer) {
- if (!fastd_peer_may_connect(ctx, peer)) {
- schedule_handshake(ctx, peer);
- return;
- }
-
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
- && 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);
- }
- else {
- pr_debug(ctx, "sending handshake to %P...", peer);
- peer->last_handshake = ctx->now;
- peer->last_handshake_address = peer->address;
- ctx->conf->protocol->handshake_init(ctx, peer->sock, &peer->local_address, &peer->address, peer);
- }
+ if (!peer->sock)
+ return;
+
+ if (peer->address.sa.sa_family == AF_UNSPEC) {
+ pr_debug(ctx, "not sending a handshake to %P (no valid address resolved)", peer);
+ return;
}
- schedule_handshake(ctx, peer);
+ if (timespec_diff(&ctx->now, &peer->last_handshake) < ctx->conf->min_handshake_interval*1000
+ && 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);
+ return;
+ }
+
+ pr_debug(ctx, "sending handshake to %P...", peer);
+ peer->last_handshake = ctx->now;
+ peer->last_handshake_address = peer->address;
+ ctx->conf->protocol->handshake_init(ctx, peer->sock, &peer->local_address, &peer->address, peer);
}
static void handle_tasks(fastd_context_t *ctx) {
@@ -822,15 +821,16 @@ static void handle_tasks(fastd_context_t *ctx) {
while ((task = fastd_task_get(ctx)) != NULL) {
switch (task->type) {
case TASK_HANDSHAKE:
- if (fastd_peer_is_dynamic(task->peer) && !(fastd_peer_is_floating(task->peer) && fastd_peer_is_established(task->peer))) {
- if (fastd_peer_may_connect(ctx, task->peer))
- fastd_resolve_peer(ctx, task->peer);
- else
- schedule_handshake(ctx, task->peer);
- }
- else {
- send_handshake(ctx, task->peer);
- }
+ schedule_handshake(ctx, task->peer);
+
+ if(!fastd_peer_may_connect(ctx, task->peer))
+ break;
+
+ if (fastd_peer_is_dynamic(task->peer) && !fastd_peer_is_established(task->peer))
+ fastd_resolve_peer(ctx, task->peer);
+
+ send_handshake(ctx, task->peer);
+
break;
case TASK_KEEPALIVE:
@@ -1045,18 +1045,18 @@ static void handle_socket(fastd_context_t *ctx, fastd_socket_t *sock) {
handle_socket_receive(ctx, sock, &local_addr, &recvaddr, buffer);
}
-static void handle_resolv_returns(fastd_context_t *ctx) {
+static void handle_resolve_returns(fastd_context_t *ctx) {
fastd_resolve_return_t resolve_return;
while (read(ctx->resolverfd, &resolve_return, sizeof(resolve_return)) < 0) {
if (errno != EINTR)
- exit_errno(ctx, "handle_resolv_return: read");
+ exit_errno(ctx, "handle_resolve_return: read");
}
char hostname[resolve_return.hostname_len+1];
while (read(ctx->resolverfd, hostname, resolve_return.hostname_len) < 0) {
if (errno != EINTR)
- exit_errno(ctx, "handle_resolv_return: read");
+ exit_errno(ctx, "handle_resolve_return: read");
}
hostname[resolve_return.hostname_len] = 0;
@@ -1072,15 +1072,8 @@ static void handle_resolv_returns(fastd_context_t *ctx) {
if (!fastd_peer_config_matches_dynamic(peer->config, &resolve_return.constraints))
continue;
- peer->last_resolve_return = ctx->now;
+ fastd_peer_handle_resolve(ctx, peer, &resolve_return.addr);
- if (fastd_peer_claim_address(ctx, peer, NULL, NULL, &resolve_return.addr)) {
- send_handshake(ctx, peer);
- }
- else {
- pr_warn(ctx, "hostname `%s' resolved to address %I which is used by a fixed peer", hostname, &resolve_return.addr);
- schedule_handshake(ctx, peer);
- }
break;
}
}
@@ -1141,7 +1134,7 @@ static void handle_input(fastd_context_t *ctx) {
if (fds[0].revents & POLLIN)
handle_tun(ctx);
if (fds[1].revents & POLLIN)
- handle_resolv_returns(ctx);
+ handle_resolve_returns(ctx);
for (i = 2; i < ctx->n_socks+2; i++) {
if (fds[i].revents & (POLLERR|POLLHUP|POLLNVAL))
diff --git a/src/peer.c b/src/peer.c
index 668b5c9..422cd2e 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -152,6 +152,27 @@ static void reset_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
fastd_task_delete_peer(ctx, peer);
}
+static void init_handshake(fastd_context_t *ctx, fastd_peer_t *peer) {
+ unsigned delay = 0;
+ if (has_group_config_constraints(peer->group->conf))
+ delay = fastd_rand(ctx, 0, 3000);
+
+ if (!fastd_peer_is_established(peer))
+ peer->state = STATE_HANDSHAKE;
+
+ fastd_task_schedule_handshake(ctx, peer, delay);
+}
+
+void fastd_peer_handle_resolve(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_peer_address_t *address) {
+ peer->last_resolve_return = ctx->now;
+
+ if (!fastd_peer_claim_address(ctx, peer, NULL, NULL, address))
+ pr_warn(ctx, "resolved address %I for peer %P which is used by a fixed peer", address, peer);
+
+ if (peer->state == STATE_RESOLVING)
+ init_handshake(ctx, peer);
+}
+
static void setup_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
if (!peer->config || peer->config->hostname)
peer->address.sa.sa_family = AF_UNSPEC;
@@ -174,12 +195,12 @@ static void setup_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
if (!peer->protocol_state)
ctx->conf->protocol->init_peer_state(ctx, peer);
- if (peer->address.sa.sa_family != AF_UNSPEC || fastd_peer_is_dynamic(peer)) {
- unsigned delay = 0;
- if (has_group_config_constraints(peer->group->conf))
- delay = fastd_rand(ctx, 0, 3000);
-
- fastd_task_schedule_handshake(ctx, peer, delay);
+ if (fastd_peer_is_dynamic(peer)) {
+ peer->state = STATE_RESOLVING;
+ fastd_resolve_peer(ctx, peer);
+ }
+ else if(peer->address.sa.sa_family != AF_UNSPEC) {
+ init_handshake(ctx, peer);
}
}
@@ -404,9 +425,11 @@ fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_con
peer->protocol_state = NULL;
peer->sock = NULL;
peer->seen = (struct timespec){0, 0};
- setup_peer(ctx, peer);
pr_verbose(ctx, "adding peer %P (group `%s')", peer, peer->group->conf->name);
+
+ setup_peer(ctx, peer);
+
ctx->n_peers++;
return peer;
@@ -426,10 +449,11 @@ fastd_peer_t* fastd_peer_add_temporary(fastd_context_t *ctx) {
peer->protocol_state = NULL;
peer->sock = NULL;
peer->seen = ctx->now;
- setup_peer(ctx, peer);
pr_debug(ctx, "adding temporary peer");
+ setup_peer(ctx, peer);
+
return peer;
}
@@ -555,7 +579,7 @@ void fastd_peer_eth_addr_add(fastd_context_t *ctx, fastd_peer_t *peer, const fas
int i;
for (i = ctx->n_eth_addr-1; i > min; i--)
ctx->eth_addr[i] = ctx->eth_addr[i-1];
-
+
ctx->eth_addr[min] = (fastd_peer_eth_addr_t){ *addr, peer, ctx->now };
pr_debug(ctx, "learned new MAC address %E on peer %P", addr, peer);
diff --git a/src/peer.h b/src/peer.h
index 43a6d02..a363424 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -111,6 +111,7 @@ bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer, const
void fastd_peer_enable_temporary(fastd_context_t *ctx, fastd_peer_t *peer);
void fastd_peer_set_established(fastd_context_t *ctx, fastd_peer_t *peer);
bool fastd_peer_may_connect(fastd_context_t *ctx, fastd_peer_t *peer);
+void fastd_peer_handle_resolve(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_peer_address_t *address);
bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *peer, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr);
void fastd_peer_reset_socket(fastd_context_t *ctx, fastd_peer_t *peer);
diff --git a/src/resolve.c b/src/resolve.c
index 062eb91..103ba5f 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -109,25 +109,7 @@ void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
}
if (timespec_diff(&ctx->now, &peer->last_resolve) < ctx->conf->min_resolve_interval*1000) {
- pr_debug(ctx, "not resolving %P as it has been resolved a short time ago", peer);
-
- size_t hostname_len = strlen(peer->config->hostname);
- char buf[sizeof(fastd_resolve_return_t) + hostname_len];
-
- fastd_resolve_return_t *ret = (void*)buf;
- char *hostname = buf + sizeof(fastd_resolve_return_t);
-
- memset(ret, 0, sizeof(fastd_resolve_return_t));
-
- ret->constraints = peer->config->address;
- ret->hostname_len = hostname_len;
- memcpy(hostname, peer->config->hostname, hostname_len);
-
- ret->addr = peer->address;
-
- if (write(ctx->resolvewfd, buf, sizeof(buf)) < 0)
- pr_error_errno(ctx, "can't write resolve return");
-
+ /* last resolve was just a few seconds ago */
return;
}
diff --git a/src/types.h b/src/types.h
index f3553c2..0425db7 100644
--- a/src/types.h
+++ b/src/types.h
@@ -50,6 +50,8 @@ typedef enum fastd_drop_caps {
typedef enum fastd_peer_state {
STATE_INIT = 0,
+ STATE_RESOLVING,
+ STATE_HANDSHAKE,
STATE_ESTABLISHED,
} fastd_peer_state_t;