From 408ca91766088b6c2d38e198b0692bf394b41248 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 20 Nov 2000 19:12:17 +0000 Subject: [PATCH] - Integrate rbl trees into tinc. --- lib/Makefile.am | 8 +- lib/rbl.c | 3 +- lib/rbl.h | 9 +- po/POTFILES.in | 2 +- src/Makefile.am | 6 +- src/conf.c | 3 +- src/{connlist.c => connection.c} | 115 ++++++++--------- src/{connlist.h => connection.h} | 54 ++++---- src/meta.c | 22 ++-- src/meta.h | 10 +- src/net.c | 141 ++++++++++++--------- src/net.h | 10 +- src/process.c | 4 +- src/protocol.c | 209 +++++++++++++++++-------------- src/protocol.h | 44 +++---- src/route.c | 16 +-- src/subnet.c | 198 ++++++++++++++--------------- src/subnet.h | 10 +- 18 files changed, 445 insertions(+), 419 deletions(-) rename src/{connlist.c => connection.c} (57%) rename src/{connlist.h => connection.h} (81%) diff --git a/lib/Makefile.am b/lib/Makefile.am index 350e8826..43629d38 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,15 +1,15 @@ ## 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 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_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 \ No newline at end of file +EXTRA_DIST = README diff --git a/lib/rbl.c b/lib/rbl.c index cf0316b7..3b97da66 100644 --- a/lib/rbl.c +++ b/lib/rbl.c @@ -17,9 +17,10 @@ along with this program; if not, write to the Free Software 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 #include #include "rbl.h" diff --git a/lib/rbl.h b/lib/rbl.h index ab6b5f99..14ef52b2 100644 --- a/lib/rbl.h +++ b/lib/rbl.h @@ -17,9 +17,14 @@ along with this program; if not, write to the Free Software 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 { /* '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_rbl(rbltree_t *, rbl_action_rbl_t); + +#endif /* __RBL_H__ */ diff --git a/po/POTFILES.in b/po/POTFILES.in index 7ec2c0f4..4abbbf84 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -6,7 +6,7 @@ lib/pidfile.c lib/utils.c src/conf.c -src/connlist.c +src/connection.c src/meta.c src/net.c src/netutl.c diff --git a/src/Makefile.am b/src/Makefile.am index c4d6576b..bb83f799 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,14 +1,14 @@ ## 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 -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 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 LIBS = @LIBS@ @INTLLIBS@ diff --git a/src/conf.c b/src/conf.c index 0a65e32d..56d1a8ac 100644 --- a/src/conf.c +++ b/src/conf.c @@ -19,7 +19,7 @@ along with this program; if not, write to the Free Software 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" @@ -39,7 +39,6 @@ #include /* for cp */ #include "config.h" -#include "connlist.h" #include "system.h" config_t *config = NULL; diff --git a/src/connlist.c b/src/connection.c similarity index 57% rename from src/connlist.c rename to src/connection.c index 5d41dcb6..dee0472a 100644 --- a/src/connlist.c +++ b/src/connection.c @@ -1,5 +1,5 @@ /* - connlist.c -- connection list management + connection.c -- connection list management Copyright (C) 2000 Guus Sliepen , 2000 Ivo Timmermans @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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" @@ -25,6 +25,8 @@ #include #include +#include + #include "net.h" /* Don't ask. */ #include "netutl.h" #include "config.h" @@ -36,14 +38,26 @@ /* Root of the connection list */ -conn_list_t *conn_list = NULL; -conn_list_t *myself = NULL; +rbltree_t *connection_tree; +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 /* initialise all those stupid pointers at once */ memset(p, '\0', sizeof(*p)); @@ -51,7 +65,7 @@ cp return p; } -void free_conn_list(conn_list_t *p) +void free_connection(connection_t *p) { cp if(p->sq) @@ -77,110 +91,83 @@ cp /* 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 - for(p = conn_list; p != NULL; ) + RBL_FOREACH(connection_tree, rbl) { - next = p->next; - - if(p->status.remove) - conn_list_del(p); - else - prev = p; - - p = next; + cl = (connection_t *) rbl->data; + if(cl->status.remove) + connection_del(cl); } 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 - for(p = conn_list; p != NULL; ) - { - next = p->next; - free_conn_list(p); - p = next; - } - - conn_list = NULL; + rbl_delete_rbltree(connection_tree); cp } /* Linked list management */ -void conn_list_add(conn_list_t *cl) +void connection_add(connection_t *cl) { cp - cl->next = conn_list; - cl->prev = NULL; - - if(cl->next) - cl->next->prev = cl; - - conn_list = cl; + rbl_insert(connection_tree, cl); cp } -void conn_list_del(conn_list_t *cl) +void connection_del(connection_t *cl) { cp - if(cl->prev) - cl->prev->next = cl->next; - else - conn_list = cl->next; - - if(cl->next) - cl->next->prev = cl->prev; - - free_conn_list(cl); + rbl_delete(connection_tree, cl); cp } /* Lookup functions */ -conn_list_t *lookup_id(char *name) +connection_t *lookup_id(char *name) { - conn_list_t *p; + connection_t cl; cp - for(p = conn_list; p != NULL; p = p->next) - if(p->status.active) - if(strcmp(name, p->name) == 0) - break; + cl.name = name; + return rbl_search(connection_tree, &cl); cp - return p; } /* Debugging */ -void dump_conn_list(void) +void dump_connection_list(void) { - conn_list_t *p; + rbl_t *rbl; + connection_t *cl; cp syslog(LOG_DEBUG, _("Connection list:")); syslog(LOG_DEBUG, _(" %s at %s port %hd flags %d sockets %d, %d status %04x"), - myself->name, myself->hostname, myself->port, myself->flags, - myself->socket, myself->meta_socket, myself->status); + myself->name, myself->hostname, myself->port, myself->flags, + 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"), - p->name, p->hostname, p->port, p->flags, - p->socket, p->meta_socket, p->status); + cl->name, cl->hostname, cl->port, cl->flags, + cl->socket, cl->meta_socket, cl->status); } - + syslog(LOG_DEBUG, _("End of connection list.")); cp } -int read_host_config(conn_list_t *cl) +int read_host_config(connection_t *cl) { char *fname; int x; diff --git a/src/connlist.h b/src/connection.h similarity index 81% rename from src/connlist.h rename to src/connection.h index 8f933bca..05972997 100644 --- a/src/connlist.h +++ b/src/connection.h @@ -1,5 +1,5 @@ /* - connlist.h -- header for connlist.c + connection.h -- header for connection.c Copyright (C) 2000 Guus Sliepen , 2000 Ivo Timmermans @@ -17,11 +17,13 @@ along with this program; if not, write to the Free Software 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__ -#define __TINC_CONNLIST_H__ +#ifndef __TINC_CONNECTION_H__ +#define __TINC_CONNECTION_H__ + +#include #include "config.h" @@ -60,7 +62,7 @@ typedef struct option_bits_t { int unused:32; } option_bits_t; -typedef struct conn_list_t { +typedef struct connection_t { char *name; /* name of this connection */ ipv4_t address; /* his real (internet) 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 *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 conn_list_t *next; /* after all, it's a list of connections */ - struct conn_list_t *prev; /* doubly linked for O(1) deletions */ -} conn_list_t; - -#include "subnet.h" - -extern conn_list_t *conn_list; -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__ */ +} connection_t; + +extern rbltree_t *connection_tree; +extern connection_t *myself; + +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); + +#endif /* __TINC_CONNECTION_H__ */ diff --git a/src/meta.c b/src/meta.c index a4cfc838..289d0b87 100644 --- a/src/meta.c +++ b/src/meta.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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" @@ -38,10 +38,11 @@ #endif #include "net.h" +#include "connection.h" #include "system.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 *bufp; @@ -71,18 +72,21 @@ cp 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 - for(p = conn_list; p != NULL; p = p->next) - if(p != cl && p->status.meta && p->status.active) - send_meta(p, buffer, length); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p != cl && p->status.meta && p->status.active) + send_meta(p, buffer, length); + } cp - return 0; } -int receive_meta(conn_list_t *cl) +int receive_meta(connection_t *cl) { int x, l = sizeof(x); int oldlen, i; diff --git a/src/meta.h b/src/meta.h index 2784947c..09df9028 100644 --- a/src/meta.h +++ b/src/meta.h @@ -17,16 +17,16 @@ along with this program; if not, write to the Free Software 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__ #define __TINC_META_H__ -#include "net.h" +#include "connection.h" -extern int send_meta(conn_list_t *, const char *, int); -extern int broadcast_meta(conn_list_t *, const char *, int); -extern int receive_meta(conn_list_t *); +extern int send_meta(connection_t *, const char *, int); +extern int broadcast_meta(connection_t *, const char *, int); +extern int receive_meta(connection_t *); #endif /* __TINC_META_H__ */ diff --git a/src/net.c b/src/net.c index 8d92cc10..adad4105 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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" @@ -67,7 +67,7 @@ #include #include "conf.h" -#include "connlist.h" +#include "connection.h" #include "list.h" #include "meta.h" #include "net.h" @@ -95,7 +95,7 @@ char *unknown = NULL; 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; int outlen, outpad; @@ -131,7 +131,7 @@ cp 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; int outlen, outpad; @@ -254,8 +254,8 @@ cp each packet, and removing it when that returned a zero exit code */ -void flush_queue(conn_list_t *cl, packet_queue_t **pq, - int (*function)(conn_list_t*,vpn_packet_t*)) +void flush_queue(connection_t *cl, packet_queue_t **pq, + int (*function)(connection_t*,vpn_packet_t*)) { queue_element_t *p, *next = NULL; cp @@ -279,7 +279,7 @@ cp void because nothing goes wrong here, packets remain in the queue if something goes wrong */ -void flush_queues(conn_list_t *cl) +void flush_queues(connection_t *cl) { cp if(cl->sq) @@ -305,7 +305,7 @@ cp */ int send_packet(ip_t to, vpn_packet_t *packet) { - conn_list_t *cl; + connection_t *cl; subnet_t *subnet; cp if((subnet = lookup_subnet_ipv4(to)) == NULL) @@ -384,6 +384,9 @@ int setup_tap_fd(void) int nfd; const char *tapfname; config_t const *cfg; +#ifdef HAVE_TUNTAP + struct ifreq ifr; +#endif cp if((cfg = get_config_val(config, config_tapdevice))) @@ -563,7 +566,7 @@ cp /* 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; struct sockaddr_in a; @@ -623,7 +626,7 @@ cp */ int setup_outgoing_connection(char *name) { - conn_list_t *ncn; + connection_t *ncn; struct hostent *h; config_t const *cfg; cp @@ -633,27 +636,27 @@ cp return -1; } - ncn = new_conn_list(); + ncn = new_connection(); asprintf(&ncn->name, "%s", name); if(read_host_config(ncn)) { syslog(LOG_ERR, _("Error reading host configuration file for %s")); - free_conn_list(ncn); + free_connection(ncn); return -1; } if(!(cfg = get_config_val(ncn->config, config_address))) { syslog(LOG_ERR, _("No address specified for %s")); - free_conn_list(ncn); + free_connection(ncn); return -1; } if(!(h = gethostbyname(cfg->data.ptr))) { syslog(LOG_ERR, _("Error looking up `%s': %m"), cfg->data.ptr); - free_conn_list(ncn); + free_connection(ncn); return -1; } @@ -664,7 +667,7 @@ cp { syslog(LOG_ERR, _("Could not set up a meta connection to %s"), ncn->hostname); - free_conn_list(ncn); + free_connection(ncn); return -1; } @@ -673,7 +676,7 @@ cp ncn->buflen = 0; ncn->last_ping_time = time(NULL); - conn_list_add(ncn); + connection_add(ncn); send_id(ncn); 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) { @@ -689,7 +692,7 @@ int setup_myself(void) config_t *next; subnet_t *net; cp - myself = new_conn_list(); + myself = new_connection(); asprintf(&myself->hostname, "MYSELF"); /* FIXME? Do hostlookup on ourselves? */ myself->flags = 0; @@ -895,10 +898,12 @@ cp */ void close_network_connections(void) { - conn_list_t *p; + rbl_t *rbl; + connection_t *p; cp - for(p = conn_list; p != NULL; p = p->next) + RBL_FOREACH(connection_tree, rbl) { + p = (connection_t *)rbl->data; p->status.active = 0; terminate_connection(p); } @@ -907,7 +912,7 @@ cp if(myself->status.active) { close(myself->meta_socket); - free_conn_list(myself); + free_connection(myself); myself = NULL; } @@ -916,7 +921,7 @@ cp /* Execute tinc-down script right after shutting down the interface */ execute_script("tinc-down"); - destroy_conn_list(); + destroy_connection_tree(); syslog(LOG_NOTICE, _("Terminating")); cp @@ -926,7 +931,7 @@ cp /* create a data (udp) socket */ -int setup_vpn_connection(conn_list_t *cl) +int setup_vpn_connection(connection_t *cl) { int nfd, flags; struct sockaddr_in a; @@ -1002,13 +1007,13 @@ cp handle an incoming tcp connect call and open 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; int len = sizeof(ci); cp - p = new_conn_list(); + p = new_connection(); if(getpeername(sfd, (struct sockaddr *) &ci, (socklen_t *) &len) < 0) { @@ -1040,16 +1045,18 @@ cp */ void build_fdset(fd_set *fs) { - conn_list_t *p; + rbl_t *rbl; + connection_t *p; cp 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) - FD_SET(p->meta_socket, fs); + FD_SET(p->meta_socket, fs); if(p->status.dataopen) - FD_SET(p->socket, fs); + FD_SET(p->socket, fs); } FD_SET(myself->meta_socket, fs); @@ -1062,7 +1069,7 @@ cp udp socket and write it to the ethertap 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; int x, l = sizeof(x); @@ -1100,10 +1107,12 @@ cp terminate a connection and notify the other 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; + rbl_t *rbl; + cp if(cl->status.remove) return; @@ -1124,21 +1133,26 @@ cp (the connection that was dropped). */ if(cl->status.meta) - for(p = conn_list; p != NULL; p = p->next) - if((p->nexthop == cl) && (p != cl)) - terminate_connection(p); /* Sounds like recursion, but p does not have a meta connection :) */ + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p->nexthop == cl && p != cl) + terminate_connection(p); + } /* Inform others of termination if it was still active */ if(cl->status.active) - for(p = conn_list; p != NULL; p = p->next) - if(p->status.meta && p->status.active && p!=cl) - send_del_host(p, cl); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p->status.meta && p->status.active && p!=cl) + send_del_host(p, cl); /* Sounds like recursion, but p does not have a meta connection :) */ + } /* Remove the associated subnets */ - for(s = cl->subnets; s; s = s->next) - subnet_del(s); + rbl_delete_rbltree(cl->subnet_tree); /* Check if this was our outgoing connection */ @@ -1164,35 +1178,37 @@ cp end does not reply in time, we consider them dead and close the connection. */ -int check_dead_connections(void) +void check_dead_connections(void) { - conn_list_t *p; time_t now; + rbl_t *rbl; + connection_t *cl; cp now = time(NULL); - for(p = conn_list; p != NULL; p = p->next) + + RBL_FOREACH(connection_tree, rbl) { - if(p->status.active && p->status.meta) - { - if(p->last_ping_time + timeout < now) + cl = (connection_t *)rbl->data; + if(cl->status.active && cl->status.meta) + { + if(cl->last_ping_time + timeout < now) { - if(p->status.pinged) + if(cl->status.pinged) { if(debug_lvl >= DEBUG_PROTOCOL) syslog(LOG_INFO, _("%s (%s) didn't respond to PING"), - p->name, p->hostname); - p->status.timeout = 1; - terminate_connection(p); + cl->name, cl->hostname); + cl->status.timeout = 1; + terminate_connection(cl); } else { - send_ping(p); + send_ping(cl); } } - } + } } cp - return 0; } /* @@ -1201,7 +1217,7 @@ cp */ int handle_new_meta_connection() { - conn_list_t *ncn; + connection_t *ncn; struct sockaddr client; int nfd, len = sizeof(client); cp @@ -1219,7 +1235,7 @@ cp return 0; } - conn_list_add(ncn); + connection_add(ncn); cp return 0; } @@ -1230,12 +1246,15 @@ cp */ void check_network_activity(fd_set *f) { - conn_list_t *p; + connection_t *p; + rbl_t *rbl; cp - for(p = conn_list; p != NULL; p = p->next) + RBL_FOREACH(connection_tree, rbl) { + p = (connection_t *)rbl->data; + if(p->status.remove) - continue; + return; if(p->status.dataopen) if(FD_ISSET(p->socket, f)) @@ -1260,7 +1279,7 @@ cp return; } } - + if(FD_ISSET(myself->meta_socket, f)) handle_new_meta_connection(); cp @@ -1330,7 +1349,7 @@ cp tv.tv_sec = timeout; tv.tv_usec = 0; - prune_conn_list(); + prune_connection_tree(); build_fdset(&fset); if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0) diff --git a/src/net.h b/src/net.h index e3d974ed..7c77fa29 100644 --- a/src/net.h +++ b/src/net.h @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software 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__ @@ -107,7 +107,7 @@ extern char *unknown; extern char *request_name[256]; 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 char *opt2str(int); @@ -115,9 +115,9 @@ extern int send_packet(ip_t, vpn_packet_t *); extern int setup_network_connections(void); extern void close_network_connections(void); extern void main_loop(void); -extern int setup_vpn_connection(conn_list_t *); -extern void terminate_connection(conn_list_t *); -extern void flush_queues(conn_list_t *); +extern int setup_vpn_connection(connection_t *); +extern void terminate_connection(connection_t *); +extern void flush_queues(connection_t *); extern void add_queue(packet_queue_t **, void *, size_t); #endif /* __TINC_NET_H__ */ diff --git a/src/process.c b/src/process.c index 5d31b8d5..6491bfc2 100644 --- a/src/process.c +++ b/src/process.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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" @@ -365,7 +365,7 @@ sigint_handler(int a) RETSIGTYPE sigusr1_handler(int a) { - dump_conn_list(); + dump_connection_list(); } RETSIGTYPE diff --git a/src/protocol.c b/src/protocol.c index dfb6ad97..75818043 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -17,7 +17,7 @@ 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.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" @@ -61,7 +61,7 @@ #include "netutl.h" #include "protocol.h" #include "meta.h" -#include "connlist.h" +#include "connection.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 */ -int send_request(conn_list_t *cl, const char *format, ...) +int send_request(connection_t *cl, const char *format, ...) { va_list args; char buffer[MAXBUFSIZE]; @@ -108,7 +108,7 @@ cp return send_meta(cl, buffer, len); } -int receive_request(conn_list_t *cl) +int receive_request(connection_t *cl) { int request; cp @@ -179,7 +179,7 @@ cp forge the key for the symmetric cipher. */ -int send_id(conn_list_t *cl) +int send_id(connection_t *cl) { cp 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); } -int id_h(conn_list_t *cl) +int id_h(connection_t *cl) { - conn_list_t *old; + connection_t *old; config_t const *cfg; cp 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); } -int send_challenge(conn_list_t *cl) +int send_challenge(connection_t *cl) { char *buffer; int len, x; @@ -308,7 +308,7 @@ cp return x; } -int challenge_h(conn_list_t *cl) +int challenge_h(connection_t *cl) { char *buffer; int len; @@ -362,7 +362,7 @@ cp 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]; cp @@ -392,7 +392,7 @@ cp 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 myhash[SHA_DIGEST_LENGTH]; @@ -450,7 +450,7 @@ cp return send_id(cl); } -int send_metakey(conn_list_t *cl) +int send_metakey(connection_t *cl) { char *buffer; int len, x; @@ -509,7 +509,7 @@ cp return x; } -int metakey_h(conn_list_t *cl) +int metakey_h(connection_t *cl) { char *buffer; int len; @@ -570,7 +570,7 @@ cp return send_metakey(cl); } -int send_ack(conn_list_t *cl) +int send_ack(connection_t *cl) { int x; cp @@ -585,10 +585,11 @@ cp return x; } -int ack_h(conn_list_t *cl) +int ack_h(connection_t *cl) { - conn_list_t *old, *p; - subnet_t *s; + connection_t *old, *p; + subnet_t *subnet; + rbl_t *rbl, *rbl2; cp /* 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 @@ -622,33 +623,42 @@ cp /* Send him our subnets */ - for(s = myself->subnets; s; s = s->next) - send_add_subnet(cl, s); - + RBL_FOREACH(myself->subnet_tree, rbl) + { + subnet = (subnet_t *)rbl->data; + send_add_subnet(cl, subnet); + } /* And send him all the hosts and their subnets we know... */ - for(p = conn_list; p; p = p->next) - if(p != cl && p->status.active) - { - /* Notify others of this connection */ - - if(p->status.meta) - send_add_host(p, cl); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + + if(p != cl && p->status.active) + { + /* Notify others of this connection */ - /* Notify new connection of everything we know */ + if(p->status.meta) + send_add_host(p, cl); - send_add_host(cl, p); - - for(s = p->subnets; s; s = s->next) - send_add_subnet(cl, s); - } + /* Notify new connection of everything we know */ + + send_add_host(cl, p); + + RBL_FOREACH(p->subnet_tree, rbl2) + { + subnet = (subnet_t *)rbl2->data; + send_add_subnet(cl, subnet); + } + } + } cp return 0; } /* 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; char *netstr; @@ -660,12 +670,13 @@ cp return x; } -int add_subnet_h(conn_list_t *cl) +int add_subnet_h(connection_t *cl) { char *subnetstr; char *name; - conn_list_t *owner, *p; + connection_t *owner, *p; subnet_t *subnet; + rbl_t *rbl; cp if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 2) { @@ -721,14 +732,17 @@ cp /* Tell the rest */ - for(p = conn_list; p; p = p->next) - if(p->status.meta && p->status.active && p!= cl) - send_add_subnet(p, subnet); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p->status.meta && p->status.active && p!= cl) + send_add_subnet(p, subnet); + } cp 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; char *netstr; @@ -740,12 +754,13 @@ cp return x; } -int del_subnet_h(conn_list_t *cl) +int del_subnet_h(connection_t *cl) { char *subnetstr; char *name; - conn_list_t *owner, *p; + connection_t *owner, *p; subnet_t *subnet; + rbl_t *rbl; cp if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 3) { @@ -801,29 +816,31 @@ cp /* Tell the rest */ - for(p = conn_list; p; p = p->next) - if(p->status.meta && p->status.active && p!= cl) - send_del_subnet(p, subnet); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p->status.meta && p->status.active && p!= cl) + send_del_subnet(p, subnet); + } cp return 0; } /* 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 return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST, 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; - conn_list_t *p; - + connection_t *old, *new, *p; + rbl_t *rbl; 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) { @@ -836,7 +853,7 @@ cp if(check_id(new->name)) { 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; } @@ -846,11 +863,11 @@ cp { syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname); sighup = 1; - free_conn_list(new); + free_connection(new); 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)); @@ -863,7 +880,7 @@ cp if(debug_lvl >= DEBUG_CONNECTIONS) syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"), old->name, old->hostname, new->name, new->hostname); - free_conn_list(new); + free_connection(new); return 0; } 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 */ - for(p = conn_list; p; p = p->next) - if(p->status.meta && p->status.active && p!=cl) - send_add_host(p, new); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p->status.meta && p->status.active && p!=cl) + send_add_host(p, new); + } - /* Fill in rest of conn_list structure */ + /* Fill in rest of connection structure */ new->nexthop = cl; new->status.active = 1; @@ -902,20 +922,21 @@ cp 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 return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST, 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; ip_t address; port_t port; long int options; - conn_list_t *old, *p; + connection_t *old, *p; + rbl_t *rbl; cp 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 */ - for(p = conn_list; p; p = p->next) - if(p->status.meta && p->status.active && p!=cl) - send_del_host(p, old); + RBL_FOREACH(connection_tree, rbl) + { + p = (connection_t *)rbl->data; + if(p->status.meta && p->status.active && p!=cl) + send_del_host(p, old); + } cp return 0; } /* 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 if(!statusstring) @@ -987,7 +1011,7 @@ cp 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; char *statusstring; @@ -1010,7 +1034,7 @@ cp return 0; } -int send_error(conn_list_t *cl, int errno, char *errstring) +int send_error(connection_t *cl, int errno, char *errstring) { cp if(!errstring) @@ -1018,7 +1042,7 @@ cp 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; char *errorstring; @@ -1042,13 +1066,13 @@ cp return 0; } -int send_termreq(conn_list_t *cl) +int send_termreq(connection_t *cl) { cp return send_request(cl, "%d", TERMREQ); } -int termreq_h(conn_list_t *cl) +int termreq_h(connection_t *cl) { cp terminate_connection(cl); @@ -1058,7 +1082,7 @@ cp /* Keepalive routines - FIXME: needs a closer look */ -int send_ping(conn_list_t *cl) +int send_ping(connection_t *cl) { cp cl->status.pinged = 1; @@ -1067,19 +1091,19 @@ cp return send_request(cl, "%d", PING); } -int ping_h(conn_list_t *cl) +int ping_h(connection_t *cl) { cp return send_pong(cl); } -int send_pong(conn_list_t *cl) +int send_pong(connection_t *cl) { cp return send_request(cl, "%d", PONG); } -int pong_h(conn_list_t *cl) +int pong_h(connection_t *cl) { cp cl->status.pinged = 0; @@ -1089,24 +1113,25 @@ cp /* 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 - for(p = conn_list; p != NULL; p = p->next) + RBL_FOREACH(connection_tree, rbl) { - if(p!=cl && p->status.meta && p->status.active) - send_request(p, "%d %s", KEY_CHANGED, - from->name); + p = (connection_t *)rbl->data; + if(p != cl && p->status.meta && p->status.active) + send_request(p, "%d %s", KEY_CHANGED, from->name); } cp return 0; } -int key_changed_h(conn_list_t *cl) +int key_changed_h(connection_t *cl) { char *from_id; - conn_list_t *from; + connection_t *from; cp if(sscanf(cl->buffer, "%*d %as", &from_id) != 1) { @@ -1133,17 +1158,17 @@ cp 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 return send_request(to->nexthop, "%d %s %s", REQ_KEY, from->name, to->name); } -int req_key_h(conn_list_t *cl) +int req_key_h(connection_t *cl) { char *from_id, *to_id; - conn_list_t *from, *to; + connection_t *from, *to; char pktkey[129]; cp if(sscanf(cl->buffer, "%*d %as %as", &from_id, &to_id) != 2) @@ -1194,18 +1219,18 @@ cp 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 return send_request(to->nexthop, "%d %s %s %s", ANS_KEY, 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; int keylength; - conn_list_t *from, *to; + connection_t *from, *to; cp if(sscanf(cl->buffer, "%*d %as %as %as", &from_id, &to_id, &pktkey) != 3) { @@ -1268,7 +1293,7 @@ cp /* 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, status_h, error_h, termreq_h, ping_h, pong_h, diff --git a/src/protocol.h b/src/protocol.h index 82e3f903..79bda43c 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,7 +17,7 @@ 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.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__ @@ -45,31 +45,31 @@ enum { 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_challenge(conn_list_t*); -extern int send_chal_reply(conn_list_t*); -extern int send_metakey(conn_list_t*); -extern int send_ack(conn_list_t*); -extern int send_status(conn_list_t*, int, char*); -extern int send_error(conn_list_t*, int, char*); -extern int send_termreq(conn_list_t*); -extern int send_ping(conn_list_t*); -extern int send_pong(conn_list_t*); -extern int send_add_host(conn_list_t*, conn_list_t*); -extern int send_del_host(conn_list_t*, conn_list_t*); -extern int send_add_subnet(conn_list_t*, subnet_t*); -extern int send_del_subnet(conn_list_t*, subnet_t*); -extern int send_key_changed(conn_list_t*, conn_list_t*); -extern int send_req_key(conn_list_t*, conn_list_t*); -extern int send_ans_key(conn_list_t*, conn_list_t*, char*); +extern int send_id(connection_t*); +extern int send_challenge(connection_t*); +extern int send_chal_reply(connection_t*); +extern int send_metakey(connection_t*); +extern int send_ack(connection_t*); +extern int send_status(connection_t*, int, char*); +extern int send_error(connection_t*, int, char*); +extern int send_termreq(connection_t*); +extern int send_ping(connection_t*); +extern int send_pong(connection_t*); +extern int send_add_host(connection_t*, connection_t*); +extern int send_del_host(connection_t*, connection_t*); +extern int send_add_subnet(connection_t*, subnet_t*); +extern int send_del_subnet(connection_t*, subnet_t*); +extern int send_key_changed(connection_t*, connection_t*); +extern int send_req_key(connection_t*, connection_t*); +extern int send_ans_key(connection_t*, connection_t*, char*); /* Old functions */ -extern int send_tcppacket(conn_list_t *, void *, int); -extern int notify_others(conn_list_t *, conn_list_t *, int (*function)(conn_list_t*, conn_list_t*)); -extern int receive_request(conn_list_t *); +extern int send_tcppacket(connection_t *, void *, int); +extern int notify_others(connection_t *, connection_t *, int (*function)(connection_t*, connection_t*)); +extern int receive_request(connection_t *); extern int check_id(char *); #endif /* __TINC_PROTOCOL_H__ */ diff --git a/src/route.c b/src/route.c index 0509b962..46206654 100644 --- a/src/route.c +++ b/src/route.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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" @@ -26,13 +26,13 @@ #include #include "net.h" -#include "connlist.h" +#include "connection.h" #include "system.h" 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; 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 cl = lookup_subnet_mac((mac_t *)(&packet.data[6])); 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; - conn_list_t *cl; + connection_t *cl; cp dest = ntohl(*((unsigned long*)(&packet.data[30]); @@ -103,7 +103,7 @@ cp return cl; } -conn_list_t *route_ipv6(vpn_packet_t *packet) +connection_t *route_ipv6(vpn_packet_t *packet) { cp syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not implemented yet")); diff --git a/src/subnet.c b/src/subnet.c index 6ca3feef..b2ced415 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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" @@ -27,113 +27,113 @@ #include "conf.h" #include "net.h" +#include "connection.h" #include "subnet.h" #include "system.h" #include #include +#include /* lists type of subnet */ -subnet_t *subnet_list[SUBNET_TYPES] = { NULL }; +rbltree_t _subnet_tree = { NULL }; +rbltree_t *subnet_tree = &_subnet_tree; -/* Allocating and freeing space for subnets */ +/* Subnet comparison */ -subnet_t *new_subnet(void) +int subnet_compare_mac(subnet_t *a, subnet_t *b) { cp - return (subnet_t *)xmalloc(sizeof(subnet_t)); + return memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t)); } -void free_subnet(subnet_t *subnet) +int subnet_compare_ipv4(subnet_t *a, subnet_t *b) { cp - free(subnet); -} + /* 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; -/* Linked list management */ + return a->net.ipv4.address - b->net.ipv4.address; +} -void subnet_add(conn_list_t *cl, subnet_t *subnet) +int subnet_compare_ipv6(subnet_t *a, subnet_t *b) { - subnet_t *p = NULL; - subnet_t *q = NULL; cp - subnet->owner = cl; - - /* 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; + /* Same as ipv4 case, but with nasty 128 bit addresses */ - /* And now add it to the global subnet list (sorted) */ - - /* Sort on size of subnet mask (IPv4 only at the moment!) + 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; - 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; + return memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); +} - q = p; - } - } +int subnet_compare(subnet_t *a, subnet_t *b) +{ + int x; cp - if(p == subnet_list[subnet->type]) /* First two cases */ + x = a->type - b->type; + if(x) + return x; + + switch(a->type) { - /* 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; + 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; } -cp - if(subnet->global_next) - subnet->global_next->global_prev = subnet; -cp } -void subnet_del(subnet_t *subnet) +/* Allocating and freeing space for subnets */ + +subnet_t *new_subnet(void) { cp - /* Remove it from owner's list */ + return (subnet_t *)xmalloc(sizeof(subnet_t)); +} - if(subnet->prev) - subnet->prev->next = subnet->next; - else - subnet->owner->subnets = subnet->next; +void free_subnet(subnet_t *subnet) +{ +cp + free(subnet); +} - if(subnet->next) - subnet->next->prev = subnet->prev; +/* Linked list management */ - /* 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; +void subnet_add(connection_t *cl, subnet_t *subnet) +{ +cp + rbl_insert(subnet_tree, subnet); + rbl_insert(cl->subnet_tree, subnet); +cp +} - if(subnet->global_next) - subnet->global_next->global_prev = subnet->global_prev; - - free_subnet(subnet); +void subnet_del(subnet_t *subnet) +{ +cp + free_rbl(rbl_unlink(subnet->owner->subnet_tree, subnet)); + rbl_delete(subnet_tree, subnet); cp } @@ -250,61 +250,47 @@ cp subnet_t *lookup_subnet_mac(mac_t address) { - subnet_t *subnet; -cp - for(subnet = subnet_list[SUBNET_MAC]; subnet != NULL; subnet = subnet->global_next) - { - if(memcmp(&address, &subnet->net.mac.address, sizeof(address)) == 0) - break; - } + subnet_t subnet; cp - return subnet; + subnet.type = SUBNET_MAC; + subnet.net.mac.address = address; + return (subnet_t *)rbl_search_closest(subnet_tree, &subnet); } subnet_t *lookup_subnet_ipv4(ipv4_t address) { - subnet_t *subnet; + subnet_t subnet; cp - for(subnet = subnet_list[SUBNET_IPV4]; subnet != NULL; subnet = subnet->global_next) - { - if((address & subnet->net.ipv4.mask) == subnet->net.ipv4.address) - break; - } -cp - return subnet; + subnet.type = SUBNET_IPV4; + subnet.net.ipv4.address = address; + subnet.net.ipv4.mask = 0xFFFFFFFF; + return (subnet_t *)rbl_search_closest(subnet_tree, &subnet); } subnet_t *lookup_subnet_ipv6(ipv6_t address) { - subnet_t *subnet; - int i; + subnet_t subnet; cp - for(subnet = subnet_list[SUBNET_IPV6]; subnet != NULL; subnet = subnet->global_next) - { - for(i=0; i<8; i++) - if((address.x[i] & subnet->net.ipv6.mask.x[i]) != subnet->net.ipv6.address.x[i]) - break; - if(i == 8) - break; - } -cp - return subnet; + subnet.type = SUBNET_IPV6; + subnet.net.ipv6.address = address; + memset(&subnet.net.ipv6.mask, 0xFF, 16); + return (subnet_t *)rbl_search_closest(subnet_tree, &subnet); } void dump_subnet_list(void) { - subnet_t *subnet; char *netstr; + subnet_t *subnet; + rbl_t *rbl; cp syslog(LOG_DEBUG, _("Subnet list:")); - - for(subnet = subnet_list[SUBNET_IPV4]; subnet != NULL; subnet = subnet->global_next) + RBL_FOREACH(subnet_tree, rbl) { + subnet = (subnet_t *)rbl->data; netstr = net2str(subnet); syslog(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name); free(netstr); } - syslog(LOG_DEBUG, _("End of subnet list.")); cp } diff --git a/src/subnet.h b/src/subnet.h index 994c541c..b409fd46 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software 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__ @@ -51,8 +51,8 @@ typedef struct subnet_ipv6_t } subnet_ipv6_t; typedef struct subnet_t { - struct conn_list_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 *owner; /* the owner of 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 *next; /* next subnet_t for this owner */ @@ -73,11 +73,11 @@ typedef struct subnet_t { } subnet_t; -#include "connlist.h" +#include "connection.h" extern subnet_t *new_subnet(void); 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 char *net2str(subnet_t *); extern subnet_t *str2net(char *); -- 2.20.1