[pisa-src] r1727 - in trunk: libpisa/global.h pisacd/cdtun.c

  • From: Thomas Jansen <mithi@xxxxxxxxx>
  • To: pisa-src@xxxxxxxxxxxxx
  • Date: Thu, 19 Nov 2009 16:28:31 +0100

Author: tjansen
Date: Thu Nov 19 16:28:30 2009
New Revision: 1727

Log:
Improved routing decision in the client.

Previously, the client would test if a NAT mapping existed for the destination
address and otherwise try to fall back to the trust point as a default route.
This is not what we want, because
  1) packets to a non-existent IP within the virtual address space can't be
     forwarded by the trust point
  2) we need the distinction between virtual and non-virtual addresses to
     determine if we want to check DNS for unknown NAT mappings.

Now we check if the destination address is in our virtual address space and
apply NAT or ask DNS. If it's not a virtual address, we use the trustpoint (if
we have one).

Modified:
   trunk/libpisa/global.h
   trunk/pisacd/cdtun.c

Modified: trunk/libpisa/global.h
==============================================================================
--- trunk/libpisa/global.h      Thu Nov 19 16:16:56 2009        (r1726)
+++ trunk/libpisa/global.h      Thu Nov 19 16:28:30 2009        (r1727)
@@ -16,6 +16,7 @@
 
 #include "config.h"
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdint.h>    /* uint*_t */
 #include <string.h>    /* memcpy */
@@ -270,6 +271,11 @@
        return begin == HIT_PREFIX;
 }
 
+static inline bool pisa_ipv4_is_in_subnet(struct in_addr *candidate, struct 
in_addr *target, struct in_addr *netmask)
+{
+       return ((candidate->s_addr & netmask->s_addr) == (target->s_addr & 
netmask->s_addr));   
+}
+
 /**
  * UNUSED macro is useful for marking function arguments that are ignored.
  * This silences warnings for the argument. However it is not supposed to be

Modified: trunk/pisacd/cdtun.c
==============================================================================
--- trunk/pisacd/cdtun.c        Thu Nov 19 16:16:56 2009        (r1726)
+++ trunk/pisacd/cdtun.c        Thu Nov 19 16:28:30 2009        (r1727)
@@ -120,32 +120,33 @@
        }
 
        pisa_arp_from_ipv4((struct in_addr *)&hdr->ip_src, mac);
-
-       /* TODO: use netmask and prefix of the virtual local address space to
-        * differentiate between the two cases of searching a NAT mapping and
-        * forwarding it to the trust point. */
-
-       /* Apply NAT if needed */
        dst = (struct in_addr *)&hdr->ip_dst;
-       map = pisa_nat_mapping_find_by_local_private(cd_ctx.natlist, dst);
-       if (map != NULL) {
-               /* found a matching NAT entry, change the destination IPv4 */
-               pisa_nat_apply(hdr, dst, &map->remote.ipv4);
-               entry = map->connection;
-       } else {
-               /* Retrieve the NAT mapping from DNS */
-               map = pisa_servers_add_via_dns(dst);
-               entry = NULL;
-       }
 
-       /* If neither NAT nor a destination server could be found we have to
-        * fall back to the default route to the Internet, the primary
-        * connection. If that fails too, we've run out of options. */
-       if (entry == NULL)
-               entry = cd_ctx.defaultroute;
-       if (entry == NULL) {
-               PISA_ERROR("local -> remote: no destination.\n");
-               return;
+       if (pisa_ipv4_is_in_subnet(dst, &cd_cfg.local_ipv4, 
&cd_cfg.local_netmask)) {
+               /* Destination is a virtual local IP address, look for NAT */
+               map = pisa_nat_mapping_find_by_local_private(cd_ctx.natlist, 
dst);
+               if (map != NULL) {
+                       if (map->state == PISA_NAT_STATE_FINAL) {
+                               /* found a matching NAT entry, change the 
destination IPv4 */
+                               pisa_nat_apply(hdr, dst, &map->remote.ipv4);
+                               entry = map->connection;
+                       } else {
+                               PISA_ERROR("local -> remote: NAT mapping not 
yet final.\n");
+                               return;
+                       }
+               } else {
+                       /* Retrieve the NAT mapping from DNS */
+                       map = pisa_servers_add_via_dns(dst);
+                       PISA_ERROR("local -> remote: no NAT mapping for virtual 
local IP.\n");
+                       return;
+               }
+       } else {
+               /* If it is not a virtual local IP address, use the trustpoint
+                * to forward the packet to the Internet. */
+               if (!(entry = cd_ctx.defaultroute)) {
+                       PISA_ERROR("local -> remote: no default route to a 
trustpoint.\n");
+                       return;
+               }
        }
 
        if (entry->status != PISA_CON_CONNECTED) {

Other related posts:

  • » [pisa-src] r1727 - in trunk: libpisa/global.h pisacd/cdtun.c - Thomas Jansen