mirror of
https://github.com/neocturne/fastd.git
synced 2025-05-14 20:25:08 +02:00
Add on-establish and on-disestablish commands
This commit is contained in:
parent
9720307ab4
commit
a6a5b5e00e
5 changed files with 179 additions and 2 deletions
31
src/config.c
31
src/config.c
|
@ -79,6 +79,13 @@ static void default_config(fastd_config *conf) {
|
||||||
|
|
||||||
conf->on_down = NULL;
|
conf->on_down = NULL;
|
||||||
conf->on_down_dir = NULL;
|
conf->on_down_dir = NULL;
|
||||||
|
|
||||||
|
conf->on_establish = NULL;
|
||||||
|
conf->on_establish_dir = NULL;
|
||||||
|
|
||||||
|
conf->on_disestablish = NULL;
|
||||||
|
conf->on_disestablish_dir = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool config_match(const char *opt, ...) {
|
static bool config_match(const char *opt, ...) {
|
||||||
|
@ -506,6 +513,26 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IF_OPTION_ARG("--on-establish") {
|
||||||
|
free(conf->on_establish);
|
||||||
|
free(conf->on_establish_dir);
|
||||||
|
|
||||||
|
conf->on_establish = strdup(arg);
|
||||||
|
conf->on_establish_dir = get_current_dir_name();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IF_OPTION_ARG("--on-disestablish") {
|
||||||
|
free(conf->on_disestablish);
|
||||||
|
free(conf->on_disestablish_dir);
|
||||||
|
|
||||||
|
conf->on_disestablish = strdup(arg);
|
||||||
|
conf->on_disestablish_dir = get_current_dir_name();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
IF_OPTION("--generate-key") {
|
IF_OPTION("--generate-key") {
|
||||||
keygen = true;
|
keygen = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -640,5 +667,9 @@ void fastd_config_release(fastd_context *ctx, fastd_config *conf) {
|
||||||
free(conf->on_up_dir);
|
free(conf->on_up_dir);
|
||||||
free(conf->on_down);
|
free(conf->on_down);
|
||||||
free(conf->on_down_dir);
|
free(conf->on_down_dir);
|
||||||
|
free(conf->on_establish);
|
||||||
|
free(conf->on_establish_dir);
|
||||||
|
free(conf->on_disestablish);
|
||||||
|
free(conf->on_disestablish_dir);
|
||||||
free(conf->protocol_config);
|
free(conf->protocol_config);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ tun { UPDATE_LOCATION; return TOK_TUN; }
|
||||||
on { UPDATE_LOCATION; return TOK_ON; }
|
on { UPDATE_LOCATION; return TOK_ON; }
|
||||||
up { UPDATE_LOCATION; return TOK_UP; }
|
up { UPDATE_LOCATION; return TOK_UP; }
|
||||||
down { UPDATE_LOCATION; return TOK_DOWN; }
|
down { UPDATE_LOCATION; return TOK_DOWN; }
|
||||||
|
establish { UPDATE_LOCATION; return TOK_ESTABLISH; }
|
||||||
|
disestablish { UPDATE_LOCATION; return TOK_DISESTABLISH; }
|
||||||
peers { UPDATE_LOCATION; return TOK_PEERS; }
|
peers { UPDATE_LOCATION; return TOK_PEERS; }
|
||||||
from { UPDATE_LOCATION; return TOK_FROM; }
|
from { UPDATE_LOCATION; return TOK_FROM; }
|
||||||
log { UPDATE_LOCATION; return TOK_LOG; }
|
log { UPDATE_LOCATION; return TOK_LOG; }
|
||||||
|
|
22
src/config.y
22
src/config.y
|
@ -73,6 +73,8 @@
|
||||||
%token TOK_ON
|
%token TOK_ON
|
||||||
%token TOK_UP
|
%token TOK_UP
|
||||||
%token TOK_DOWN
|
%token TOK_DOWN
|
||||||
|
%token TOK_ESTABLISH
|
||||||
|
%token TOK_DISESTABLISH
|
||||||
%token TOK_PEERS
|
%token TOK_PEERS
|
||||||
%token TOK_FROM
|
%token TOK_FROM
|
||||||
%token TOK_LOG
|
%token TOK_LOG
|
||||||
|
@ -131,6 +133,8 @@ statement: TOK_LOG log ';'
|
||||||
| TOK_SECRET secret ';'
|
| TOK_SECRET secret ';'
|
||||||
| TOK_ON TOK_UP on_up ';'
|
| TOK_ON TOK_UP on_up ';'
|
||||||
| TOK_ON TOK_DOWN on_down ';'
|
| TOK_ON TOK_DOWN on_down ';'
|
||||||
|
| TOK_ON TOK_ESTABLISH on_establish ';'
|
||||||
|
| TOK_ON TOK_DISESTABLISH on_disestablish ';'
|
||||||
| TOK_PEER peer '{' peer_conf '}'
|
| TOK_PEER peer '{' peer_conf '}'
|
||||||
| TOK_PEER_TO_PEER peer_to_peer ';'
|
| TOK_PEER_TO_PEER peer_to_peer ';'
|
||||||
| TOK_INCLUDE include ';'
|
| TOK_INCLUDE include ';'
|
||||||
|
@ -212,6 +216,24 @@ on_down: TOK_STRING {
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
on_establish: TOK_STRING {
|
||||||
|
free(conf->on_establish);
|
||||||
|
free(conf->on_establish_dir);
|
||||||
|
|
||||||
|
conf->on_establish = strdup($1->str);
|
||||||
|
conf->on_establish_dir = get_current_dir_name();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
on_disestablish: TOK_STRING {
|
||||||
|
free(conf->on_disestablish);
|
||||||
|
free(conf->on_disestablish_dir);
|
||||||
|
|
||||||
|
conf->on_disestablish = strdup($1->str);
|
||||||
|
conf->on_disestablish_dir = get_current_dir_name();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
peer: maybe_string {
|
peer: maybe_string {
|
||||||
fastd_peer_config_new(ctx, conf);
|
fastd_peer_config_new(ctx, conf);
|
||||||
conf->peers->name = strdup($1->str);
|
conf->peers->name = strdup($1->str);
|
||||||
|
|
|
@ -115,6 +115,12 @@ struct _fastd_config {
|
||||||
|
|
||||||
char *on_down;
|
char *on_down;
|
||||||
char *on_down_dir;
|
char *on_down_dir;
|
||||||
|
|
||||||
|
char *on_establish;
|
||||||
|
char *on_establish_dir;
|
||||||
|
|
||||||
|
char *on_disestablish;
|
||||||
|
char *on_disestablish_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _fastd_context {
|
struct _fastd_context {
|
||||||
|
|
120
src/peer.c
120
src/peer.c
|
@ -29,8 +29,120 @@
|
||||||
#include "peer.h"
|
#include "peer.h"
|
||||||
#include "task.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) {
|
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);
|
ctx->conf->protocol->free_peer_state(ctx, peer);
|
||||||
peer->protocol_state = NULL;
|
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);
|
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->address = temp_peer->address;
|
||||||
perm_peer->state = STATE_ESTABLISHED;
|
perm_peer->state = STATE_ESTABLISHED;
|
||||||
perm_peer->seen = temp_peer->seen;
|
perm_peer->seen = temp_peer->seen;
|
||||||
perm_peer->protocol_state = temp_peer->protocol_state;
|
perm_peer->protocol_state = temp_peer->protocol_state;
|
||||||
|
|
||||||
temp_peer->protocol_state = NULL;
|
temp_peer->protocol_state = NULL;
|
||||||
|
|
||||||
int i;
|
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);
|
fastd_peer_reset(ctx, temp_peer);
|
||||||
|
|
||||||
|
on_establish(ctx, perm_peer);
|
||||||
pr_info(ctx, "Connection with %P established.", perm_peer);
|
pr_info(ctx, "Connection with %P established.", perm_peer);
|
||||||
|
|
||||||
return 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) {
|
void fastd_peer_set_established(fastd_context *ctx, fastd_peer *peer) {
|
||||||
switch(peer->state) {
|
switch(peer->state) {
|
||||||
case STATE_WAIT:
|
case STATE_WAIT:
|
||||||
pr_info(ctx, "Connection with %P established.", peer);
|
|
||||||
peer->state = STATE_ESTABLISHED;
|
peer->state = STATE_ESTABLISHED;
|
||||||
|
on_establish(ctx, peer);
|
||||||
|
pr_info(ctx, "Connection with %P established.", peer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_TEMP:
|
case STATE_TEMP:
|
||||||
|
|
Loading…
Add table
Reference in a new issue