From: Guus Sliepen Date: Fri, 4 Jun 2010 12:53:52 +0000 (+0200) Subject: Detect and prevent two nodes with the same Name being on the VPN simultaneously. X-Git-Tag: release-1.0.14~49 X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=commitdiff_plain;h=4a21aabada23d1d2c8a10f54dd7248171c4ec82f Detect and prevent two nodes with the same Name being on the VPN simultaneously. In this situation, the two nodes will start fighting over the edges they announced. When we have to contradict both ADD_EDGE and DEL_EDGE messages, we log a warning, and with 25% chance per PingTimeout we quit. --- diff --git a/src/net.c b/src/net.c index 64bca947..ee58ac0a 100644 --- a/src/net.c +++ b/src/net.c @@ -44,6 +44,8 @@ bool do_purge = false; volatile bool running = false; time_t now = 0; +int contradicting_add_edge = 0; +int contradicting_del_edge = 0; /* Purge edges and subnets of unreachable nodes. Use carefully. */ @@ -415,6 +417,19 @@ int main_loop(void) { send_key_changed(broadcast, myself); keyexpires = now + keylifetime; } + + if(contradicting_del_edge && contradicting_add_edge) { + 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; + } } if(sigalrm) { diff --git a/src/net.h b/src/net.h index a97759fc..eae979cd 100644 --- a/src/net.h +++ b/src/net.h @@ -115,6 +115,8 @@ extern bool do_prune; extern bool do_purge; extern char *myport; extern time_t now; +extern int contradicting_add_edge; +extern int contradicting_del_edge; /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */ #include "connection.h" diff --git a/src/protocol_edge.c b/src/protocol_edge.c index 300333b6..32102d27 100644 --- a/src/protocol_edge.c +++ b/src/protocol_edge.c @@ -133,6 +133,7 @@ bool add_edge_h(connection_t *c) { } else if(from == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist", "ADD_EDGE", c->name, c->hostname); + contradicting_add_edge++; e = new_edge(); e->from = from; e->to = to; @@ -229,6 +230,7 @@ bool del_edge_h(connection_t *c) { if(e->from == myself) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself", "DEL_EDGE", c->name, c->hostname); + contradicting_del_edge++; send_add_edge(c, e); /* Send back a correction */ return true; }