summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-07-25 13:49:01 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-07-25 13:49:01 +0200
commitfcc5bcad1add369b7b9e0a25cc63b88dfb83e5fe (patch)
tree87c22a602541d499d2a416e42facaa2a74ea4aae
parent530c6eaf60cb76ab79b326c348b2039ed396e687 (diff)
downloadfastd-fcc5bcad1add369b7b9e0a25cc63b88dfb83e5fe.tar
fastd-fcc5bcad1add369b7b9e0a25cc63b88dfb83e5fe.zip
Improve handling of similar remote resolves
-rw-r--r--src/fastd.c14
-rw-r--r--src/fastd.h4
-rw-r--r--src/peer.c13
-rw-r--r--src/peer.h15
-rw-r--r--src/resolve.c29
5 files changed, 36 insertions, 39 deletions
diff --git a/src/fastd.c b/src/fastd.c
index a142cb2..63e77c5 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -850,7 +850,7 @@ static void handle_tasks(fastd_context_t *ctx) {
if (!task->peer->next_remote)
task->peer->next_remote = task->peer->remotes;
- if (fastd_peer_remote_is_dynamic(task->peer->next_remote))
+ if (fastd_remote_is_dynamic(task->peer->next_remote))
fastd_resolve_peer(ctx, task->peer, task->peer->next_remote);
break;
@@ -1078,14 +1078,6 @@ static void handle_resolve_returns(fastd_context_t *ctx) {
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_resolve_return: read");
- }
-
- hostname[resolve_return.hostname_len] = 0;
-
fastd_peer_t *peer;
for (peer = ctx->peers; peer; peer = peer->next) {
if (!peer->config)
@@ -1093,7 +1085,7 @@ static void handle_resolve_returns(fastd_context_t *ctx) {
fastd_remote_t *remote;
for (remote = peer->remotes; remote; remote = remote->next) {
- if (strequal(remote->config->hostname, hostname) && fastd_peer_remote_matches_dynamic(remote->config, &resolve_return.constraints))
+ if (remote == resolve_return.remote)
break;
}
@@ -1104,6 +1096,8 @@ static void handle_resolve_returns(fastd_context_t *ctx) {
break;
}
+
+ fastd_remote_unref(resolve_return.remote);
}
static inline void handle_socket_error(fastd_context_t *ctx, fastd_socket_t *sock) {
diff --git a/src/fastd.h b/src/fastd.h
index 2e92013..d61178a 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -112,10 +112,8 @@ union fastd_peer_address {
};
struct fastd_resolve_return {
+ fastd_remote_t *remote;
fastd_peer_address_t addr;
-
- fastd_peer_address_t constraints;
- size_t hostname_len;
};
struct fastd_log_file {
diff --git a/src/peer.c b/src/peer.c
index 3915b8e..9b15332 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -195,7 +195,7 @@ static void setup_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
ctx->conf->protocol->init_peer_state(ctx, peer);
if(peer->next_remote) {
- if (fastd_peer_remote_is_dynamic(peer->next_remote)) {
+ if (fastd_remote_is_dynamic(peer->next_remote)) {
peer->state = STATE_RESOLVING;
fastd_resolve_peer(ctx, peer, peer->next_remote);
}
@@ -234,7 +234,7 @@ static void delete_peer(fastd_context_t *ctx, fastd_peer_t *peer) {
fastd_remote_t *remote = peer->remotes;
peer->remotes = remote->next;
- free(remote);
+ fastd_remote_unref(remote);
}
free(peer);
@@ -400,7 +400,7 @@ bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *new_peer, fast
return true;
}
-static bool fastd_remote_configs_equal(const fastd_remote_config_t *remote1, const fastd_remote_config_t *remote2) {
+static bool remote_configs_equal(const fastd_remote_config_t *remote1, const fastd_remote_config_t *remote2) {
if (!remote1 && !remote2)
return true;
@@ -413,7 +413,7 @@ static bool fastd_remote_configs_equal(const fastd_remote_config_t *remote1, con
if (!strequal(remote1->hostname, remote2->hostname))
return false;
- return fastd_remote_configs_equal(remote1->next, remote2->next);
+ return remote_configs_equal(remote1->next, remote2->next);
}
bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_config_t *peer2) {
@@ -423,7 +423,7 @@ bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_
if(peer1->floating != peer2->floating)
return false;
- if (!fastd_remote_configs_equal(peer1->remotes, peer2->remotes))
+ if (!remote_configs_equal(peer1->remotes, peer2->remotes))
return false;
if (!strequal(peer1->key, peer2->key))
@@ -487,6 +487,7 @@ fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_con
while (remote_config) {
*remote = calloc(1, sizeof(fastd_remote_t));
+ (*remote)->ref = 1;
(*remote)->config = remote_config;
if (!remote_config->hostname)
@@ -580,7 +581,7 @@ const fastd_eth_addr_t* fastd_get_dest_address(const fastd_context_t *ctx, fastd
}
}
-bool fastd_peer_remote_matches_dynamic(const fastd_remote_config_t *remote, const fastd_peer_address_t *addr) {
+bool fastd_remote_matches_dynamic(const fastd_remote_config_t *remote, const fastd_peer_address_t *addr) {
if (!remote->hostname)
return false;
diff --git a/src/peer.h b/src/peer.h
index 1b6303e..7d85c39 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -82,6 +82,8 @@ struct fastd_peer_eth_addr {
struct fastd_remote {
fastd_remote_t *next;
+ unsigned ref;
+
fastd_remote_config_t *config;
fastd_peer_address_t address;
struct timespec last_resolve;
@@ -143,7 +145,7 @@ static inline bool fastd_peer_config_is_floating(const fastd_peer_config_t *conf
return (!config->remotes || config->floating);
}
-bool fastd_peer_remote_matches_dynamic(const fastd_remote_config_t *remote, const fastd_peer_address_t *addr);
+bool fastd_remote_matches_dynamic(const fastd_remote_config_t *remote, const fastd_peer_address_t *addr);
static inline bool fastd_peer_is_floating(const fastd_peer_t *peer) {
return peer->config ? fastd_peer_config_is_floating(peer->config) : true;
@@ -163,7 +165,16 @@ static inline bool fastd_peer_is_established(const fastd_peer_t *peer) {
}
}
-static inline bool fastd_peer_remote_is_dynamic(const fastd_remote_t *remote) {
+static inline void fastd_remote_ref(fastd_remote_t *remote) {
+ remote->ref++;
+}
+
+static inline void fastd_remote_unref(fastd_remote_t *remote) {
+ if(!--remote->ref)
+ free(remote);
+}
+
+static inline bool fastd_remote_is_dynamic(const fastd_remote_t *remote) {
return remote->config->hostname;
}
diff --git a/src/resolve.c b/src/resolve.c
index 5a18002..8cc5f13 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -35,6 +35,7 @@
typedef struct resolv_arg {
fastd_context_t *ctx;
+ fastd_remote_t *remote;
char *hostname;
fastd_peer_address_t constraints;
} resolv_arg_t;
@@ -68,28 +69,17 @@ static void* resolve_peer(void *varg) {
error = true;
}
- size_t hostname_len = strlen(arg->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 = arg->constraints;
- ret->hostname_len = hostname_len;
- memcpy(hostname, arg->hostname, hostname_len);
+ fastd_resolve_return_t ret = {
+ .remote = arg->remote
+ };
if (!error) {
pr_verbose(arg->ctx, "resolved host `%s' successfully", arg->hostname);
- memcpy(&ret->addr, res->ai_addr, res->ai_addrlen);
- fastd_peer_address_simplify(&ret->addr);
- }
- else {
- ret->addr.sa.sa_family = AF_UNSPEC;
+ memcpy(&ret.addr, res->ai_addr, res->ai_addrlen);
+ fastd_peer_address_simplify(&ret.addr);
}
- if (write(arg->ctx->resolvewfd, buf, sizeof(buf)) < 0)
+ if (write(arg->ctx->resolvewfd, &ret, sizeof(ret)) < 0)
pr_error_errno(arg->ctx, "can't write resolve return");
freeaddrinfo(res);
@@ -115,9 +105,13 @@ void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer, fastd_remote_t
pr_verbose(ctx, "resolving host `%s' for peer %P...", remote->config->hostname, peer);
+ fastd_remote_ref(remote);
+ remote->last_resolve = ctx->now;
+
resolv_arg_t *arg = malloc(sizeof(resolv_arg_t));
arg->ctx = ctx;
+ arg->remote = remote;
arg->hostname = strdup(remote->config->hostname);
arg->constraints = remote->config->address;
@@ -132,5 +126,4 @@ void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer, fastd_remote_t
}
pthread_detach(thread);
- remote->last_resolve = ctx->now;
}