- Let user choose whether keys are in the config files or separate
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 5 Jan 2001 23:53:53 +0000 (23:53 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 5 Jan 2001 23:53:53 +0000 (23:53 +0000)
- Use AVL trees instead of RBL trees
- Fixed a lot of annoying subtle bugs! Thanks to gdb...

12 files changed:
src/conf.c
src/conf.h
src/connection.c
src/connection.h
src/meta.c
src/net.c
src/process.c
src/protocol.c
src/route.c
src/subnet.c
src/subnet.h
src/tincd.c

index 3edcb30238a1fd54dcbcd9bffd4b037a429f13d9..5aaa22a085f3002674ed1fb30134210a3dd103cf 100644 (file)
     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.35 2000/12/22 21:34:20 guus Exp $
+    $Id: conf.c,v 1.9.4.36 2001/01/05 23:53:49 guus Exp $
 */
 
 #include "config.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <netdb.h>
@@ -35,6 +34,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <syslog.h>
 
 #include <xalloc.h>
 #include <utils.h> /* for cp */
@@ -311,7 +311,7 @@ cp
   x = read_config_file(&config, fname);
   if(x == -1) /* System error */
     {
-      fprintf(stderr, _("Failed to read `%s': %m\n"),
+      syslog(LOG_ERR, _("Failed to read `%s': %m"),
              fname);
     }
   free(fname);
@@ -358,7 +358,7 @@ int isadir(const char* f)
 
   if(stat(f, &s) < 0)
     {
-      fprintf(stderr, _("Couldn't stat `%s': %m\n"),
+      syslog(LOG_ERR, _("Couldn't stat `%s': %m"),
              f);
       return -1;
     }
@@ -371,24 +371,29 @@ int is_safe_path(const char *file)
   char *p;
   struct stat s;
 
+  if(*file != '/')
+    {
+      syslog(LOG_ERR, _("`%s' is not an absolute path"), file);
+      return 0;
+    }
+
   p = strrchr(file, '/');
-  assert(p); /* p has to contain a / */
   *p = '\0';
   if(stat(file, &s) < 0)
     {
-      fprintf(stderr, _("Couldn't stat `%s': %m\n"),
+      syslog(LOG_ERR, _("Couldn't stat `%s': %m"),
              file);
       return 0;
     }
   if(s.st_uid != geteuid())
     {
-      fprintf(stderr, _("`%s' is owned by UID %d instead of %d.\n"),
+      syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"),
              file, s.st_uid, geteuid());
       return 0;
     }
   if(S_ISLNK(s.st_mode))
     {
-      fprintf(stderr, _("Warning: `%s' is a symlink\n"),
+      syslog(LOG_WARNING, _("Warning: `%s' is a symlink"),
              file);
       /* fixme: read the symlink and start again */
     }
@@ -396,7 +401,7 @@ int is_safe_path(const char *file)
   *p = '/';
   if(stat(file, &s) < 0 && errno != ENOENT)
     {
-      fprintf(stderr, _("Couldn't stat `%s': %m\n"),
+      syslog(LOG_ERR, _("Couldn't stat `%s': %m"),
              file);
       return 0;
     }
@@ -404,20 +409,20 @@ int is_safe_path(const char *file)
     return 1;
   if(s.st_uid != geteuid())
     {
-      fprintf(stderr, _("`%s' is owned by UID %d instead of %d.\n"),
+      syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"),
              file, s.st_uid, geteuid());
       return 0;
     }
   if(S_ISLNK(s.st_mode))
     {
-      fprintf(stderr, _("Warning: `%s' is a symlink\n"),
+      syslog(LOG_WARNING, _("Warning: `%s' is a symlink"),
              file);
       /* fixme: read the symlink and start again */
     }
   if(s.st_mode & 0007)
     {
       /* Accessible by others */
-      fprintf(stderr, _("`%s' has unsecure permissions.\n"),
+      syslog(LOG_ERR, _("`%s' has unsecure permissions"),
              file);
       return 0;
     }
@@ -445,12 +450,14 @@ FILE *ask_and_safe_open(const char* filename, const char* what)
       /* Ask for a file and/or directory name. */
       fprintf(stdout, _("Please enter a file to save %s to [%s]: "),
              what, filename);
-      fflush(stdout);  /* Don't wait for a newline */
+      fflush(stdout);
+
       if((fn = readline(stdin, NULL, NULL)) == NULL)
        {
          fprintf(stderr, _("Error while reading stdin: %m\n"));
          return NULL;
        }
+
       if(strlen(fn) == 0)
        /* User just pressed enter. */
        fn = xstrdup(filename);
index de527d25fde3407760a4c2b115e0897870bdbac4..00fbcb19d83e052e992218275f2d5f7308dd6ece 100644 (file)
@@ -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: conf.h,v 1.6.4.19 2000/12/22 21:34:20 guus Exp $
+    $Id: conf.h,v 1.6.4.20 2001/01/05 23:53:49 guus Exp $
 */
 
 #ifndef __TINC_CONF_H__
@@ -63,7 +63,7 @@ typedef struct config_t {
   int argtype;
   union data {
     unsigned long val;
-    void *ptr;
+    char *ptr;
     ip_mask_t *ip;
     struct config_t *next;     /* For nested configs! */
   } data;
index 7f48697d77188dccf9053706541767f72ba632a1..59ff1201cac74a1884264647c46b6eeba08a5e73 100644 (file)
@@ -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: connection.c,v 1.1.2.6 2000/11/24 23:13:01 guus Exp $
+    $Id: connection.c,v 1.1.2.7 2001/01/05 23:53:49 guus Exp $
 */
 
 #include "config.h"
@@ -25,7 +25,7 @@
 #include <stdio.h>
 #include <syslog.h>
 
-#include <rbl.h>
+#include <avl_tree.h>
 
 #include "net.h"       /* Don't ask. */
 #include "netutl.h"
 
 /* Root of the connection list */
 
-rbltree_t *connection_tree;
-rbltree_t *id_tree;
+avl_tree_t *connection_tree;
+avl_tree_t *id_tree;
+
+/* Pointer to connection describing myself */
 
 connection_t *myself = NULL;
 
@@ -49,6 +51,7 @@ connection_t *myself = NULL;
 int connection_compare(connection_t *a, connection_t *b)
 {
   ipv4_t result;
+
   result = a->address - b->address;
   if(result)
     return result;
@@ -63,8 +66,8 @@ int id_compare(connection_t *a, connection_t *b)
 
 void init_connections(void)
 {
-  connection_tree = new_rbltree((rbl_compare_t)connection_compare, (rbl_action_t)free_connection);
-  id_tree = new_rbltree((rbl_compare_t)id_compare, NULL);
+  connection_tree = avl_alloc_tree((avl_compare_t)connection_compare, (avl_action_t)free_connection);
+  id_tree = avl_alloc_tree((avl_compare_t)id_compare, NULL);
 }
 
 /* Creation and deletion of connection elements */
@@ -73,7 +76,7 @@ connection_t *new_connection(void)
 {
   connection_t *p = (connection_t *)xmalloc_and_zero(sizeof(*p));
 cp
-  p->subnet_tree = new_rbltree((rbl_compare_t)subnet_compare, NULL);
+  p->subnet_tree = avl_alloc_tree((avl_compare_t)subnet_compare, NULL);
 cp
   return p;
 }
@@ -106,12 +109,13 @@ cp
 */
 void prune_connection_tree(void)
 {
-  rbl_t *rbl;
+  avl_node_t *node, *next;
   connection_t *cl;
 cp
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = next)
     {
-      cl = (connection_t *) rbl->data;
+      next = node->next;
+      cl = (connection_t *)node->data;
       if(cl->status.remove)
         connection_del(cl);
     }
@@ -124,8 +128,8 @@ cp
 void destroy_connection_tree(void)
 {
 cp
-  rbl_delete_rbltree(id_tree);
-  rbl_delete_rbltree(connection_tree);
+  avl_delete_tree(id_tree);
+  avl_delete_tree(connection_tree);
 cp
 }
 
@@ -134,22 +138,22 @@ cp
 void connection_add(connection_t *cl)
 {
 cp
-  rbl_insert(connection_tree, cl);
+  avl_insert(connection_tree, cl);
 cp
 }
 
 void id_add(connection_t *cl)
 {
 cp
-  rbl_insert(id_tree, cl);
+  avl_insert(id_tree, cl);
 cp
 }
 
 void connection_del(connection_t *cl)
 {
 cp
-  rbl_delete(id_tree, cl);
-  rbl_delete(connection_tree, cl);
+  avl_delete(id_tree, cl);
+  avl_delete(connection_tree, cl);
 cp
 }
 
@@ -162,7 +166,7 @@ cp
   cl.address = address;
   cl.port = port;
 
-  return rbl_search(connection_tree, &cl);
+  return avl_search(connection_tree, &cl);
 }
 
 connection_t *lookup_id(char *name)
@@ -170,7 +174,7 @@ connection_t *lookup_id(char *name)
   connection_t cl, *p;
 cp
   cl.name = name;
-  p = rbl_search(id_tree, &cl);
+  p = avl_search(id_tree, &cl);
   if(p && p->status.active)
     return p;
   else
@@ -181,7 +185,7 @@ cp
 
 void dump_connection_list(void)
 {
-  rbl_t *rbl;
+  avl_node_t *node;
   connection_t *cl;
 cp
   syslog(LOG_DEBUG, _("Connection list:"));
@@ -190,9 +194,9 @@ cp
          myself->name, myself->hostname, myself->port, myself->flags,
          myself->socket, myself->meta_socket, myself->status);
 
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      cl = (connection_t *)rbl->data;
+      cl = (connection_t *)node->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);
index e7397810b4d2c80c896caa4cde935df92cf90cfe..195cb1bb381acbcb0eda1cc88d5707bb17a3724d 100644 (file)
     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.3 2000/11/22 22:18:03 guus Exp $
+    $Id: connection.h,v 1.1.2.4 2001/01/05 23:53:49 guus Exp $
 */
 
 #ifndef __TINC_CONNECTION_H__
 #define __TINC_CONNECTION_H__
 
-#include <rbl.h>
+#include <avl_tree.h>
 
 #include "config.h"
 
@@ -66,8 +66,8 @@ 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 */
+  short unsigned int port;         /* port number for UDP traffic */
   long unsigned int options;       /* options turned on for this connection */
 
   int flags;                       /* his flags */
@@ -100,12 +100,12 @@ typedef struct connection_t {
 
   struct connection_t *nexthop;    /* nearest meta-hop in this direction */
   
-  rbltree_t *subnet_tree;          /* Pointer to a tree of subnets belonging to this connection */
+  avl_tree_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 avl_tree_t *connection_tree;
 extern connection_t *myself;
 
 extern void init_connections(void);
index 289d0b873bc032a3b21e6279c372a07e8e14e2a6..14a3c1d041e7ac883ff9efefb386ea08221c3903 100644 (file)
     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.12 2000/11/20 19:12:12 guus Exp $
+    $Id: meta.c,v 1.1.2.13 2001/01/05 23:53:49 guus Exp $
 */
 
 #include "config.h"
 #include <utils.h>
+#include <avl_tree.h>
 
 #include <errno.h>
 #include <syslog.h>
@@ -74,12 +75,12 @@ cp
 
 void broadcast_meta(connection_t *cl, char *buffer, int length)
 {
-  rbl_t *rbl;
+  avl_node_t *node;
   connection_t *p;
 cp
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p != cl && p->status.meta && p->status.active)
         send_meta(p, buffer, length);
     }
index cb32caba83de56bcca5f1ff5dbe15b9bd64f823d..a42ebce43de590c42c43722c0f15eab3b1b89e7c 100644 (file)
--- 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.88 2000/12/22 21:34:20 guus Exp $
+    $Id: net.c,v 1.35.4.89 2001/01/05 23:53:49 guus Exp $
 */
 
 #include "config.h"
@@ -71,6 +71,7 @@
 
 #include <utils.h>
 #include <xalloc.h>
+#include <avl_tree.h>
 
 #include "conf.h"
 #include "connection.h"
@@ -165,7 +166,7 @@ cp
      
   if(debug_lvl >= DEBUG_TRAFFIC)
     syslog(LOG_ERR, _("Writing packet of %d bytes to tap device"),
-           outpkt.len, outlen);
+           outpkt.len);
 
   /* Fix mac address */
 
@@ -320,7 +321,7 @@ int send_packet(ip_t to, vpn_packet_t *packet)
   connection_t *cl;
   subnet_t *subnet;
 cp
-  if((subnet = lookup_subnet_ipv4(to)) == NULL)
+  if((subnet = lookup_subnet_ipv4(&to)) == NULL)
     {
       if(debug_lvl >= DEBUG_TRAFFIC)
         {
@@ -607,6 +608,19 @@ cp
       return -1;
     }
 
+  /* Bind first to get a fix on our source port */
+
+  a.sin_family = AF_INET;
+  a.sin_port = htons(0);
+  a.sin_addr.s_addr = htonl(INADDR_ANY);
+
+  if(bind(cl->meta_socket, (struct sockaddr *)&a, sizeof(struct sockaddr)))
+    {
+      close(cl->meta_socket);
+      syslog(LOG_ERR, _("System call `%s' failed: %m"), "bind");
+      return -1;
+    }
+  
   a.sin_family = AF_INET;
   a.sin_port = htons(cl->port);
   a.sin_addr.s_addr = htonl(cl->address);
@@ -656,14 +670,14 @@ cp
     
   if(read_host_config(ncn))
     {
-      syslog(LOG_ERR, _("Error reading host configuration file for %s"));
+      syslog(LOG_ERR, _("Error reading host configuration file for %s"), ncn->name);
       free_connection(ncn);
       return -1;
     }
     
   if(!(cfg = get_config_val(ncn->config, config_address)))
     {
-      syslog(LOG_ERR, _("No address specified for %s"));
+      syslog(LOG_ERR, _("No address specified for %s"), ncn->name);
       free_connection(ncn);
       return -1;
     }
@@ -876,7 +890,7 @@ cp
       syslog(LOG_ERR, _("Unable to set up a listening UDP socket!"));
       return -1;
     }
-
+cp
   /* Generate packet encryption key */
 
   myself->cipher_pkttype = EVP_bf_cfb();
@@ -892,9 +906,9 @@ cp
     keylifetime = cfg->data.val;
     
   keyexpires = time(NULL) + keylifetime;
-
+cp
   /* Activate ourselves */
-  
+
   myself->status.active = 1;
 
   syslog(LOG_NOTICE, _("Ready: listening on port %hd"), myself->port);
@@ -991,12 +1005,12 @@ cp
 */
 void close_network_connections(void)
 {
-  rbl_t *rbl;
+  avl_node_t *node;
   connection_t *p;
 cp
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       p->status.active = 0;
       terminate_connection(p);
     }
@@ -1117,6 +1131,7 @@ cp
   p->name = unknown;
   p->address = ntohl(ci.sin_addr.s_addr);
   p->hostname = hostlookup(ci.sin_addr.s_addr);
+  p->port = htons(ci.sin_port);                                /* This one will be overwritten later */
   p->meta_socket = sfd;
   p->status.meta = 1;
   p->buffer = xmalloc(MAXBUFSIZE);
@@ -1137,16 +1152,16 @@ cp
 */
 void build_fdset(fd_set *fs)
 {
-  rbl_t *rbl;
+  avl_node_t *node;
   connection_t *p;
 cp
   FD_ZERO(fs);
 
   FD_SET(myself->socket, fs);
 
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p->status.meta)
         FD_SET(p->meta_socket, fs);
     }
@@ -1192,7 +1207,7 @@ cp
   
   if(!cl)
     {
-      syslog(LOG_WARNING, _("Received UDP packets on port %d from unknown source %lx:%d"), myself->port, ntohl(from.sin_addr.s_addr), ntohs(from.sin_port));
+      syslog(LOG_WARNING, _("Received UDP packets on port %hd from unknown source %x:%hd"), myself->port, ntohl(from.sin_addr.s_addr), ntohs(from.sin_port));
       return 0;
     }
 
@@ -1214,7 +1229,7 @@ void terminate_connection(connection_t *cl)
 {
   connection_t *p;
   subnet_t *subnet;
-  rbl_t *rbl;
+  avl_node_t *node, *next;
 cp
   if(cl->status.remove)
     return;
@@ -1234,9 +1249,9 @@ cp
      (the connection that was dropped). */
 
   if(cl->status.meta)
-    RBL_FOREACH(connection_tree, rbl)
+    for(node = connection_tree->head; node; node = node->next)
       {
-        p = (connection_t *)rbl->data;
+        p = (connection_t *)node->data;
         if(p->nexthop == cl && p != cl)
           terminate_connection(p);
       }
@@ -1244,18 +1259,19 @@ cp
   /* Inform others of termination if it was still active */
 
   if(cl->status.active)
-    RBL_FOREACH(connection_tree, rbl)
+    for(node = connection_tree->head; node; node = node->next)
       {
-        p = (connection_t *)rbl->data;
+        p = (connection_t *)node->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 */
 
-  RBL_FOREACH(cl->subnet_tree, rbl)
+  for(node = cl->subnet_tree->head; node; node = next)
     {
-      subnet = (subnet_t *)rbl->data;
+      next = node->next;
+      subnet = (subnet_t *)node->data;
       subnet_del(subnet);
     }
 
@@ -1286,14 +1302,14 @@ cp
 void check_dead_connections(void)
 {
   time_t now;
-  rbl_t *rbl;
+  avl_node_t *node;
   connection_t *cl;
 cp
   now = time(NULL);
 
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      cl = (connection_t *)rbl->data;
+      cl = (connection_t *)node->data;
       if(cl->status.active && cl->status.meta)
         {
           if(cl->last_ping_time + timeout < now)
@@ -1352,14 +1368,14 @@ cp
 void check_network_activity(fd_set *f)
 {
   connection_t *p;
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
   if(FD_ISSET(myself->socket, f))
     handle_incoming_vpn_data();
 
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
 
       if(p->status.remove)
        return;
index 695f1f7ed9a757d7239c522f51839b02a075aa8e..01ca31e1525f3a1cc3caac50ee2f68b7f2dbf8ef 100644 (file)
@@ -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.17 2000/11/28 08:59:27 zarq Exp $
+    $Id: process.c,v 1.1.2.18 2001/01/05 23:53:51 guus Exp $
 */
 
 #include "config.h"
@@ -159,6 +159,8 @@ cp
 
   /* If we succeeded in doing that, detach */
 
+  closelog();
+
   if(do_detach)
     {
       if(daemon(0, 0) < 0)
index 57814fdd5c71b53ae7460aa277019f5a519e1045..85a4047c2c9360886a96233504588b30209987ae 100644 (file)
@@ -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.70 2000/12/22 21:34:24 guus Exp $
+    $Id: protocol.c,v 1.28.4.71 2001/01/05 23:53:51 guus Exp $
 */
 
 #include "config.h"
@@ -34,6 +34,7 @@
 
 #include <utils.h>
 #include <xalloc.h>
+#include <avl_tree.h>
 
 #include <netinet/in.h>
 
@@ -193,10 +194,10 @@ cp
 int id_h(connection_t *cl)
 {
   connection_t *old;
-  config_t const *cfg;
+  unsigned short int port;
   char name[MAX_STRING_SIZE];
 cp
-  if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &cl->port) != 4)
+  if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &port) != 4)
     {
        syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
        return -1;
@@ -253,6 +254,12 @@ cp
   
   id_add(cl);
 
+  /* And uhr... cl->port just changed so we have to unlink it from the connection tree and re-insert... */
+  
+  avl_unlink(connection_tree, cl);
+  cl->port = port;
+  avl_insert(connection_tree, cl);
+
   /* Read in the public key, so that we can send a challenge */
 
   if(read_rsa_public_key(cl))
@@ -283,7 +290,7 @@ cp
   RAND_bytes(cl->hischallenge, len);
 
   cl->hischallenge[0] &= 0x7F; /* Somehow if the first byte is more than 0xD0 or something like that, decryption fails... */
-
+cp
   if(debug_lvl >= DEBUG_SCARY_THINGS)
     {
       bin2hex(cl->hischallenge, buffer, len);
@@ -304,7 +311,7 @@ cp
 
   bin2hex(buffer, buffer, len);
   buffer[len*2] = '\0';
-
+cp
   /* Send the challenge */
 
   cl->allow_request = CHAL_REPLY;
@@ -580,7 +587,7 @@ int ack_h(connection_t *cl)
 {
   connection_t *old, *p;
   subnet_t *subnet;
-  rbl_t *rbl, *rbl2;
+  avl_node_t *node, *node2;
 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
@@ -614,16 +621,16 @@ cp
 
   /* Send him our subnets */
   
-  RBL_FOREACH(myself->subnet_tree, rbl)
+  for(node = myself->subnet_tree->head; node; node = node->next)
     {
-      subnet = (subnet_t *)rbl->data;
+      subnet = (subnet_t *)node->data;
       send_add_subnet(cl, subnet);
     }
   /* And send him all the hosts and their subnets we know... */
   
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       
       if(p != cl && p->status.active)
         {
@@ -636,9 +643,9 @@ cp
 
           send_add_host(cl, p);
 
-          RBL_FOREACH(p->subnet_tree, rbl2)
+          for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
             {
-              subnet = (subnet_t *)rbl2->data;
+              subnet = (subnet_t *)node2->data;
               send_add_subnet(cl, subnet);
             }
         }
@@ -667,7 +674,7 @@ int add_subnet_h(connection_t *cl)
   char name[MAX_STRING_SIZE];
   connection_t *owner, *p;
   subnet_t *subnet;
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
     {
@@ -716,9 +723,9 @@ cp
 
   /* Tell the rest */
   
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p->status.meta && p->status.active && p!= cl)
         send_add_subnet(p, subnet);
     }
@@ -744,7 +751,7 @@ int del_subnet_h(connection_t *cl)
   char name[MAX_STRING_SIZE];
   connection_t *owner, *p;
   subnet_t *subnet;
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
     {
@@ -795,9 +802,9 @@ cp
 
   /* Tell the rest */
   
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p->status.meta && p->status.active && p!= cl)
         send_del_subnet(p, subnet);
     }
@@ -818,7 +825,7 @@ int add_host_h(connection_t *cl)
 {
   connection_t *old, *new, *p;
   char name[MAX_STRING_SIZE];
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
   new = new_connection();
 
@@ -881,9 +888,9 @@ cp
 
   /* Tell the rest about the new host */
 
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p->status.meta && p->status.active && p!=cl)
         send_add_host(p, new);
     }
@@ -912,7 +919,7 @@ int del_host_h(connection_t *cl)
   port_t port;
   long int options;
   connection_t *old, *p;
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &address, &port, &options) != 4)
     {
@@ -963,9 +970,9 @@ cp
 
   /* Tell the rest about the new host */
 
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p->status.meta && p->status.active && p!=cl)
         send_del_host(p, old);
     }
@@ -1087,11 +1094,11 @@ cp
 int send_key_changed(connection_t *from, connection_t *cl)
 {
   connection_t *p;
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
-  RBL_FOREACH(connection_tree, rbl)
+  for(node = connection_tree->head; node; node = node->next)
     {
-      p = (connection_t *)rbl->data;
+      p = (connection_t *)node->data;
       if(p != cl && p->status.meta && p->status.active)
         send_request(p, "%d %s", KEY_CHANGED, from->name);
     }
index 4620665461d130a2a8fecc5f51f2a3cab8d362fb..8ff2e39cbad1ace318c6c669ca5ac823688ebeda 100644 (file)
     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.3 2000/11/20 19:12:17 guus Exp $
+    $Id: route.c,v 1.1.2.4 2001/01/05 23:53:53 guus Exp $
 */
 
 #include "config.h"
 
 #include <utils.h>
 #include <xalloc.h>
+#include <syslog.h>
 
 #include "net.h"
 #include "connection.h"
+#include "subnet.h"
+#include "route.h"
 
 #include "system.h"
 
-int routing_mode = 0;          /* Will be used to determine if we route by MAC or by payload's protocol */
+int routing_mode = RMODE_ROUTER;       /* Will be used to determine if we route by MAC or by payload's protocol */
 
-connection_t *route_packet(vpn_packet_t *packet)
+connection_t *route_mac(connection_t *source, vpn_packet_t *packet)
 {
-  unsigned short type;
+  connection_t *oldsrc, *dst;
+  subnet_t *subnet;
 cp
-  type = ntohs(*((unsigned short*)(&packet.data[12])))
+  /* Learn source address */
 
-  if(routing_mode)
+  oldsrc = lookup_subnet_mac((mac_t *)(&packet->data[0]))->owner;
+  
+  if(!oldsrc)
     {
-      return route_mac(packet);
+      subnet = new_subnet();
+      subnet->type = SUBNET_MAC;
+      memcpy(&subnet->net.mac.address, (mac_t *)(&packet->data[0]), sizeof(mac_t));
+      subnet_add(source, subnet);
     }
 
-  switch(type)
-    {
-      case 0x0800:
-        return route_ipv4(packet);
-      case 0x86DD:
-        return route_ipv6(packet);
-/*
-      case 0x8137:
-        return route_ipx(packet);
-      case 0x0806:
-        return route_arp(packet);
-*/
-      default:
-        if(debug_lvl >= DEBUG_TRAFFIC)
-          {
-            syslog(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
-          }
-        return NULL;
-     }
-}
+  /* FIXME: do ageing and roaming */
+  
+  /* Lookup destination address */
+    
+  dst = lookup_subnet_mac((mac_t *)(&packet->data[6]))->owner;
 
-connection_t *route_mac(vpn_packet_t *packet)
-{
-  connection_t *cl;
-cp
-  cl = lookup_subnet_mac((mac_t *)(&packet.data[6]));
-  if(!cl)
+  if(!dst)
     if(debug_lvl >= DEBUG_TRAFFIC)
       {
         syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %x:%x:%x:%x:%x:%x"),
-               packet.data[6],
-               packet.data[7],
-               packet.data[8],
-               packet.data[9],
-               packet.data[10],
-               packet.data[11]);
+               packet->data[6],
+               packet->data[7],
+               packet->data[8],
+               packet->data[9],
+               packet->data[10],
+               packet->data[11]);
       } 
 cp  
-  return cl;  
+  return dst;  
 }
 
-
 connection_t *route_ipv4(vpn_packet_t *packet)
 {
   ipv4_t dest;
   connection_t *cl;
 cp
-  dest = ntohl(*((unsigned long*)(&packet.data[30]);
+  dest = ntohl(*((unsigned long*)(&packet->data[30])));
   
-  cl = lookup_subnet_ipv4(dest);
+  cl = lookup_subnet_ipv4(&dest)->owner;
   if(!cl)
     if(debug_lvl >= DEBUG_TRAFFIC)
       {
         syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %d.%d.%d.%d"),
-               packet.data[30], packet.data[31], packet.data[32], packet.data[33]);
+               packet->data[30], packet->data[31], packet->data[32], packet->data[33]);
       } 
 cp
   return cl;  
@@ -106,7 +94,48 @@ cp
 connection_t *route_ipv6(vpn_packet_t *packet)
 {
 cp
-  syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not implemented yet"));
+  if(debug_lvl > DEBUG_NOTHING)
+    {
+      syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not implemented yet"));
+    } 
 cp
   return NULL;
 }
+
+connection_t *route_packet(connection_t *source, vpn_packet_t *packet)
+{
+  unsigned short int type;
+cp
+  /* FIXME: multicast? */
+
+  switch(routing_mode)
+    {
+      case RMODE_HUB:
+        return broadcast;
+        
+      case RMODE_SWITCH:
+        return route_mac(source, packet);
+        
+      case RMODE_ROUTER:
+        type = ntohs(*((unsigned short*)(&packet->data[12])));
+        switch(type)
+          {
+            case 0x0800:
+              return route_ipv4(packet);
+            case 0x86DD:
+              return route_ipv6(packet);
+      /*
+            case 0x8137:
+              return route_ipx(packet);
+            case 0x0806:
+              return route_arp(packet);
+      */
+            default:
+              if(debug_lvl >= DEBUG_TRAFFIC)
+                {
+                  syslog(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
+                }
+              return NULL;
+           }
+    }
+}
index 574e7a061734442ac846a323c7359396297a845d..28a203dc21ca66b2e2f91a4db3c7aef49a3d44e5 100644 (file)
@@ -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.15 2000/11/24 23:13:06 guus Exp $
+    $Id: subnet.c,v 1.1.2.16 2001/01/05 23:53:53 guus Exp $
 */
 
 #include "config.h"
 
 #include <utils.h>
 #include <xalloc.h>
-#include <rbl.h>
+#include <avl_tree.h>
 
 /* lists type of subnet */
 
-rbltree_t *subnet_tree;
+avl_tree_t *subnet_tree;
 
 void init_subnets(void)
 {
 cp
-  subnet_tree = new_rbltree((rbl_compare_t)subnet_compare, (rbl_action_t)free_subnet);
+  subnet_tree = avl_alloc_tree((avl_compare_t)subnet_compare, (avl_action_t)free_subnet);
 cp
 }
 
@@ -131,17 +131,17 @@ void subnet_add(connection_t *cl, subnet_t *subnet)
 {
 cp
   subnet->owner = cl;
-  rbl_insert(subnet_tree, subnet);
-  rbl_insert(cl->subnet_tree, subnet);
+  avl_insert(subnet_tree, subnet);
+  avl_insert(cl->subnet_tree, subnet);
 cp
 }
 
 void subnet_del(subnet_t *subnet)
 {
 cp
-  rbl_delete(subnet->owner->subnet_tree, subnet);
+  avl_delete(subnet->owner->subnet_tree, subnet);
 cp
-  rbl_delete(subnet_tree, subnet);
+  avl_delete(subnet_tree, subnet);
 cp
 }
 
@@ -256,62 +256,59 @@ cp
 
 /* Subnet lookup routines */
 
-subnet_t *lookup_subnet_mac(mac_t address)
+subnet_t *lookup_subnet_mac(mac_t *address)
 {
   subnet_t subnet, *p;
 cp
   subnet.type = SUBNET_MAC;
-  subnet.net.mac.address = address;
+  memcpy(&subnet.net.mac.address, address, sizeof(mac_t));
 
-  p = (subnet_t *)rbl_search_closest(subnet_tree, &subnet);
+  p = (subnet_t *)avl_search(subnet_tree, &subnet);
 cp
-  if(p && !memcmp(&address, &p->net.mac.address, sizeof(mac_t)))
-    return p;
-  else
-    return NULL;
+  return p;
 }
 
-subnet_t *lookup_subnet_ipv4(ipv4_t address)
+subnet_t *lookup_subnet_ipv4(ipv4_t *address)
 {
   subnet_t subnet, *p;
 cp
   subnet.type = SUBNET_IPV4;
-  subnet.net.ipv4.address = address;
+  subnet.net.ipv4.address = *address;
   subnet.net.ipv4.mask = 0xFFFFFFFF;
 
-  p = (subnet_t *)rbl_search_closest_greater(subnet_tree, &subnet);
+  p = (subnet_t *)avl_search_closest_greater(subnet_tree, &subnet);
 
   /* Check if the found subnet REALLY matches */
 cp
-  if(p && ((address & p->net.ipv4.mask) == p->net.ipv4.address))
+  if(p && ((*address & p->net.ipv4.mask) == p->net.ipv4.address))
     return p;
   else
     return NULL;
 }
 
-subnet_t *lookup_subnet_ipv6(ipv6_t address)
+subnet_t *lookup_subnet_ipv6(ipv6_t *address)
 {
   subnet_t subnet;
 cp
   subnet.type = SUBNET_IPV6;
-  subnet.net.ipv6.address = address;
+  memcpy(&subnet.net.ipv6.address, address, sizeof(ipv6_t));
   memset(&subnet.net.ipv6.mask, 0xFF, 16);
   
 /* FIXME: check if it REALLY matches */
 
-  return (subnet_t *)rbl_search_closest(subnet_tree, &subnet);
+  return (subnet_t *)avl_search_closest_greater(subnet_tree, &subnet);
 }
 
 void dump_subnet_list(void)
 {
   char *netstr;
   subnet_t *subnet;
-  rbl_t *rbl;
+  avl_node_t *node;
 cp
   syslog(LOG_DEBUG, _("Subnet list:"));
-  RBL_FOREACH(subnet_tree, rbl)
+  for(node = subnet_tree->head; node; node = node->next)
     {
-      subnet = (subnet_t *)rbl->data;
+      subnet = (subnet_t *)node->data;
       netstr = net2str(subnet);
       syslog(LOG_DEBUG, " %s owner %s", netstr, subnet->owner->name);
       free(netstr);
index 1aab681ab868708bf0afb6f2d402c46994c5ba82..a572953c17d9c738b5df158f3cabc7ddcf0bc757 100644 (file)
@@ -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.7 2000/11/20 19:41:13 guus Exp $
+    $Id: subnet.h,v 1.1.2.8 2001/01/05 23:53:53 guus Exp $
 */
 
 #ifndef __TINC_SUBNET_H__
@@ -83,9 +83,9 @@ extern void subnet_del(subnet_t *);
 extern char *net2str(subnet_t *);
 extern subnet_t *str2net(char *);
 extern int subnet_compare(subnet_t *, subnet_t *);
-extern subnet_t *lookup_subnet_mac(mac_t);
-extern subnet_t *lookup_subnet_ipv4(ipv4_t);
-extern subnet_t *lookup_subnet_ipv6(ipv6_t);
+extern subnet_t *lookup_subnet_mac(mac_t *);
+extern subnet_t *lookup_subnet_ipv4(ipv4_t *);
+extern subnet_t *lookup_subnet_ipv6(ipv6_t *);
 extern void dump_subnet_list(void);
 
 #endif /* __TINC_SUBNET_H__ */
index 3dbac7e30f9f59d2626630d0f33cd1d6a68e9960..535fdb32a75aa60548458ac82beeca4ad84f434a 100644 (file)
@@ -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: tincd.c,v 1.10.4.38 2000/12/03 12:23:06 zarq Exp $
+    $Id: tincd.c,v 1.10.4.39 2001/01/05 23:53:53 guus Exp $
 */
 
 #include "config.h"
@@ -283,6 +283,8 @@ void make_names(void)
 int
 main(int argc, char **argv, char **envp)
 {
+  openlog("tinc", LOG_PERROR, LOG_DAEMON);     /* Catch all syslog() calls issued before detaching */
+
   program_name = argv[0];
 
   setlocale (LC_ALL, "");
@@ -322,9 +324,9 @@ main(int argc, char **argv, char **envp)
   make_names();
 
   /* Slllluuuuuuurrrrp! */
-
+cp
   RAND_load_file("/dev/urandom", 1024);
-
+cp
   if(generate_keys)
     exit(keygen(generate_keys));
 
@@ -333,10 +335,10 @@ main(int argc, char **argv, char **envp)
 
   if(read_server_config())
     return 1;
-
+cp
   if(detach())
     exit(0);
-
+cp
   if(debug_lvl >= DEBUG_ERROR)
     ERR_load_crypto_strings();