diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-04-05 20:38:30 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-04-05 20:38:30 +0200 |
commit | a6a5b5e00e98aa27644a1afa4a461819221b758d (patch) | |
tree | cf1fc8ba118e3114172f488f3b3fddde73399240 /src/peer.c | |
parent | 9720307ab4d78bec3fc7bc7e44cf8ba217584a17 (diff) | |
download | fastd-a6a5b5e00e98aa27644a1afa4a461819221b758d.tar fastd-a6a5b5e00e98aa27644a1afa4a461819221b758d.zip |
Add on-establish and on-disestablish commandsv0.2
Diffstat (limited to 'src/peer.c')
-rw-r--r-- | src/peer.c | 120 |
1 files changed, 118 insertions, 2 deletions
@@ -29,8 +29,120 @@ #include "peer.h" #include "task.h" +#include <arpa/inet.h> +#include <unistd.h> + + +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: |