]> git.meshlink.io Git - meshlink/blobdiff - src/net.c
Merge branch 'mesh_topology_output' into roles
[meshlink] / src / net.c
index 654a7813cee55fca752d9092458a9a0cd6bc9091..80e866a0ad461fc49bce1794379044ca97e2e33c 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -31,6 +31,7 @@
 #include "protocol.h"
 #include "xalloc.h"
 
+#include <assert.h>
 
 static const int min(int a, int b) {
        return a < b ? a : b;
@@ -185,6 +186,102 @@ static int node_compare_devclass_desc(const void *a, const void *b)
 }
 
 
+/*
+
+
+autoconnect()
+{
+       timeout = 5
+
+       // find the best one for initial connect
+
+       if cur < min
+               newcon =
+                       first from nodes
+                               where dclass <= my.dclass and !connection and (timestamp - last_retry) > retry_timeout
+                               order by dclass asc, last_connection desc
+               if newcon
+                       timeout = 0
+                       goto connect
+
+
+       // find better nodes to connect to: in case we have less than min connections within [BACKBONE, i] and there are nodes which we are not connected to within the range
+
+       if min <= cur < max
+               j = 0
+               for i = BACKBONE to my.dclass
+                       j += count(from connections where node.dclass = i)
+                       if j < min
+                               newcon =
+                                       first from nodes
+                                               where dclass = i and !connection and (timestamp - last_retry) > retry_timeout
+                                               order by last_connection desc
+                               if newcon
+                                       goto connect
+                       else
+                               break
+
+
+       // heal partitions
+
+       if min <= cur < max
+               newcon =
+                       first from nodes
+                               where dclass <= my.dclass and !reachable and (timestamp - last_retry) > retry_timeout
+                               order by dclass asc, last_connection desc
+               if newcon
+                       goto connect
+
+
+       // connect
+
+connect:
+       if newcon
+               connect newcon
+
+
+       // disconnect outgoing connections in case we have more than min connections within [BACKBONE, i] and there are nodes which we are connected to within the range [i, PORTABLE]
+
+       if min < cur <= max
+               j = 0
+               for i = BACKBONE to my.dclass
+                       j += count(from connections where node.dclass = i)
+                       if min < j
+                               delcon =
+                                       first from nodes
+                                               where dclass >= i and outgoing_connection
+                                               order by dclass desc
+                               if disconnect
+                                       goto disconnect
+                               else
+                                       break
+
+
+       // disconnect connections in case we have more than enough connections
+
+       if max < cur
+               delcon =
+                       first from nodes
+                               where outgoing_connection
+                               order by dclass desc
+               goto disconnect
+
+       // disconnect
+
+disconnect
+       if delcon
+               disconnect delcon
+
+
+       // next iteration
+       next (timeout, autoconnect)
+
+}
+
+
+ */
+
+
 static void periodic_handler(event_loop_t *loop, void *data) {
        meshlink_handle_t *mesh = loop->data;
 
@@ -242,6 +339,8 @@ static void periodic_handler(event_loop_t *loop, void *data) {
 
                // get min_connects and max_connects
 
+               assert(mesh->devclass >= 0 && mesh->devclass <= _DEV_CLASS_MAX);
+
                int min_connects = dev_class_traits[mesh->devclass].min_connects;
                int max_connects = dev_class_traits[mesh->devclass].max_connects;
 
@@ -265,7 +364,7 @@ static void periodic_handler(event_loop_t *loop, void *data) {
                        {
                                logger(mesh, MESHLINK_INFO, "* found best one for initial connect");
 
-                               timeout = 0;
+                               //timeout = 0;
                                connect_to = (node_t*)nodes->head->data;
                        }
 
@@ -275,7 +374,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;
 
@@ -316,7 +415,7 @@ static void periodic_handler(event_loop_t *loop, void *data) {
 
                // 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);
 
@@ -340,18 +439,30 @@ 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);
+                       /* 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_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);      
+                       }
                }
 
 
                // disconnect suboptimal outgoing connections
 
-               if(min_connects < cur_connects <= max_connects)
+               if(min_connects < cur_connects && cur_connects <= max_connects)
                {
                        unsigned int connects = 0;
 
@@ -402,7 +513,7 @@ static void periodic_handler(event_loop_t *loop, void *data) {
                        {
                                logger(mesh, MESHLINK_INFO, "* disconnect connection (too many connections");
 
-                               timeout = 0;
+                               //timeout = 0;
                                disconnect_from = (node_t*)nodes->head->data;
                        }
 
@@ -465,7 +576,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;
        }