Put a break on requests that run around in circles.
This commit is contained in:
parent
f48f8f4fed
commit
9da5390666
5 changed files with 114 additions and 24 deletions
|
@ -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*) = {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
Loading…
Reference in a new issue