From 698d6ddac6ab32d5a4b802941b02232793442684 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 4 Sep 2002 08:33:08 +0000 Subject: [PATCH] Prevent looping DEL_NODE/ADD_NODE messages after a node disconnects. --- src/node.h | 3 +- src/protocol.h | 4 +-- src/protocol_node.c | 67 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/node.h b/src/node.h index 174a4c1e..f2bea91b 100644 --- a/src/node.h +++ b/src/node.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: node.h,v 1.1.2.17 2002/09/03 20:43:25 guus Exp $ + $Id: node.h,v 1.1.2.18 2002/09/04 08:33:08 guus Exp $ */ #ifndef __TINC_NODE_H__ @@ -65,6 +65,7 @@ typedef struct node_t { list_t *queue; /* Queue for packets awaiting to be encrypted */ struct node_t *nexthop; /* nearest node from us to him */ + struct node_t *prevhop; /* nearest node from him to us */ struct node_t *via; /* next hop for UDP packets */ avl_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */ diff --git a/src/protocol.h b/src/protocol.h index dea2e9f0..1fd760a2 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol.h,v 1.5.4.31 2002/09/03 20:43:25 guus Exp $ + $Id: protocol.h,v 1.5.4.32 2002/09/04 08:33:08 guus Exp $ */ #ifndef __TINC_PROTOCOL_H__ @@ -31,7 +31,7 @@ incompatible version have different protocols. */ -#define PROT_CURRENT 15 +#define PROT_CURRENT 16 /* Request numbers */ diff --git a/src/protocol_node.c b/src/protocol_node.c index e407977b..c27f254d 100644 --- a/src/protocol_node.c +++ b/src/protocol_node.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol_node.c,v 1.1.4.4 2002/09/03 22:49:55 guus Exp $ + $Id: protocol_node.c,v 1.1.4.5 2002/09/04 08:33:08 guus Exp $ */ #include "config.h" @@ -52,9 +52,10 @@ cp return 0; sockaddr2str(&n->address, &address, &port); - x = send_request(c, "%d %s %s %s %lx %d", ADD_NODE, + x = send_request(c, "%d %s %s %s %lx %d %s %s", ADD_NODE, n->name, address, port, - n->options, n->distance + 1); // Alternatively, use n->distance + c->estimated_weight + n->options, n->distance + 1, // Alternatively, use n->distance + c->estimated_weight + n->prevhop->name, n->via->name); free(address); free(port); cp @@ -64,16 +65,18 @@ cp int add_node_h(connection_t *c) { connection_t *other; - node_t *n; + node_t *n, *prevhop, *via; char name[MAX_STRING_SIZE]; char address[MAX_STRING_SIZE]; char port[MAX_STRING_SIZE]; + char prevhopname[MAX_STRING_SIZE]; + char vianame[MAX_STRING_SIZE]; long int options; int distance; avl_node_t *node; cp - if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d", - name, address, port, &options, &distance) != 5) + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d "MAX_STRING" "MAX_STRING, + name, address, port, &options, &distance, prevhopname, vianame) != 7) { syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_NODE", c->name, c->hostname); return -1; @@ -94,6 +97,24 @@ cp /* Lookup nodes */ + prevhop = lookup_node(prevhopname); + + if(!prevhop) + { + prevhop = new_node(); + prevhop->name = xstrdup(prevhopname); + node_add(prevhop); + } + + via = lookup_node(vianame); + + if(!via) + { + via = new_node(); + via->name = xstrdup(vianame); + node_add(via); + } + n = lookup_node(name); if(!n) @@ -105,16 +126,30 @@ cp n->hostname = sockaddr2hostname(&n->address); n->options = options; n->distance = distance; - n->via = n->nexthop = c->node; - n->status.reachable = 1; + n->nexthop = c->node; + n->prevhop = prevhop; + n->via = via; node_add(n); + if(prevhop == myself) + { + syslog(LOG_WARNING, _("Got ADD_NODE %s prevhop %s via %s from %s, sending back a DEL_NODE!"), name, prevhopname, vianame, c->name); + send_del_node(c, n); + return 0; + } + n->status.reachable = 1; } else { // If this ADD_NODE is closer or more direct, use it instead of the old one. if(!n->status.reachable || ((n->options & OPTION_INDIRECT) && !(options & OPTION_INDIRECT)) || n->distance > distance) { - avl_node_t *node = avl_unlink(node_udp_tree, n); + if(prevhop == myself) + { + syslog(LOG_WARNING, _("Got ADD_NODE %s prevhop %s via %s from %s!"), name, prevhopname, vianame, c->name); + send_del_node(c, n); + return 0; + } + node = avl_unlink(node_udp_tree, n); n->address = str2sockaddr(address, port); avl_insert_node(node_udp_tree, node); if(n->hostname) @@ -148,17 +183,18 @@ cp int send_del_node(connection_t *c, node_t *n) { cp - return send_request(c, "%d %s", DEL_NODE, n->name); + return send_request(c, "%d %s %s", DEL_NODE, n->name, n->prevhop->name); } int del_node_h(connection_t *c) { char name[MAX_STRING_SIZE]; - node_t *n; + char prevhopname[MAX_STRING_SIZE]; + node_t *n, *prevhop; connection_t *other; avl_node_t *node; cp - if(sscanf(c->buffer, "%*d "MAX_STRING, name) != 1) + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING, name, prevhopname) != 2) { syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_NODE", c->name, c->hostname); @@ -176,8 +212,9 @@ cp /* Lookup nodes */ n = lookup_node(name); - - if(!n) + prevhop = lookup_node(prevhopname); + + if(!n || !prevhop) { if(debug_lvl >= DEBUG_PROTOCOL) syslog(LOG_WARNING, _("Got %s from %s (%s) which does not appear in the node tree"), "DEL_NODE", c->name, c->hostname); @@ -186,7 +223,7 @@ cp /* If we got a DEL_NODE but we know of a different route to it, tell the one who send the DEL_NODE */ - if(n->nexthop != c->node) + if(n->nexthop != c->node || n->prevhop != prevhop) { return send_add_node(c, n); } -- 2.39.5