From 6c401d89e229fe24cb35b4758f1abb3cfb1cc966 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 2 Apr 2012 21:52:21 +0200 Subject: Allow peer-to-peer forwarding --- src/config.c | 7 +++++++ src/config.l | 3 +++ src/config.y | 14 ++++++++++++++ src/fastd.c | 31 ++++++++++++++++++++++++++++++- src/fastd.h | 2 ++ 5 files changed, 56 insertions(+), 1 deletion(-) 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 TOK_ADDR %token TOK_ADDR6 @@ -103,6 +107,7 @@ %type maybe_string %type port +%type boolean %type maybe_port %type 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; -- cgit v1.2.3