First step for implementation of the "indirectdata" directive. This should
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 23 Jun 2000 19:27:03 +0000 (19:27 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 23 Jun 2000 19:27:03 +0000 (19:27 +0000)
allow _leaf_ tincds to be behind firewalls.
The protocol has changed and is INCOMPATIBLE with previous versions. The
PROT_CURRENT value has been incremented.

TODO
src/net.c
src/net.h
src/protocol.c
src/protocol.h

diff --git a/TODO b/TODO
index 3d0a7c8..4415e16 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,13 +3,7 @@ Things left to do to make cabal superstable:
  * Check for connection loops. Inter-daemon
    connections should always satisfy the
    tree property.
- * Check for duplicates. If there's a
-   timeout and a host reconnects before the
-   old connection is closed, duplicate
-   entries appear in every connection list.
  * Redundancy: multiple ConnectTo lines, if
    one fails others might be tried.
- * Persistence: don't quit when no connection
-   can be made directly after start of the
-   daemon.
-
+ * Allow connects to hosts that use
+   nodirectdata.
index 54e1323..62cdb14 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 2000/05/31 18:23:05 zarq Exp $
+    $Id: net.c,v 1.35.4.1 2000/06/23 19:27:02 guus Exp $
 */
 
 #include "config.h"
@@ -277,6 +277,11 @@ cp
           syslog(LOG_NOTICE, _("trying to look up " IP_ADDR_S " in connection list failed."),
                 IP_ADDR_V(to));
         }
+        
+      /* Is this really necessary? If we can't find "to", then neither should any uplink. (GS) */
+      
+      return -1;
+        
       for(cl = conn_list; cl != NULL && !cl->status.outgoing; cl = cl->next);
       if(!cl)
         { /* No open outgoing connection has been found. */
@@ -286,6 +291,33 @@ cp
         }
     }
 
+  /* If indirectdata flag is set, then real_ip is actually the vpn_ip of the gateway tincd
+   * it is behind.
+   */
+   
+  if(cl->flags & INDIRECTDATA)
+    {
+      if((cl = lookup_conn(cl->vpn_ip)) == NULL)
+        {
+          if(debug_lvl > 2)
+            {
+              syslog(LOG_NOTICE, _("indirect look up " IP_ADDR_S " in connection list failed."),
+                    IP_ADDR_V(to));
+            }
+            
+          /* Gateway tincd dead? Should we kill it? (GS) */
+
+          return -1;
+        }
+      if(cl->flags & INDIRECTDATA)  /* This should not happen */
+        if(debug_lvl > 1)
+          {
+            syslog(LOG_NOTICE, _("double indirection for " IP_ADDR_S),
+                  IP_ADDR_V(to));
+          }
+        return -1;        
+    }            
+
   if(my_key_expiry <= time(NULL))
     regenerate_keys();
 
@@ -522,12 +554,17 @@ cp
 
   myself->vpn_ip = cfg->data.ip->ip;
   myself->vpn_mask = cfg->data.ip->mask;
+  myself->flags = 0;
 
   if(!(cfg = get_config_val(listenport)))
     myself->port = 655;
   else
     myself->port = cfg->data.val;
 
+  if(cfg = get_config_val(indirectdata))
+    if(cfg->data.val)
+      myself->flags |= EXPORTINDIRECTDATA;
+
   if((myself->meta_socket = setup_listen_meta_socket(myself->port)) < 0)
     {
       syslog(LOG_ERR, _("Unable to set up a listening socket"));
index 3dfc3a5..fdda07e 100644 (file)
--- a/src/net.h
+++ b/src/net.h
 
 #define MAXBUFSIZE 2048 /* Probably way too much, but it must fit every possible request. */
 
+/* flags */
+#define INDIRECTDATA        0x0001 /* Used to indicate that this host has to be reached indirect */
+#define EXPORTINDIRECTDATA  0x0002 /* Used to indicate uplink that it has to tell others to do INDIRECTDATA */
+
 typedef unsigned long ip_t;
 typedef short length_t;
 
@@ -102,6 +106,7 @@ typedef struct conn_list_t {
   ip_t real_ip;                    /* his real (internet) ip */
   char *hostname;                  /* the hostname of its real ip */
   short unsigned int port;         /* his portnumber */
+  int flags;                       /* his flags */
   int socket;                      /* our udp vpn socket */
   int meta_socket;                 /* our tcp meta socket */
   int protocol_version;            /* used protocol */
index e9bad82..1e96493 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 2000/05/30 21:36:16 zarq Exp $
+    $Id: protocol.c,v 1.28.4.1 2000/06/23 19:27:03 guus Exp $
 */
 
 #include "config.h"
@@ -154,12 +154,30 @@ cp
 
 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
 {
+  ip_t real_ip;
+  int flags;
 cp
   if(debug_lvl > 2)
     syslog(LOG_DEBUG, _("Sending add host to " IP_ADDR_S),
           IP_ADDR_V(cl->vpn_ip));
 
-  buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x\n", ADD_HOST, new_host->real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port);
+  real_ip = new_host->real_ip;
+  flags = new_host->flags;
+  
+  /* If we need to propagate information about a new host that wants us to export
+   * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
+   * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
+   * work correctly.
+   */
+     
+  if(flags & EXPORTINDIRECTDATA)
+    {
+      flags &= ~EXPORTINDIRECTDATA;
+      flags |= INDIRECTDATA;
+      real_ip = myself->vpn_ip;
+    }
+
+  buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x %d\n", ADD_HOST, new_host->real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port, flags);
 
   if((write(cl->meta_socket, buffer, buflen)) < 0)
     {
@@ -205,7 +223,7 @@ cp
     syslog(LOG_DEBUG, _("Send BASIC_INFO to " IP_ADDR_S),
           IP_ADDR_V(cl->real_ip));
 
-  buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port);
+  buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x %d\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port, myself->flags);
 
   if((write(cl->meta_socket, buffer, buflen)) < 0)
     {
@@ -365,7 +383,7 @@ cp
 int basic_info_h(conn_list_t *cl)
 {
 cp
-  if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port) != 4)
+  if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx %d", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port, &cl->flags) != 5)
     {
        syslog(LOG_ERR, _("got bad BASIC_INFO request: %s"), cl->buffer);
        return -1;
@@ -568,11 +586,12 @@ int add_host_h(conn_list_t *cl)
   ip_t vpn_ip;
   ip_t vpn_mask;
   unsigned short port;
+  int flags;
   conn_list_t *ncn, *fw;
 cp
   if(!cl->status.active)
     return -1;
-  if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx", &real_ip, &vpn_ip, &vpn_mask, &port) != 4)
+  if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
     {
        syslog(LOG_ERR, _("got bad ADD_HOST request: %s"), cl->buffer);
        return -1;
@@ -603,6 +622,7 @@ cp
   ncn->vpn_ip = vpn_ip;
   ncn->vpn_mask = vpn_mask;
   ncn->port = port;
+  ncn->flags = flags;
   ncn->hostname = hostlookup(real_ip);
   ncn->nexthop = cl;
   ncn->next = conn_list;
index 88a0de2..89da86d 100644 (file)
@@ -29,6 +29,7 @@ enum {
   PROT_3,
   PROT_4,
   PROT_ECHELON,
+  PROT_6,
   PROT_CURRENT,                      /* protocol currently in use */
 };