[pisa-src] r1703 - in trunk: libpisa/nat.c libpisa/nat.h pisacd/cdservers.c pisacd/cdservers.h

  • From: Thomas Jansen <mithi@xxxxxxxxx>
  • To: pisa-src@xxxxxxxxxxxxx
  • Date: Thu, 19 Nov 2009 13:18:43 +0100

Author: tjansen
Date: Thu Nov 19 13:18:42 2009
New Revision: 1703

Log:
Split NAT mapping creation into two steps.

In the preliminary state, a mapping contains only the virtual local IPv4
address. The preliminary entry can be upgraded to its final state by filling
the empty parts of the struct. This is a preparation for creating new mappings
at runtime via DNS.

Modified:
   trunk/libpisa/nat.c
   trunk/libpisa/nat.h
   trunk/pisacd/cdservers.c
   trunk/pisacd/cdservers.h

Modified: trunk/libpisa/nat.c
==============================================================================
--- trunk/libpisa/nat.c Thu Nov 19 03:12:27 2009        (r1702)
+++ trunk/libpisa/nat.c Thu Nov 19 13:18:42 2009        (r1703)
@@ -134,17 +134,56 @@
 }
 
 /**
- * Add a NAT mapping to the list.
+ * Add a NAT mapping to the list. Convenience function wrapping the two step
+ * process of creating and upgrading a preliminary NAT mapping.
+ *
+ * @param natlist NAT list containing the heads of the hashes.
  * @param local_private the local private IPv4 address
  * @param remote_private the remote private IPv4 address
  * @param entry associated connection manager entry
+ * @param mac MAC address, may be NULL if irrelevant
  * @return the new NAT mapping
  */
 pisa_nat_mapping *pisa_nat_add_mapping(pisa_nat_list *natlist, struct in_addr 
*local_private, struct in_addr *remote_private, pisa_conmgr_entry *entry, 
pisa_mac *mac)
 {
+       pisa_nat_mapping *map = pisa_nat_add_preliminary(natlist, 
local_private);
+       pisa_nat_upgrade_preliminary(natlist, map, remote_private, entry, mac);
+       return map;
+}
+
+/**
+ * Add a preliminary NAT mapping to the list.
+ *
+ * @param natlist NAT list containing the heads of the hashes.
+ * @param local_private the local private IPv4 address
+ * @return the new NAT mapping
+ */
+pisa_nat_mapping *pisa_nat_add_preliminary(pisa_nat_list *natlist, struct 
in_addr *local_private)
+{
        pisa_nat_mapping *map = malloc(sizeof(pisa_nat_mapping));
 
+       memset(map, 0, sizeof(pisa_nat_mapping));
+       map->state = PISA_NAT_STATE_PRELIMINARY;
        pisa_ipv4_copy(&map->local_private, local_private);
+
+       HASH_ADD(hh_local_private, natlist->hash_local_private, local_private, 
sizeof(struct in_addr), map);
+
+       return map;
+}
+
+/**
+ * Fill in the remaining blank fields in a preliminary NAT mapping, thus
+ * upgrading it to the final state.
+ *
+ * @param natlist NAT list containing the heads of the hashes.
+ * @param map NAT mapping
+ * @param remove_private remote IPv4 address
+ * @param entry conmgr entry to the service gateway
+ * @param mac MAC address, may be NULL if irrelevant
+ */
+void pisa_nat_upgrade_preliminary(pisa_nat_list *natlist, pisa_nat_mapping 
*map, struct in_addr *remote_private, pisa_conmgr_entry *entry, pisa_mac *mac)
+{
+       map->state = PISA_NAT_STATE_FINAL;
        pisa_ipv4_copy(&map->remote.ipv4, remote_private);
        pisa_ipv6_copy(&map->remote.hit, &entry->hit);
        if (mac == NULL)
@@ -154,10 +193,7 @@
        map->connection = entry;
 
        HASH_ADD(hh_remote, natlist->hash_remote, remote, sizeof(map->remote), 
map);
-       HASH_ADD(hh_local_private, natlist->hash_local_private, local_private, 
sizeof(struct in_addr), map);
        HASH_ADD(hh_mac, natlist->hash_mac, mac, sizeof(pisa_mac), map);
-
-       return map;
 }
 
 /**
@@ -171,9 +207,11 @@
        while (cur) {
                next = cur->hh_remote.next;
                if (!memcmp(remote_hit, &cur->remote.hit, sizeof(struct 
in6_addr))) {
-                       HASH_DELETE(hh_remote, natlist->hash_remote, cur);
+                       if (cur->state == PISA_NAT_STATE_FINAL) {
+                               HASH_DELETE(hh_remote, natlist->hash_remote, 
cur);
+                               HASH_DELETE(hh_mac, natlist->hash_mac, cur);
+                       }
                        HASH_DELETE(hh_local_private, 
natlist->hash_local_private, cur);
-                       HASH_DELETE(hh_mac, natlist->hash_mac, cur);
                        free(cur);
                }
                cur = next;

Modified: trunk/libpisa/nat.h
==============================================================================
--- trunk/libpisa/nat.h Thu Nov 19 03:12:27 2009        (r1702)
+++ trunk/libpisa/nat.h Thu Nov 19 13:18:42 2009        (r1703)
@@ -19,6 +19,11 @@
 #include "conmgr.h"
 #include "arp.h"
 
+typedef enum {
+       PISA_NAT_STATE_PRELIMINARY = 1,
+       PISA_NAT_STATE_FINAL = 2
+} pisa_nat_state;
+
 typedef struct pisa_nat_mapping {
        struct in_addr local_private;
        pisa_mac mac;
@@ -27,6 +32,7 @@
                struct in6_addr hit;
        } remote;
        pisa_conmgr_entry *connection;
+       pisa_nat_state state;
 
        UT_hash_handle hh_local_private;
        UT_hash_handle hh_mac;
@@ -43,6 +49,8 @@
 void pisa_nat_destroy(pisa_nat_list *natlist);
 
 pisa_nat_mapping *pisa_nat_add_mapping(pisa_nat_list *natlist, struct in_addr 
*local_private, struct in_addr *remote_private, pisa_conmgr_entry *entry, 
pisa_mac *mac);
+pisa_nat_mapping *pisa_nat_add_preliminary(pisa_nat_list *natlist, struct 
in_addr *local_private);
+void pisa_nat_upgrade_preliminary(pisa_nat_list *natlist, pisa_nat_mapping 
*map, struct in_addr *remote_private, pisa_conmgr_entry *entry, pisa_mac *mac);
 void pisa_nat_del_mapping(pisa_nat_list *natlist, struct in6_addr *remote_hit);
 pisa_nat_mapping *pisa_nat_mapping_find_by_remote(pisa_nat_list *natlist, 
struct in6_addr *remote_hit, struct in_addr *remote_ipv4);
 pisa_nat_mapping *pisa_nat_mapping_find_by_local_private(pisa_nat_list 
*natlist, struct in_addr *local_private);

Modified: trunk/pisacd/cdservers.c
==============================================================================
--- trunk/pisacd/cdservers.c    Thu Nov 19 03:12:27 2009        (r1702)
+++ trunk/pisacd/cdservers.c    Thu Nov 19 13:18:42 2009        (r1703)
@@ -209,3 +209,24 @@
                pisa_servers_add_mapping(config_setting_get_elem(mappings, i), 
entry);
        PISA_DEBUG(PL_CONFIG, "\n");
 }
+
+/**
+ * Retrieve the conmgr entry for a given local IP address. If the entry
+ * already exists we return it. Otherwise we create a preliminary entry and
+ * schedule a DNS query.
+ *
+ * @param local_ip virtual local IP address of the service
+ * @return nat mappin, either full or preliminary
+ */
+pisa_nat_mapping *pisa_servers_add_via_dns(struct in_addr *local_ip)
+{
+       pisa_nat_mapping *nat;
+
+       if ((nat = pisa_nat_mapping_find_by_local_private(cd_ctx.natlist, 
local_ip)))
+               return nat;
+
+       nat = pisa_nat_add_preliminary(cd_ctx.natlist, local_ip);
+       /* Todo: schedule DNS query */
+
+       return nat;
+}

Modified: trunk/pisacd/cdservers.h
==============================================================================
--- trunk/pisacd/cdservers.h    Thu Nov 19 03:12:27 2009        (r1702)
+++ trunk/pisacd/cdservers.h    Thu Nov 19 13:18:42 2009        (r1703)
@@ -12,4 +12,6 @@
 void pisa_servers_add_services(pisa_conmgr_entry *entry);
 pisa_conmgr_entry *pisa_server_add(struct in6_addr *hit, int port, 
pisa_contype type);
 
+pisa_nat_mapping *pisa_servers_add_via_dns(struct in_addr *local_ip);
+
 #endif /* PISA_CDSERVERS_H */

Other related posts:

  • » [pisa-src] r1703 - in trunk: libpisa/nat.c libpisa/nat.h pisacd/cdservers.c pisacd/cdservers.h - Thomas Jansen