## 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
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 <stdlib.h>
#include <xalloc.h>
#include "rbl.h"
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 */
extern void rbl_foreach(rbltree_t *, rbl_action_t);
extern void rbl_foreach_rbl(rbltree_t *, rbl_action_rbl_t);
+
+#endif /* __RBL_H__ */
lib/pidfile.c
lib/utils.c
src/conf.c
-src/connlist.c
+src/connection.c
src/meta.c
src/net.c
src/netutl.c
## 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@
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"
#include <utils.h> /* for cp */
#include "config.h"
-#include "connlist.h"
#include "system.h"
config_t *config = NULL;
--- /dev/null
+/*
+ connection.c -- connection list management
+ Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>,
+ 2000 Ivo Timmermans <itimmermans@bigfoot.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: connection.c,v 1.1.2.1 2000/11/20 19:12:11 guus Exp $
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <syslog.h>
+
+#include <rbl.h>
+
+#include "net.h" /* Don't ask. */
+#include "netutl.h"
+#include "config.h"
+#include "conf.h"
+#include <utils.h>
+
+#include "xalloc.h"
+#include "system.h"
+
+/* Root of the connection list */
+
+rbltree_t *connection_tree;
+connection_t *myself = NULL;
+
+/* Initialization and callbacks */
+
+int connection_compare(connection_t *a, connection_t *b)
+{
+ 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));
+cp
+ return p;
+}
+
+void free_connection(connection_t *p)
+{
+cp
+ if(p->sq)
+ destroy_queue(p->sq);
+ if(p->rq)
+ destroy_queue(p->rq);
+ if(p->name && p->name!=unknown)
+ free(p->name);
+ if(p->hostname)
+ free(p->hostname);
+ if(p->rsa_key)
+ RSA_free(p->rsa_key);
+ if(p->cipher_pktkey)
+ free(p->cipher_pktkey);
+ if(p->buffer)
+ free(p->buffer);
+ if(p->config)
+ clear_config(&p->config);
+ free(p);
+cp
+}
+
+/*
+ remove all marked connections
+*/
+void prune_connection_tree(void)
+{
+ rbl_t *rbl;
+ connection_t *cl;
+cp
+ RBL_FOREACH(connection_tree, rbl)
+ {
+ cl = (connection_t *) rbl->data;
+ if(cl->status.remove)
+ connection_del(cl);
+ }
+cp
+}
+
+/*
+ free all elements of connection
+*/
+void destroy_connection_tree(void)
+{
+cp
+ rbl_delete_rbltree(connection_tree);
+cp
+}
+
+/* Linked list management */
+
+void connection_add(connection_t *cl)
+{
+cp
+ rbl_insert(connection_tree, cl);
+cp
+}
+
+void connection_del(connection_t *cl)
+{
+cp
+ rbl_delete(connection_tree, cl);
+cp
+}
+
+/* Lookup functions */
+
+connection_t *lookup_id(char *name)
+{
+ connection_t cl;
+cp
+ cl.name = name;
+ return rbl_search(connection_tree, &cl);
+cp
+}
+
+/* Debugging */
+
+void dump_connection_list(void)
+{
+ 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);
+
+ 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"),
+ 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(connection_t *cl)
+{
+ char *fname;
+ int x;
+cp
+ asprintf(&fname, "%s/hosts/%s", confbase, cl->name);
+ x = read_config_file(&cl->config, fname);
+ free(fname);
+cp
+ return x;
+}
--- /dev/null
+/*
+ connection.h -- header for connection.c
+ Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>,
+ 2000 Ivo Timmermans <itimmermans@bigfoot.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: connection.h,v 1.1.2.1 2000/11/20 19:12:11 guus Exp $
+*/
+
+#ifndef __TINC_CONNECTION_H__
+#define __TINC_CONNECTION_H__
+
+#include <rbl.h>
+
+#include "config.h"
+
+#ifdef HAVE_OPENSSL_EVP_H
+# include <openssl/evp.h>
+#else
+# include <evp.h>
+#endif
+
+#ifdef HAVE_OPENSSL_RSA_H
+# include <openssl/rsa.h>
+#else
+# include <rsa.h>
+#endif
+
+#include "net.h"
+#include "conf.h"
+
+typedef struct status_bits_t {
+ int pinged:1; /* sent ping */
+ int meta:1; /* meta connection exists */
+ int active:1; /* 1 if active.. */
+ int outgoing:1; /* I myself asked for this conn */
+ int termreq:1; /* the termination of this connection was requested */
+ int remove:1; /* Set to 1 if you want this connection removed */
+ int timeout:1; /* 1 if gotten timeout */
+ int validkey:1; /* 1 if we currently have a valid key for him */
+ int waitingforkey:1; /* 1 if we already sent out a request */
+ int dataopen:1; /* 1 if we have a valid UDP connection open */
+ int encryptout:1; /* 1 if we can encrypt outgoing traffic */
+ int decryptin:1; /* 1 if we have to decrypt incoming traffic */
+ int unused:18;
+} status_bits_t;
+
+typedef struct option_bits_t {
+ int unused:32;
+} option_bits_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 */
+ short unsigned int port; /* his portnumber */
+ int protocol_version; /* used protocol */
+ long unsigned int options; /* options turned on for this connection */
+
+ int flags; /* his flags */
+ int socket; /* our udp vpn socket */
+ int meta_socket; /* our tcp meta socket */
+ status_bits_t status; /* status info */
+ packet_queue_t *sq; /* pending outgoing packets */
+ packet_queue_t *rq; /* pending incoming packets (they have no
+ valid key to be decrypted with) */
+ RSA *rsa_key; /* the public/private key */
+
+ EVP_CIPHER_CTX *cipher_inctx; /* Context of encrypted meta data that will come from him to us */
+ EVP_CIPHER_CTX *cipher_outctx; /* Context of encrypted meta data that will be sent from us to him */
+ char *cipher_inkey; /* His symmetric meta key */
+ char *cipher_outkey; /* Our symmetric meta key */
+
+ EVP_CIPHER *cipher_pkttype; /* Cipher type for encrypted vpn packets */
+ char *cipher_pktkey; /* Cipher key and iv */
+ int cipher_pktkeylength; /* Cipher key and iv length*/
+
+ char *buffer; /* metadata input buffer */
+ int buflen; /* bytes read into buffer */
+ int reqlen; /* length of first request in buffer */
+ int allow_request; /* defined if there's only one request possible */
+
+ time_t last_ping_time; /* last time we saw some activity from the other end */
+
+ char *mychallenge; /* challenge we received from him */
+ char *hischallenge; /* challenge we sent to him */
+
+ struct connection_t *nexthop; /* nearest meta-hop in this direction */
+
+ 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 */
+} 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__ */
+++ /dev/null
-/*
- connlist.c -- connection list management
- Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>,
- 2000 Ivo Timmermans <itimmermans@bigfoot.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- 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 $
-*/
-
-#include "config.h"
-
-#include <stdio.h>
-#include <syslog.h>
-
-#include "net.h" /* Don't ask. */
-#include "netutl.h"
-#include "config.h"
-#include "conf.h"
-#include <utils.h>
-
-#include "xalloc.h"
-#include "system.h"
-
-/* Root of the connection list */
-
-conn_list_t *conn_list = NULL;
-conn_list_t *myself = NULL;
-
-/* Creation and deletion of conn_list elements */
-
-conn_list_t *new_conn_list(void)
-{
- conn_list_t *p = (conn_list_t *)xmalloc(sizeof(*p));
-cp
- /* initialise all those stupid pointers at once */
- memset(p, '\0', sizeof(*p));
-cp
- return p;
-}
-
-void free_conn_list(conn_list_t *p)
-{
-cp
- if(p->sq)
- destroy_queue(p->sq);
- if(p->rq)
- destroy_queue(p->rq);
- if(p->name && p->name!=unknown)
- free(p->name);
- if(p->hostname)
- free(p->hostname);
- if(p->rsa_key)
- RSA_free(p->rsa_key);
- if(p->cipher_pktkey)
- free(p->cipher_pktkey);
- if(p->buffer)
- free(p->buffer);
- if(p->config)
- clear_config(&p->config);
- free(p);
-cp
-}
-
-/*
- remove all marked connections
-*/
-void prune_conn_list(void)
-{
- conn_list_t *p, *prev = NULL, *next = NULL;
-cp
- for(p = conn_list; p != NULL; )
- {
- next = p->next;
-
- if(p->status.remove)
- conn_list_del(p);
- else
- prev = p;
-
- p = next;
- }
-cp
-}
-
-/*
- free all elements of conn_list
-*/
-void destroy_conn_list(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;
-cp
-}
-
-/* Linked list management */
-
-void conn_list_add(conn_list_t *cl)
-{
-cp
- cl->next = conn_list;
- cl->prev = NULL;
-
- if(cl->next)
- cl->next->prev = cl;
-
- conn_list = cl;
-cp
-}
-
-void conn_list_del(conn_list_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);
-cp
-}
-
-/* Lookup functions */
-
-conn_list_t *lookup_id(char *name)
-{
- conn_list_t *p;
-cp
- for(p = conn_list; p != NULL; p = p->next)
- if(p->status.active)
- if(strcmp(name, p->name) == 0)
- break;
-cp
- return p;
-}
-
-/* Debugging */
-
-void dump_conn_list(void)
-{
- conn_list_t *p;
-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);
-
- for(p = conn_list; p != NULL; p = p->next)
- {
- 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);
- }
-
- syslog(LOG_DEBUG, _("End of connection list."));
-cp
-}
-
-int read_host_config(conn_list_t *cl)
-{
- char *fname;
- int x;
-cp
- asprintf(&fname, "%s/hosts/%s", confbase, cl->name);
- x = read_config_file(&cl->config, fname);
- free(fname);
-cp
- return x;
-}
+++ /dev/null
-/*
- connlist.h -- header for connlist.c
- Copyright (C) 2000 Guus Sliepen <guus@sliepen.warande.net>,
- 2000 Ivo Timmermans <itimmermans@bigfoot.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- 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 $
-*/
-
-#ifndef __TINC_CONNLIST_H__
-#define __TINC_CONNLIST_H__
-
-#include "config.h"
-
-#ifdef HAVE_OPENSSL_EVP_H
-# include <openssl/evp.h>
-#else
-# include <evp.h>
-#endif
-
-#ifdef HAVE_OPENSSL_RSA_H
-# include <openssl/rsa.h>
-#else
-# include <rsa.h>
-#endif
-
-#include "net.h"
-#include "conf.h"
-
-typedef struct status_bits_t {
- int pinged:1; /* sent ping */
- int meta:1; /* meta connection exists */
- int active:1; /* 1 if active.. */
- int outgoing:1; /* I myself asked for this conn */
- int termreq:1; /* the termination of this connection was requested */
- int remove:1; /* Set to 1 if you want this connection removed */
- int timeout:1; /* 1 if gotten timeout */
- int validkey:1; /* 1 if we currently have a valid key for him */
- int waitingforkey:1; /* 1 if we already sent out a request */
- int dataopen:1; /* 1 if we have a valid UDP connection open */
- int encryptout:1; /* 1 if we can encrypt outgoing traffic */
- int decryptin:1; /* 1 if we have to decrypt incoming traffic */
- int unused:18;
-} status_bits_t;
-
-typedef struct option_bits_t {
- int unused:32;
-} option_bits_t;
-
-typedef struct conn_list_t {
- char *name; /* name of this connection */
- ipv4_t address; /* his real (internet) ip */
- char *hostname; /* the hostname of its real ip */
- short unsigned int port; /* his portnumber */
- int protocol_version; /* used protocol */
- long unsigned int options; /* options turned on for this connection */
-
- int flags; /* his flags */
- int socket; /* our udp vpn socket */
- int meta_socket; /* our tcp meta socket */
- status_bits_t status; /* status info */
- packet_queue_t *sq; /* pending outgoing packets */
- packet_queue_t *rq; /* pending incoming packets (they have no
- valid key to be decrypted with) */
- RSA *rsa_key; /* the public/private key */
-
- EVP_CIPHER_CTX *cipher_inctx; /* Context of encrypted meta data that will come from him to us */
- EVP_CIPHER_CTX *cipher_outctx; /* Context of encrypted meta data that will be sent from us to him */
- char *cipher_inkey; /* His symmetric meta key */
- char *cipher_outkey; /* Our symmetric meta key */
-
- EVP_CIPHER *cipher_pkttype; /* Cipher type for encrypted vpn packets */
- char *cipher_pktkey; /* Cipher key and iv */
- int cipher_pktkeylength; /* Cipher key and iv length*/
-
- char *buffer; /* metadata input buffer */
- int buflen; /* bytes read into buffer */
- int reqlen; /* length of first request in buffer */
- int allow_request; /* defined if there's only one request possible */
-
- time_t last_ping_time; /* last time we saw some activity from the other end */
-
- 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 subnet_t *subnets; /* Pointer to a list 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__ */
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"
#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;
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;
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__ */
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"
#include <xalloc.h>
#include "conf.h"
-#include "connlist.h"
+#include "connection.h"
#include "list.h"
#include "meta.h"
#include "net.h"
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;
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;
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
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)
*/
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)
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)))
/*
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;
*/
int setup_outgoing_connection(char *name)
{
- conn_list_t *ncn;
+ connection_t *ncn;
struct hostent *h;
config_t const *cfg;
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;
}
{
syslog(LOG_ERR, _("Could not set up a meta connection to %s"),
ncn->hostname);
- free_conn_list(ncn);
+ free_connection(ncn);
return -1;
}
ncn->buflen = 0;
ncn->last_ping_time = time(NULL);
- conn_list_add(ncn);
+ connection_add(ncn);
send_id(ncn);
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)
{
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;
*/
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);
}
if(myself->status.active)
{
close(myself->meta_socket);
- free_conn_list(myself);
+ free_connection(myself);
myself = NULL;
}
/* 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
/*
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;
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)
{
*/
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);
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);
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;
(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 */
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;
}
/*
*/
int handle_new_meta_connection()
{
- conn_list_t *ncn;
+ connection_t *ncn;
struct sockaddr client;
int nfd, len = sizeof(client);
cp
return 0;
}
- conn_list_add(ncn);
+ connection_add(ncn);
cp
return 0;
}
*/
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))
return;
}
}
-
+
if(FD_ISSET(myself->meta_socket, f))
handle_new_meta_connection();
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)
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__
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);
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__ */
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"
RETSIGTYPE
sigusr1_handler(int a)
{
- dump_conn_list();
+ dump_connection_list();
}
RETSIGTYPE
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"
#include "netutl.h"
#include "protocol.h"
#include "meta.h"
-#include "connlist.h"
+#include "connection.h"
#include "system.h"
/* 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];
return send_meta(cl, buffer, len);
}
-int receive_request(conn_list_t *cl)
+int receive_request(connection_t *cl)
{
int request;
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;
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)
return send_challenge(cl);
}
-int send_challenge(conn_list_t *cl)
+int send_challenge(connection_t *cl)
{
char *buffer;
int len, x;
return x;
}
-int challenge_h(conn_list_t *cl)
+int challenge_h(connection_t *cl)
{
char *buffer;
int len;
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
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];
return send_id(cl);
}
-int send_metakey(conn_list_t *cl)
+int send_metakey(connection_t *cl)
{
char *buffer;
int len, x;
return x;
}
-int metakey_h(conn_list_t *cl)
+int metakey_h(connection_t *cl)
{
char *buffer;
int len;
return send_metakey(cl);
}
-int send_ack(conn_list_t *cl)
+int send_ack(connection_t *cl)
{
int x;
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
/* 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;
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)
{
/* 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;
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)
{
/* 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)
{
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;
}
{
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));
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
}
}
- /* 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;
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)
{
/* 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)
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;
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)
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;
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);
/* 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;
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;
/* 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)
{
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)
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)
{
/* 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,
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__
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__ */
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"
#include <xalloc.h>
#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
}
}
-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)
}
-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]);
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"));
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"
#include "conf.h"
#include "net.h"
+#include "connection.h"
#include "subnet.h"
#include "system.h"
#include <utils.h>
#include <xalloc.h>
+#include <rbl.h>
/* 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
}
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
}
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__
} 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 */
} 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 *);