- Integrate rbl trees into tinc.

This commit is contained in:
Guus Sliepen 2000-11-20 19:12:17 +00:00
parent 9024e01ce6
commit 408ca91766
18 changed files with 443 additions and 417 deletions

View file

@ -1,15 +1,15 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
# $Id: Makefile.am,v 1.2.4.2 2000/11/15 22:04:48 zarq Exp $ # $Id: Makefile.am,v 1.2.4.3 2000/11/20 19:12:10 guus Exp $
noinst_LIBRARIES = libvpn.a noinst_LIBRARIES = libvpn.a
INCLUDES = -I. -I$(top_builddir) -I$(top_srcdir)/intl INCLUDES = -I. -I$(top_builddir) -I$(top_srcdir)/intl
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c list.c libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c list.c rbl.c
libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@ libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@
libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD) libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD)
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h rbl.h
EXTRA_DIST = README EXTRA_DIST = README

View file

@ -17,9 +17,10 @@
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: rbl.c,v 1.1.2.7 2000/11/19 22:12:46 guus Exp $ $Id: rbl.c,v 1.1.2.8 2000/11/20 19:12:10 guus Exp $
*/ */
#include <stdlib.h>
#include <xalloc.h> #include <xalloc.h>
#include "rbl.h" #include "rbl.h"

View file

