along with this program; if not, write to the Free Software
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 <errno.h>
#include <utils.h>
+#include <xalloc.h>
#include "conf.h"
#include "protocol.h"
#include "system.h"
+avl_tree_t *past_request_tree;
+
int check_id(char *id)
{
int i;
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 */
int (*request_handlers[])(connection_t*) = {
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.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__
incompatible version have different protocols.
*/
-#define PROT_CURRENT 13
+#define PROT_CURRENT 14
/* Request numbers */
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 */
#define MAX_STRING_SIZE 2048
along with this program; if not, write to the Free Software
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"
sockaddr2str(&e->from.udpaddress, &from_udpaddress, &from_udpport);
sockaddr2str(&e->to.tcpaddress, &to_tcpaddress, &to_tcpport);
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->to.node->name, to_tcpaddress, to_tcpport, to_udpport,
e->options, e->weight);
int weight;
avl_node_t *node;
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,
to_name, to_address, to_tcpport, to_udpport,
&options, &weight) != 10)
return -1;
}
+ if(seen_request(c->buffer))
+ return 0;
+
/* Lookup nodes */
from = lookup_node(from_name);
return 0;
}
-
-
e = new_edge();
e->from.node = from;
e->from.tcpaddress = from_tcpaddress;
{
other = (connection_t *)node->data;
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? */
int send_del_edge(connection_t *c, edge_t *e)
{
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);
}
connection_t *other;
avl_node_t *node;
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",
c->name, c->hostname);
return -1;
}
+ if(seen_request(c->buffer))
+ return 0;
+
/* Lookup nodes */
from = lookup_node(from_name);
{
other = (connection_t *)node->data;
if(other->status.active && other != c)
- send_del_edge(other, e);
+ send_request(other, "%s", c->buffer);
}
/* Delete the edge */
along with this program; if not, write to the Free Software
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"
for(node = connection_tree->head; node; node = node->next)
{
other = (connection_t *)node->data;
- if(other->status.active && other->status.mst && other != c)
- send_request(other, "%d %s", KEY_CHANGED, n->name);
+ if(other->status.active && other != c)
+ send_request(other, "%d %lx %s", KEY_CHANGED, random(), n->name);
}
cp
return 0;
int key_changed_h(connection_t *c)
{
char name[MAX_STRING_SIZE];
+ avl_node_t *node;
+ connection_t *other;
node_t *n;
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",
c->name, c->hostname);
return -1;
}
+ if(seen_request(c->buffer))
+ return 0;
+
n = lookup_node(name);
if(!n)
n->status.waitingforkey = 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
return 0;
}
along with this program; if not, write to the Free Software
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"
int x;
char *netstr;
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));
free(netstr);
cp
subnet_t *s;
avl_node_t *node;
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);
return -1;
return -1;
}
+ if(seen_request(c->buffer))
+ return 0;
+
/* Check if the owner of the new subnet is in the connection list */
owner = lookup_node(name);
{
other = (connection_t *)node->data;
if(other->status.active && other != c)
- send_add_subnet(other, s);
+ send_request(other, "%s", c->buffer);
}
cp
return 0;
char *netstr;
cp
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);
cp
return x;
subnet_t *s, *find;
avl_node_t *node;
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);
return -1;
return -1;
}
+ if(seen_request(c->buffer))
+ return 0;
+
/* If everything is correct, delete the subnet from the list of the owner */
s->owner = owner;
{
other = (connection_t *)node->data;
if(other->status.active && other != c)
- send_del_subnet(other, find);
+ send_request(other, "%s", c->buffer);
}
/* Finally, delete it. */