summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-04-02 21:52:21 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-04-02 21:52:21 +0200
commit6c401d89e229fe24cb35b4758f1abb3cfb1cc966 (patch)
tree35ffc937a8684de1b1634d0f41cde7824abc9a26
parent77520caad8302266537e87104f6496040fc98bb4 (diff)
downloadfastd-6c401d89e229fe24cb35b4758f1abb3cfb1cc966.tar
fastd-6c401d89e229fe24cb35b4758f1abb3cfb1cc966.zip
Allow peer-to-peer forwarding
-rw-r--r--src/config.c7
-rw-r--r--src/config.l3
-rw-r--r--src/config.y14
-rw-r--r--src/fastd.c31
-rw-r--r--src/fastd.h2
5 files changed, 56 insertions, 1 deletions
diff --git a/src/config.c b/src/config.c
index 1842891..964c2d6 100644
--- a/src/config.c
+++ b/src/config.c
@@ -64,6 +64,8 @@ static void default_config(fastd_config *conf) {
conf->mtu = 1500;
conf->mode = MODE_TAP;
+ conf->peer_to_peer = false;
+
conf->protocol = &fastd_protocol_null;
conf->secret = NULL;
conf->key_valid = 3600; /* 60 minutes */
@@ -394,6 +396,11 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
continue;
}
+ IF_OPTION("--peer-to-peer") {
+ conf->peer_to_peer = true;
+ continue;
+ }
+
IF_OPTION_ARG("--on-up") {
free(conf->on_up);
free(conf->on_up_dir);
diff --git a/src/config.l b/src/config.l
index 7901faa..f2a9002 100644
--- a/src/config.l
+++ b/src/config.l
@@ -80,6 +80,9 @@ warn { UPDATE_LOCATION; return TOK_WARN; }
info { UPDATE_LOCATION; return TOK_INFO; }
verbose { UPDATE_LOCATION; return TOK_VERBOSE; }
debug { UPDATE_LOCATION; return TOK_DEBUG; }
+peer-to-peer { UPDATE_LOCATION; return TOK_PEER_TO_PEER; }
+yes { UPDATE_LOCATION; return TOK_YES; }
+no { UPDATE_LOCATION; return TOK_NO; }
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
UPDATE_LOCATION;
diff --git a/src/config.y b/src/config.y
index 37a4ea9..be30ab0 100644
--- a/src/config.y
+++ b/src/config.y
@@ -44,6 +44,7 @@
%union {
int num;
char* str;
+ bool boolean;
struct in_addr addr;
struct in6_addr addr6;
}
@@ -80,6 +81,9 @@
%token TOK_INFO
%token TOK_VERBOSE
%token TOK_DEBUG
+%token TOK_PEER_TO_PEER
+%token TOK_YES
+%token TOK_NO
%token <addr> TOK_ADDR
%token <addr6> TOK_ADDR6
@@ -103,6 +107,7 @@
%type <str> maybe_string
%type <num> port
+%type <boolean> boolean
%type <num> maybe_port
%type <str> maybe_as
@@ -124,6 +129,7 @@ statement: TOK_LOG log ';'
| TOK_SECRET secret ';'
| TOK_ON TOK_UP on_up ';'
| TOK_PEER peer '{' peer_conf '}'
+ | TOK_PEER_TO_PEER peer_to_peer ';'
| TOK_INCLUDE include ';'
;
@@ -226,6 +232,10 @@ peer_include: TOK_STRING { fastd_read_config(ctx, conf, $1, true, depth); free($
;
+peer_to_peer: boolean { conf->peer_to_peer = $1; }
+ ;
+
+
include: TOK_PEER TOK_STRING maybe_as {
fastd_peer_config_new(ctx, conf);
conf->peers->name = $3;
@@ -253,6 +263,10 @@ maybe_as: TOK_AS TOK_STRING { $$ = $2; }
| { $$ = NULL; }
;
+boolean: TOK_YES { $$ = true; }
+ | TOK_NO { $$ = false; }
+ ;
+
port: TOK_INTEGER {
if ($1 < 0 || $1 > 65635)
exit_error(ctx, "invalid port %i", $1);
diff --git a/src/fastd.c b/src/fastd.c
index 373277d..21e5027 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -203,7 +203,36 @@ static void handle_tasks(fastd_context *ctx) {
}
write(ctx->tunfd, task->handle_recv.buffer.data, task->handle_recv.buffer.len);
- fastd_buffer_free(task->handle_recv.buffer);
+
+ if (ctx->conf->mode == MODE_TAP && ctx->conf->peer_to_peer) {
+ const fastd_eth_addr *dest_addr = fastd_get_dest_address(ctx, task->handle_recv.buffer);
+
+ if (fastd_eth_addr_is_unicast(dest_addr)) {
+ fastd_peer *dest_peer = fastd_peer_find_by_eth_addr(ctx, dest_addr);
+
+ if (dest_peer && dest_peer != task->peer && dest_peer->state == STATE_ESTABLISHED) {
+ ctx->conf->protocol->send(ctx, dest_peer, task->handle_recv.buffer);
+ }
+ else {
+ fastd_buffer_free(task->handle_recv.buffer);
+ }
+ }
+ else {
+ fastd_peer *dest_peer;
+ for (dest_peer = ctx->peers; dest_peer; dest_peer = dest_peer->next) {
+ if (dest_peer != task->peer && dest_peer->state == STATE_ESTABLISHED) {
+ fastd_buffer send_buffer = fastd_buffer_alloc(task->handle_recv.buffer.len, ctx->conf->protocol->min_encrypt_head_space(ctx), 0);
+ memcpy(send_buffer.data, task->handle_recv.buffer.data, task->handle_recv.buffer.len);
+ ctx->conf->protocol->send(ctx, dest_peer, send_buffer);
+ }
+ }
+
+ fastd_buffer_free(task->handle_recv.buffer);
+ }
+ }
+ else {
+ fastd_buffer_free(task->handle_recv.buffer);
+ }
break;
case TASK_HANDSHAKE:
diff --git a/src/fastd.h b/src/fastd.h
index 2c1b02c..5e62fb0 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -92,6 +92,8 @@ struct _fastd_config {
uint16_t mtu;
fastd_mode mode;
+ bool peer_to_peer;
+
fastd_protocol *protocol;
char *secret;
unsigned key_valid;