From a6a5b5e00e98aa27644a1afa4a461819221b758d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 5 Apr 2012 20:38:30 +0200 Subject: Add on-establish and on-disestablish commands --- src/peer.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 2 deletions(-) (limited to 'src/peer.c') diff --git a/src/peer.c b/src/peer.c index 3566cfc..fd8577b 100644 --- a/src/peer.c +++ b/src/peer.c @@ -29,8 +29,120 @@ #include "peer.h" #include "task.h" +#include +#include + + +static void on_establish(fastd_context *ctx, fastd_peer *peer) { + if (!ctx->conf->on_establish) + return; + + char *cwd = get_current_dir_name(); + chdir(ctx->conf->on_establish_dir); + + setenv("INTERFACE", ctx->ifname, 1); + + char buf[INET6_ADDRSTRLEN]; + snprintf(buf, sizeof(buf), "%u", ctx->conf->mtu); + setenv("MTU", buf, 1); + + if (peer->config && peer->config->name) + setenv("PEER_NAME", peer->config->name, 1); + else + unsetenv("PEER_NAME"); + + switch(peer->address.sa.sa_family) { + case AF_INET: + inet_ntop(AF_INET, &peer->address.in.sin_addr, buf, sizeof(buf)); + setenv("PEER_ADDRESS", buf, 1); + + snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in.sin_port)); + setenv("PEER_PORT", buf, 1); + + break; + + case AF_INET6: + inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, buf, sizeof(buf)); + setenv("PEER_ADDRESS", buf, 1); + + snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in6.sin6_port)); + setenv("PEER_PORT", buf, 1); + + break; + + default: + unsetenv("PEER_ADDRESS"); + unsetenv("PEER_PORT"); + } + + int ret = system(ctx->conf->on_establish); + + if (WIFSIGNALED(ret)) + pr_error(ctx, "on-establish command exited with signal %i", WTERMSIG(ret)); + else if(ret) + pr_warn(ctx, "on-establish command exited with status %i", WEXITSTATUS(ret)); + + chdir(cwd); + free(cwd); +} + +static void on_disestablish(fastd_context *ctx, fastd_peer *peer) { + if (!ctx->conf->on_disestablish) + return; + + char *cwd = get_current_dir_name(); + chdir(ctx->conf->on_disestablish_dir); + + setenv("INTERFACE", ctx->ifname, 1); + + char buf[INET6_ADDRSTRLEN]; + snprintf(buf, sizeof(buf), "%u", ctx->conf->mtu); + setenv("MTU", buf, 1); + + if (peer->config && peer->config->name) + setenv("PEER_NAME", peer->config->name, 1); + else + unsetenv("PEER_NAME"); + + switch(peer->address.sa.sa_family) { + case AF_INET: + inet_ntop(AF_INET, &peer->address.in.sin_addr, buf, sizeof(buf)); + setenv("PEER_ADDRESS", buf, 1); + + snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in.sin_port)); + setenv("PEER_PORT", buf, 1); + + break; + + case AF_INET6: + inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, buf, sizeof(buf)); + setenv("PEER_ADDRESS", buf, 1); + + snprintf(buf, sizeof(buf), "%u", ntohs(peer->address.in6.sin6_port)); + setenv("PEER_PORT", buf, 1); + + break; + + default: + unsetenv("PEER_ADDRESS"); + unsetenv("PEER_PORT"); + } + + int ret = system(ctx->conf->on_disestablish); + + if (WIFSIGNALED(ret)) + pr_error(ctx, "on-disestablish command exited with signal %i", WTERMSIG(ret)); + else if(ret) + pr_warn(ctx, "on-disestablish command exited with status %i", WEXITSTATUS(ret)); + + chdir(cwd); + free(cwd); +} static inline void reset_peer(fastd_context *ctx, fastd_peer *peer) { + if (peer->state == STATE_ESTABLISHED) + on_disestablish(ctx, peer); + ctx->conf->protocol->free_peer_state(ctx, peer); peer->protocol_state = NULL; @@ -217,11 +329,13 @@ fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *per ctx->conf->protocol->free_peer_state(ctx, perm_peer); + if (perm_peer->state == STATE_ESTABLISHED) + on_disestablish(ctx, perm_peer); + perm_peer->address = temp_peer->address; perm_peer->state = STATE_ESTABLISHED; perm_peer->seen = temp_peer->seen; perm_peer->protocol_state = temp_peer->protocol_state; - temp_peer->protocol_state = NULL; int i; @@ -235,6 +349,7 @@ fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *per fastd_peer_reset(ctx, temp_peer); + on_establish(ctx, perm_peer); pr_info(ctx, "Connection with %P established.", perm_peer); return perm_peer; @@ -243,8 +358,9 @@ fastd_peer* fastd_peer_set_established_merge(fastd_context *ctx, fastd_peer *per void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer) { switch(peer->state) { case STATE_WAIT: - pr_info(ctx, "Connection with %P established.", peer); peer->state = STATE_ESTABLISHED; + on_establish(ctx, peer); + pr_info(ctx, "Connection with %P established.", peer); break; case STATE_TEMP: -- cgit v1.2.3