diff --git a/src/net.c b/src/net.c index 1167b908..d1c3569a 100644 --- a/src/net.c +++ b/src/net.c @@ -209,15 +209,14 @@ 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; - int i = 0; + splay_tree_t *tmp_node_tree; + + tmp_node_tree = splay_alloc_tree((splay_compare_t) node_compare, NULL); for splay_each(node_t, n, node_tree) { - if(i++ != r) - continue; - if(n->connection) - break; + if(!n->status.has_known_address || n->connection) + continue; bool found = false; @@ -227,16 +226,26 @@ static void periodic_handler(void *data) { break; } } - - if(!found) { - logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); - outgoing_t *outgoing = xzalloc(sizeof *outgoing); - outgoing->name = xstrdup(n->name); - list_insert_tail(outgoing_list, outgoing); - setup_outgoing_connection(outgoing); + if (!found) + splay_insert(tmp_node_tree, n); } - break; + + int r = rand() % tmp_node_tree->count; + int i = 0; + + for splay_each(node_t, n, tmp_node_tree) { + + if(i++ != r) + continue; + + + logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); + outgoing_t *outgoing = xzalloc(sizeof *outgoing); + outgoing->name = xstrdup(n->name); + list_insert_tail(outgoing_list, outgoing); + setup_outgoing_connection(outgoing); } + splay_delete_tree(tmp_node_tree); } else if(nc > 3) { /* Too many active connections, try to remove one. Choose a random outgoing connection to a node diff --git a/src/net_setup.c b/src/net_setup.c index 09580739..63853de5 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -398,6 +398,9 @@ void load_all_subnets(void) { } } + if (lookup_config(config_tree, "Address")) + n->status.has_known_address = true; + exit_configuration(&config_tree); } diff --git a/src/node.c b/src/node.c index e3fbeeda..9597aaf8 100644 --- a/src/node.c +++ b/src/node.c @@ -39,7 +39,7 @@ static hash_t *node_id_cache; node_t *myself; -static int node_compare(const node_t *a, const node_t *b) { +int node_compare(const node_t *a, const node_t *b) { return strcmp(a->name, b->name); } @@ -175,6 +175,9 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) { free(n->hostname); n->hostname = sockaddr2hostname(&n->address); logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname); + n->status.has_known_address = true; + } else { + n->status.has_known_address = false; } /* invalidate UDP information - note that this is a security feature as well to make sure diff --git a/src/node.h b/src/node.h index 02e2a6d6..73170226 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 if we have sent a valid key to him */ - unsigned int unused:22; + unsigned int has_known_address; /* 1 if this node has Address in node's config */ + unsigned int unused:21; } node_status_t; typedef struct node_t { @@ -116,6 +117,7 @@ extern splay_tree_t *node_tree; extern void init_nodes(void); extern void exit_nodes(void); +extern int node_compare(const node_t *, const node_t *); extern node_t *new_node(void) __attribute__ ((__malloc__)); extern void free_node(node_t *); extern void node_add(node_t *);