From 2055c3e21d5b3f4217883d52d5e5b0fbad504785 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sat, 30 Apr 2016 20:05:22 +0200 Subject: [PATCH] AutoConnect now only chooses from nodes for which we know an address. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based partially on work from Rafał Leśniak. --- NEWS | 2 +- THANKS | 1 - src/net.c | 29 +++++++++++---- src/net.h | 1 - src/net_setup.c | 98 ++++++++++++++++--------------------------------- src/node.h | 3 +- 6 files changed, 56 insertions(+), 78 deletions(-) diff --git a/NEWS b/NEWS index bedca1c2..f49e3d3a 100644 --- a/NEWS +++ b/NEWS @@ -21,7 +21,7 @@ * Initial support for generating a tinc-up script from an invitation. * Many small fixes, documentation updates. -Thanks to Etienne Dechamps, thorkill, Vittorio Gambaletta, Martin Weinelt, +Thanks to Etienne Dechamps, Rafał Leśniak, Vittorio Gambaletta, Martin Weinelt, Sven-Haegar Koch, Florian Klink, LunnarShadow, Dato Simó, Jo-Philipp Wich, Jochen Voss, Nathan Stratton Treadway, Pierre Emeriaud, xentec, Samuel Thibault and Michael Tokarev for their contributions to this version of tinc. diff --git a/THANKS b/THANKS index 527cc61d..dfb03659 100644 --- a/THANKS +++ b/THANKS @@ -84,7 +84,6 @@ We would like to thank the following people for their contributions to tinc: * Sven-Haegar Koch * Teemu Kiviniemi * Thomas Tsiakalakis -* thorkill * Timothy Redaelli * Tomasz Fortuna * Tomislav Čohar diff --git a/src/net.c b/src/net.c index 8328db91..52c7fe3e 100644 --- a/src/net.c +++ b/src/net.c @@ -210,19 +210,25 @@ static void periodic_handler(void *data) { and we are not already trying to make one, create an outgoing connection to this node. */ - int r = rand() % (node_tree->count - 1); - int i = 0; + int count = 0; + for splay_each(node_t, n, node_tree) { + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) + continue; + count++; + } + + if(!count) + goto end; + + int r = rand() % count; for splay_each(node_t, n, node_tree) { - if(n == myself) + if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) continue; - if(i++ != r) + if(r--) continue; - if(n->connection) - break; - bool found = false; for list_each(outgoing_t, outgoing, outgoing_list) { @@ -239,6 +245,7 @@ static void periodic_handler(void *data) { list_insert_tail(outgoing_list, outgoing); setup_outgoing_connection(outgoing); } + break; } } else if(nc > 3) { @@ -287,6 +294,7 @@ static void periodic_handler(void *data) { } } +end: timeout_set(data, &(struct timeval){5, rand() % 100000}); } @@ -344,9 +352,14 @@ int reload_configuration(void) { for splay_each(subnet_t, subnet, subnet_tree) if (subnet->owner) subnet->expires = 1; + } - load_all_subnets(); + for splay_each(node_t, n, node_tree) + n->status.has_address = false; + load_all_nodes(); + + if(strictsubnets) { for splay_each(subnet_t, subnet, subnet_tree) { if (!subnet->owner) continue; diff --git a/src/net.h b/src/net.h index c3c82de3..70808695 100644 --- a/src/net.h +++ b/src/net.h @@ -217,7 +217,6 @@ extern void regenerate_key(void); extern void purge(void); extern void retry(void); extern int reload_configuration(void); -extern void load_all_subnets(void); extern void load_all_nodes(void); extern void try_tx(struct node_t *n, bool); diff --git a/src/net_setup.c b/src/net_setup.c index 30e6f848..4e1cacaf 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -324,62 +324,6 @@ void regenerate_key(void) { n->status.validkey_in = false; } -/* - Read Subnets from all host config files -*/ -void load_all_subnets(void) { - DIR *dir; - struct dirent *ent; - char dname[PATH_MAX]; - - snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); - dir = opendir(dname); - if(!dir) { - logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno)); - return; - } - - while((ent = readdir(dir))) { - if(!check_id(ent->d_name)) - continue; - - node_t *n = lookup_node(ent->d_name); - #ifdef _DIRENT_HAVE_D_TYPE - //if(ent->d_type != DT_REG) - // continue; - #endif - - splay_tree_t *config_tree; - init_configuration(&config_tree); - read_config_options(config_tree, ent->d_name); - read_host_config(config_tree, ent->d_name); - - if(!n) { - n = new_node(); - n->name = xstrdup(ent->d_name); - node_add(n); - } - - for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { - subnet_t *s, *s2; - - if(!get_config_subnet(cfg, &s)) - continue; - - if((s2 = lookup_subnet(n, s))) { - s2->expires = -1; - free(s); - } else { - subnet_add(n, s); - } - } - - exit_configuration(&config_tree); - } - - closedir(dir); -} - void load_all_nodes(void) { DIR *dir; struct dirent *ent; @@ -397,18 +341,43 @@ void load_all_nodes(void) { continue; node_t *n = lookup_node(ent->d_name); - if(n) - continue; - n = new_node(); - n->name = xstrdup(ent->d_name); - node_add(n); + splay_tree_t *config_tree; + init_configuration(&config_tree); + read_config_options(config_tree, ent->d_name); + read_host_config(config_tree, ent->d_name); + + if(!n) { + n = new_node(); + n->name = xstrdup(ent->d_name); + node_add(n); + } + + if(strictsubnets) { + for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) { + subnet_t *s, *s2; + + if(!get_config_subnet(cfg, &s)) + continue; + + if((s2 = lookup_subnet(n, s))) { + s2->expires = -1; + free(s); + } else { + subnet_add(n, s); + } + } + } + + if(lookup_config(config_tree, "Address")) + n->status.has_address = true; + + exit_configuration(&config_tree); } closedir(dir); } - char *get_name(void) { char *name = NULL; char *returned_name; @@ -947,10 +916,7 @@ static bool setup_myself(void) { graph(); - if(strictsubnets) - load_all_subnets(); - else if(autoconnect) - load_all_nodes(); + load_all_nodes(); /* Open device */ diff --git a/src/node.h b/src/node.h index 6ca6432b..b48fe88f 100644 --- a/src/node.h +++ b/src/node.h @@ -40,7 +40,8 @@ typedef struct node_status_t { unsigned int send_locally:1; /* 1 if the next UDP packet should be sent on the local network */ unsigned int udppacket:1; /* 1 if the most recently received packet was UDP */ unsigned int validkey_in:1; /* 1 if we have sent a valid key to him */ - unsigned int unused:21; + unsigned int has_address:1; /* 1 if we know an external address for this node */ + unsigned int unused:20; } node_status_t; typedef struct node_t {