X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fnet.c;h=1e04bc9ae685a9c0c100a18d6ac9ac2477cb6183;hb=89d675c474a6717d9daa8b5d9ff2c0f2c03666f9;hp=9659a8f26236f19b8e0e7d8859744d5a7dd38673;hpb=1bcadbde8302683f9803129f847ded42a4f66d27;p=meshlink diff --git a/src/net.c b/src/net.c index 9659a8f2..1e04bc9a 100644 --- a/src/net.c +++ b/src/net.c @@ -33,9 +33,11 @@ #include +#if !defined(min) static const int min(int a, int b) { return a < b ? a : b; } +#endif /* Terminate a connection: @@ -131,8 +133,8 @@ static void timeout_handler(event_loop_t *loop, void *data) { timeout_set(&mesh->loop, data, &(struct timeval){mesh->pingtimeout, rand() % 100000}); } -// devclass asc, last_connect_try desc -static int node_compare_devclass_asc_last_connect_try_desc(const void *a, const void *b) +// devclass asc, last_successfull_connection desc +static int node_compare_devclass_asc_lsc_desc(const void *a, const void *b) { const node_t *na = a, *nb = b; @@ -142,30 +144,42 @@ static int node_compare_devclass_asc_last_connect_try_desc(const void *a, const if(na->devclass > nb->devclass) { return 1; } - if(na->last_connect_try == nb->last_connect_try) + if(na->last_successfull_connection == nb->last_successfull_connection) return 0; - if(nb->last_connect_try == 0 || na->last_connect_try < nb->last_connect_try) + if(na->last_successfull_connection == 0 || na->last_successfull_connection > nb->last_successfull_connection) + return -1; + + if(nb->last_successfull_connection == 0 || na->last_successfull_connection < nb->last_successfull_connection) + return 1; + + if(na < nb) return -1; - if(na->last_connect_try == 0 || na->last_connect_try > nb->last_connect_try) + if(na > nb) return 1; return 0; } -// last_connect_try desc -static int node_compare_last_connect_try_desc(const void *a, const void *b) +// last_successfull_connection desc +static int node_compare_lsc_desc(const void *a, const void *b) { const node_t *na = a, *nb = b; - if(na->last_connect_try == nb->last_connect_try) + if(na->last_successfull_connection == nb->last_successfull_connection) return 0; - if(nb->last_connect_try == 0 || na->last_connect_try < nb->last_connect_try) + if(na->last_successfull_connection == 0 || na->last_successfull_connection > nb->last_successfull_connection) + return -1; + + if(nb->last_successfull_connection == 0 || na->last_successfull_connection < nb->last_successfull_connection) + return 1; + + if(na < nb) return -1; - if(na->last_connect_try == 0 || na->last_connect_try > nb->last_connect_try) + if(na > nb) return 1; return 0; @@ -182,13 +196,18 @@ static int node_compare_devclass_desc(const void *a, const void *b) if(na->devclass > nb->devclass) { return 1; } + if(na < nb) + return -1; + + if(na > nb) + return 1; + return 0; } /* - autoconnect() { timeout = 5 @@ -278,8 +297,7 @@ disconnect } - - */ +*/ static void periodic_handler(event_loop_t *loop, void *data) { @@ -311,11 +329,15 @@ static void periodic_handler(event_loop_t *loop, void *data) { if(mesh->nodes->count > 1) { - logger(mesh, MESHLINK_INFO, "--- autoconnect begin ---"); - + logger(mesh, MESHLINK_DEBUG, "--- autoconnect begin ---"); int retry_timeout = min(mesh->nodes->count * 5, 60); + logger(mesh, MESHLINK_DEBUG, "* devclass = %d", mesh->devclass); + logger(mesh, MESHLINK_DEBUG, "* nodes = %d", mesh->nodes->count); + logger(mesh, MESHLINK_DEBUG, "* retry_timeout = %d", retry_timeout); + + // connect disconnect nodes node_t* connect_to = NULL; @@ -328,14 +350,14 @@ static void periodic_handler(event_loop_t *loop, void *data) { for list_each(connection_t, c, mesh->connections) { - if(!c->status.remove_unused) + if(c->status.active) { cur_connects += 1; } } - logger(mesh, MESHLINK_INFO, "* cur_connects = %d", cur_connects); - + logger(mesh, MESHLINK_DEBUG, "* cur_connects = %d", cur_connects); + logger(mesh, MESHLINK_DEBUG, "* outgoings = %d", mesh->outgoings->count); // get min_connects and max_connects @@ -344,29 +366,32 @@ static void periodic_handler(event_loop_t *loop, void *data) { int min_connects = dev_class_traits[mesh->devclass].min_connects; int max_connects = dev_class_traits[mesh->devclass].max_connects; - logger(mesh, MESHLINK_INFO, "* min_connects = %d", min_connects); - logger(mesh, MESHLINK_INFO, "* max_connects = %d", max_connects); + logger(mesh, MESHLINK_DEBUG, "* min_connects = %d", min_connects); + logger(mesh, MESHLINK_DEBUG, "* max_connects = %d", max_connects); // find the best one for initial connect if(cur_connects < min_connects) { - splay_tree_t *nodes = splay_alloc_tree(node_compare_devclass_asc_last_connect_try_desc, NULL); + splay_tree_t *nodes = splay_alloc_tree(node_compare_devclass_asc_lsc_desc, NULL); for splay_each(node_t, n, mesh->nodes) { - if(n->devclass <= mesh->devclass && !n->connection && (n->last_connect_try == 0 || (time(NULL) - n->last_connect_try) > retry_timeout)) + logger(mesh, MESHLINK_DEBUG, "* n->devclass = %d", n->devclass); + if(n != mesh->self && n->devclass <= mesh->devclass && !n->connection && (n->last_connect_try == 0 || (time(NULL) - n->last_connect_try) > retry_timeout)) { splay_insert(nodes, n); } } if(nodes->head) { - logger(mesh, MESHLINK_INFO, "* found best one for initial connect"); + logger(mesh, MESHLINK_DEBUG, "* found best one for initial connect"); //timeout = 0; connect_to = (node_t*)nodes->head->data; } + else + { logger(mesh, MESHLINK_DEBUG, "* could not find node for initial connect"); } splay_free_tree(nodes); } @@ -374,7 +399,7 @@ static void periodic_handler(event_loop_t *loop, void *data) { // find better nodes to connect to - if(!connect_to && min_connects <= cur_connects < max_connects) + if(!connect_to && min_connects <= cur_connects && cur_connects < max_connects) { unsigned int connects = 0; @@ -382,23 +407,23 @@ static void periodic_handler(event_loop_t *loop, void *data) { { for list_each(connection_t, c, mesh->connections) { - if(!c->status.remove_unused && c->node && c->node->devclass == devclass) + if(c->status.active && c->node && c->node->devclass == devclass) { connects += 1; } } if( connects < min_connects ) { - splay_tree_t *nodes = splay_alloc_tree(node_compare_last_connect_try_desc, NULL); + splay_tree_t *nodes = splay_alloc_tree(node_compare_lsc_desc, NULL); for splay_each(node_t, n, mesh->nodes) { - if(n->devclass == devclass && !n->connection && (n->last_connect_try == 0 || (time(NULL) - n->last_connect_try) > retry_timeout)) + if(n != mesh->self && n->devclass == devclass && !n->connection && (n->last_connect_try == 0 || (time(NULL) - n->last_connect_try) > retry_timeout)) { splay_insert(nodes, n); } } if(nodes->head) { - logger(mesh, MESHLINK_INFO, "* found better node"); + logger(mesh, MESHLINK_DEBUG, "* found better node"); connect_to = (node_t*)nodes->head->data; splay_free_tree(nodes); @@ -410,26 +435,31 @@ static void periodic_handler(event_loop_t *loop, void *data) { else { break; } } + + if(!connect_to) + { logger(mesh, MESHLINK_DEBUG, "* could not find better nodes"); } } // heal partitions - if(!connect_to && min_connects <= cur_connects < max_connects) + if(!connect_to && min_connects <= cur_connects && cur_connects < max_connects) { - splay_tree_t *nodes = splay_alloc_tree(node_compare_devclass_asc_last_connect_try_desc, NULL); + splay_tree_t *nodes = splay_alloc_tree(node_compare_devclass_asc_lsc_desc, NULL); for splay_each(node_t, n, mesh->nodes) { - if(n->devclass <= mesh->devclass && !n->status.reachable && (n->last_connect_try == 0 || (time(NULL) - n->last_connect_try) > retry_timeout)) + if(n != mesh->self && n->devclass <= mesh->devclass && !n->status.reachable && (n->last_connect_try == 0 || (time(NULL) - n->last_connect_try) > retry_timeout)) { splay_insert(nodes, n); } } if(nodes->head) { - logger(mesh, MESHLINK_INFO, "* try to heal partition"); + logger(mesh, MESHLINK_DEBUG, "* try to heal partition"); connect_to = (node_t*)nodes->head->data; } + else + { logger(mesh, MESHLINK_DEBUG, "* could not find nodes for partition healing"); } splay_free_tree(nodes); } @@ -439,18 +469,36 @@ static void periodic_handler(event_loop_t *loop, void *data) { if(connect_to && !connect_to->connection) { - logger(mesh, MESHLINK_INFO, "Autoconnecting to %s", connect_to->name); - outgoing_t *outgoing = xzalloc(sizeof(outgoing_t)); - outgoing->mesh = mesh; - outgoing->name = xstrdup(connect_to->name); - list_insert_tail(mesh->outgoings, outgoing); - setup_outgoing_connection(mesh, outgoing); + connect_to->last_connect_try = time(NULL); + + /* check if there is already a connection attempt to this node */ + bool found = false; + for list_each(outgoing_t, outgoing, mesh->outgoings) + { + if(!strcmp(outgoing->name, connect_to->name)) + { + found = true; + break; + } + } + + if(!found) + { + logger(mesh, MESHLINK_DEBUG, "Autoconnecting to %s", connect_to->name); + outgoing_t *outgoing = xzalloc(sizeof(outgoing_t)); + outgoing->mesh = mesh; + outgoing->name = xstrdup(connect_to->name); + list_insert_tail(mesh->outgoings, outgoing); + setup_outgoing_connection(mesh, outgoing); + } + else + { logger(mesh, MESHLINK_DEBUG, "* skip autoconnect since it is an outgoing connection already"); } } // disconnect suboptimal outgoing connections - if(min_connects < cur_connects <= max_connects) + if(min_connects < cur_connects /*&& cur_connects <= max_connects*/) { unsigned int connects = 0; @@ -458,7 +506,7 @@ static void periodic_handler(event_loop_t *loop, void *data) { { for list_each(connection_t, c, mesh->connections) { - if(!c->status.remove_unused && c->node && c->node->devclass == devclass) + if(c->status.active && c->node && c->node->devclass == devclass) { connects += 1; } } @@ -468,13 +516,13 @@ static void periodic_handler(event_loop_t *loop, void *data) { for list_each(connection_t, c, mesh->connections) { - if(!c->status.remove_unused && c->outgoing && c->node && c->node->devclass >= devclass) + if(c->outgoing && c->node && c->node->devclass >= devclass) { splay_insert(nodes, c->node); } } if(nodes->head) { - logger(mesh, MESHLINK_INFO, "* disconnect suboptimal outgoing connection"); + logger(mesh, MESHLINK_DEBUG, "* disconnect suboptimal outgoing connection"); disconnect_from = (node_t*)nodes->head->data; } @@ -482,6 +530,9 @@ static void periodic_handler(event_loop_t *loop, void *data) { break; } } + + if(!disconnect_from) + { logger(mesh, MESHLINK_DEBUG, "* no suboptimal outgoing connections"); } } @@ -493,17 +544,19 @@ static void periodic_handler(event_loop_t *loop, void *data) { for list_each(connection_t, c, mesh->connections) { - if(!c->status.remove_unused && c->node) + if(c->status.active && c->node) { splay_insert(nodes, c->node); } } if(nodes->head) { - logger(mesh, MESHLINK_INFO, "* disconnect connection (too many connections"); + logger(mesh, MESHLINK_DEBUG, "* disconnect connection (too many connections)"); //timeout = 0; disconnect_from = (node_t*)nodes->head->data; } + else + { logger(mesh, MESHLINK_DEBUG, "* no node we want to disconnect, even though we have too many connections"); } splay_free_tree(nodes); } @@ -513,7 +566,7 @@ static void periodic_handler(event_loop_t *loop, void *data) { if(disconnect_from && disconnect_from->connection) { - logger(mesh, MESHLINK_INFO, "Autodisconnecting from %s", disconnect_from->connection->name); + logger(mesh, MESHLINK_DEBUG, "Autodisconnecting from %s", disconnect_from->connection->name); list_delete(mesh->outgoings, disconnect_from->connection->outgoing); disconnect_from->connection->outgoing = NULL; terminate_connection(mesh, disconnect_from->connection, disconnect_from->connection->status.active); @@ -522,7 +575,7 @@ static void periodic_handler(event_loop_t *loop, void *data) { // done! - logger(mesh, MESHLINK_INFO, "--- autoconnect end ---"); + logger(mesh, MESHLINK_DEBUG, "--- autoconnect end ---"); } timeout_set(&mesh->loop, data, &(struct timeval){timeout, rand() % 100000}); @@ -564,7 +617,7 @@ int main_loop(meshlink_handle_t *mesh) { mesh->datafromapp.signum = 0; signal_add(&(mesh->loop),&(mesh->datafromapp), (signal_cb_t)meshlink_send_from_queue,mesh, mesh->datafromapp.signum); - if(!event_loop_run(&mesh->loop)) { + if(!event_loop_run(&(mesh->loop), &(mesh->mesh_mutex))) { logger(mesh, MESHLINK_ERROR, "Error while waiting for input: %s", strerror(errno)); return 1; }