gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] 01/02: add PORT to NAT configuration, generate nat


From: gnunet
Subject: [GNUnet-SVN] [gnunet] 01/02: add PORT to NAT configuration, generate nat.conf from nat.conf.in, implement more of new NAT service
Date: Fri, 16 Dec 2016 11:44:52 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

commit 8108e41d89bb771fe8bcf887919de3f581f1cc0d
Author: Christian Grothoff <address@hidden>
AuthorDate: Fri Dec 16 10:53:58 2016 +0100

    add PORT to NAT configuration, generate nat.conf from nat.conf.in, 
implement more of new NAT service
---
 configure.ac                          |   1 +
 src/conversation/conversation.conf.in |   2 +-
 src/include/gnunet_nat_service.h      |  10 +-
 src/nat/Makefile.am                   |   2 +-
 src/nat/gnunet-service-nat.c          | 274 ++++++++++++++++++++--------------
 src/nat/gnunet-service-nat_helper.c   |  40 +++--
 src/nat/gnunet-service-nat_helper.h   |   8 +-
 src/nat/{nat.conf => nat.conf.in}     |  10 ++
 src/rps/rps.conf.in                   |   2 +-
 9 files changed, 217 insertions(+), 132 deletions(-)

diff --git a/configure.ac b/configure.ac
index ebe5753..faf0588 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1595,6 +1595,7 @@ src/namecache/namecache.conf
 src/namestore/Makefile
 src/namestore/namestore.conf
 src/nat/Makefile
+src/nat/nat.conf
 src/nse/Makefile
 src/nse/nse.conf
 src/peerinfo/Makefile
diff --git a/src/conversation/conversation.conf.in 
b/src/conversation/conversation.conf.in
index fb0478f..e966ed6 100644
--- a/src/conversation/conversation.conf.in
+++ b/src/conversation/conversation.conf.in
@@ -3,7 +3,7 @@ AUTOSTART = @AUTOSTART@
 BINARY = gnunet-service-conversation
 UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-conversation.sock
 HOSTNAME = localhost
address@hidden@ PORT = 2106
address@hidden@ PORT = 2120
 
 # Desired phone line.  Change if multiple users are using
 # the same peer and we thus need disjoint phone lines.
diff --git a/src/include/gnunet_nat_service.h b/src/include/gnunet_nat_service.h
index 378f5a8..b66b442 100644
--- a/src/include/gnunet_nat_service.h
+++ b/src/include/gnunet_nat_service.h
@@ -64,7 +64,7 @@ enum GNUNET_NAT_AddressClass
   GNUNET_NAT_AC_OTHER = 1,
 
   /**
-   * Addresses that are highly sensitive
+   * Flag for addresses that are highly sensitive
    * (i.e. IPv6 with our MAC).
    */
   GNUNET_NAT_AC_PRIVATE = 2,
@@ -83,6 +83,7 @@ enum GNUNET_NAT_AddressClass
   /**
    * Addresses useful in the local wired network,
    * i.e. a MAC.  Sensitive, but obvious to people nearby.
+
    * Useful for broadcasts.
    */
   GNUNET_NAT_AC_LAN = 8,
@@ -113,6 +114,13 @@ enum GNUNET_NAT_AddressClass
   GNUNET_NAT_AC_LOOPBACK = 64,
   
   /**
+   * Addresses that should be our global external IP address
+   * on the outside of a NAT.  Might be incorrectly determined.
+   * Used as a bit in combination with #GNUNET_NAT_AC_GLOBAL.
+   */
+  GNUNET_NAT_AC_GLOBAL_EXTERN = 128,
+
+  /**
    * Bitmask for "any" address.
    */
   GNUNET_NAT_AC_ANY = 65535
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index d304a57..c62a8d2 100644
--- a/src/nat/Makefile.am
+++ b/src/nat/Makefile.am
@@ -12,7 +12,7 @@ libexecdir= $(pkglibdir)/libexec/
 
 pkgcfgdir= $(pkgdatadir)/config.d/
 
-dist_pkgcfg_DATA = \
+pkgcfg_DATA = \
   nat.conf
 
 if LINUX
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index f475565..1ebf756 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -28,10 +28,8 @@
  * knowledge about the local network topology.
  *
  * TODO:
