Never delete Subnets when StrictSubnets is set
authorSven-Haegar Koch <haegar@ccc.de>
Wed, 10 Mar 2010 01:50:51 +0000 (02:50 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 18 Mar 2010 10:50:45 +0000 (11:50 +0100)
If a node is unreachable, and not connected to an edge anymore, it gets
deleted. When this happens its subnets are also removed, which should
not happen with StrictSubnets=yes.

Solution:
- do not remove subnets in src/net.c::purge(), we know that all subnets
  in the list came from our hosts files.
  I think here you got the check wrong by looking at the tunnelserver
  code below it - with strictsubnets we still inform others but do not
  remove the subnet from our data.
- do not remove nodes in net.c::purge() that still have subnets
  attached.

src/net.c

index 309ebe4..6ffd998 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -68,9 +68,9 @@ static void purge(void) {
                        for(snode = n->subnet_tree->head; snode; snode = snext) {
                                snext = snode->next;
                                s = snode->data;
                        for(snode = n->subnet_tree->head; snode; snode = snext) {
                                snext = snode->next;
                                s = snode->data;
+                               send_del_subnet(broadcast, s);
                                if(!strictsubnets)
                                if(!strictsubnets)
-                                       send_del_subnet(broadcast, s);
-                               subnet_del(n, s);
+                                       subnet_del(n, s);
                        }
 
                        for(enode = n->edge_tree->head; enode; enode = enext) {
                        }
 
                        for(enode = n->edge_tree->head; enode; enode = enext) {
@@ -98,7 +98,8 @@ static void purge(void) {
                                        break;
                        }
 
                                        break;
                        }
 
-                       if(!enode)
+                       if(!enode && (!strictsubnets || !n->subnet_tree->head))
+                               /* in strictsubnets mode do not delete nodes with subnets */
                                node_del(n);
                }
        }
                                node_del(n);
                }
        }