Never delete Subnets when StrictSubnets is set
[oweals/tinc.git] / src / net.c
index 7f1f77b38b192ea2e14db8b1a5afe300a6333371..6ffd9989d5d4356e6e83c1e3cc08edfa20e16b08 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -1,7 +1,8 @@
 /*
     net.c -- most of the network code
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2006      Scott Lamb <slamb@slamb.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -67,9 +68,9 @@ static void purge(void) {
                        for(snode = n->subnet_tree->head; snode; snode = snext) {
                                snext = snode->next;
                                s = snode->data;
-                               if(!tunnelserver)
-                                       send_del_subnet(broadcast, s);
-                               subnet_del(n, s);
+                               send_del_subnet(broadcast, s);
+                               if(!strictsubnets)
+                                       subnet_del(n, s);
                        }
 
                        for(enode = n->edge_tree->head; enode; enode = enext) {
@@ -97,7 +98,8 @@ static void purge(void) {
                                        break;
                        }
 
-                       if(!enode)
+                       if(!enode && (!strictsubnets || !n->subnet_tree->head))
+                               /* in strictsubnets mode do not delete nodes with subnets */
                                node_del(n);
                }
        }
@@ -302,7 +304,7 @@ static void check_network_activity(fd_set * readset, fd_set * writeset) {
                                else {
                                        ifdebug(CONNECTIONS) logger(LOG_DEBUG,
                                                           "Error while connecting to %s (%s): %s",
-                                                          c->name, c->hostname, strerror(result));
+                                                          c->name, c->hostname, sockstrerror(result));
                                        closesocket(c->socket);
                                        do_outgoing_connection(c);
                                        continue;
@@ -368,17 +370,15 @@ int main_loop(void) {
 #endif
 
                if(r < 0) {
-                       if(errno != EINTR && errno != EAGAIN) {
-                               logger(LOG_ERR, "Error while waiting for input: %s",
-                                          strerror(errno));
+                       if(!sockwouldblock(sockerrno)) {
+                               logger(LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
                                dump_connections();
                                return 1;
                        }
-
-                       continue;
                }
 
-               check_network_activity(&readset, &writeset);
+               if(r > 0)
+                       check_network_activity(&readset, &writeset);
 
                if(do_purge) {
                        purge();
@@ -418,8 +418,13 @@ int main_loop(void) {
                }
 
                if(sigalrm) {
+                       avl_node_t *node;
                        logger(LOG_INFO, "Flushing event queue");
                        expire_events();
+                       for(node = connection_tree->head; node; node = node->next) {
+                               connection_t *c = node->data;
+                               send_ping(c);
+                       }
                        sigalrm = false;
                }
 
@@ -430,7 +435,7 @@ int main_loop(void) {
 
                if(sighup) {
                        connection_t *c;
-                       avl_node_t *node;
+                       avl_node_t *node, *next;
                        char *fname;
                        struct stat s;
                        
@@ -446,6 +451,31 @@ int main_loop(void) {
                                return 1;
                        }
 
+                       /* Cancel non-active outgoing connections */
+
+                       for(node = connection_tree->head; node; node = next) {
+                               next = node->next;
+                               c = node->data;
+
+                               c->outgoing = NULL;
+
+                               if(c->status.connecting) {
+                                       terminate_connection(c, false);
+                                       connection_del(c);
+                               }
+                       }
+
+                       /* Wipe list of outgoing connections */
+
+                       for(list_node_t *node = outgoing_list->head; node; node = node->next) {
+                               outgoing_t *outgoing = node->data;
+
+                               if(outgoing->event)
+                                       event_del(outgoing->event);
+                       }
+
+                       list_delete_list(outgoing_list);
+
                        /* Close connections to hosts that have a changed or deleted host config file */
                        
                        for(node = connection_tree->head; node; node = node->next) {