- * - call GN_start_gnunet_nat_server_() if possible (i.e.
- *   when we find we have a non-global IPv4 address)
+ * - implement UPnPC/PMP-based NAT traversal
  * - implement autoconfig
- * - implmeent UPnPC/PMP-based NAT traversal
  * - implement NEW logic for external IP detection
  */
 #include "platform.h"
@@ -91,6 +89,11 @@ struct ClientHandle
   enum GNUNET_NAT_RegisterFlags flags;
 
   /**
+   * Is any of the @e addrs in a reserved subnet for NAT?
+   */
+  int natted_address;
+  
+  /**
    * Port we would like as we are configured to use this one for
    * advertising (in addition to the one we are binding to).
    */
@@ -306,6 +309,108 @@ check_register (void *cls,
 
 
 /**
+ * Check if @a ip is in @a network with @a bits netmask.
+ *
+ * @param network to test
+ * @param ip IP address to test
+ * @param bits bitmask for the network
+ * @return #GNUNET_YES if @a ip is in @a network
+ */
+static int
+match_ipv4 (const char *network,
+           const struct in_addr *ip,
+           uint8_t bits)
+{
+  struct in_addr net;
+  
+  if (0 == bits)
+    return GNUNET_YES;
+  GNUNET_assert (1 == inet_pton (AF_INET,
+                                network,
+                                &net));
+  return ! ((ip->s_addr ^ net.s_addr) & htonl (0xFFFFFFFFu << (32 - bits)));
+}
+
+
+/**
+ * Check if @a ip is in @a network with @a bits netmask.
+ *
+ * @param network to test
+ * @param ip IP address to test
+ * @param bits bitmask for the network
+ * @return #GNUNET_YES if @a ip is in @a network
+ */
+static int
+match_ipv6 (const char *network,
+           const struct in6_addr *ip,
+           uint8_t bits)
+{
+  struct in6_addr net;
+  struct in6_addr mask;
+  unsigned int off;
+  
+  if (0 == bits)
+    return GNUNET_YES;
+  GNUNET_assert (1 == inet_pton (AF_INET,
+                                network,
+                                &net));
+  memset (&mask, 0, sizeof (mask));
+  off = 0;
+  while (bits > 8)
+  {
+    mask.s6_addr[off++] = 0xFF;
+    bits -= 8;
+  }
+  while (bits > 0)
+  {
+    mask.s6_addr[off] = (mask.s6_addr[off] >> 1) + 0x80;
+    bits--;
+  }
+  for (unsigned j = 0; j < sizeof (struct in6_addr) / sizeof (uint32_t); j++)
+    if (((((uint32_t *) ip)[j] & ((uint32_t *) &mask)[j])) !=
+       (((uint32_t *) &net)[j] & ((int *) &mask)[j]))
+      return GNUNET_NO;
+  return GNUNET_YES;
+}
+
+
+/**
+ * Test if the given IPv4 address is in a known range
+ * for private networks.
+ *
+ * @param ip address to test
+ * @return #GNUNET_YES if @a ip is in a NAT range
+ */
+static int
+is_nat_v4 (const struct in_addr *ip)
+{
+  return
+    match_ipv4 ("10.0.0.0", ip, 8) || /* RFC 1918 */
+    match_ipv4 ("100.64.0.0", ip, 10) || /* CG-NAT, RFC 6598 */
+    match_ipv4 ("192.168.0.0", ip, 12) || /* RFC 1918 */
+    match_ipv4 ("169.254.0.0", ip, 16) || /* AUTO, RFC 3927 */
+    match_ipv4 ("172.16.0.0", ip, 16);  /* RFC 1918 */
+}
+
+
+/**
+ * Test if the given IPv6 address is in a known range
+ * for private networks.
+ *
+ * @param ip address to test
+ * @return #GNUNET_YES if @a ip is in a NAT range
+ */
+static int
+is_nat_v6 (const struct in6_addr *ip)
+{
+  return
+    match_ipv6 ("fc00::", ip, 7) || /* RFC 4193 */
+    match_ipv6 ("fec0::", ip, 10) || /* RFC 3879 */
+    match_ipv6 ("fe80::", ip, 10); /* RFC 4291, link-local */
+}
+
+
+/**
  * Handler for #GNUNET_MESSAGE_TYPE_NAT_REGISTER message from client.
  * We remember the client for updates upon future NAT events.
  *
@@ -352,10 +457,22 @@ handle_register (void *cls,
     switch (sa->sa_family)
     {
     case AF_INET:
-      alen = sizeof (struct sockaddr_in);
+      {
+       const struct sockaddr_in *s4 = (const struct sockaddr_in *) sa;
+       
+       alen = sizeof (struct sockaddr_in);
+       if (is_nat_v4 (&s4->sin_addr))
+         ch->natted_address = GNUNET_YES;
+      }
       break;
     case AF_INET6:
-      alen = sizeof (struct sockaddr_in6);
+      {
+       const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) sa;
+       
+       alen = sizeof (struct sockaddr_in6);
+       if (is_nat_v6 (&s6->sin6_addr))
+         ch->natted_address = GNUNET_YES;
+      }
       break;
 #if AF_UNIX
     case AF_UNIX:
@@ -418,7 +535,30 @@ static void
 notify_clients_stun_change (const struct sockaddr_in *ip,
                            int add)
 {
-  /* FIXME: notify clients about add/drop */
+  for (struct ClientHandle *ch = ch_head;
+       NULL != ch;
+       ch = ch->next)
+  {
+    struct sockaddr_in v4;
+    struct GNUNET_NAT_AddressChangeNotificationMessage *msg;
+    struct GNUNET_MQ_Envelope *env;
+    
+    if (! ch->natted_address)
+      continue;
+    v4 = *ip;
+    v4.sin_port = htons (ch->adv_port);
+    env = GNUNET_MQ_msg_extra (msg,
+                              sizeof (v4),
+                              GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE);
+    msg->add_remove = htonl ((int32_t) add);
+    msg->addr_class = htonl (GNUNET_NAT_AC_GLOBAL_EXTERN |
+                            GNUNET_NAT_AC_GLOBAL);
+    GNUNET_memcpy (&msg[1],
+                  &v4,
+                  sizeof (v4));
+    GNUNET_MQ_send (ch->mq,
+                   env);
+  }
 }
 
 
