From df48485aeab897c50fd792a740d1a5aed4378fc9 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 18 Oct 2015 02:57:26 +0200 Subject: peer_group: move to a new header, add recursive lookup macros --- src/config.c | 1 + src/config.y | 3 +- src/handshake.c | 3 +- src/peer.c | 1 + src/peer.h | 32 ----------- src/peer_group.h | 92 ++++++++++++++++++++++++++++++++ src/protocols/ec25519_fhmqvc/handshake.c | 3 +- 7 files changed, 100 insertions(+), 35 deletions(-) create mode 100644 src/peer_group.h diff --git a/src/config.c b/src/config.c index 33621c7..034ad75 100644 --- a/src/config.c +++ b/src/config.c @@ -40,6 +40,7 @@ #include "lex.h" #include "method.h" #include "peer.h" +#include "peer_group.h" #include #include diff --git a/src/config.y b/src/config.y index 8ab7b7b..4f55d91 100644 --- a/src/config.y +++ b/src/config.y @@ -137,8 +137,9 @@ %code { - #include #include + #include + #include #include diff --git a/src/handshake.c b/src/handshake.c index d82a4b2..2c50c0e 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -33,6 +33,7 @@ #include "handshake.h" #include "method.h" #include "peer.h" +#include "peer_group.h" #include @@ -424,7 +425,7 @@ static inline const fastd_method_info_t * get_method_by_name(const fastd_string_ /** Returns the most appropriate method to negotiate with a peer a handshake was received from */ const fastd_method_info_t * fastd_handshake_get_method(const fastd_peer_t *peer, const fastd_handshake_t *handshake) { - const fastd_string_stack_t *methods = fastd_peer_get_methods(peer); + const fastd_string_stack_t *methods = *fastd_peer_group_lookup_peer(peer, methods); if (handshake->records[RECORD_METHOD_LIST].data && handshake->records[RECORD_METHOD_LIST].length) { fastd_string_stack_t *method_list = parse_string_list(handshake->records[RECORD_METHOD_LIST].data, handshake->records[RECORD_METHOD_LIST].length); diff --git a/src/peer.c b/src/peer.c index 363bdd7..de8846e 100644 --- a/src/peer.c +++ b/src/peer.c @@ -30,6 +30,7 @@ */ #include "peer.h" +#include "peer_group.h" #include "peer_hashtable.h" #include "poll.h" diff --git a/src/peer.h b/src/peer.h index ea1b950..298adf4 100644 --- a/src/peer.h +++ b/src/peer.h @@ -110,24 +110,6 @@ struct fastd_peer { }; -/** - A group of peers - - Peer groups may be nested and form a tree -*/ -struct fastd_peer_group { - fastd_peer_group_t *next; /**< The next sibling in the group tree */ - fastd_peer_group_t *parent; /**< The group's parent group */ - fastd_peer_group_t *children; /**< The group's first child */ - - char *name; /**< The group's name; NULL for the root group */ - fastd_string_stack_t *peer_dirs; /**< List of peer directories which belong to this group */ - - /* constraints */ - int max_connections; /**< The maximum number of connections to allow in this group; -1 for no limit */ - fastd_string_stack_t *methods; /**< The list of configured method names */ -}; - /** An entry for a MAC address seen at another peer */ struct fastd_peer_eth_addr { fastd_eth_addr_t addr; /**< The MAC address */ @@ -270,20 +252,6 @@ static inline bool fastd_peer_is_socket_dynamic(const fastd_peer_t *peer) { return (!peer->sock || !peer->sock->addr); } -/** Returns the configured methods for a peer's group */ -static inline const fastd_string_stack_t * fastd_peer_get_methods(const fastd_peer_t *peer) { - if (!peer) - return conf.peer_group->methods; - - const fastd_peer_group_t *group; - for (group = peer->group; group; group = group->parent) { - if (group->methods) - return group->methods; - } - - return NULL; -} - /** Returns the MTU to use for a peer */ static inline uint16_t fastd_peer_get_mtu(const fastd_peer_t *peer) { if (conf.mode == MODE_TAP) diff --git a/src/peer_group.h b/src/peer_group.h new file mode 100644 index 0000000..ce3a2dc --- /dev/null +++ b/src/peer_group.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2012-2015, Matthias Schiffer + 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. +*/ + +/** + \file + + Peer groups +*/ + + +#pragma once + +#include "fastd.h" + + +/** + A group of peers + + Peer groups may be nested and form a tree +*/ +struct fastd_peer_group { + fastd_peer_group_t *next; /**< The next sibling in the group tree */ + fastd_peer_group_t *parent; /**< The group's parent group */ + fastd_peer_group_t *children; /**< The group's first child */ + + char *name; /**< The group's name; NULL for the root group */ + fastd_string_stack_t *peer_dirs; /**< List of peer directories which belong to this group */ + + /* constraints */ + int max_connections; /**< The maximum number of connections to allow in this group; -1 for no limit */ + fastd_string_stack_t *methods; /**< The list of configured method names */ +}; + + +/** + Looks up an attribute in the peer group tree + + Returns a pointer to the attribute, going up the group tree to the first group + where the attribute is not NULL if such a group exists. + + @param group the peer group + @param attr the name of the member + + \hideinitializer + */ +#define fastd_peer_group_lookup(group, attr) ({ \ + const fastd_peer_group_t *_grp = (group); \ + \ + while (_grp->parent && !_grp->attr) \ + _grp = _grp->parent; \ + \ + &_grp->attr; \ + }) + +/** + Looks up an attribute in the peer group tree, for a given peer + + Returns a pointer to the attribute, going up the group tree to the first group + where the attribute is not NULL if such a group exists. Uses the default group + if no peer is given. + + @param peer the peer + @param attr the name of the member + + \hideinitializer + */ +#define fastd_peer_group_lookup_peer(peer, attr) ({ \ + const fastd_peer_t *_peer = (peer); \ + _peer ? fastd_peer_group_lookup(_peer->group, attr) : &conf.peer_group->attr; \ + }) diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c index 0cbe15a..80dbd5c 100644 --- a/src/protocols/ec25519_fhmqvc/handshake.c +++ b/src/protocols/ec25519_fhmqvc/handshake.c @@ -33,6 +33,7 @@ #include "../../crypto.h" #include "../../handshake.h" #include "../../hkdf_sha256.h" +#include "../../peer_group.h" #include "../../verify.h" @@ -314,7 +315,7 @@ static void respond_handshake(const fastd_socket_t *sock, const fastd_peer_addre if (!update_shared_handshake_key(peer, handshake_key, peer_handshake_key)) return; - fastd_handshake_buffer_t buffer = fastd_handshake_new_reply(2, little_endian, fastd_peer_get_mtu(peer), method, fastd_peer_get_methods(peer), 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES)); + fastd_handshake_buffer_t buffer = fastd_handshake_new_reply(2, little_endian, fastd_peer_get_mtu(peer), method, *fastd_peer_group_lookup_peer(peer, methods), 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES)); fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public); fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key); -- cgit v1.2.3