From 359e9b6c2b0cc4817b55338f0b89638945d98c50 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 24 Mar 2012 22:32:24 +0100 Subject: Rename methods to protocols; fix some command line parse bugs; implement most of the config file parser --- src/CMakeLists.txt | 14 +-- src/config.c | 90 +++++++++------ src/config.l | 6 +- src/config.y | 119 +++++++++++++++----- src/fastd.c | 8 +- src/fastd.h | 9 +- src/handshake.c | 24 ++-- src/method_ec25519_fhmqvc_xsalsa20_poly1305.c | 128 --------------------- src/method_null.c | 144 ------------------------ src/packet.h | 2 +- src/peer.c | 6 +- src/peer.h | 2 +- src/printf.c | 2 +- src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c | 128 +++++++++++++++++++++ src/protocol_null.c | 144 ++++++++++++++++++++++++ src/types.h | 2 +- 16 files changed, 456 insertions(+), 372 deletions(-) delete mode 100644 src/method_ec25519_fhmqvc_xsalsa20_poly1305.c delete mode 100644 src/method_null.c create mode 100644 src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c create mode 100644 src/protocol_null.c (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1da7d13..bd97f31 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,12 @@ -set(METHODS method_null.c) +set(PROTOCOLS protocol_null.c) set(FASTD_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${FASTD_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) set(FASTD_LIBS "") -if(WITH_METHOD_ECFXP) - set(METHODS ${METHODS} method_ec25519_fhmqvc_xsalsa20_poly1305.c) - set(FASTD_INCLUDES ${FASTD_INCLUDES} ${UECC_INCLUDE_DIR} ${NACL_INCLUDE_DIR}) - set(FASTD_LIBS ${FASTD_LIBS} ${UECC_LIBRARY} ${NACL_LIBRARY}) -endif(WITH_METHOD_ECFXP) +if(WITH_PROTOCOL_ECFXP) + list(APPEND PROTOCOLS protocol_ec25519_fhmqvc_xsalsa20_poly1305.c) + list(APPEND FASTD_INCLUDES ${UECC_INCLUDE_DIR} ${NACL_INCLUDE_DIR}) + list(APPEND FASTD_LIBS ${UECC_LIBRARY} ${NACL_LIBRARY}) +endif(WITH_PROTOCOL_ECFXP) include_directories(${FASTD_INCLUDES}) @@ -23,6 +23,6 @@ add_executable(fastd task.c ${FLEX_fastd_config_lex_OUTPUTS} ${BISON_fastd_config_parse_OUTPUTS} - ${METHODS} + ${PROTOCOLS} ) target_link_libraries(fastd rt ${FASTD_LIBS}) diff --git a/src/config.c b/src/config.c index 18fe120..13fb8b5 100644 --- a/src/config.c +++ b/src/config.c @@ -36,10 +36,10 @@ #include -extern fastd_method fastd_method_null; +extern fastd_protocol fastd_protocol_null; -#ifdef WITH_METHOD_ECFXP -extern fastd_method fastd_method_ec25519_fhmqvc_xsalsa20_poly1305; +#ifdef WITH_PROTOCOL_ECFXP +extern fastd_protocol fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; #endif @@ -64,7 +64,7 @@ static void default_config(fastd_config *conf) { conf->mtu = 1500; conf->mode = MODE_TAP; - conf->method = &fastd_method_null; + conf->protocol = &fastd_protocol_null; conf->peers = NULL; } @@ -115,8 +115,7 @@ static void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]) { default_config(conf); - fastd_peer_config **current_peer = &conf->peers; - + fastd_peer_config *current_peer; int i = 1; const char *arg; long l; @@ -124,11 +123,6 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con char *endptr; char *addrstr; - bool v4_peers = false, v6_peers = false; - - - conf->n_floating = 0; - while (i < argc) { IF_OPTION_ARG("-c", "--config") { @@ -169,6 +163,9 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con if (*endptr || l > 65535) exit_error(ctx, "invalid bind port `%s'", charptr+1); } + else { + l = 0; + } if (strcmp(addrstr, "any") == 0) { conf->bind_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); @@ -215,10 +212,10 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con IF_OPTION_ARG("-P", "--protocol") { if (!strcmp(arg, "null")) - conf->method = &fastd_method_null; -#ifdef WITH_METHOD_ECFXP - if (!strcmp(arg, "ecfxp")) - conf->method = &fastd_method_ec25519_fhmqvc_xsalsa20_poly1305; + conf->protocol = &fastd_protocol_null; +#ifdef WITH_PROTOCOL_ECFXP + else if (!strcmp(arg, "ecfxp")) + conf->protocol = &fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; #endif else exit_error(ctx, "invalid protocol `%s'", arg); @@ -226,13 +223,13 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con } IF_OPTION_ARG("-p", "--peer") { - *current_peer = malloc(sizeof(fastd_peer_config)); - (*current_peer)->next = NULL; + current_peer = malloc(sizeof(fastd_peer_config)); + current_peer->next = conf->peers; + conf->peers = current_peer; - memset(&(*current_peer)->address, 0, sizeof(fastd_peer_address)); + memset(¤t_peer->address, 0, sizeof(fastd_peer_address)); if (strcmp(arg, "float") == 0) { - (*current_peer)->address.sa.sa_family = AF_UNSPEC; - conf->n_floating++; + current_peer->address.sa.sa_family = AF_UNSPEC; continue; } @@ -266,40 +263,59 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con } if (arg[0] == '[') { - v6_peers = true; - (*current_peer)->address.in6.sin6_family = AF_INET6; - if (inet_pton(AF_INET6, addrstr, &(*current_peer)->address.in6.sin6_addr) != 1) + current_peer->address.in6.sin6_family = AF_INET6; + if (inet_pton(AF_INET6, addrstr, ¤t_peer->address.in6.sin6_addr) != 1) exit_error(ctx, "invalid peer address `%s'", addrstr); - (*current_peer)->address.in6.sin6_port = htons(l); + current_peer->address.in6.sin6_port = htons(l); } else { - v4_peers = true; - (*current_peer)->address.in.sin_family = AF_INET; - if (inet_pton(AF_INET, addrstr, &(*current_peer)->address.in.sin_addr) != 1) + current_peer->address.in.sin_family = AF_INET; + if (inet_pton(AF_INET, addrstr, ¤t_peer->address.in.sin_addr) != 1) exit_error(ctx, "invalid peer address `%s'", addrstr); - (*current_peer)->address.in.sin_port = htons(l); + current_peer->address.in.sin_port = htons(l); } free(addrstr); - - current_peer = &(*current_peer)->next; - continue; } exit_error(ctx, "config error: unknown option `%s'", argv[i]); } + conf->n_floating = 0; + conf->n_v4 = 0; + conf->n_v6 = 0; + + for (current_peer = conf->peers; current_peer; current_peer = current_peer->next) { + switch (current_peer->address.sa.sa_family) { + case AF_UNSPEC: + conf->n_floating++; + break; + + case AF_INET: + conf->n_v4++; + break; + + case AF_INET6: + conf->n_v6++; + break; + + default: + exit_bug(ctx, "invalid peer address family"); + } + } + if (conf->n_floating && conf->bind_addr_in.sin_family == AF_UNSPEC && conf->bind_addr_in6.sin6_family == AF_UNSPEC) { conf->bind_addr_in.sin_family = AF_INET; conf->bind_addr_in6.sin6_family = AF_INET6; } - else if (v4_peers) { - conf->bind_addr_in.sin_family = AF_INET; - } - else if (v6_peers) { - conf->bind_addr_in6.sin6_family = AF_INET6; + else { + if (conf->n_v4) + conf->bind_addr_in.sin_family = AF_INET; + + if (conf->n_v6) + conf->bind_addr_in6.sin6_family = AF_INET6; } bool ok = true; @@ -309,7 +325,7 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con } if (ok) - ok = conf->method->check_config(ctx, conf); + ok = conf->protocol->check_config(ctx, conf); if (!ok) exit_error(ctx, "config error"); diff --git a/src/config.l b/src/config.l index e9dd235..f18dca7 100644 --- a/src/config.l +++ b/src/config.l @@ -4,9 +4,11 @@ %option reentrant %top { + #define YY_DECL int fastd_config_lex(YYSTYPE *yylval_param, fastd_context *ctx, void *yyscanner) + #include #include - #define YY_DECL int fastd_config_lex(YYSTYPE *yylval_param, fastd_context *ctx, void *yyscanner) + YY_DECL; } %x STRING @@ -21,6 +23,7 @@ mtu { yylval->str = yytext; return TOK_MTU; } mode { yylval->str = yytext; return TOK_MODE; } protocol { yylval->str = yytext; return TOK_PROTOCOL; } peer { yylval->str = yytext; return TOK_PEER; } +address { yylval->str = yytext; return TOK_ADDRESS; } [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} { if (!inet_pton(AF_INET, yytext, &yylval->addr)) @@ -30,7 +33,6 @@ peer { yylval->str = yytext; return TOK_PEER; } } any { yylval->str = yytext; return TOK_ANY; } -float { yylval->str = yytext; return TOK_FLOAT; } tap { yylval->str = yytext; return TOK_TAP; } tun { yylval->str = yytext; return TOK_TUN; } diff --git a/src/config.y b/src/config.y index 08c5050..a949860 100644 --- a/src/config.y +++ b/src/config.y @@ -3,7 +3,7 @@ %lex-param {fastd_context *ctx} %lex-param {yyscan_t scanner} %parse-param {fastd_context *ctx} -%parse-param {fastd_config *config} +%parse-param {fastd_config *conf} %parse-param {yyscan_t scanner} %code requires { @@ -27,32 +27,41 @@ %token TOK_MODE %token TOK_PROTOCOL %token TOK_PEER +%token TOK_ADDRESS %token TOK_ADDR %token TOK_ADDR6 %token TOK_ANY -%token TOK_FLOAT %token TOK_TAP %token TOK_TUN -/* %code top { - #define YY_DECL int fastd_config_lex(YYSTYPE *yylval_param, fastd_context *ctx, yyscan_t yyscanner) -}*/ - - %code { + #include #include - YY_DECL; + #include + #include + + void fastd_config_error(fastd_context *ctx, fastd_config *conf, yyscan_t scanner, char *s); - void fastd_config_error(fastd_context *ctx, fastd_config *config, void *scanner, char *s); + extern fastd_protocol fastd_protocol_null; + + #ifdef WITH_PROTOCOL_ECFXP + extern fastd_protocol fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; + #endif } %code provides { #include - int fastd_config_parse (fastd_context *ctx, fastd_config *config, void *scanner); + int fastd_config_parse (fastd_context *ctx, fastd_config *conf, void *scanner); } +%type maybe_string + +%type port +%type maybe_port +%type maybe_port_default + %% config: config statement | @@ -63,44 +72,98 @@ statement: TOK_INTERFACE interface ';' | TOK_MTU mtu ';' | TOK_MODE mode ';' | TOK_PROTOCOL protocol ';' - | TOK_PEER peer '{' peer_config '}' + | TOK_PEER peer '{' peer_conf '}' ; -interface: TOK_STRING { config->ifname = strdup($1); } +interface: TOK_STRING { conf->ifname = strdup($1); } ; -bind: TOK_ADDR - | TOK_ADDR ':' port - | TOK_ADDR6 - | TOK_ADDR6 ':' port - | TOK_ANY - | TOK_ANY ':' port +bind: TOK_ADDR maybe_port { + conf->bind_addr_in.sin_family = AF_INET; + conf->bind_addr_in.sin_addr = $1; + conf->bind_addr_in.sin_port = $2; + } + | TOK_ADDR6 maybe_port { + conf->bind_addr_in6.sin6_family = AF_INET6; + conf->bind_addr_in6.sin6_addr = $1; + conf->bind_addr_in6.sin6_port = $2; + } + | TOK_ANY maybe_port { + conf->bind_addr_in.sin_addr.s_addr = htonl(INADDR_ANY); + conf->bind_addr_in.sin_port = $2; + conf->bind_addr_in6.sin6_addr = in6addr_any; + conf->bind_addr_in6.sin6_port = $2; + } ; -mtu: TOK_INTEGER { config->mtu = $1; } +mtu: TOK_INTEGER { conf->mtu = $1; } ; -mode: TOK_TAP { config->mode = MODE_TAP; } - | TOK_TUN { config->mode = MODE_TUN; } +mode: TOK_TAP { conf->mode = MODE_TAP; } + | TOK_TUN { conf->mode = MODE_TUN; } ; -protocol: TOK_STRING +protocol: maybe_string { + if (!strcmp($1, "null")) + conf->protocol = &fastd_protocol_null; +#ifdef WITH_PROTOCOL_ECFXP + if (!strcmp($1, "ecfxp")) + conf->protocol = &fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305; +#endif + else + exit_error(ctx, "config error: invalid protocol `%s'", $1); +} ; -peer: TOK_STRING - | +peer: maybe_string { + fastd_peer_config *current_peer = malloc(sizeof(fastd_peer_config)); + current_peer->next = conf->peers; + conf->peers = current_peer; + + memset(¤t_peer->address, 0, sizeof(fastd_peer_address)); + + current_peer->address.sa.sa_family = AF_UNSPEC; + } ; -peer_config: peer_config peer_statement +peer_conf: peer_conf peer_statement | ; -peer_statement: ':' +peer_statement: TOK_ADDRESS peer_address + ; + +peer_address: TOK_ADDR maybe_port_default { + conf->peers->address.in.sin_family = AF_INET; + conf->peers->address.in.sin_addr = $1; + conf->peers->address.in.sin_port = $2; + } + | TOK_ADDR6 maybe_port_default { + conf->peers->address.in6.sin6_family = AF_INET6; + conf->peers->address.in6.sin6_addr = $1; + conf->peers->address.in6.sin6_port = $2; + } + ; + +maybe_string: TOK_STRING + | { $$[0] = '\0'; } + ; + +maybe_port: ':' port { $$ = $2; } + | { $$ = 0; } + ; + +maybe_port_default: ':' port { $$ = $2; } + | { $$ = htons(1337); } ; -port: TOK_INTEGER +port: TOK_INTEGER { + if ($1 < 0 || $1 > 65635) + exit_error(ctx, "invalid port %i", $1); + $$ = htons($1); + } ; %% -void fastd_config_error(fastd_context *ctx, fastd_config *config, yyscan_t scanner, char *s) { +void fastd_config_error(fastd_context *ctx, fastd_config *conf, yyscan_t scanner, char *s) { exit_error(ctx, "config error: %s", s); } diff --git a/src/fastd.c b/src/fastd.c index 3b27e98..479ac95 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -219,7 +219,7 @@ static void handle_tun(fastd_context *ctx) { } if (peer->state == STATE_ESTABLISHED) { - ctx->conf->method->send(ctx, peer, buffer); + ctx->conf->protocol->send(ctx, peer, buffer); } else { fastd_buffer_free(buffer); @@ -231,7 +231,7 @@ static void handle_tun(fastd_context *ctx) { if (peer->state == STATE_ESTABLISHED) { fastd_buffer send_buffer = fastd_buffer_alloc(len, 0, 0); memcpy(send_buffer.data, buffer.data, len); - ctx->conf->method->send(ctx, peer, send_buffer); + ctx->conf->protocol->send(ctx, peer, send_buffer); } } @@ -240,7 +240,7 @@ static void handle_tun(fastd_context *ctx) { } static void handle_socket(fastd_context *ctx, int sockfd) { - size_t max_len = ctx->conf->method->max_packet_size(ctx); + size_t max_len = ctx->conf->protocol->max_packet_size(ctx); fastd_buffer buffer = fastd_buffer_alloc(max_len, 0, 0); uint8_t packet_type; @@ -295,7 +295,7 @@ static void handle_socket(fastd_context *ctx, int sockfd) { switch (packet_type) { case PACKET_DATA: peer->seen = ctx->now; - ctx->conf->method->handle_recv(ctx, peer, buffer); + ctx->conf->protocol->handle_recv(ctx, peer, buffer); break; case PACKET_HANDSHAKE: diff --git a/src/fastd.h b/src/fastd.h index 4af9f20..d911a71 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -56,7 +56,7 @@ struct _fastd_eth_addr { uint8_t data[ETH_ALEN]; }; -struct _fastd_method { +struct _fastd_protocol { const char *name; bool (*handle_config)(fastd_context *ctx, const fastd_config *conf, const char *option); @@ -89,10 +89,13 @@ struct _fastd_config { uint16_t mtu; fastd_mode mode; - fastd_method *method; + fastd_protocol *protocol; - unsigned n_floating; fastd_peer_config *peers; + + unsigned n_floating; + unsigned n_v4; + unsigned n_v6; }; struct _fastd_context { diff --git a/src/handshake.c b/src/handshake.c index 19f15a9..6220ddf 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -37,8 +37,8 @@ static const char const *RECORD_TYPES[RECORD_MAX] = { "reply code", "error detail", "flags", - "protocol", - "method name", + "mode", + "protocol name", }; static const char const *REPLY_TYPES[REPLY_MAX] = { @@ -62,10 +62,10 @@ static inline void handshake_add(fastd_context *ctx, fastd_buffer *buffer, fastd } void fastd_handshake_send(fastd_context *ctx, fastd_peer *peer) { - size_t method_len = strlen(ctx->conf->method->name); + size_t protocol_len = strlen(ctx->conf->protocol->name); fastd_buffer buffer = fastd_buffer_alloc(sizeof(fastd_packet), 0, - 2+1 + /* protocol */ - 2+method_len /* method name */ + 2+1 + /* mode */ + 2+protocol_len /* protocol name */ ); fastd_packet *request = buffer.data; @@ -77,7 +77,7 @@ void fastd_handshake_send(fastd_context *ctx, fastd_peer *peer) { uint8_t mode = ctx->conf->mode; handshake_add(ctx, &buffer, RECORD_MODE, 1, &mode); - handshake_add(ctx, &buffer, RECORD_METHOD_NAME, method_len, ctx->conf->method->name); + handshake_add(ctx, &buffer, RECORD_PROTOCOL_NAME, protocol_len, ctx->conf->protocol->name); fastd_task_put_send_handshake(ctx, peer, buffer); } @@ -131,16 +131,16 @@ void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer b goto send_reply; } - if (!records[RECORD_METHOD_NAME]) { + if (!records[RECORD_PROTOCOL_NAME]) { reply_code = REPLY_MANDATORY_MISSING; - error_detail = RECORD_METHOD_NAME; + error_detail = RECORD_PROTOCOL_NAME; goto send_reply; } - if (lengths[RECORD_METHOD_NAME] != strlen(ctx->conf->method->name) - || strncmp((char*)records[RECORD_METHOD_NAME], ctx->conf->method->name, lengths[RECORD_METHOD_NAME])) { + if (lengths[RECORD_PROTOCOL_NAME] != strlen(ctx->conf->protocol->name) + || strncmp((char*)records[RECORD_PROTOCOL_NAME], ctx->conf->protocol->name, lengths[RECORD_PROTOCOL_NAME])) { reply_code = REPLY_UNACCEPTABLE_VALUE; - error_detail = RECORD_METHOD_NAME; + error_detail = RECORD_PROTOCOL_NAME; goto send_reply; } @@ -184,7 +184,7 @@ void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer b case REPLY_SUCCESS: pr_info(ctx, "Handshake with %P successful.", peer); fastd_peer_set_established(ctx, peer); - ctx->conf->method->init(ctx, peer); + ctx->conf->protocol->init(ctx, peer); break; default: diff --git a/src/method_ec25519_fhmqvc_xsalsa20_poly1305.c b/src/method_ec25519_fhmqvc_xsalsa20_poly1305.c deleted file mode 100644 index b57531f..0000000 --- a/src/method_ec25519_fhmqvc_xsalsa20_poly1305.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (c) 2012, Matthias Schiffer - Partly based on QuickTun Copyright (c) 2010, Ivo Smits . - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _GNU_SOURCE - -#include "fastd.h" -#include "peer.h" - -#include - -#include -#include - - -typedef struct _method_config { - ecc_secret_key_256 secret_key; -} method_config; - -typedef struct _method_peer_config { - ecc_public_key_256 public_key; -} method_peer_config; - -typedef struct _method_peer_state { -} method_peer_state; - - -static bool method_handle_config(fastd_context *ctx, const fastd_config *conf, const char *option) { - printf("Unknown option: %s\n", option); - return false; -} - -static bool method_check_config(fastd_context *ctx, const fastd_config *conf) { - return true; -} - -static size_t method_max_packet_size(fastd_context *ctx) { - return (fastd_max_packet_size(ctx) - crypto_secretbox_xsalsa20poly1305_NONCEBYTES); -} - -static char* method_peer_str(const fastd_context *ctx, const fastd_peer *peer) { - char addr_buf[INET6_ADDRSTRLEN] = ""; - char *ret; - - const char *temp = fastd_peer_is_temporary(peer) ? " (temporary)" : ""; - - switch (peer->address.sa.sa_family) { - case AF_UNSPEC: - if (asprintf(&ret, "%s", temp) > 0) - return ret; - break; - - case AF_INET: - if (inet_ntop(AF_INET, &peer->address.in.sin_addr, addr_buf, sizeof(addr_buf))) { - if (asprintf(&ret, "%s:%u%s", addr_buf, ntohs(peer->address.in.sin_port), temp) > 0) - return ret; - } - break; - - case AF_INET6: - if (inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, addr_buf, sizeof(addr_buf))) { - if (asprintf(&ret, "[%s]:%u%s", addr_buf, ntohs(peer->address.in6.sin6_port), temp) > 0) - return ret; - } - break; - - default: - exit_bug(ctx, "unsupported address family"); - } - - return NULL; -} - -static void method_init(fastd_context *ctx, fastd_peer *peer) { - pr_info(ctx, "Initializing session with %P...", peer); -} - -static void method_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { - fastd_buffer_free(buffer); -} - -static void method_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { - fastd_buffer_free(buffer); -} - -static void method_free_peer_private(fastd_context *ctx, fastd_peer *peer) { -} - - -const fastd_method fastd_method_ec25519_fhmqvc_xsalsa20_poly1305 = { - .name = "ec25519-fhmqvc-xsalsa20-poly1305", - - .handle_config = method_handle_config, - .check_config = method_check_config, - - .max_packet_size = method_max_packet_size, - - .peer_str = method_peer_str, - - .init = method_init, - .handle_recv = method_handle_recv, - .send = method_send, - - .free_peer_private = method_free_peer_private, -}; diff --git a/src/method_null.c b/src/method_null.c deleted file mode 100644 index 70c5a09..0000000 --- a/src/method_null.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - Copyright (c) 2012, Matthias Schiffer - Partly based on QuickTun Copyright (c) 2010, Ivo Smits . - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#define _GNU_SOURCE - -#include "fastd.h" -#include "task.h" -#include "peer.h" - -#include - - -static bool method_handle_config(fastd_context *ctx, const fastd_config *conf, const char *option) { - return false; -} - -static bool method_check_config(fastd_context *ctx, const fastd_config *conf) { - if (conf->n_floating > 1) { - pr_error(ctx, "with method `null' use can't define more than one floating peer"); - return false; - } - - return true; -} - -static size_t method_max_packet_size(fastd_context *ctx) { - return fastd_max_packet_size(ctx); -} - -static char* method_peer_str(const fastd_context *ctx, const fastd_peer *peer) { - char addr_buf[INET6_ADDRSTRLEN] = ""; - char *ret; - - const char *temp = fastd_peer_is_temporary(peer) ? " (temporary)" : ""; - - switch (peer->address.sa.sa_family) { - case AF_UNSPEC: - if (asprintf(&ret, "%s", temp) > 0) - return ret; - break; - - case AF_INET: - if (inet_ntop(AF_INET, &peer->address.in.sin_addr, addr_buf, sizeof(addr_buf))) { - if (asprintf(&ret, "%s:%u%s", addr_buf, ntohs(peer->address.in.sin_port), temp) > 0) - return ret; - } - break; - - case AF_INET6: - if (inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, addr_buf, sizeof(addr_buf))) { - if (asprintf(&ret, "[%s]:%u%s", addr_buf, ntohs(peer->address.in6.sin6_port), temp) > 0) - return ret; - } - break; - - default: - exit_bug(ctx, "unsupported address family"); - } - - return NULL; -} - -static void method_init(fastd_context *ctx, fastd_peer *peer) { - pr_info(ctx, "Connection with %P established.", peer); - - fastd_task_put_send(ctx, peer, fastd_buffer_alloc(0, 0, 0)); -} - -static void method_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { - if (!fastd_peer_is_established(peer)) { - pr_info(ctx, "Connection with %P established.", peer); - - fastd_peer_set_established(ctx, peer); - } - - if (fastd_peer_is_temporary(peer)) { - fastd_peer *perm_peer; - for (perm_peer = ctx->peers; perm_peer; perm_peer = perm_peer->next) { - if (fastd_peer_is_floating(perm_peer)) - break; - } - - if (!perm_peer) { - fastd_buffer_free(buffer); - return; - } - - peer = fastd_peer_merge(ctx, perm_peer, peer); - } - - if (buffer.len) - fastd_task_put_handle_recv(ctx, peer, buffer); - else - fastd_buffer_free(buffer); -} - -static void method_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { - fastd_task_put_send(ctx, peer, buffer); -} - -static void method_free_peer_private(fastd_context *ctx, fastd_peer *peer) { -} - - -const fastd_method fastd_method_null = { - .name = "null", - - .handle_config = method_handle_config, - .check_config = method_check_config, - - .max_packet_size = method_max_packet_size, - - .peer_str = method_peer_str, - - .init = method_init, - .handle_recv = method_handle_recv, - .send = method_send, - - .free_peer_private = method_free_peer_private, -}; diff --git a/src/packet.h b/src/packet.h index b206663..0960cce 100644 --- a/src/packet.h +++ b/src/packet.h @@ -43,7 +43,7 @@ typedef enum _fastd_handshake_record_type { RECORD_ERROR_DETAIL, RECORD_FLAGS, RECORD_MODE, - RECORD_METHOD_NAME, + RECORD_PROTOCOL_NAME, RECORD_MAX, } fastd_handshake_record_type; diff --git a/src/peer.c b/src/peer.c index 3aecdc0..282159a 100644 --- a/src/peer.c +++ b/src/peer.c @@ -50,8 +50,8 @@ const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buf } static inline void reset_peer(fastd_context *ctx, fastd_peer *peer) { - ctx->conf->method->free_peer_private(ctx, peer); - peer->method_private = NULL; + ctx->conf->protocol->free_peer_private(ctx, peer); + peer->protocol_private = NULL; int i, deleted = 0; for (i = 0; i < ctx->n_eth_addr; i++) { @@ -95,7 +95,7 @@ static fastd_peer* add_peer(fastd_context *ctx) { peer->next = ctx->peers; peer->last_req_id = 0; - peer->method_private = NULL; + peer->protocol_private = NULL; ctx->peers = peer; diff --git a/src/peer.h b/src/peer.h index 121276c..39fcc02 100644 --- a/src/peer.h +++ b/src/peer.h @@ -49,7 +49,7 @@ struct _fastd_peer { struct timespec seen; - void *method_private; + void *protocol_private; }; struct _fastd_peer_config { diff --git a/src/printf.c b/src/printf.c index 72bc941..bef598c 100644 --- a/src/printf.c +++ b/src/printf.c @@ -183,7 +183,7 @@ void fastd_printf(const fastd_context *ctx, const char *format, ...) { p = va_arg(ap, void*); if (p) { - char* str = ctx->conf->method->peer_str(ctx, (fastd_peer*)p); + char* str = ctx->conf->protocol->peer_str(ctx, (fastd_peer*)p); fprintf(stderr, "%s", str); free(str); } diff --git a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c new file mode 100644 index 0000000..53901ba --- /dev/null +++ b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c @@ -0,0 +1,128 @@ +/* + Copyright (c) 2012, Matthias Schiffer + Partly based on QuickTun Copyright (c) 2010, Ivo Smits . + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#define _GNU_SOURCE + +#include "fastd.h" +#include "peer.h" + +#include + +#include +#include + + +typedef struct _protocol_config { + ecc_secret_key_256 secret_key; +} protocol_config; + +typedef struct _protocol_peer_config { + ecc_public_key_256 public_key; +} protocol_peer_config; + +typedef struct _protocol_peer_state { +} protocol_peer_state; + + +static bool protocol_handle_config(fastd_context *ctx, const fastd_config *conf, const char *option) { + printf("Unknown option: %s\n", option); + return false; +} + +static bool protocol_check_config(fastd_context *ctx, const fastd_config *conf) { + return true; +} + +static size_t protocol_max_packet_size(fastd_context *ctx) { + return (fastd_max_packet_size(ctx) - crypto_secretbox_xsalsa20poly1305_NONCEBYTES); +} + +static char* protocol_peer_str(const fastd_context *ctx, const fastd_peer *peer) { + char addr_buf[INET6_ADDRSTRLEN] = ""; + char *ret; + + const char *temp = fastd_peer_is_temporary(peer) ? " (temporary)" : ""; + + switch (peer->address.sa.sa_family) { + case AF_UNSPEC: + if (asprintf(&ret, "%s", temp) > 0) + return ret; + break; + + case AF_INET: + if (inet_ntop(AF_INET, &peer->address.in.sin_addr, addr_buf, sizeof(addr_buf))) { + if (asprintf(&ret, "%s:%u%s", addr_buf, ntohs(peer->address.in.sin_port), temp) > 0) + return ret; + } + break; + + case AF_INET6: + if (inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, addr_buf, sizeof(addr_buf))) { + if (asprintf(&ret, "[%s]:%u%s", addr_buf, ntohs(peer->address.in6.sin6_port), temp) > 0) + return ret; + } + break; + + default: + exit_bug(ctx, "unsupported address family"); + } + + return NULL; +} + +static void protocol_init(fastd_context *ctx, fastd_peer *peer) { + pr_info(ctx, "Initializing session with %P...", peer); +} + +static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { + fastd_buffer_free(buffer); +} + +static void protocol_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { + fastd_buffer_free(buffer); +} + +static void protocol_free_peer_private(fastd_context *ctx, fastd_peer *peer) { +} + + +const fastd_protocol fastd_protocol_ec25519_fhmqvc_xsalsa20_poly1305 = { + .name = "ec25519-fhmqvc-xsalsa20-poly1305", + + .handle_config = protocol_handle_config, + .check_config = protocol_check_config, + + .max_packet_size = protocol_max_packet_size, + + .peer_str = protocol_peer_str, + + .init = protocol_init, + .handle_recv = protocol_handle_recv, + .send = protocol_send, + + .free_peer_private = protocol_free_peer_private, +}; diff --git a/src/protocol_null.c b/src/protocol_null.c new file mode 100644 index 0000000..f365228 --- /dev/null +++ b/src/protocol_null.c @@ -0,0 +1,144 @@ +/* + Copyright (c) 2012, Matthias Schiffer + Partly based on QuickTun Copyright (c) 2010, Ivo Smits . + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#define _GNU_SOURCE + +#include "fastd.h" +#include "task.h" +#include "peer.h" + +#include + + +static bool protocol_handle_config(fastd_context *ctx, const fastd_config *conf, const char *option) { + return false; +} + +static bool protocol_check_config(fastd_context *ctx, const fastd_config *conf) { + if (conf->n_floating > 1) { + pr_error(ctx, "with protocol `null' use can't define more than one floating peer"); + return false; + } + + return true; +} + +static size_t protocol_max_packet_size(fastd_context *ctx) { + return fastd_max_packet_size(ctx); +} + +static char* protocol_peer_str(const fastd_context *ctx, const fastd_peer *peer) { + char addr_buf[INET6_ADDRSTRLEN] = ""; + char *ret; + + const char *temp = fastd_peer_is_temporary(peer) ? " (temporary)" : ""; + + switch (peer->address.sa.sa_family) { + case AF_UNSPEC: + if (asprintf(&ret, "%s", temp) > 0) + return ret; + break; + + case AF_INET: + if (inet_ntop(AF_INET, &peer->address.in.sin_addr, addr_buf, sizeof(addr_buf))) { + if (asprintf(&ret, "%s:%u%s", addr_buf, ntohs(peer->address.in.sin_port), temp) > 0) + return ret; + } + break; + + case AF_INET6: + if (inet_ntop(AF_INET6, &peer->address.in6.sin6_addr, addr_buf, sizeof(addr_buf))) { + if (asprintf(&ret, "[%s]:%u%s", addr_buf, ntohs(peer->address.in6.sin6_port), temp) > 0) + return ret; + } + break; + + default: + exit_bug(ctx, "unsupported address family"); + } + + return NULL; +} + +static void protocol_init(fastd_context *ctx, fastd_peer *peer) { + pr_info(ctx, "Connection with %P established.", peer); + + fastd_task_put_send(ctx, peer, fastd_buffer_alloc(0, 0, 0)); +} + +static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { + if (!fastd_peer_is_established(peer)) { + pr_info(ctx, "Connection with %P established.", peer); + + fastd_peer_set_established(ctx, peer); + } + + if (fastd_peer_is_temporary(peer)) { + fastd_peer *perm_peer; + for (perm_peer = ctx->peers; perm_peer; perm_peer = perm_peer->next) { + if (fastd_peer_is_floating(perm_peer)) + break; + } + + if (!perm_peer) { + fastd_buffer_free(buffer); + return; + } + + peer = fastd_peer_merge(ctx, perm_peer, peer); + } + + if (buffer.len) + fastd_task_put_handle_recv(ctx, peer, buffer); + else + fastd_buffer_free(buffer); +} + +static void protocol_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { + fastd_task_put_send(ctx, peer, buffer); +} + +static void protocol_free_peer_private(fastd_context *ctx, fastd_peer *peer) { +} + + +const fastd_protocol fastd_protocol_null = { + .name = "null", + + .handle_config = protocol_handle_config, + .check_config = protocol_check_config, + + .max_packet_size = protocol_max_packet_size, + + .peer_str = protocol_peer_str, + + .init = protocol_init, + .handle_recv = protocol_handle_recv, + .send = protocol_send, + + .free_peer_private = protocol_free_peer_private, +}; diff --git a/src/types.h b/src/types.h index 61417fc..2f6b36a 100644 --- a/src/types.h +++ b/src/types.h @@ -66,6 +66,6 @@ typedef struct _fastd_peer_eth_addr fastd_peer_eth_addr; typedef struct _fastd_config fastd_config; typedef struct _fastd_context fastd_context; -typedef struct _fastd_method fastd_method; +typedef struct _fastd_protocol fastd_protocol; #endif /* _FASTD_TYPES_H_ */ -- cgit v1.2.3