From fcc5bcad1add369b7b9e0a25cc63b88dfb83e5fe Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 25 Jul 2013 13:49:01 +0200 Subject: Improve handling of similar remote resolves --- src/fastd.c | 14 ++++---------- src/fastd.h | 4 +--- src/peer.c | 13 +++++++------ src/peer.h | 15 +++++++++++++-- src/resolve.c | 29 +++++++++++------------------ 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; } -- cgit v1.2.3