@@ -599,6 +739,9 @@ handle_request_connection_reversal (void *cls,
   size_t remote_sa_len = ntohs (message->remote_addr_size);
   const struct sockaddr *local_sa = (const struct sockaddr *) &buf[0];
   const struct sockaddr *remote_sa = (const struct sockaddr *) 
&buf[local_sa_len];
+  const struct sockaddr_in *l4 = NULL;
+  const struct sockaddr_in *r4;
+  int ret;
   
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received REQUEST CONNECTION REVERSAL message from client\n");
@@ -611,6 +754,7 @@ handle_request_connection_reversal (void *cls,
       GNUNET_SERVICE_client_drop (ch->client);
       return;
     }
+    l4 = (const struct sockaddr_in *) local_sa;    
     break;
   case AF_INET6:
     if (local_sa_len != sizeof (struct sockaddr_in6))
@@ -619,6 +763,9 @@ handle_request_connection_reversal (void *cls,
       GNUNET_SERVICE_client_drop (ch->client);
       return;
     }
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Connection reversal for IPv6 not supported yet\n"));
+    ret = GNUNET_SYSERR;
     break;
   default:
     GNUNET_break (0);
@@ -634,6 +781,10 @@ handle_request_connection_reversal (void *cls,
       GNUNET_SERVICE_client_drop (ch->client);
       return;
     }
+    r4 = (const struct sockaddr_in *) remote_sa;
+    ret = GN_request_connection_reversal (&l4->sin_addr,
+                                         ntohs (l4->sin_port),
+                                         &r4->sin_addr);
     break;
   case AF_INET6:
     if (remote_sa_len != sizeof (struct sockaddr_in6))
@@ -642,15 +793,18 @@ handle_request_connection_reversal (void *cls,
       GNUNET_SERVICE_client_drop (ch->client);
       return;
     }
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Connection reversal for IPv6 not supported yet\n"));
+    ret = GNUNET_SYSERR;
     break;
   default:
     GNUNET_break (0);
     GNUNET_SERVICE_client_drop (ch->client);
     return;
   }
-  /* FIXME: actually run the logic by
-     calling 'GN_request_connection_reversal()' */
-  
+  if (GNUNET_OK != ret)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("Connection reversal request failed\n"));  
   GNUNET_SERVICE_client_continue (ch->client);
 }
 
