TunnelServer: Don't disconnect client on DEL_SUBNET too
authorMichael Tokarev <mjt@corpit.ru>
Wed, 20 May 2009 14:40:04 +0000 (18:40 +0400)
committerGuus Sliepen <guus@tinc-vpn.org>
Wed, 20 May 2009 18:16:19 +0000 (20:16 +0200)
Similar changes as was in 2327d3f6eb5982bcc922ff1ab1ec436ba6aeffdc
but for del_subnet_h().

Before, we vere returning false (and causing disconnect of the
client) in case of tunnelserver and the client sending DEL_SUBNET
for non-his subnet or for subnet which owner isn't in our connection
list.

After the mentioned change to add_subnet_h() that routine does not
add such indirect owners to the connection list anymore, so that
was ok (owner == NULL and we return true).

But if we too has a connection with the node about which the client
is sending DEL_SUBNET notification, say, because that client lost
connection with that other node, we'll disconnect this client from
us too, returning false for indirect DEL_SUBNET.

Fix that by allowing and ignoring indirect DEL_SUBNET in tunnelserver
mode.

Also rearranged the function a bit, to match add_subnet_h() (in
particular, syntax-check everything first, see if we've seen this
request before).

And also fix some comments.

src/protocol_subnet.c

index 6e7d706e153171f484c829047e57c6c854bec129..3e5dadd18ece0176d819474ea1c3d326c9b6434c 100644 (file)
@@ -60,7 +60,7 @@ bool add_subnet_h(connection_t *c)
                return false;
        }
 
                return false;
        }
 
-       /* Check if owner name is valid */
+       /* Check if owner name is valid */
 
        if(!check_id(name)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
 
        if(!check_id(name)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
@@ -176,7 +176,7 @@ bool del_subnet_h(connection_t *c)
                return false;
        }
 
                return false;
        }
 
-       /* Check if owner name is valid */
+       /* Check if owner name is valid */
 
        if(!check_id(name)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
 
        if(!check_id(name)) {
                logger(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
@@ -184,19 +184,6 @@ bool del_subnet_h(connection_t *c)
                return false;
        }
 
                return false;
        }
 
-       /* Check if the owner of the new subnet is in the connection list */
-
-       owner = lookup_node(name);
-
-       if(!owner) {
-               ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which is not in our node tree"),
-                                  "DEL_SUBNET", c->name, c->hostname, name);
-               return true;
-       }
-
-       if(tunnelserver && owner != myself && owner != c->node)
-               return false;
-
        /* Check if subnet string is valid */
 
        if(!str2net(&s, subnetstr)) {
        /* Check if subnet string is valid */
 
        if(!str2net(&s, subnetstr)) {
@@ -208,6 +195,23 @@ bool del_subnet_h(connection_t *c)
        if(seen_request(c->buffer))
                return true;
 
        if(seen_request(c->buffer))
                return true;
 
+       /* Check if the owner of the subnet being deleted is in the connection list */
+
+       owner = lookup_node(name);
+
+       if(tunnelserver && owner != myself && owner != c->node) {
+               /* in case of tunnelserver, ignore indirect subnet deletion */
+               ifdebug(PROTOCOL) logger(LOG_WARNING, _("Ignoring indirect %s from %s (%s) for %s"),
+                                  "DEL_SUBNET", c->name, c->hostname, subnetstr);
+               return true;
+       }
+
+       if(!owner) {
+               ifdebug(PROTOCOL) logger(LOG_WARNING, _("Got %s from %s (%s) for %s which is not in our node tree"),
+                                  "DEL_SUBNET", c->name, c->hostname, name);
+               return true;
+       }
+
        /* If everything is correct, delete the subnet from the list of the owner */
 
        s.owner = owner;
        /* If everything is correct, delete the subnet from the list of the owner */
 
        s.owner = owner;