Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
[tinc] / src / net.c
index 7ce4f31..336bf9e 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -39,6 +39,7 @@
 
 int contradicting_add_edge = 0;
 int contradicting_del_edge = 0;
+static int sleeptime = 10;
 
 /* Purge edges and subnets of unreachable nodes. Use carefully. */
 
@@ -63,7 +64,7 @@ void purge(void) {
                        for(snode = n->subnet_tree->head; snode; snode = snext) {
                                snext = snode->next;
                                s = snode->data;
-                               send_del_subnet(broadcast, s);
+                               send_del_subnet(everyone, s);
                                if(!strictsubnets)
                                        subnet_del(n, s);
                        }
@@ -72,7 +73,7 @@ void purge(void) {
                                enext = enode->next;
                                e = enode->data;
                                if(!tunnelserver)
-                                       send_del_edge(broadcast, e);
+                                       send_del_edge(everyone, e);
                                edge_del(e);
                        }
                }
@@ -116,12 +117,9 @@ void terminate_connection(connection_t *c, bool report) {
        if(c->node)
                c->node->connection = NULL;
 
-       if(c->socket)
-               closesocket(c->socket);
-
        if(c->edge) {
                if(report && !tunnelserver)
-                       send_del_edge(broadcast, c->edge);
+                       send_del_edge(everyone, c->edge);
 
                edge_del(c->edge);
 
@@ -136,7 +134,7 @@ void terminate_connection(connection_t *c, bool report) {
                        e = lookup_edge(c->node, myself);
                        if(e) {
                                if(!tunnelserver)
-                                       send_del_edge(broadcast, e);
+                                       send_del_edge(everyone, e);
                                edge_del(e);
                        }
                }
@@ -193,19 +191,21 @@ static void timeout_handler(int fd, short events, void *event) {
                }
        }
 
-       if(contradicting_del_edge && contradicting_add_edge) {
-               logger(LOG_WARNING, "Possible node with same Name as us!");
-
-               if(rand() % 3 == 0) {
-                       logger(LOG_ERR, "Shutting down, check configuration of all nodes for duplicate Names!");
-                       event_loopexit(NULL);
-                       return;
-               }
-
-               contradicting_add_edge = 0;
-               contradicting_del_edge = 0;
+       if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
+               logger(LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
+               usleep(sleeptime * 1000000LL);
+               sleeptime *= 2;
+               if(sleeptime < 0)
+                       sleeptime = 3600;
+       } else {
+               sleeptime /= 2;
+               if(sleeptime < 10)
+                       sleeptime = 10;
        }
 
+       contradicting_add_edge = 0;
+       contradicting_del_edge = 0;
+
        event_add(event, &(struct timeval){pingtimeout, 0});
 }
 
@@ -310,14 +310,14 @@ int reload_configuration(void) {
                        next = node->next;
                        subnet = node->data;
                        if(subnet->expires == 1) {
-                               send_del_subnet(broadcast, subnet);
+                               send_del_subnet(everyone, subnet);
                                if(subnet->owner->status.reachable)
                                        subnet_update(subnet->owner, subnet, false);
                                subnet_del(subnet->owner, subnet);
                        } else if(subnet->expires == -1) {
                                subnet->expires = 0;
                        } else {
-                               send_add_subnet(broadcast, subnet);
+                               send_add_subnet(everyone, subnet);
                                if(subnet->owner->status.reachable)
                                        subnet_update(subnet->owner, subnet, true);
                        }