@@ -757,108 +911,6 @@ struct IfcProcContext
 
 
 /**
- * Check if @a ip is in @a network with @a bits netmask.
- *
- * @param network to test
- * @param ip IP address to test
- * @param bits bitmask for the network
- * @return #GNUNET_YES if @a ip is in @a network
- */
-static int
-match_ipv4 (const char *network,
-           const struct in_addr *ip,
-           uint8_t bits)
-{
-  struct in_addr net;
-  
-  if (0 == bits)
-    return GNUNET_YES;
-  GNUNET_assert (1 == inet_pton (AF_INET,
-                                network,
-                                &net));
-  return ! ((ip->s_addr ^ net.s_addr) & htonl (0xFFFFFFFFu << (32 - bits)));
-}
-
-
-/**
- * Check if @a ip is in @a network with @a bits netmask.
- *
- * @param network to test
- * @param ip IP address to test
- * @param bits bitmask for the network
- * @return #GNUNET_YES if @a ip is in @a network
- */
-static int
-match_ipv6 (const char *network,
-           const struct in6_addr *ip,
-           uint8_t bits)
-{
-  struct in6_addr net;
-  struct in6_addr mask;
-  unsigned int off;
-  
-  if (0 == bits)
-    return GNUNET_YES;
-  GNUNET_assert (1 == inet_pton (AF_INET,
-                                network,
-                                &net));
-  memset (&mask, 0, sizeof (mask));
-  off = 0;
-  while (bits > 8)
-  {
-    mask.s6_addr[off++] = 0xFF;
-    bits -= 8;
-  }
-  while (bits > 0)
-  {
-    mask.s6_addr[off] = (mask.s6_addr[off] >> 1) + 0x80;
-    bits--;
-  }
-  for (unsigned j = 0; j < sizeof (struct in6_addr) / sizeof (uint32_t); j++)
-    if (((((uint32_t *) ip)[j] & ((uint32_t *) &mask)[j])) !=
-       (((uint32_t *) &net)[j] & ((int *) &mask)[j]))
-      return GNUNET_NO;
-  return GNUNET_YES;
-}
-
-
-/**
- * Test if the given IPv4 address is in a known range
- * for private networks.
- *
- * @param ip address to test
- * @return #GNUNET_YES if @a ip is in a NAT range
- */
-static int
-is_nat_v4 (const struct in_addr *ip)
-{
-  return
-    match_ipv4 ("10.0.0.0", ip, 8) || /* RFC 1918 */
-    match_ipv4 ("100.64.0.0", ip, 10) || /* CG-NAT, RFC 6598 */
-    match_ipv4 ("192.168.0.0", ip, 12) || /* RFC 1918 */
-    match_ipv4 ("169.254.0.0", ip, 16) || /* AUTO, RFC 3927 */
-    match_ipv4 ("172.16.0.0", ip, 16);  /* RFC 1918 */
-}
-
-
-/**
- * Test if the given IPv6 address is in a known range
- * for private networks.
- *
- * @param ip address to test
- * @return #GNUNET_YES if @a ip is in a NAT range
- */
-static int
-is_nat_v6 (const struct in6_addr *ip)
-{
-  return
-    match_ipv6 ("fc00::", ip, 7) || /* RFC 4193 */
-    match_ipv6 ("fec0::", ip, 10) || /* RFC 3879 */
-    match_ipv6 ("fe80::", ip, 10); /* RFC 4291, link-local */
-}
-
-
-/**
  * Callback function invoked for each interface found.  Adds them
  * to our new address list.
  *
diff --git a/src/nat/gnunet-service-nat_helper.c 
b/src/nat/gnunet-service-nat_helper.c
index e476da1..379603a 100644
--- a/src/nat/gnunet-service-nat_helper.c
+++ b/src/nat/gnunet-service-nat_helper.c
@@ -319,7 +319,7 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h)
     GNUNET_SCHEDULER_cancel (h->server_read_task);
     h->server_read_task = NULL;
   }
-    if (NULL != h->server_proc)
+  if (NULL != h->server_proc)
   {
     if (0 != GNUNET_OS_process_kill (h->server_proc,
                                      GNUNET_TERM_SIG))
@@ -349,23 +349,25 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h)
  * that peer to connect to us (connection reversal).
  *
  * @param internal_address out internal address to use
- * @param sa the address of the peer (IPv4-only)
+ * @param internal_port port to use
+ * @param remote_v4 the address of the peer (IPv4-only)
  * @return #GNUNET_SYSERR on error,
  *         #GNUNET_OK otherwise
  */
 int
