Skip to content

Commit

Permalink
Use pipe to transmit resolved addresses to main thread
Browse files Browse the repository at this point in the history
  • Loading branch information
neocturne committed May 3, 2012
1 parent 1519fd2 commit 6e39dfe
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 64 deletions.
95 changes: 49 additions & 46 deletions src/fastd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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);

Expand All @@ -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);
Expand Down Expand Up @@ -658,8 +663,6 @@ int main(int argc, char *argv[]) {
fastd_reconfigure(&ctx, &conf);
}

handle_resolv_returns(&ctx);

pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}

Expand Down
9 changes: 3 additions & 6 deletions src/fastd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -173,6 +169,9 @@ struct _fastd_context {
fastd_peer *peers;
fastd_queue task_queue;

int resolverfd;
int resolvewfd;

int tunfd;
int sockfd;
int sock6fd;
Expand All @@ -184,8 +183,6 @@ struct _fastd_context {
unsigned int randseed;

fastd_protocol_state *protocol_state;

fastd_resolve_return *resolve_returns;
};

struct _fastd_string_stack {
Expand Down
20 changes: 8 additions & 12 deletions src/resolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#include <netdb.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>


typedef struct _resolv_arg {
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 6e39dfe

Please sign in to comment.