Put a break on requests that run around in circles.

This commit is contained in:
Guus Sliepen 2002-03-21 23:11:53 +00:00
parent f48f8f4fed
commit 9da5390666
5 changed files with 114 additions and 24 deletions

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.c,v 1.28.4.123 2002/02/27 22:37:54 guus Exp $ $Id: protocol.c,v 1.28.4.124 2002/03/21 23:11:53 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -32,6 +32,7 @@
#include <errno.h> #include <errno.h>
#include <utils.h> #include <utils.h>
#include <xalloc.h>
#include "conf.h" #include "conf.h"
#include "protocol.h" #include "protocol.h"
@ -40,6 +41,8 @@
#include "system.h" #include "system.h"
avl_tree_t *past_request_tree;
int check_id(char *id) int check_id(char *id)
{ {
int i; int i;
@ -143,6 +146,66 @@ cp
return 0; return 0;
} }
int request_compare(past_request_t *a, past_request_t *b)
{
cp
return strcmp(a->request, b->request);
}
void init_requests(void)
{
cp
past_request_tree = avl_alloc_tree((avl_compare_t)request_compare, (avl_action_t)free);
cp
}
void exit_request(void)
{
cp
avl_delete_tree(past_request_tree);
cp
}
int seen_request(char *request)
{
past_request_t p, *new;
cp
p.request = request;
if(avl_search(past_request_tree, &p))
return 1;
else
{
new = (past_request_t *)xmalloc(sizeof(*new));
new->request = xstrdup(request);
new->firstseen = now;
avl_insert(past_request_tree, new);
return 0;
}
cp
}
void age_past_requests(void)
{
avl_node_t *node, *next;
past_request_t *p;
int left = 0, deleted = 0;
cp
for(node = past_request_tree->head; node; node = next)
{
next = node->next;
p = (past_request_t *)node->data;
if(p->firstseen + pingtimeout < now)
avl_delete_node(past_request_tree, node), deleted++;
else
left++;
}
if(debug_lvl >= DEBUG_SCARY_THINGS && left + deleted)
syslog(LOG_DEBUG, _("Aging past requests: deleted %d, left %d\n"), deleted, left);
cp
}
/* Jumptable for the request handlers */ /* Jumptable for the request handlers */
int (*request_handlers[])(connection_t*) = { int (*request_handlers[])(connection_t*) = {

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.h,v 1.5.4.27 2002/02/26 23:26:41 guus Exp $ $Id: protocol.h,v 1.5.4.28 2002/03/21 23:11:53 guus Exp $
*/ */
#ifndef __TINC_PROTOCOL_H__ #ifndef __TINC_PROTOCOL_H__
@ -31,7 +31,7 @@
incompatible version have different protocols. incompatible version have different protocols.
*/ */
#define PROT_CURRENT 13 #define PROT_CURRENT 14
/* Request numbers */ /* Request numbers */
@ -48,6 +48,11 @@ enum {
LAST /* Guardian for the highest request number */ LAST /* Guardian for the highest request number */
}; };
typedef struct past_request_t {
char *request;
time_t firstseen;
} past_request_t;
/* Maximum size of strings in a request */ /* Maximum size of strings in a request */
#define MAX_STRING_SIZE 2048 #define MAX_STRING_SIZE 2048

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_edge.c,v 1.1.4.2 2002/02/18 16:25:18 guus Exp $ $Id: protocol_edge.c,v 1.1.4.3 2002/03/21 23:11:53 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -55,7 +55,7 @@ cp
sockaddr2str(&e->from.udpaddress, &from_udpaddress, &from_udpport); sockaddr2str(&e->from.udpaddress, &from_udpaddress, &from_udpport);
sockaddr2str(&e->to.tcpaddress, &to_tcpaddress, &to_tcpport); sockaddr2str(&e->to.tcpaddress, &to_tcpaddress, &to_tcpport);
sockaddr2str(&e->to.udpaddress, &to_udpaddress, &to_udpport); sockaddr2str(&e->to.udpaddress, &to_udpaddress, &to_udpport);
x = send_request(c, "%d %s %s %s %s %s %s %s %s %lx %d", ADD_EDGE, x = send_request(c, "%d %lx %s %s %s %s %s %s %s %s %lx %d", ADD_EDGE, random(),
e->from.node->name, from_tcpaddress, from_tcpport, from_udpport, e->from.node->name, from_tcpaddress, from_tcpport, from_udpport,
e->to.node->name, to_tcpaddress, to_tcpport, to_udpport, e->to.node->name, to_tcpaddress, to_tcpport, to_udpport,
e->options, e->weight); e->options, e->weight);
@ -90,7 +90,7 @@ int add_edge_h(connection_t *c)
int weight; int weight;
avl_node_t *node; avl_node_t *node;
cp cp
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d", if(sscanf(c->buffer, "%*d %*lx "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d",
from_name, from_address, from_tcpport, from_udpport, from_name, from_address, from_tcpport, from_udpport,
to_name, to_address, to_tcpport, to_udpport, to_name, to_address, to_tcpport, to_udpport,
&options, &weight) != 10) &options, &weight) != 10)
@ -113,6 +113,9 @@ cp
return -1; return -1;
} }
if(seen_request(c->buffer))
return 0;
/* Lookup nodes */ /* Lookup nodes */
from = lookup_node(from_name); from = lookup_node(from_name);
@ -180,8 +183,6 @@ cp
return 0; return 0;
} }
e = new_edge(); e = new_edge();
e->from.node = from; e->from.node = from;
e->from.tcpaddress = from_tcpaddress; e->from.tcpaddress = from_tcpaddress;
@ -199,7 +200,7 @@ cp
{ {
other = (connection_t *)node->data; other = (connection_t *)node->data;
if(other->status.active && other != c) if(other->status.active && other != c)
send_add_edge(other, e); send_request(other, "%s", c->buffer);
} }
/* Run MST before or after we tell the rest? */ /* Run MST before or after we tell the rest? */
@ -212,7 +213,7 @@ cp
int send_del_edge(connection_t *c, edge_t *e) int send_del_edge(connection_t *c, edge_t *e)
{ {
cp cp
return send_request(c, "%d %s %s", DEL_EDGE, return send_request(c, "%d %lx %s %s", DEL_EDGE, random(),
e->from.node->name, e->to.node->name); e->from.node->name, e->to.node->name);
} }
@ -225,7 +226,7 @@ int del_edge_h(connection_t *c)
connection_t *other; connection_t *other;
avl_node_t *node; avl_node_t *node;
cp cp
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING"", from_name, to_name) != 2) if(sscanf(c->buffer, "%*d %*lx "MAX_STRING" "MAX_STRING"", from_name, to_name) != 2)
{ {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE",
c->name, c->hostname); c->name, c->hostname);
@ -246,6 +247,9 @@ cp
return -1; return -1;
} }
if(seen_request(c->buffer))
return 0;
/* Lookup nodes */ /* Lookup nodes */
from = lookup_node(from_name); from = lookup_node(from_name);
@ -291,7 +295,7 @@ cp
{ {
other = (connection_t *)node->data; other = (connection_t *)node->data;
if(other->status.active && other != c) if(other->status.active && other != c)
send_del_edge(other, e); send_request(other, "%s", c->buffer);
} }
/* Delete the edge */ /* Delete the edge */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_key.c,v 1.1.4.4 2002/02/27 22:37:55 guus Exp $ $Id: protocol_key.c,v 1.1.4.5 2002/03/21 23:11:53 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -61,8 +61,8 @@ cp
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next)
{ {
other = (connection_t *)node->data; other = (connection_t *)node->data;
if(other->status.active && other->status.mst && other != c) if(other->status.active && other != c)
send_request(other, "%d %s", KEY_CHANGED, n->name); send_request(other, "%d %lx %s", KEY_CHANGED, random(), n->name);
} }
cp cp
return 0; return 0;
@ -71,15 +71,20 @@ cp
int key_changed_h(connection_t *c) int key_changed_h(connection_t *c)
{ {
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
avl_node_t *node;
connection_t *other;
node_t *n; node_t *n;
cp cp
if(sscanf(c->buffer, "%*d "MAX_STRING, name) != 1) if(sscanf(c->buffer, "%*d %*lx "MAX_STRING, name) != 1)
{ {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "KEY_CHANGED", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "KEY_CHANGED",
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
if(seen_request(c->buffer))
return 0;
n = lookup_node(name); n = lookup_node(name);
if(!n) if(!n)
@ -93,7 +98,14 @@ cp
n->status.waitingforkey = 0; n->status.waitingforkey = 0;
n->sent_seqno = 0; n->sent_seqno = 0;
send_key_changed(c, n); /* Tell the others */
for(node = connection_tree->head; node; node = node->next)
{
other = (connection_t *)node->data;
if(other->status.active && other != c)
send_request(other, "%s", c->buffer);
}
cp cp
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_subnet.c,v 1.1.4.1 2002/02/11 10:05:58 guus Exp $ $Id: protocol_subnet.c,v 1.1.4.2 2002/03/21 23:11:53 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -50,7 +50,7 @@ int send_add_subnet(connection_t *c, subnet_t *subnet)
int x; int x;
char *netstr; char *netstr;
cp cp
x = send_request(c, "%d %s %s", ADD_SUBNET, x = send_request(c, "%d %lx %s %s", ADD_SUBNET, random(),
subnet->owner->name, netstr = net2str(subnet)); subnet->owner->name, netstr = net2str(subnet));
free(netstr); free(netstr);
cp cp
@ -66,7 +66,7 @@ int add_subnet_h(connection_t *c)
subnet_t *s; subnet_t *s;
avl_node_t *node; avl_node_t *node;
cp cp
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2) if(sscanf(c->buffer, "%*d %*lx "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
{ {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name, c->hostname);
return -1; return -1;
@ -88,6 +88,9 @@ cp
return -1; return -1;
} }
if(seen_request(c->buffer))
return 0;
/* Check if the owner of the new subnet is in the connection list */ /* Check if the owner of the new subnet is in the connection list */
owner = lookup_node(name); owner = lookup_node(name);
@ -128,7 +131,7 @@ cp
{ {
other = (connection_t *)node->data; other = (connection_t *)node->data;
if(other->status.active && other != c) if(other->status.active && other != c)
send_add_subnet(other, s); send_request(other, "%s", c->buffer);
} }
cp cp
return 0; return 0;
@ -140,7 +143,7 @@ int send_del_subnet(connection_t *c, subnet_t *s)
char *netstr; char *netstr;
cp cp
netstr = net2str(s); netstr = net2str(s);
x = send_request(c, "%d %s %s", DEL_SUBNET, s->owner->name, netstr); x = send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
free(netstr); free(netstr);
cp cp
return x; return x;
@ -155,7 +158,7 @@ int del_subnet_h(connection_t *c)
subnet_t *s, *find; subnet_t *s, *find;
avl_node_t *node; avl_node_t *node;
cp cp
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2) if(sscanf(c->buffer, "%*d %*lx "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
{ {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name, c->hostname);
return -1; return -1;
@ -187,6 +190,9 @@ cp
return -1; return -1;
} }
if(seen_request(c->buffer))
return 0;
/* If everything is correct, delete the subnet from the list of the owner */ /* If everything is correct, delete the subnet from the list of the owner */
s->owner = owner; s->owner = owner;
@ -219,7 +225,7 @@ cp
{ {
other = (connection_t *)node->data; other = (connection_t *)node->data;
if(other->status.active && other != c) if(other->status.active && other != c)
send_del_subnet(other, find); send_request(other, "%s", c->buffer);
} }
/* Finally, delete it. */ /* Finally, delete it. */