-GN_request_connection_reversal (const char *internal_address,
-                               const struct sockaddr_in *sa)
+GN_request_connection_reversal (const struct in_addr *internal_address,
+                               uint16_t internal_port,
+                               const struct in_addr *remote_v4)
 {
-  char inet4[INET_ADDRSTRLEN];
+  char intv4[INET_ADDRSTRLEN];
+  char remv4[INET_ADDRSTRLEN];
   char port_as_string[6];
   struct GNUNET_OS_Process *proc;
   char *binary;
 
-  GNUNET_assert (sa->sin_family == AF_INET);
   if (NULL == inet_ntop (AF_INET,
-                        &sa->sin_addr,
-                        inet4,
+                        internal_address,
+                        intv4,
                         INET_ADDRSTRLEN))
   {
     GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
@@ -373,15 +375,25 @@ GN_request_connection_reversal (const char 
*internal_address,
                               "inet_ntop");
     return GNUNET_SYSERR;
   }
+  if (NULL == inet_ntop (AF_INET,
+                        remote_v4,
+                        remv4,
+                        INET_ADDRSTRLEN))
+  {
+    GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
+                              "nat",
+                              "inet_ntop");
+    return GNUNET_SYSERR;
+  }  
   GNUNET_snprintf (port_as_string,
                    sizeof (port_as_string),
                    "%d",
-                   ntohs (sa->sin_port));
+                   internal_port);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        _("Running gnunet-helper-nat-client %s %s %u\n"),
-       internal_address,
-       inet4,
-       ntohs (sa->sin_port));
+       intv4,
+       remv4,
+       internal_port);
   binary
     = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client");
   proc
@@ -392,8 +404,8 @@ GN_request_connection_reversal (const char 
*internal_address,
                               NULL,
                                binary,
                                "gnunet-helper-nat-client",
-                               internal_address,
-                               inet4,
+                               intv4,
+                               remv4,
                               port_as_string,
                               NULL);
   GNUNET_free (binary);
diff --git a/src/nat/gnunet-service-nat_helper.h 
b/src/nat/gnunet-service-nat_helper.h
index 861d62c..d3f1a75 100644
--- a/src/nat/gnunet-service-nat_helper.h
+++ b/src/nat/gnunet-service-nat_helper.h
@@ -77,13 +77,15 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h);
  * that peer to connect to us (connection reversal).
  *
  * @param internal_address out internal address to use
- * @param sa the address of the peer (IPv4-only)
+ * @param internal_port internal port to use
+ * @param remote_v4 the address of the peer (IPv4-only)
  * @return #GNUNET_SYSERR on error,
  *         #GNUNET_OK otherwise
  */
 int
-GN_request_connection_reversal (const char *internal_address,
-                               const struct sockaddr_in *sa);
+GN_request_connection_reversal (const struct in_addr *internal_address,
+                               uint16_t internal_port,
+                               const struct in_addr *sa);
 
 
 /* end of gnunet-service-nat_helper.h */
diff --git a/src/nat/nat.conf b/src/nat/nat.conf.in
similarity index 88%
rename from src/nat/nat.conf
rename to src/nat/nat.conf.in
index 4493a6e..304db3c 100644
--- a/src/nat/nat.conf
+++ b/src/nat/nat.conf.in
@@ -1,4 +1,14 @@
 [nat]
+AUTOSTART = @AUTOSTART@
address@hidden@ PORT = 2121
+HOSTNAME = localhost
+BINARY = gnunet-service-nat
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
+UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-nat.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
+
 # Are we behind NAT?
 BEHIND_NAT = NO
 
diff --git a/src/rps/rps.conf.in b/src/rps/rps.conf.in
index 046a8b5..b5feb1b 100644
--- a/src/rps/rps.conf.in
+++ b/src/rps/rps.conf.in
@@ -8,7 +8,7 @@ UNIX_MATCH_GID = YES
 HOSTNAME = localhost
 ACCEPT_FROM = 127.0.0.1;
 ACCEPT_FROM6 = ::1;
-# PORT = 2106
+# PORT = 2119
 @UNIXONLY@ PORT = 2119
 
 # This is the timeinterval between the rounds

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]