From 35a18b1dea21f006b38694dcf5c99f817411ad4d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 19 Aug 2014 00:10:48 +0200 Subject: Create peer structures for disabled peers as well We have a 1:1 association between peers and peer configs now. --- src/async.c | 2 +- src/fastd.c | 23 ++++++++++----------- src/peer.c | 34 +++++++++++++++++++++----------- src/peer.h | 19 ++++++++++++++++-- src/protocols/ec25519_fhmqvc/handshake.c | 3 +++ 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/async.c b/src/async.c index 3ab5f5d..46419ee 100644 --- a/src/async.c +++ b/src/async.c @@ -63,7 +63,7 @@ void fastd_async_init(void) { /** Handles a DNS resolver response */ static void handle_resolve_return(const fastd_async_resolve_return_t *resolve_return) { fastd_peer_t *peer = fastd_peer_find_by_id(resolve_return->peer_id); - if (!peer) + if (!peer || !fastd_peer_is_enabled(peer)) return; if (fastd_peer_is_dynamic(peer)) diff --git a/src/fastd.c b/src/fastd.c index 0be82c4..9be4290 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -206,16 +206,11 @@ static inline void on_post_down(void) { */ static void init_peers(void) { fastd_peer_config_t *peer_conf; - for (peer_conf = ctx.peer_configs; peer_conf; peer_conf = peer_conf->next) - conf.protocol->peer_configure(peer_conf); - for (peer_conf = ctx.peer_configs; peer_conf; peer_conf = peer_conf->next) { - bool enable = conf.protocol->peer_check(peer_conf); + conf.protocol->peer_configure(peer_conf); - if (enable && peer_conf->config_state == CONFIG_DISABLED) + if (peer_conf->config_state == CONFIG_NEW) fastd_peer_add(peer_conf); - - peer_conf->config_state = enable ? CONFIG_STATIC : CONFIG_DISABLED; } size_t i; @@ -229,10 +224,13 @@ static void init_peers(void) { } } else { - if (peer->config->config_state == CONFIG_DISABLED) { - pr_info("previously enabled peer %P disabled, deleting.", peer); - fastd_peer_delete(peer); - continue; + fastd_peer_config_state_t state = conf.protocol->peer_check(peer->config) ? CONFIG_STATIC : CONFIG_DISABLED; + if (state != peer->config->config_state) { + if (peer->config->config_state != CONFIG_NEW) + pr_info("peer %P is %s now.", peer, (state == CONFIG_DISABLED) ? "disabled" : "enabled"); + + peer->config->config_state = state; + fastd_peer_reset(peer); } } @@ -258,6 +256,9 @@ static void dump_state(void) { for (i = 0; i < VECTOR_LEN(ctx.peers); i++) { fastd_peer_t *peer = VECTOR_INDEX(ctx.peers, i); + if (!fastd_peer_is_enabled(peer)) + continue; + if (!fastd_peer_is_established(peer)) { pr_info("peer %P not connected, address: %I", peer, &peer->address); continue; diff --git a/src/peer.c b/src/peer.c index 8609894..19b10d8 100644 --- a/src/peer.c +++ b/src/peer.c @@ -136,7 +136,7 @@ static int peer_id_cmp(fastd_peer_t *const *a, fastd_peer_t *const *b) { } /** Finds the entry for a peer with a specified ID in the array \e ctx.peers */ -static fastd_peer_t** peer_p_find_by_id(uint64_t id) { +static fastd_peer_t ** peer_p_find_by_id(uint64_t id) { fastd_peer_t key = {.id = id}; fastd_peer_t *const keyp = &key; @@ -304,6 +304,11 @@ static bool is_peer_in_group(const fastd_peer_t *peer, const fastd_peer_group_t After a call to reset_peer a peer must be deleted by delete_peer or re-initialized by setup_peer. */ static void reset_peer(fastd_peer_t *peer) { + if (peer->state == STATE_INACTIVE) + return; + + pr_debug("resetting peer %P", peer); + if (fastd_peer_is_established(peer)) { on_disestablish(peer); pr_info("connection with %P disestablished.", peer); @@ -311,8 +316,6 @@ static void reset_peer(fastd_peer_t *peer) { free_socket(peer); - memset(&peer->local_address, 0, sizeof(peer->local_address)); - conf.protocol->reset_peer_state(peer); size_t i, deleted = 0; @@ -328,6 +331,12 @@ static void reset_peer(fastd_peer_t *peer) { VECTOR_RESIZE(ctx.eth_addrs, VECTOR_LEN(ctx.eth_addrs)-deleted); fastd_peer_unschedule_handshake(peer); + + fastd_peer_hashtable_remove(peer); + + peer->address.sa.sa_family = AF_UNSPEC; + peer->local_address.sa.sa_family = AF_UNSPEC; + peer->state = STATE_INACTIVE; } /** @@ -367,13 +376,6 @@ static inline bool has_remote_hostname(const fastd_remote_t *remote) { /** Initializes a peer */ static void setup_peer(fastd_peer_t *peer) { - fastd_peer_hashtable_remove(peer); - peer->address.sa.sa_family = AF_UNSPEC; - - peer->local_address.sa.sa_family = AF_UNSPEC; - - peer->state = STATE_INIT; - if (VECTOR_LEN(peer->remotes) == 0) { peer->next_remote = -1; } @@ -393,6 +395,10 @@ static void setup_peer(fastd_peer_t *peer) { peer->establish_handshake_timeout = ctx.now; + if (!fastd_peer_is_enabled(peer)) + /* Keep the peer in STATE_INACTIVE */ + return; + if (!peer->protocol_state) conf.protocol->init_peer_state(peer); @@ -409,6 +415,9 @@ static void setup_peer(fastd_peer_t *peer) { init_handshake(peer); } } + else { + peer->state = STATE_PASSIVE; + } } /** Frees a peer */ @@ -599,6 +608,9 @@ bool fastd_peer_claim_address(fastd_peer_t *new_peer, fastd_socket_t *sock, cons if (peer == new_peer) continue; + if (!fastd_peer_is_enabled(peer)) + continue; + if (fastd_peer_owns_address(peer, remote_addr)) { reset_peer_address(new_peer); return false; @@ -667,8 +679,6 @@ bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_ /** Resets and re-initializes a peer */ void fastd_peer_reset(fastd_peer_t *peer) { - pr_debug("resetting peer %P", peer); - reset_peer(peer); setup_peer(peer); } diff --git a/src/peer.h b/src/peer.h index eec7bb0..f1187d8 100644 --- a/src/peer.h +++ b/src/peer.h @@ -37,7 +37,8 @@ /** The state of a peer */ typedef enum fastd_peer_state { - STATE_INIT = 0, /**< The peer peer was just created */ + STATE_INACTIVE = 0, /**< The peer is not active at the moment */ + STATE_PASSIVE, /**< The peer is waiting for incoming connections */ STATE_RESOLVING, /**< The peer is currently resolving its first remote */ STATE_HANDSHAKE, /**< The peer has tried to perform a handshake */ STATE_ESTABLISHED, /**< The peer has established a connection */ @@ -45,8 +46,9 @@ typedef enum fastd_peer_state { /** The config state of a peer */ typedef enum fastd_peer_config_state { - CONFIG_DISABLED = 0, /**< The peer is configured statically, but has been not yet been enabled or disabled because of a configuration error */ + CONFIG_NEW = 0, /**< The peer is configured statically, but has been not been enabled yet */ CONFIG_STATIC, /**< The peer is configured statically */ + CONFIG_DISABLED, /**< The peer is configured statically, but has been disabled because of a configuration error */ #ifdef WITH_DYNAMIC_PEERS CONFIG_DYNAMIC, /**< The peer is configured dynamically (using a on-verify handler) */ #endif @@ -245,6 +247,19 @@ static inline bool fastd_peer_is_dynamic(const fastd_peer_t *peer UNUSED) { #endif } +/** Checks if a peer is enabled */ +static inline bool fastd_peer_is_enabled(const fastd_peer_t *peer) { + switch (peer->config->config_state) { + case CONFIG_STATIC: +#ifdef WITH_DYNAMIC_PEERS + case CONFIG_DYNAMIC: +#endif + return true; + default: + return false; + } +} + /** Returns the currently active remote entry */ static inline fastd_remote_t * fastd_peer_get_next_remote(fastd_peer_t *peer) { if (peer->next_remote < 0) diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c index 498a6fd..86f9f9e 100644 --- a/src/protocols/ec25519_fhmqvc/handshake.c +++ b/src/protocols/ec25519_fhmqvc/handshake.c @@ -439,6 +439,9 @@ static fastd_peer_t* find_sender_key(const fastd_peer_address_t *address, const for (i = 0; i < VECTOR_LEN(ctx.peers); i++) { fastd_peer_t *peer = VECTOR_INDEX(ctx.peers, i); + if (!fastd_peer_is_enabled(peer)) + continue; + if (memcmp(&peer->config->protocol_config->public_key, key, PUBLICKEYBYTES) == 0) { if (!fastd_peer_matches_address(peer, address)) { errno = EPERM; -- cgit v1.2.3