@ -17,9 +17,14 @@
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: rbl.h,v 1.1.2.6 2000/11/19 22:12:46 guus Exp $ $Id: rbl.h,v 1.1.2.7 2000/11/20 19:12:10 guus Exp $
*/ */
#ifndef __RBL_H__
#define __RBL_H__
#define RBL_FOREACH(tree,rbl) for(rbl = tree->head; rbl; rbl = rbl->next)
typedef struct rbl_t typedef struct rbl_t
{ {
/* 'red-black tree' part */ /* 'red-black tree' part */
@ -91,3 +96,5 @@ extern void rbl_delete_rbltree(rbltree_t *);
extern void rbl_foreach(rbltree_t *, rbl_action_t); extern void rbl_foreach(rbltree_t *, rbl_action_t);
extern void rbl_foreach_rbl(rbltree_t *, rbl_action_rbl_t); extern void rbl_foreach_rbl(rbltree_t *, rbl_action_rbl_t);
#endif /* __RBL_H__ */

View file

@ -6,7 +6,7 @@
lib/pidfile.c lib/pidfile.c
lib/utils.c lib/utils.c
src/conf.c src/conf.c
src/connlist.c src/connection.c
src/meta.c src/meta.c
src/net.c src/net.c
src/netutl.c src/netutl.c

View file

@ -1,14 +1,14 @@
## Produce this file with automake to get Makefile.in ## Produce this file with automake to get Makefile.in
# $Id: Makefile.am,v 1.4.4.8 2000/11/17 10:03:02 guus Exp $ # $Id: Makefile.am,v 1.4.4.9 2000/11/20 19:12:11 guus Exp $
sbin_PROGRAMS = tincd sbin_PROGRAMS = tincd
tincd_SOURCES = conf.c connlist.c meta.c net.c netutl.c process.c \ tincd_SOURCES = conf.c connection.c meta.c net.c netutl.c process.c \
protocol.c subnet.c tincd.c protocol.c subnet.c tincd.c
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/lib -I$(top_srcdir)/intl INCLUDES = -I$(top_builddir) -I$(top_srcdir)/lib -I$(top_srcdir)/intl
noinst_HEADERS = conf.h connlist.h meta.h net.h netutl.h process.h \ noinst_HEADERS = conf.h connection.h meta.h net.h netutl.h process.h \
protocol.h subnet.h protocol.h subnet.h
LIBS = @LIBS@ @INTLLIBS@ LIBS = @LIBS@ @INTLLIBS@

View file

@ -19,7 +19,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: conf.c,v 1.9.4.21 2000/11/04 22:57:30 guus Exp $ $Id: conf.c,v 1.9.4.22 2000/11/20 19:12:11 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -39,7 +39,6 @@
#include <utils.h> /* for cp */ #include <utils.h> /* for cp */
#include "config.h" #include "config.h"
#include "connlist.h"
#include "system.h" #include "system.h"
config_t *config = NULL; config_t *config = NULL;

View file

@ -1,5 +1,5 @@
/* /*
connlist.c -- connection list management connection.c -- connection list management
Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>, Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>,
2000 Ivo Timmermans <itimmermans@bigfoot.com> 2000 Ivo Timmermans <itimmermans@bigfoot.com>
@ -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: connlist.c,v 1.1.2.15 2000/11/04 22:57:30 guus Exp $ $Id: connection.c,v 1.1.2.1 2000/11/20 19:12:11 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -25,6 +25,8 @@
#include <stdio.h> #include <stdio.h>
#include <syslog.h> #include <syslog.h>
#include <rbl.h>
#include "net.h" /* Don't ask. */ #include "net.h" /* Don't ask. */
#include "netutl.h" #include "netutl.h"
#include "config.h" #include "config.h"
@ -36,14 +38,26 @@
/* Root of the connection list */ /* Root of the connection list */
conn_list_t *conn_list = NULL; rbltree_t *connection_tree;
conn_list_t *myself = NULL; connection_t *myself = NULL;
/* Creation and deletion of conn_list elements */ /* Initialization and callbacks */
conn_list_t *new_conn_list(void) int connection_compare(connection_t *a, connection_t *b)
{ {
conn_list_t *p = (conn_list_t *)xmalloc(sizeof(*p)); return strcmp(a->name, b->name);
}
void init_connections(void)
{
connection_tree = new_rbltree((rbl_compare_t)connection_compare, (rbl_action_t)free_connection);
}
/* Creation and deletion of connection elements */
connection_t *new_connection(void)
{
connection_t *p = (connection_t *)xmalloc(sizeof(*p));
cp cp
/* initialise all those stupid pointers at once */ /* initialise all those stupid pointers at once */
memset(p, '\0', sizeof(*p)); memset(p, '\0', sizeof(*p));
@ -51,7 +65,7 @@ cp
return p; return p;
} }
void free_conn_list(conn_list_t *p) void free_connection(connection_t *p)
{ {
cp cp
if(p->sq) if(p->sq)
@ -77,91 +91,63 @@ cp
/* /*
remove all marked connections remove all marked connections
*/ */
void prune_conn_list(void) void prune_connection_tree(void)
{ {
conn_list_t *p, *prev = NULL, *next = NULL; rbl_t *rbl;
connection_t *cl;
cp cp
for(p = conn_list; p != NULL; ) RBL_FOREACH(connection_tree, rbl)
{ {
next = p->next; cl = (connection_t *) rbl->data;
if(cl->status.remove)
if(p->status.remove) connection_del(cl);
conn_list_del(p);
else
prev = p;
p = next;
} }
cp cp
} }
/* /*
free all elements of conn_list free all elements of connection
*/ */
void destroy_conn_list(void) void destroy_connection_tree(void)
{ {
conn_list_t *p, *next;
cp cp
for(p = conn_list; p != NULL; ) rbl_delete_rbltree(connection_tree);
{
next = p->next;
free_conn_list(p);
p = next;
}
conn_list = NULL;
cp cp
} }
/* Linked list management */ /* Linked list management */
void conn_list_add(conn_list_t *cl) void connection_add(connection_t *cl)
{ {
cp cp
cl->next = conn_list; rbl_insert(connection_tree, cl);
cl->prev = NULL;
if(cl->next)
cl->next->prev = cl;
conn_list = cl;
cp cp
} }
void conn_list_del(conn_list_t *cl) void connection_del(connection_t *cl)
{ {
cp cp
if(cl->prev) rbl_delete(connection_tree, cl);
cl->prev->next = cl->next;
else
conn_list = cl->next;
if(cl->next)
cl->next->prev = cl->prev;
free_conn_list(cl);
cp cp
} }
/* Lookup functions */ /* Lookup functions */
conn_list_t *lookup_id(char *name) connection_t *lookup_id(char *name)
{ {
conn_list_t *p; connection_t cl;
cp cp
for(p = conn_list; p != NULL; p = p->next) cl.name = name;
if(p->status.active) return rbl_search(connection_tree, &cl);
if(strcmp(name, p->name) == 0)
break;
cp cp
return p;
} }
/* Debugging */ /* Debugging */
void dump_conn_list(void) void dump_connection_list(void)
{ {
conn_list_t *p; rbl_t *rbl;
connection_t *cl;
cp cp
syslog(LOG_DEBUG, _("Connection list:")); syslog(LOG_DEBUG, _("Connection list:"));
@ -169,18 +155,19 @@ cp
myself->name, myself->hostname, myself->port, myself->flags, myself->name, myself->hostname, myself->port, myself->flags,
myself->socket, myself->meta_socket, myself->status); myself->socket, myself->meta_socket, myself->status);
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{ {
cl = (connection_t *)rbl->data;
syslog(LOG_DEBUG, _(" %s at %s port %hd flags %d sockets %d, %d status %04x"), syslog(LOG_DEBUG, _(" %s at %s port %hd flags %d sockets %d, %d status %04x"),
p->name, p->hostname, p->port, p->flags, cl->name, cl->hostname, cl->port, cl->flags,
p->socket, p->meta_socket, p->status); cl->socket, cl->meta_socket, cl->status);
} }
syslog(LOG_DEBUG, _("End of connection list.")); syslog(LOG_DEBUG, _("End of connection list."));
cp cp
} }
int read_host_config(conn_list_t *cl) int read_host_config(connection_t *cl)
{ {
char *fname; char *fname;
int x; int x;

View file

@ -1,5 +1,5 @@
/* /*
connlist.h -- header for connlist.c connection.h -- header for connection.c
Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>, Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>,
2000 Ivo Timmermans <itimmermans@bigfoot.com> 2000 Ivo Timmermans <itimmermans@bigfoot.com>
@ -17,11 +17,13 @@
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: connlist.h,v 1.1.2.13 2000/11/15 01:06:10 zarq Exp $ $Id: connection.h,v 1.1.2.1 2000/11/20 19:12:11 guus Exp $
*/ */
#ifndef __TINC_CONNLIST_H__ #ifndef __TINC_CONNECTION_H__
#define __TINC_CONNLIST_H__ #define __TINC_CONNECTION_H__
#include <rbl.h>
#include "config.h" #include "config.h"
@ -60,7 +62,7 @@ typedef struct option_bits_t {
int unused:32; int unused:32;
} option_bits_t; } option_bits_t;
typedef struct conn_list_t { typedef struct connection_t {
char *name; /* name of this connection */ char *name; /* name of this connection */
ipv4_t address; /* his real (internet) ip */ ipv4_t address; /* his real (internet) ip */
char *hostname; /* the hostname of its real ip */ char *hostname; /* the hostname of its real ip */
@ -96,29 +98,25 @@ typedef struct conn_list_t {
char *mychallenge; /* challenge we received from him */ char *mychallenge; /* challenge we received from him */
char *hischallenge; /* challenge we sent to him */ char *hischallenge; /* challenge we sent to him */
struct conn_list_t *nexthop; /* nearest meta-hop in this direction */ struct connection_t *nexthop; /* nearest meta-hop in this direction */
struct subnet_t *subnets; /* Pointer to a list of subnets belonging to this connection */ rbltree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this connection */
struct config_t *config; /* Pointer to configuration tree belonging to this host */ struct config_t *config; /* Pointer to configuration tree belonging to this host */
} connection_t;
struct conn_list_t *next; /* after all, it's a list of connections */ extern rbltree_t *connection_tree;
struct conn_list_t *prev; /* doubly linked for O(1) deletions */ extern connection_t *myself;
} conn_list_t;
#include "subnet.h" extern void init_connections(void);
extern connection_t *new_connection(void);
extern void free_connection(connection_t *);
extern void connection_add(connection_t *);
extern void connection_del(connection_t *);
extern connection_t *lookup_id(char *);
extern void dump_connection_list(void);
extern int read_host_config(connection_t *);
extern void destroy_connection(void);
extern void prune_connection_tree(void);
extern conn_list_t *conn_list; #endif /* __TINC_CONNECTION_H__ */
extern conn_list_t *myself;
extern conn_list_t *new_conn_list();
extern void free_conn_list(conn_list_t *);
extern void conn_list_add(conn_list_t *);
extern void conn_list_del(conn_list_t *);
extern conn_list_t *lookup_id(char *);
extern void dump_conn_list(void);
extern int read_host_config(conn_list_t *);
extern void destroy_conn_list(void);
extern void prune_conn_list(void);
#endif /* __TINC_CONNLIST_H__ */

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: meta.c,v 1.1.2.11 2000/11/15 13:33:25 guus Exp $ $Id: meta.c,v 1.1.2.12 2000/11/20 19:12:12 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -38,10 +38,11 @@
#endif #endif
#include "net.h" #include "net.h"
#include "connection.h"
#include "system.h" #include "system.h"
#include "protocol.h" #include "protocol.h"
int send_meta(conn_list_t *cl, char *buffer, int length) int send_meta(connection_t *cl, char *buffer, int length)
{ {
char outbuf[MAXBUFSIZE]; char outbuf[MAXBUFSIZE];
char *bufp; char *bufp;
@ -71,18 +72,21 @@ cp
return 0; return 0;
} }
int broadcast_meta(conn_list_t *cl, char *buffer, int length) void broadcast_meta(connection_t *cl, char *buffer, int length)
{ {
conn_list_t *p; rbl_t *rbl;
connection_t *p;
cp cp
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p != cl && p->status.meta && p->status.active) if(p != cl && p->status.meta && p->status.active)
send_meta(p, buffer, length); send_meta(p, buffer, length);
}
cp cp
return 0;
} }
int receive_meta(conn_list_t *cl) int receive_meta(connection_t *cl)
{ {
int x, l = sizeof(x); int x, l = sizeof(x);
int oldlen, i; int oldlen, i;

View file

@ -17,16 +17,16 @@
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: meta.h,v 1.1.2.3 2000/10/11 10:35:16 guus Exp $ $Id: meta.h,v 1.1.2.4 2000/11/20 19:12:12 guus Exp $
*/ */
#ifndef __TINC_META_H__ #ifndef __TINC_META_H__
#define __TINC_META_H__ #define __TINC_META_H__
#include "net.h" #include "connection.h"
extern int send_meta(conn_list_t *, const char *, int); extern int send_meta(connection_t *, const char *, int);
extern int broadcast_meta(conn_list_t *, const char *, int); extern int broadcast_meta(connection_t *, const char *, int);
extern int receive_meta(conn_list_t *); extern int receive_meta(connection_t *);
#endif /* __TINC_META_H__ */ #endif /* __TINC_META_H__ */

129
src/net.c
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: net.c,v 1.35.4.76 2000/11/16 22:11:40 zarq Exp $ $Id: net.c,v 1.35.4.77 2000/11/20 19:12:12 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -67,7 +67,7 @@
#include <xalloc.h> #include <xalloc.h>
#include "conf.h" #include "conf.h"
#include "connlist.h" #include "connection.h"
#include "list.h" #include "list.h"
#include "meta.h" #include "meta.h"
#include "net.h" #include "net.h"
@ -95,7 +95,7 @@ char *unknown = NULL;
subnet_t mymac; subnet_t mymac;
int xsend(conn_list_t *cl, vpn_packet_t *inpkt) int xsend(connection_t *cl, vpn_packet_t *inpkt)
{ {
vpn_packet_t outpkt; vpn_packet_t outpkt;
int outlen, outpad; int outlen, outpad;
@ -131,7 +131,7 @@ cp
return 0; return 0;
} }
int xrecv(conn_list_t *cl, vpn_packet_t *inpkt) int xrecv(connection_t *cl, vpn_packet_t *inpkt)
{ {
vpn_packet_t outpkt; vpn_packet_t outpkt;
int outlen, outpad; int outlen, outpad;
@ -254,8 +254,8 @@ cp
each packet, and removing it when that each packet, and removing it when that
returned a zero exit code returned a zero exit code
*/ */
void flush_queue(conn_list_t *cl, packet_queue_t **pq, void flush_queue(connection_t *cl, packet_queue_t **pq,
int (*function)(conn_list_t*,vpn_packet_t*)) int (*function)(connection_t*,vpn_packet_t*))
{ {
queue_element_t *p, *next = NULL; queue_element_t *p, *next = NULL;
cp cp
@ -279,7 +279,7 @@ cp
void because nothing goes wrong here, packets void because nothing goes wrong here, packets
remain in the queue if something goes wrong remain in the queue if something goes wrong
*/ */
void flush_queues(conn_list_t *cl) void flush_queues(connection_t *cl)
{ {
cp cp
if(cl->sq) if(cl->sq)
@ -305,7 +305,7 @@ cp
*/ */
int send_packet(ip_t to, vpn_packet_t *packet) int send_packet(ip_t to, vpn_packet_t *packet)
{ {
conn_list_t *cl; connection_t *cl;
subnet_t *subnet; subnet_t *subnet;
cp cp
if((subnet = lookup_subnet_ipv4(to)) == NULL) if((subnet = lookup_subnet_ipv4(to)) == NULL)
@ -384,6 +384,9 @@ int setup_tap_fd(void)
int nfd; int nfd;
const char *tapfname; const char *tapfname;
config_t const *cfg; config_t const *cfg;
#ifdef HAVE_TUNTAP
struct ifreq ifr;
#endif
cp cp
if((cfg = get_config_val(config, config_tapdevice))) if((cfg = get_config_val(config, config_tapdevice)))
@ -563,7 +566,7 @@ cp
/* /*
setup an outgoing meta (tcp) socket setup an outgoing meta (tcp) socket
*/ */
int setup_outgoing_meta_socket(conn_list_t *cl) int setup_outgoing_meta_socket(connection_t *cl)
{ {
int flags; int flags;
struct sockaddr_in a; struct sockaddr_in a;
@ -623,7 +626,7 @@ cp
*/ */
int setup_outgoing_connection(char *name) int setup_outgoing_connection(char *name)
{ {
conn_list_t *ncn; connection_t *ncn;
struct hostent *h; struct hostent *h;
config_t const *cfg; config_t const *cfg;
cp cp
@ -633,27 +636,27 @@ cp
return -1; return -1;
} }
ncn = new_conn_list(); ncn = new_connection();
asprintf(&ncn->name, "%s", name); asprintf(&ncn->name, "%s", name);
if(read_host_config(ncn)) if(read_host_config(ncn))
{ {
syslog(LOG_ERR, _("Error reading host configuration file for %s")); syslog(LOG_ERR, _("Error reading host configuration file for %s"));
free_conn_list(ncn); free_connection(ncn);
return -1; return -1;
} }
if(!(cfg = get_config_val(ncn->config, config_address))) if(!(cfg = get_config_val(ncn->config, config_address)))
{ {
syslog(LOG_ERR, _("No address specified for %s")); syslog(LOG_ERR, _("No address specified for %s"));
free_conn_list(ncn); free_connection(ncn);
return -1; return -1;
} }
if(!(h = gethostbyname(cfg->data.ptr))) if(!(h = gethostbyname(cfg->data.ptr)))
{ {
syslog(LOG_ERR, _("Error looking up `%s': %m"), cfg->data.ptr); syslog(LOG_ERR, _("Error looking up `%s': %m"), cfg->data.ptr);
free_conn_list(ncn); free_connection(ncn);
return -1; return -1;
} }
@ -664,7 +667,7 @@ cp
{ {
syslog(LOG_ERR, _("Could not set up a meta connection to %s"), syslog(LOG_ERR, _("Could not set up a meta connection to %s"),
ncn->hostname); ncn->hostname);
free_conn_list(ncn); free_connection(ncn);
return -1; return -1;
} }
@ -673,7 +676,7 @@ cp
ncn->buflen = 0; ncn->buflen = 0;
ncn->last_ping_time = time(NULL); ncn->last_ping_time = time(NULL);
conn_list_add(ncn); connection_add(ncn);
send_id(ncn); send_id(ncn);
cp cp
@ -681,7 +684,7 @@ cp
} }
/* /*
Configure conn_list_t myself and set up the local sockets (listen only) Configure connection_t myself and set up the local sockets (listen only)
*/ */
int setup_myself(void) int setup_myself(void)
{ {
@ -689,7 +692,7 @@ int setup_myself(void)
config_t *next; config_t *next;
subnet_t *net; subnet_t *net;
cp cp
myself = new_conn_list(); myself = new_connection();
asprintf(&myself->hostname, "MYSELF"); /* FIXME? Do hostlookup on ourselves? */ asprintf(&myself->hostname, "MYSELF"); /* FIXME? Do hostlookup on ourselves? */
myself->flags = 0; myself->flags = 0;
@ -895,10 +898,12 @@ cp
*/ */
void close_network_connections(void) void close_network_connections(void)
{ {
conn_list_t *p; rbl_t *rbl;
connection_t *p;
cp cp
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{ {
p = (connection_t *)rbl->data;
p->status.active = 0; p->status.active = 0;
terminate_connection(p); terminate_connection(p);
} }
@ -907,7 +912,7 @@ cp
if(myself->status.active) if(myself->status.active)
{ {
close(myself->meta_socket); close(myself->meta_socket);
free_conn_list(myself); free_connection(myself);
myself = NULL; myself = NULL;
} }
@ -916,7 +921,7 @@ cp
/* Execute tinc-down script right after shutting down the interface */ /* Execute tinc-down script right after shutting down the interface */
execute_script("tinc-down"); execute_script("tinc-down");
destroy_conn_list(); destroy_connection_tree();
syslog(LOG_NOTICE, _("Terminating")); syslog(LOG_NOTICE, _("Terminating"));
cp cp
@ -926,7 +931,7 @@ cp
/* /*
create a data (udp) socket create a data (udp) socket
*/ */
int setup_vpn_connection(conn_list_t *cl) int setup_vpn_connection(connection_t *cl)
{ {
int nfd, flags; int nfd, flags;
struct sockaddr_in a; struct sockaddr_in a;
@ -1002,13 +1007,13 @@ cp
handle an incoming tcp connect call and open handle an incoming tcp connect call and open
a connection to it. a connection to it.
*/ */
conn_list_t *create_new_connection(int sfd) connection_t *create_new_connection(int sfd)
{ {
conn_list_t *p; connection_t *p;
struct sockaddr_in ci; struct sockaddr_in ci;
int len = sizeof(ci); int len = sizeof(ci);
cp cp
p = new_conn_list(); p = new_connection();
if(getpeername(sfd, (struct sockaddr *) &ci, (socklen_t *) &len) < 0) if(getpeername(sfd, (struct sockaddr *) &ci, (socklen_t *) &len) < 0)
{ {
@ -1040,12 +1045,14 @@ cp
*/ */
void build_fdset(fd_set *fs) void build_fdset(fd_set *fs)
{ {
conn_list_t *p; rbl_t *rbl;
connection_t *p;
cp cp
FD_ZERO(fs); FD_ZERO(fs);
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{ {
p = (connection_t *)rbl->data;
if(p->status.meta) if(p->status.meta)
FD_SET(p->meta_socket, fs); FD_SET(p->meta_socket, fs);
if(p->status.dataopen) if(p->status.dataopen)
@ -1062,7 +1069,7 @@ cp
udp socket and write it to the ethertap udp socket and write it to the ethertap
device after being decrypted device after being decrypted
*/ */
int handle_incoming_vpn_data(conn_list_t *cl) int handle_incoming_vpn_data(connection_t *cl)
{ {
vpn_packet_t pkt; vpn_packet_t pkt;
int x, l = sizeof(x); int x, l = sizeof(x);
@ -1100,10 +1107,12 @@ cp
terminate a connection and notify the other terminate a connection and notify the other
end before closing the sockets end before closing the sockets
*/ */
void terminate_connection(conn_list_t *cl) void terminate_connection(connection_t *cl)
{ {
conn_list_t *p; connection_t *p;
subnet_t *s; subnet_t *s;
rbl_t *rbl;
cp cp
if(cl->status.remove) if(cl->status.remove)
return; return;
@ -1124,21 +1133,26 @@ cp
(the connection that was dropped). */ (the connection that was dropped). */
if(cl->status.meta) if(cl->status.meta)
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
if((p->nexthop == cl) && (p != cl)) {
terminate_connection(p); /* Sounds like recursion, but p does not have a meta connection :) */ p = (connection_t *)rbl->data;
if(p->nexthop == cl && p != cl)
terminate_connection(p);
}
/* Inform others of termination if it was still active */ /* Inform others of termination if it was still active */
if(cl->status.active) if(cl->status.active)
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p->status.meta && p->status.active && p!=cl) if(p->status.meta && p->status.active && p!=cl)
send_del_host(p, cl); send_del_host(p, cl); /* Sounds like recursion, but p does not have a meta connection :) */
}
/* Remove the associated subnets */ /* Remove the associated subnets */
for(s = cl->subnets; s; s = s->next) rbl_delete_rbltree(cl->subnet_tree);
subnet_del(s);
/* Check if this was our outgoing connection */ /* Check if this was our outgoing connection */
@ -1164,35 +1178,37 @@ cp
end does not reply in time, we consider them dead end does not reply in time, we consider them dead
and close the connection. and close the connection.
*/ */
int check_dead_connections(void) void check_dead_connections(void)
{ {
conn_list_t *p;
time_t now; time_t now;
rbl_t *rbl;
connection_t *cl;
cp cp
now = time(NULL); now = time(NULL);
for(p = conn_list; p != NULL; p = p->next)
RBL_FOREACH(connection_tree, rbl)
{ {
if(p->status.active && p->status.meta) cl = (connection_t *)rbl->data;
if(cl->status.active && cl->status.meta)
{ {
if(p->last_ping_time + timeout < now) if(cl->last_ping_time + timeout < now)
{ {
if(p->status.pinged) if(cl->status.pinged)
{ {
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_INFO, _("%s (%s) didn't respond to PING"), syslog(LOG_INFO, _("%s (%s) didn't respond to PING"),
p->name, p->hostname); cl->name, cl->hostname);
p->status.timeout = 1; cl->status.timeout = 1;
terminate_connection(p); terminate_connection(cl);
} }
else else
{ {
send_ping(p); send_ping(cl);
} }
} }
} }
} }
cp cp
return 0;
} }
/* /*
@ -1201,7 +1217,7 @@ cp
*/ */
int handle_new_meta_connection() int handle_new_meta_connection()
{ {
conn_list_t *ncn; connection_t *ncn;
struct sockaddr client; struct sockaddr client;
int nfd, len = sizeof(client); int nfd, len = sizeof(client);
cp cp
@ -1219,7 +1235,7 @@ cp
return 0; return 0;
} }
conn_list_add(ncn); connection_add(ncn);
cp cp
return 0; return 0;
} }
@ -1230,12 +1246,15 @@ cp
*/ */
void check_network_activity(fd_set *f) void check_network_activity(fd_set *f)
{ {
conn_list_t *p; connection_t *p;
rbl_t *rbl;
cp cp
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{ {
p = (connection_t *)rbl->data;
if(p->status.remove) if(p->status.remove)
continue; return;
if(p->status.dataopen) if(p->status.dataopen)
if(FD_ISSET(p->socket, f)) if(FD_ISSET(p->socket, f))
@ -1330,7 +1349,7 @@ cp
tv.tv_sec = timeout; tv.tv_sec = timeout;
tv.tv_usec = 0; tv.tv_usec = 0;
prune_conn_list(); prune_connection_tree();
build_fdset(&fset); build_fdset(&fset);
if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0) if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0)

View file

@ -16,7 +16,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: net.h,v 1.9.4.21 2000/11/04 22:57:31 guus Exp $ $Id: net.h,v 1.9.4.22 2000/11/20 19:12:13 guus Exp $
*/ */
#ifndef __TINC_NET_H__ #ifndef __TINC_NET_H__
@ -107,7 +107,7 @@ extern char *unknown;
extern char *request_name[256]; extern char *request_name[256];
extern char *status_text[10]; extern char *status_text[10];
#include "connlist.h" /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */ #include "connection.h" /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
extern int str2opt(const char *); extern int str2opt(const char *);
extern char *opt2str(int); extern char *opt2str(int);
@ -115,9 +115,9 @@ extern int send_packet(ip_t, vpn_packet_t *);
extern int setup_network_connections(void); extern int setup_network_connections(void);
extern void close_network_connections(void); extern void close_network_connections(void);
extern void main_loop(void); extern void main_loop(void);
extern int setup_vpn_connection(conn_list_t *); extern int setup_vpn_connection(connection_t *);
extern void terminate_connection(conn_list_t *); extern void terminate_connection(connection_t *);
extern void flush_queues(conn_list_t *); extern void flush_queues(connection_t *);
extern void add_queue(packet_queue_t **, void *, size_t); extern void add_queue(packet_queue_t **, void *, size_t);
#endif /* __TINC_NET_H__ */ #endif /* __TINC_NET_H__ */

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: process.c,v 1.1.2.4 2000/11/17 10:03:02 guus Exp $ $Id: process.c,v 1.1.2.5 2000/11/20 19:12:13 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -365,7 +365,7 @@ sigint_handler(int a)
RETSIGTYPE RETSIGTYPE
sigusr1_handler(int a) sigusr1_handler(int a)
{ {
dump_conn_list(); dump_connection_list();
} }
RETSIGTYPE RETSIGTYPE

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.61 2000/11/15 13:33:27 guus Exp $ $Id: protocol.c,v 1.28.4.62 2000/11/20 19:12:13 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -61,7 +61,7 @@
#include "netutl.h" #include "netutl.h"
#include "protocol.h" #include "protocol.h"
#include "meta.h" #include "meta.h"
#include "connlist.h" #include "connection.h"
#include "system.h" #include "system.h"
@ -78,7 +78,7 @@ int check_id(char *id)
/* Generic request routines - takes care of logging and error detection as well */ /* Generic request routines - takes care of logging and error detection as well */
int send_request(conn_list_t *cl, const char *format, ...) int send_request(connection_t *cl, const char *format, ...)
{ {
va_list args; va_list args;
char buffer[MAXBUFSIZE]; char buffer[MAXBUFSIZE];
@ -108,7 +108,7 @@ cp
return send_meta(cl, buffer, len); return send_meta(cl, buffer, len);
} }
int receive_request(conn_list_t *cl) int receive_request(connection_t *cl)
{ {
int request; int request;
cp cp
@ -179,7 +179,7 @@ cp
forge the key for the symmetric cipher. forge the key for the symmetric cipher.
*/ */
int send_id(conn_list_t *cl) int send_id(connection_t *cl)
{ {
cp cp
cl->allow_request = CHALLENGE; cl->allow_request = CHALLENGE;
@ -187,9 +187,9 @@ cp
return send_request(cl, "%d %s %d %lx %hd", ID, myself->name, myself->protocol_version, myself->options, myself->port); return send_request(cl, "%d %s %d %lx %hd", ID, myself->name, myself->protocol_version, myself->options, myself->port);
} }
int id_h(conn_list_t *cl) int id_h(connection_t *cl)
{ {
conn_list_t *old; connection_t *old;
config_t const *cfg; config_t const *cfg;
cp cp
if(sscanf(cl->buffer, "%*d %as %d %lx %hd", &cl->name, &cl->protocol_version, &cl->options, &cl->port) != 4) if(sscanf(cl->buffer, "%*d %as %d %lx %hd", &cl->name, &cl->protocol_version, &cl->options, &cl->port) != 4)
@ -256,7 +256,7 @@ cp
return send_challenge(cl); return send_challenge(cl);
} }
int send_challenge(conn_list_t *cl) int send_challenge(connection_t *cl)
{ {
char *buffer; char *buffer;
int len, x; int len, x;
@ -308,7 +308,7 @@ cp
return x; return x;
} }
int challenge_h(conn_list_t *cl) int challenge_h(connection_t *cl)
{ {
char *buffer; char *buffer;
int len; int len;
@ -362,7 +362,7 @@ cp
return send_chal_reply(cl); return send_chal_reply(cl);
} }
int send_chal_reply(conn_list_t *cl) int send_chal_reply(connection_t *cl)
{ {
char hash[SHA_DIGEST_LENGTH*2+1]; char hash[SHA_DIGEST_LENGTH*2+1];
cp cp
@ -392,7 +392,7 @@ cp
return send_request(cl, "%d %s", CHAL_REPLY, hash); return send_request(cl, "%d %s", CHAL_REPLY, hash);
} }
int chal_reply_h(conn_list_t *cl) int chal_reply_h(connection_t *cl)
{ {
char *hishash; char *hishash;
char myhash[SHA_DIGEST_LENGTH]; char myhash[SHA_DIGEST_LENGTH];
@ -450,7 +450,7 @@ cp
return send_id(cl); return send_id(cl);
} }
int send_metakey(conn_list_t *cl) int send_metakey(connection_t *cl)
{ {
char *buffer; char *buffer;
int len, x; int len, x;
@ -509,7 +509,7 @@ cp
return x; return x;
} }
int metakey_h(conn_list_t *cl) int metakey_h(connection_t *cl)
{ {
char *buffer; char *buffer;
int len; int len;
@ -570,7 +570,7 @@ cp
return send_metakey(cl); return send_metakey(cl);
} }
int send_ack(conn_list_t *cl) int send_ack(connection_t *cl)
{ {
int x; int x;
cp cp
@ -585,10 +585,11 @@ cp
return x; return x;
} }
int ack_h(conn_list_t *cl) int ack_h(connection_t *cl)
{ {
conn_list_t *old, *p; connection_t *old, *p;
subnet_t *s; subnet_t *subnet;
rbl_t *rbl, *rbl2;
cp cp
/* Okay, before we active the connection, we check if there is another entry /* Okay, before we active the connection, we check if there is another entry
in the connection list with the same name. If so, it presumably is an in the connection list with the same name. If so, it presumably is an
@ -622,12 +623,17 @@ cp
/* Send him our subnets */ /* Send him our subnets */
for(s = myself->subnets; s; s = s->next) RBL_FOREACH(myself->subnet_tree, rbl)
send_add_subnet(cl, s); {
subnet = (subnet_t *)rbl->data;
send_add_subnet(cl, subnet);
}
/* And send him all the hosts and their subnets we know... */ /* And send him all the hosts and their subnets we know... */
for(p = conn_list; p; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p != cl && p->status.active) if(p != cl && p->status.active)
{ {
/* Notify others of this connection */ /* Notify others of this connection */
@ -639,8 +645,12 @@ cp
send_add_host(cl, p); send_add_host(cl, p);
for(s = p->subnets; s; s = s->next) RBL_FOREACH(p->subnet_tree, rbl2)
send_add_subnet(cl, s); {
subnet = (subnet_t *)rbl2->data;
send_add_subnet(cl, subnet);
}
}
} }
cp cp
return 0; return 0;
@ -648,7 +658,7 @@ cp
/* Address and subnet information exchange */ /* Address and subnet information exchange */
int send_add_subnet(conn_list_t *cl, subnet_t *subnet) int send_add_subnet(connection_t *cl, subnet_t *subnet)
{ {
int x; int x;
char *netstr; char *netstr;
@ -660,12 +670,13 @@ cp
return x; return x;
} }
int add_subnet_h(conn_list_t *cl) int add_subnet_h(connection_t *cl)
{ {
char *subnetstr; char *subnetstr;
char *name; char *name;
conn_list_t *owner, *p; connection_t *owner, *p;
subnet_t *subnet; subnet_t *subnet;
rbl_t *rbl;
cp cp
if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 2) if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 2)
{ {
@ -721,14 +732,17 @@ cp
/* Tell the rest */ /* Tell the rest */
for(p = conn_list; p; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p->status.meta && p->status.active && p!= cl) if(p->status.meta && p->status.active && p!= cl)
send_add_subnet(p, subnet); send_add_subnet(p, subnet);
}
cp cp
return 0; return 0;
} }
int send_del_subnet(conn_list_t *cl, subnet_t *subnet) int send_del_subnet(connection_t *cl, subnet_t *subnet)
{ {
int x; int x;
char *netstr; char *netstr;
@ -740,12 +754,13 @@ cp
return x; return x;
} }
int del_subnet_h(conn_list_t *cl) int del_subnet_h(connection_t *cl)
{ {
char *subnetstr; char *subnetstr;
char *name; char *name;
conn_list_t *owner, *p; connection_t *owner, *p;
subnet_t *subnet; subnet_t *subnet;
rbl_t *rbl;
cp cp
if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 3) if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 3)
{ {
@ -801,29 +816,31 @@ cp
/* Tell the rest */ /* Tell the rest */
for(p = conn_list; p; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p->status.meta && p->status.active && p!= cl) if(p->status.meta && p->status.active && p!= cl)
send_del_subnet(p, subnet); send_del_subnet(p, subnet);
}
cp cp
return 0; return 0;
} }
/* New and closed connections notification */ /* New and closed connections notification */
int send_add_host(conn_list_t *cl, conn_list_t *other) int send_add_host(connection_t *cl, connection_t *other)
{ {
cp cp
return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST, return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
other->name, other->address, other->port, other->options); other->name, other->address, other->port, other->options);
} }
int add_host_h(conn_list_t *cl) int add_host_h(connection_t *cl)
{ {
conn_list_t *old, *new; connection_t *old, *new, *p;
conn_list_t *p; rbl_t *rbl;
cp cp
new = new_conn_list(); new = new_connection();
if(sscanf(cl->buffer, "%*d %as %lx:%d %lx", &new->name, &new->address, &new->port, &new->options) != 4) if(sscanf(cl->buffer, "%*d %as %lx:%d %lx", &new->name, &new->address, &new->port, &new->options) != 4)
{ {
@ -836,7 +853,7 @@ cp
if(check_id(new->name)) if(check_id(new->name))
{ {
syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname); syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
free_conn_list(new); free_connection(new);
return -1; return -1;
} }
@ -846,11 +863,11 @@ cp
{ {
syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname); syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
sighup = 1; sighup = 1;
free_conn_list(new); free_connection(new);
return 0; return 0;
} }
/* Fill in more of the new conn_list structure */ /* Fill in more of the new connection structure */
new->hostname = hostlookup(htonl(new->address)); new->hostname = hostlookup(htonl(new->address));
@ -863,7 +880,7 @@ cp
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"), syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
old->name, old->hostname, new->name, new->hostname); old->name, old->hostname, new->name, new->hostname);
free_conn_list(new); free_connection(new);
return 0; return 0;
} }
else else
@ -876,17 +893,20 @@ cp
} }
} }
/* Hook it up into the conn_list */ /* Hook it up into the connection */
conn_list_add(new); connection_add(new);
/* Tell the rest about the new host */ /* Tell the rest about the new host */
for(p = conn_list; p; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p->status.meta && p->status.active && p!=cl) if(p->status.meta && p->status.active && p!=cl)
send_add_host(p, new); send_add_host(p, new);
}
/* Fill in rest of conn_list structure */ /* Fill in rest of connection structure */
new->nexthop = cl; new->nexthop = cl;
new->status.active = 1; new->status.active = 1;
@ -902,20 +922,21 @@ cp
return 0; return 0;
} }
int send_del_host(conn_list_t *cl, conn_list_t *other) int send_del_host(connection_t *cl, connection_t *other)
{ {
cp cp
return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST, return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
other->name, other->address, other->port, other->options); other->name, other->address, other->port, other->options);
} }
int del_host_h(conn_list_t *cl) int del_host_h(connection_t *cl)
{ {
char *name; char *name;
ip_t address; ip_t address;
port_t port; port_t port;
long int options; long int options;
conn_list_t *old, *p; connection_t *old, *p;
rbl_t *rbl;
cp cp
if(sscanf(cl->buffer, "%*d %as %lx:%d %lx", &name, &address, &port, &options) != 4) if(sscanf(cl->buffer, "%*d %as %lx:%d %lx", &name, &address, &port, &options) != 4)
{ {
@ -969,16 +990,19 @@ cp
/* Tell the rest about the new host */ /* Tell the rest about the new host */
for(p = conn_list; p; p = p->next) RBL_FOREACH(connection_tree, rbl)
{
p = (connection_t *)rbl->data;
if(p->status.meta && p->status.active && p!=cl) if(p->status.meta && p->status.active && p!=cl)
send_del_host(p, old); send_del_host(p, old);
}
cp cp
return 0; return 0;
} }
/* Status and error notification routines */ /* Status and error notification routines */
int send_status(conn_list_t *cl, int statusno, char *statusstring) int send_status(connection_t *cl, int statusno, char *statusstring)
{ {
cp cp
if(!statusstring) if(!statusstring)
@ -987,7 +1011,7 @@ cp
return send_request(cl, "%d %d %s", STATUS, statusno, statusstring); return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
} }
int status_h(conn_list_t *cl) int status_h(connection_t *cl)
{ {
int statusno; int statusno;
char *statusstring; char *statusstring;
@ -1010,7 +1034,7 @@ cp
return 0; return 0;
} }
int send_error(conn_list_t *cl, int errno, char *errstring) int send_error(connection_t *cl, int errno, char *errstring)
{ {
cp cp
if(!errstring) if(!errstring)
@ -1018,7 +1042,7 @@ cp
return send_request(cl, "%d %d %s", ERROR, errno, errstring); return send_request(cl, "%d %d %s", ERROR, errno, errstring);
} }
int error_h(conn_list_t *cl) int error_h(connection_t *cl)
{ {
int errno; int errno;
char *errorstring; char *errorstring;
@ -1042,13 +1066,13 @@ cp
return 0; return 0;
} }
int send_termreq(conn_list_t *cl) int send_termreq(connection_t *cl)
{ {
cp cp
return send_request(cl, "%d", TERMREQ); return send_request(cl, "%d", TERMREQ);
} }
int termreq_h(conn_list_t *cl) int termreq_h(connection_t *cl)
{ {
cp cp
terminate_connection(cl); terminate_connection(cl);
@ -1058,7 +1082,7 @@ cp
/* Keepalive routines - FIXME: needs a closer look */ /* Keepalive routines - FIXME: needs a closer look */
int send_ping(conn_list_t *cl) int send_ping(connection_t *cl)
{ {
cp cp
cl->status.pinged = 1; cl->status.pinged = 1;
@ -1067,19 +1091,19 @@ cp
return send_request(cl, "%d", PING); return send_request(cl, "%d", PING);
} }
int ping_h(conn_list_t *cl) int ping_h(connection_t *cl)
{ {
cp cp
return send_pong(cl); return send_pong(cl);
} }
int send_pong(conn_list_t *cl) int send_pong(connection_t *cl)
{ {
cp cp
return send_request(cl, "%d", PONG); return send_request(cl, "%d", PONG);
} }
int pong_h(conn_list_t *cl) int pong_h(connection_t *cl)
{ {
cp cp
cl->status.pinged = 0; cl->status.pinged = 0;
@ -1089,24 +1113,25 @@ cp
/* Key exchange */ /* Key exchange */
int send_key_changed(conn_list_t *from, conn_list_t *cl) int send_key_changed(connection_t *from, connection_t *cl)
{ {
conn_list_t *p; connection_t *p;
rbl_t *rbl;
cp cp
for(p = conn_list; p != NULL; p = p->next) RBL_FOREACH(connection_tree, rbl)
{ {
if(p!=cl && p->status.meta && p->status.active) p = (connection_t *)rbl->data;
send_request(p, "%d %s", KEY_CHANGED, if(p != cl && p->status.meta && p->status.active)
from->name); send_request(p, "%d %s", KEY_CHANGED, from->name);
} }
cp cp
return 0; return 0;
} }
int key_changed_h(conn_list_t *cl) int key_changed_h(connection_t *cl)
{ {
char *from_id; char *from_id;
conn_list_t *from; connection_t *from;
cp cp
if(sscanf(cl->buffer, "%*d %as", &from_id) != 1) if(sscanf(cl->buffer, "%*d %as", &from_id) != 1)
{ {
@ -1133,17 +1158,17 @@ cp
return 0; return 0;
} }
int send_req_key(conn_list_t *from, conn_list_t *to) int send_req_key(connection_t *from, connection_t *to)
{ {
cp cp
return send_request(to->nexthop, "%d %s %s", REQ_KEY, return send_request(to->nexthop, "%d %s %s", REQ_KEY,
from->name, to->name); from->name, to->name);
} }
int req_key_h(conn_list_t *cl) int req_key_h(connection_t *cl)
{ {
char *from_id, *to_id; char *from_id, *to_id;
conn_list_t *from, *to; connection_t *from, *to;
char pktkey[129]; char pktkey[129];
cp cp
if(sscanf(cl->buffer, "%*d %as %as", &from_id, &to_id) != 2) if(sscanf(cl->buffer, "%*d %as %as", &from_id, &to_id) != 2)
@ -1194,18 +1219,18 @@ cp
return 0; return 0;
} }
int send_ans_key(conn_list_t *from, conn_list_t *to, char *pktkey) int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
{ {
cp cp
return send_request(to->nexthop, "%d %s %s %s", ANS_KEY, return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
from->name, to->name, pktkey); from->name, to->name, pktkey);
} }
int ans_key_h(conn_list_t *cl) int ans_key_h(connection_t *cl)
{ {
char *from_id, *to_id, *pktkey; char *from_id, *to_id, *pktkey;
int keylength; int keylength;
conn_list_t *from, *to; connection_t *from, *to;
cp cp
if(sscanf(cl->buffer, "%*d %as %as %as", &from_id, &to_id, &pktkey) != 3) if(sscanf(cl->buffer, "%*d %as %as %as", &from_id, &to_id, &pktkey) != 3)
{ {
@ -1268,7 +1293,7 @@ cp
/* Jumptable for the request handlers */ /* Jumptable for the request handlers */
int (*request_handlers[])(conn_list_t*) = { int (*request_handlers[])(connection_t*) = {
id_h, challenge_h, chal_reply_h, metakey_h, ack_h, id_h, challenge_h, chal_reply_h, metakey_h, ack_h,
status_h, error_h, termreq_h, status_h, error_h, termreq_h,
ping_h, pong_h, ping_h, pong_h,

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.15 2000/11/03 22:35:12 zarq Exp $ $Id: protocol.h,v 1.5.4.16 2000/11/20 19:12:16 guus Exp $
*/ */
#ifndef __TINC_PROTOCOL_H__ #ifndef __TINC_PROTOCOL_H__
@ -45,31 +45,31 @@ enum {
LAST /* Guardian for the highest request number */ LAST /* Guardian for the highest request number */
}; };
extern int (*request_handlers[])(conn_list_t*); extern int (*request_handlers[])(connection_t*);
extern int send_id(conn_list_t*); extern int send_id(connection_t*);
extern int send_challenge(conn_list_t*); extern int send_challenge(connection_t*);
extern int send_chal_reply(conn_list_t*); extern int send_chal_reply(connection_t*);
extern int send_metakey(conn_list_t*); extern int send_metakey(connection_t*);
extern int send_ack(conn_list_t*); extern int send_ack(connection_t*);
extern int send_status(conn_list_t*, int, char*); extern int send_status(connection_t*, int, char*);
extern int send_error(conn_list_t*, int, char*); extern int send_error(connection_t*, int, char*);
extern int send_termreq(conn_list_t*); extern int send_termreq(connection_t*);
extern int send_ping(conn_list_t*); extern int send_ping(connection_t*);
extern int send_pong(conn_list_t*); extern int send_pong(connection_t*);
extern int send_add_host(conn_list_t*, conn_list_t*); extern int send_add_host(connection_t*, connection_t*);
extern int send_del_host(conn_list_t*, conn_list_t*); extern int send_del_host(connection_t*, connection_t*);
extern int send_add_subnet(conn_list_t*, subnet_t*); extern int send_add_subnet(connection_t*, subnet_t*);
extern int send_del_subnet(conn_list_t*, subnet_t*); extern int send_del_subnet(connection_t*, subnet_t*);
extern int send_key_changed(conn_list_t*, conn_list_t*); extern int send_key_changed(connection_t*, connection_t*);
extern int send_req_key(conn_list_t*, conn_list_t*); extern int send_req_key(connection_t*, connection_t*);
extern int send_ans_key(conn_list_t*, conn_list_t*, char*); extern int send_ans_key(connection_t*, connection_t*, char*);
/* Old functions */ /* Old functions */
extern int send_tcppacket(conn_list_t *, void *, int); extern int send_tcppacket(connection_t *, void *, int);
extern int notify_others(conn_list_t *, conn_list_t *, int (*function)(conn_list_t*, conn_list_t*)); extern int notify_others(connection_t *, connection_t *, int (*function)(connection_t*, connection_t*));
extern int receive_request(conn_list_t *); extern int receive_request(connection_t *);
extern int check_id(char *); extern int check_id(char *);
#endif /* __TINC_PROTOCOL_H__ */ #endif /* __TINC_PROTOCOL_H__ */

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: route.c,v 1.1.2.2 2000/11/04 22:57:33 guus Exp $ $Id: route.c,v 1.1.2.3 2000/11/20 19:12:17 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -26,13 +26,13 @@
#include <xalloc.h> #include <xalloc.h>
#include "net.h" #include "net.h"
#include "connlist.h" #include "connection.h"
#include "system.h" #include "system.h"
int routing_mode = 0; /* Will be used to determine if we route by MAC or by payload's protocol */ int routing_mode = 0; /* Will be used to determine if we route by MAC or by payload's protocol */
conn_list_t *route_packet(vpn_packet_t *packet) connection_t *route_packet(vpn_packet_t *packet)
{ {
unsigned short type; unsigned short type;
cp cp
@ -64,9 +64,9 @@ cp
} }
} }
conn_list_t *route_mac(vpn_packet_t *packet) connection_t *route_mac(vpn_packet_t *packet)
{ {
conn_list_t *cl; connection_t *cl;
cp cp
cl = lookup_subnet_mac((mac_t *)(&packet.data[6])); cl = lookup_subnet_mac((mac_t *)(&packet.data[6]));
if(!cl) if(!cl)
@ -85,10 +85,10 @@ cp
} }
conn_list_t *route_ipv4(vpn_packet_t *packet) connection_t *route_ipv4(vpn_packet_t *packet)
{ {
ipv4_t dest; ipv4_t dest;
conn_list_t *cl; connection_t *cl;
cp cp
dest = ntohl(*((unsigned long*)(&packet.data[30]); dest = ntohl(*((unsigned long*)(&packet.data[30]);
@ -103,7 +103,7 @@ cp
return cl; return cl;
} }
conn_list_t *route_ipv6(vpn_packet_t *packet) connection_t *route_ipv6(vpn_packet_t *packet)
{ {
cp cp
syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not implemented yet")); syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not implemented yet"));

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: subnet.c,v 1.1.2.11 2000/11/04 22:57:33 guus Exp $ $Id: subnet.c,v 1.1.2.12 2000/11/20 19:12:17 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -27,15 +27,83 @@
#include "conf.h" #include "conf.h"
#include "net.h" #include "net.h"
#include "connection.h"
#include "subnet.h" #include "subnet.h"
#include "system.h" #include "system.h"
#include <utils.h> #include <utils.h>
#include <xalloc.h> #include <xalloc.h>
#include <rbl.h>
/* lists type of subnet */ /* lists type of subnet */
subnet_t *subnet_list[SUBNET_TYPES] = { NULL }; rbltree_t _subnet_tree = { NULL };
rbltree_t *subnet_tree = &_subnet_tree;
/* Subnet comparison */
int subnet_compare_mac(subnet_t *a, subnet_t *b)
{
cp
return memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t));
}
int subnet_compare_ipv4(subnet_t *a, subnet_t *b)
{
cp
/* If the subnet of a falls within the range of subnet b,
then we consider a smaller then b.
Otherwise, the addresses alone (and not the subnet masks) will be compared.
*/
if(a->net.ipv4.mask > b->net.ipv4.mask)
if((a->net.ipv4.address & b->net.ipv4.mask) == b->net.ipv4.address)
return -1;
return a->net.ipv4.address - b->net.ipv4.address;
}
int subnet_compare_ipv6(subnet_t *a, subnet_t *b)
{
cp
/* Same as ipv4 case, but with nasty 128 bit addresses */
if(memcmp(&a->net.ipv6.mask, &b->net.ipv6.mask, sizeof(ipv6_t)) > 0)
if((a->net.ipv6.address.x[0] & b->net.ipv6.mask.x[0]) == b->net.ipv6.address.x[0] &&
(a->net.ipv6.address.x[1] & b->net.ipv6.mask.x[1]) == b->net.ipv6.address.x[1] &&
(a->net.ipv6.address.x[2] & b->net.ipv6.mask.x[2]) == b->net.ipv6.address.x[2] &&
(a->net.ipv6.address.x[3] & b->net.ipv6.mask.x[3]) == b->net.ipv6.address.x[3] &&
(a->net.ipv6.address.x[4] & b->net.ipv6.mask.x[4]) == b->net.ipv6.address.x[4] &&
(a->net.ipv6.address.x[5] & b->net.ipv6.mask.x[5]) == b->net.ipv6.address.x[5] &&
(a->net.ipv6.address.x[6] & b->net.ipv6.mask.x[6]) == b->net.ipv6.address.x[6] &&
(a->net.ipv6.address.x[7] & b->net.ipv6.mask.x[7]) == b->net.ipv6.address.x[7])
return -1;
return memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
}
int subnet_compare(subnet_t *a, subnet_t *b)
{
int x;
cp
x = a->type - b->type;
if(x)
return x;
switch(a->type)
{
case SUBNET_MAC:
return subnet_compare_mac(a, b);
case SUBNET_IPV4:
return subnet_compare_ipv4(a, b);
case SUBNET_IPV6:
return subnet_compare_ipv6(a, b);
default:
syslog(LOG_ERR, _("subnet_compare() was called with unknown subnet type %d, restarting!"), a->type);
sighup = 1;
return 0;
}
}
/* Allocating and freeing space for subnets */ /* Allocating and freeing space for subnets */
@ -53,87 +121,19 @@ cp
/* Linked list management */ /* Linked list management */
void subnet_add(conn_list_t *cl, subnet_t *subnet) void subnet_add(connection_t *cl, subnet_t *subnet)
{ {
subnet_t *p = NULL;
subnet_t *q = NULL;
cp cp
subnet->owner = cl; rbl_insert(subnet_tree, subnet);
rbl_insert(cl->subnet_tree, subnet);
/* Link it into the owners list of subnets (unsorted) */
subnet->next = cl->subnets;
subnet->prev = NULL;
if(subnet->next)
subnet->next->prev = subnet;
cl->subnets = subnet;
/* And now add it to the global subnet list (sorted) */
/* Sort on size of subnet mask (IPv4 only at the moment!)
Three cases: subnet_list[] = NULL -> just add this subnet
insert before first -> add it in front of list
rest: insert after another subnet
*/
cp
if(subnet_list[subnet->type])
{
p = q = subnet_list[subnet->type];
for(; p; p = p->global_next)
{
if(subnet->net.ipv4.mask >= p->net.ipv4.mask)
break;
q = p;
}
}
cp
if(p == subnet_list[subnet->type]) /* First two cases */
{
/* Insert in front */
subnet->global_next = subnet_list[subnet->type];
subnet->global_prev = NULL;
subnet_list[subnet->type] = subnet;
}
else /* Third case */
{
/* Insert after q */
subnet->global_next = q->global_next;
subnet->global_prev = q;
q->global_next = subnet;
}
cp
if(subnet->global_next)
subnet->global_next->global_prev = subnet;
cp cp
} }
void subnet_del(subnet_t *subnet) void subnet_del(subnet_t *subnet)
{ {
cp cp
/* Remove it from owner's list */ free_rbl(rbl_unlink(subnet->owner->subnet_tree, subnet));
rbl_delete(subnet_tree, subnet);
if(subnet->prev)
subnet->prev->next = subnet->next;
else
subnet->owner->subnets = subnet->next;
if(subnet->next)
subnet->next->prev = subnet->prev;
/* Remove it from the global list */
if(subnet->global_prev)
subnet->global_prev->global_next = subnet->global_next;
else
subnet_list[subnet->type] = subnet->global_next;
if(subnet->global_next)
subnet->global_next->global_prev = subnet->global_prev;
free_subnet(subnet);
cp cp
} }
@ -250,61 +250,47 @@ cp
subnet_t *lookup_subnet_mac(mac_t address) subnet_t *lookup_subnet_mac(mac_t address)
{ {
subnet_t *subnet; subnet_t subnet;
cp cp
for(subnet = subnet_list[SUBNET_MAC]; subnet != NULL; subnet = subnet->global_next) subnet.type = SUBNET_MAC;
{ subnet.net.mac.address = address;
if(memcmp(&address, &subnet->net.mac.address, sizeof(address)) == 0) return (subnet_t *)rbl_search_closest(subnet_tree, &subnet);
break;
}
cp
return subnet;
} }
subnet_t *lookup_subnet_ipv4(ipv4_t address) subnet_t *lookup_subnet_ipv4(ipv4_t address)
{ {
subnet_t *subnet; subnet_t subnet;
cp cp
for(subnet = subnet_list[SUBNET_IPV4]; subnet != NULL; subnet = subnet->global_next) subnet.type = SUBNET_IPV4;
{ subnet.net.ipv4.address = address;
if((address & subnet->net.ipv4.mask) == subnet->net.ipv4.address) subnet.net.ipv4.mask = 0xFFFFFFFF;
break; return (subnet_t *)rbl_search_closest(subnet_tree, &subnet);
}
cp
return subnet;
} }
subnet_t *lookup_subnet_ipv6(ipv6_t address) subnet_t *lookup_subnet_ipv6(ipv6_t address)
{ {
subnet_t *subnet; subnet_t subnet;
int i;
cp cp
for(subnet = subnet_list[SUBNET_IPV6]; subnet != NULL; subnet = subnet->global_next) subnet.type = SUBNET_IPV6;
{ subnet.net.ipv6.address = address;
for(i=0; i<8; i++) memset(&subnet.net.ipv6.mask, 0xFF, 16);
if((address.x[i] & subnet->net.ipv6.mask.x[i]) != subnet->net.ipv6.address.x[i]) return (subnet_t *)rbl_search_closest(subnet_tree, &subnet);
break;
if(i == 8)
break;
}
cp
return subnet;
} }
void dump_subnet_list(void) void dump_subnet_list(void)
{ {
subnet_t *subnet;
char *netstr; char *netstr;
subnet_t *subnet;
rbl_t *rbl;
cp cp
syslog(LOG_DEBUG, _("Subnet list:")); syslog(LOG_DEBUG, _("Subnet list:"));
RBL_FOREACH(subnet_tree, rbl)
for(subnet = subnet_list[SUBNET_IPV4]; subnet != NULL; subnet = subnet->global_next)
{ {
subnet = (subnet_t *)rbl->data;
netstr = net2str(subnet); netstr = net2str(subnet);
syslog(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name); syslog(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name);
free(netstr); free(netstr);
} }
syslog(LOG_DEBUG, _("End of subnet list.")); syslog(LOG_DEBUG, _("End of subnet list."));
cp cp
} }

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: subnet.h,v 1.1.2.5 2000/10/28 21:05:20 guus Exp $ $Id: subnet.h,v 1.1.2.6 2000/11/20 19:12:17 guus Exp $
*/ */
#ifndef __TINC_SUBNET_H__ #ifndef __TINC_SUBNET_H__
@ -51,8 +51,8 @@ typedef struct subnet_ipv6_t
} subnet_ipv6_t; } subnet_ipv6_t;
typedef struct subnet_t { typedef struct subnet_t {
struct conn_list_t *owner; /* the owner of this subnet */ struct connection_t *owner; /* the owner of this subnet */
struct conn_list_t *uplink; /* the uplink which we should send packets to for this subnet */ struct connection_t *uplink; /* the uplink which we should send packets to for this subnet */
struct subnet_t *prev; /* previous subnet_t for this owner */ struct subnet_t *prev; /* previous subnet_t for this owner */
struct subnet_t *next; /* next subnet_t for this owner */ struct subnet_t *next; /* next subnet_t for this owner */
@ -73,11 +73,11 @@ typedef struct subnet_t {
} subnet_t; } subnet_t;
#include "connlist.h" #include "connection.h"
extern subnet_t *new_subnet(void); extern subnet_t *new_subnet(void);
extern void free_subnet(subnet_t *); extern void free_subnet(subnet_t *);
extern void subnet_add(struct conn_list_t *, subnet_t *); extern void subnet_add(struct connection_t *, subnet_t *);
extern void subnet_del(subnet_t *); extern void subnet_del(subnet_t *);
extern char *net2str(subnet_t *); extern char *net2str(subnet_t *);
extern subnet_t *str2net(char *); extern subnet_t *str2net(char *);