summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-05-03 20:00:20 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-05-03 20:00:20 +0200
commit6e39dfe32584e9edaa45d0df31765839dae219c5 (patch)
tree38760ff8eb30f12b6616c06cefebd77718e37376
parent1519fd273496e412a3bad908313d5d60cc9f4f57 (diff)
downloadfastd-6e39dfe32584e9edaa45d0df31765839dae219c5.tar
fastd-6e39dfe32584e9edaa45d0df31765839dae219c5.zip
Use pipe to transmit resolved addresses to main threadv0.4-rc7
-rw-r--r--src/fastd.c95
-rw-r--r--src/fastd.h9
-rw-r--r--src/resolve.c20
3 files changed, 60 insertions, 64 deletions
diff --git a/src/fastd.c b/src/fastd.c
index 49238f3..d001ba4 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -55,17 +55,6 @@ static void on_terminate(int signo) {
terminate = true;
}
-static void on_sigusr1(int signo, siginfo_t *siginfo, void *context) {
- if (siginfo->si_code != SI_QUEUE || !siginfo->si_value.sival_ptr)
- return;
-
- 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;
@@ -83,11 +72,16 @@ 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_pipes(fastd_context *ctx) {
+ int pipefd[2];
+
+ if (pipe(pipefd))
+ exit_errno(ctx, "pipe");
+
+ ctx->resolverfd = pipefd[0];
+ ctx->resolvewfd = pipefd[1];
}
static void init_sockets(fastd_context *ctx) {
@@ -530,6 +524,40 @@ static void handle_socket(fastd_context *ctx, int sockfd) {
}
}
+static void handle_resolv_returns(fastd_context *ctx) {
+ fastd_resolve_return resolve_return;
+
+ if (read(ctx->resolverfd, &resolve_return, sizeof(resolve_return)) < 0) {
+ if (errno != EINTR)
+ pr_warn(ctx, "recvfrom: %s", strerror(errno));
+
+ return;
+ }
+
+ fastd_peer *peer;
+ for (peer = ctx->peers; peer; peer = peer->next) {
+ if (!peer->config)
+ continue;
+
+ if (!strequal(peer->config->hostname, resolve_return.hostname))
+ continue;
+
+ if (!fastd_peer_config_matches_dynamic(peer->config, &resolve_return.constraints))
+ continue;
+
+ if (fastd_peer_claim_address(ctx, peer, &resolve_return.addr)) {
+ send_handshake(ctx, peer);
+ }
+ else {
+ pr_warn(ctx, "hostname `%s' resolved to address %I which is used by a fixed peer", resolve_return.hostname, &resolve_return.addr);
+ fastd_task_schedule_handshake(ctx, peer, fastd_rand(ctx, 17500, 22500));
+ }
+ break;
+ }
+
+ free(resolve_return.hostname);
+}
+
static void handle_input(fastd_context *ctx) {
struct pollfd fds[3];
fds[0].fd = ctx->tunfd;
@@ -538,13 +566,15 @@ static void handle_input(fastd_context *ctx) {
fds[1].events = POLLIN;
fds[2].fd = ctx->sock6fd;
fds[2].events = POLLIN;
+ fds[3].fd = ctx->resolverfd;
+ fds[3].events = POLLIN;
int timeout = fastd_task_timeout(ctx);
if (timeout < 0 || timeout > 60000)
timeout = 60000; /* call maintenance at least once a minute */
- int ret = poll(fds, 3, timeout);
+ int ret = poll(fds, 4, timeout);
if (ret < 0) {
if (errno == EINTR)
return;
@@ -560,6 +590,8 @@ static void handle_input(fastd_context *ctx) {
handle_socket(ctx, ctx->sockfd);
if (fds[2].revents & POLLIN)
handle_socket(ctx, ctx->sock6fd);
+ if (fds[3].revents & POLLIN)
+ handle_resolv_returns(ctx);
}
static void cleanup_peers(fastd_context *ctx) {
@@ -575,34 +607,6 @@ static void cleanup_peers(fastd_context *ctx) {
}
}
-
-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->config)
- continue;
-
- if (!strequal(peer->config->hostname, ctx->resolve_returns->hostname))
- continue;
-
- if (!fastd_peer_config_matches_dynamic(peer->config, &ctx->resolve_returns->constraints))
- continue;
-
- if (fastd_peer_claim_address(ctx, peer, &ctx->resolve_returns->addr))
- send_handshake(ctx, peer);
- else
- pr_warn(ctx, "hostname `%s' resolved to address %I which is used by a fixed peer", ctx->resolve_returns->hostname, ctx->resolve_returns->addr);
- break;
- }
-
- fastd_resolve_return *next = ctx->resolve_returns->next;
- free(ctx->resolve_returns->hostname);
- free(ctx->resolve_returns);
- ctx->resolve_returns = next;
- }
-}
-
static void maintenance(fastd_context *ctx) {
cleanup_peers(ctx);
@@ -617,6 +621,7 @@ int main(int argc, char *argv[]) {
fastd_random_bytes(&ctx, &ctx.randseed, sizeof(ctx.randseed), false);
init_signals(&ctx);
+ init_pipes(&ctx);
fastd_config conf;
fastd_configure(&ctx, &conf, argc, argv);
@@ -658,8 +663,6 @@ int main(int argc, char *argv[]) {
fastd_reconfigure(&ctx, &conf);
}
- handle_resolv_returns(&ctx);
-
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
diff --git a/src/fastd.h b/src/fastd.h
index 1de2e2d..6a503d8 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -101,10 +101,6 @@ union _fastd_peer_address {
};
struct _fastd_resolve_return {
- fastd_resolve_return *next;
-
- fastd_context *ctx;
-
char *hostname;
fastd_peer_address constraints;
@@ -173,6 +169,9 @@ struct _fastd_context {
fastd_peer *peers;
fastd_queue task_queue;
+ int resolverfd;
+ int resolvewfd;
+
int tunfd;
int sockfd;
int sock6fd;
@@ -184,8 +183,6 @@ struct _fastd_context {
unsigned int randseed;
fastd_protocol_state *protocol_state;
-
- fastd_resolve_return *resolve_returns;
};
struct _fastd_string_stack {
diff --git a/src/resolve.c b/src/resolve.c
index 23e7f32..6848a11 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -31,7 +31,7 @@
#include <netdb.h>
#include <pthread.h>
-#include <signal.h>
+#include <unistd.h>
typedef struct _resolv_arg {
@@ -70,25 +70,21 @@ static void* resolve_peer(void *varg) {
error = true;
}
- fastd_resolve_return *ret = malloc(sizeof(fastd_resolve_return));
+ fastd_resolve_return ret;
- ret->ctx = arg->ctx;
-
- ret->hostname = arg->hostname;
- ret->constraints = arg->constraints;
+ ret.hostname = arg->hostname;
+ ret.constraints = arg->constraints;
if (!error) {
pr_debug(arg->ctx, "Resolved host `%s' successfully", arg->hostname);
- memcpy(&ret->addr, res->ai_addr, res->ai_addrlen);
+ memcpy(&ret.addr, res->ai_addr, res->ai_addrlen);
}
else {
- ret->addr.sa.sa_family = AF_UNSPEC;
+ 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");
+ if (write(arg->ctx->resolvewfd, &ret, sizeof(ret)) < 0)
+ exit_errno(arg->ctx, "write");
freeaddrinfo(res);
free(arg);