Merge branch 'master' of black:tinc
[tinc] / src / net.c
index c2f7022..ea4bbcf 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -50,6 +50,7 @@ bool graph_dump = false;
 time_t now = 0;
 int contradicting_add_edge = 0;
 int contradicting_del_edge = 0;
+static int sleeptime = 10;
 
 /* Purge edges and subnets of unreachable nodes. Use carefully. */
 
@@ -288,7 +289,7 @@ static void check_network_activity(fd_set * readset, fd_set * writeset) {
 
        /* check input from kernel */
        if(device_fd >= 0 && FD_ISSET(device_fd, readset)) {
-               if(read_packet(&packet)) {
+               if(devops.read(&packet)) {
                        errors = 0;
                        packet.priority = 0;
                        route(myself, &packet);
@@ -464,18 +465,25 @@ int main_loop(void) {
                                keyexpires = now + keylifetime;
                        }
 
-                       if(contradicting_del_edge > 10 && contradicting_add_edge > 10) {
-                               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!");
-                                       running = false;
-                                       break;
-                               }
-
-                               contradicting_add_edge = 0;
-                               contradicting_del_edge = 0;
+                       /* Detect ADD_EDGE/DEL_EDGE storms that are caused when
+                        * two tinc daemons with the same name are on the VPN.
+                        * If so, sleep a while. If this happens multiple times
+                        * in a row, sleep longer. */
+
+                       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;
                }
 
                if(sigalrm) {
@@ -501,6 +509,8 @@ int main_loop(void) {
                        struct stat s;
                        
                        sighup = false;
+
+                       reopenlogger();
                        
                        /* Reread our own configuration file */