AutoConnect now only chooses from nodes for which we know an address.

Based partially on work from Rafał Leśniak.
This commit is contained in:
Guus Sliepen 2016-04-30 20:05:22 +02:00
parent 0b6f84f96e
commit 2055c3e21d
6 changed files with 56 additions and 78 deletions

2
NEWS
View file

@ -21,7 +21,7 @@
* Initial support for generating a tinc-up script from an invitation. * Initial support for generating a tinc-up script from an invitation.
* Many small fixes, documentation updates. * 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, Sven-Haegar Koch, Florian Klink, LunnarShadow, Dato Simó, Jo-Philipp Wich,
Jochen Voss, Nathan Stratton Treadway, Pierre Emeriaud, xentec, Samuel Jochen Voss, Nathan Stratton Treadway, Pierre Emeriaud, xentec, Samuel
Thibault and Michael Tokarev for their contributions to this version of tinc. Thibault and Michael Tokarev for their contributions to this version of tinc.

1
THANKS
View file

@ -84,7 +84,6 @@ We would like to thank the following people for their contributions to tinc:
* Sven-Haegar Koch * Sven-Haegar Koch
* Teemu Kiviniemi * Teemu Kiviniemi
* Thomas Tsiakalakis * Thomas Tsiakalakis
* thorkill
* Timothy Redaelli * Timothy Redaelli
* Tomasz Fortuna * Tomasz Fortuna
* Tomislav Čohar * Tomislav Čohar

View file

@ -210,19 +210,25 @@ static void periodic_handler(void *data) {
and we are not already trying to make one, create an and we are not already trying to make one, create an
outgoing connection to this node. outgoing connection to this node.
*/ */
int r = rand() % (node_tree->count - 1); int count = 0;
int i = 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) { for splay_each(node_t, n, node_tree) {
if(n == myself) if(n == myself || n->connection || !(n->status.has_address || n->status.reachable))
continue; continue;
if(i++ != r) if(r--)
continue; continue;
if(n->connection)
break;
bool found = false; bool found = false;
for list_each(outgoing_t, outgoing, outgoing_list) { for list_each(outgoing_t, outgoing, outgoing_list) {
@ -239,6 +245,7 @@ static void periodic_handler(void *data) {
list_insert_tail(outgoing_list, outgoing); list_insert_tail(outgoing_list, outgoing);
setup_outgoing_connection(outgoing); setup_outgoing_connection(outgoing);
} }
break; break;
} }
} else if(nc > 3) { } else if(nc > 3) {
@ -287,6 +294,7 @@ static void periodic_handler(void *data) {
} }
} }
end:
timeout_set(data, &(struct timeval){5, rand() % 100000}); timeout_set(data, &(struct timeval){5, rand() % 100000});
} }
@ -344,9 +352,14 @@ int reload_configuration(void) {
for splay_each(subnet_t, subnet, subnet_tree) for splay_each(subnet_t, subnet, subnet_tree)
if (subnet->owner) if (subnet->owner)
subnet->expires = 1; 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) { for splay_each(subnet_t, subnet, subnet_tree) {
if (!subnet->owner) if (!subnet->owner)
continue; continue;

View file

@ -217,7 +217,6 @@ extern void regenerate_key(void);
extern void purge(void); extern void purge(void);
extern void retry(void); extern void retry(void);
extern int reload_configuration(void); extern int reload_configuration(void);
extern void load_all_subnets(void);
extern void load_all_nodes(void); extern void load_all_nodes(void);
extern void try_tx(struct node_t *n, bool); extern void try_tx(struct node_t *n, bool);

View file

@ -324,62 +324,6 @@ void regenerate_key(void) {
n->status.validkey_in = false; 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) { void load_all_nodes(void) {
DIR *dir; DIR *dir;
struct dirent *ent; struct dirent *ent;
@ -397,17 +341,42 @@ void load_all_nodes(void) {
continue; continue;
node_t *n = lookup_node(ent->d_name); node_t *n = lookup_node(ent->d_name);
if(n)
continue;
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 = new_node();
n->name = xstrdup(ent->d_name); n->name = xstrdup(ent->d_name);
node_add(n); node_add(n);
} }
closedir(dir); 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 *get_name(void) {
char *name = NULL; char *name = NULL;
@ -947,9 +916,6 @@ static bool setup_myself(void) {
graph(); graph();
if(strictsubnets)
load_all_subnets();
else if(autoconnect)
load_all_nodes(); load_all_nodes();
/* Open device */ /* Open device */

View file

@ -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 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 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 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; } node_status_t;
typedef struct node_t { typedef struct node_t {