gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] 02/03: implement keeping and timeout of NAT STUN d


From: gnunet
Subject: [GNUnet-SVN] [gnunet] 02/03: implement keeping and timeout of NAT STUN data
Date: Wed, 30 Nov 2016 21:14:40 +0100

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

grothoff pushed a commit to branch master
in repository gnunet.

commit 8a5c5861114433d0d267885bb29f21a0c160d1f4
Author: Christian Grothoff <address@hidden>
AuthorDate: Wed Nov 30 12:17:19 2016 +0100

    implement keeping and timeout of NAT STUN data
---
 src/nat/gnunet-service-nat.c | 156 ++++++++++++++++++++++++++++++++++++++++++-
 src/nat/nat.conf             |   3 +
 src/nat/nat_api_stun.c       |   3 +-
 3 files changed, 158 insertions(+), 4 deletions(-)

diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index d8a3438..f475565 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -144,6 +144,51 @@ struct LocalAddressList
 
 
 /**
+ * External IP address as given to us via some STUN server.
+ */
+struct StunExternalIP
+{
+  /**
+   * Kept in a DLL.
+   */ 
+  struct StunExternalIP *next;
+
+  /**
+   * Kept in a DLL.
+   */ 
+  struct StunExternalIP *prev;
+
+  /**
+   * Task we run to remove this entry when it is stale.
+   */
+  struct GNUNET_SCHEDULER_Task *timeout_task;
+
+  /**
+   * Our external IP address as reported by the 
+   * STUN server.
+   */
+  struct sockaddr_in external_addr;
+
+  /**
+   * Address of the reporting STUN server.  Used to 
+   * detect when a STUN server changes its opinion
+   * to more quickly remove stale results.
+   */
+  struct sockaddr_storage stun_server_addr;
+
+  /**
+   * Number of bytes used in @e stun_server_addr.
+   */
+  size_t stun_server_addr_len;
+};
+
+
+/**
+ * Timeout to use when STUN data is considered stale.
+ */
+static struct GNUNET_TIME_Relative stun_stale_timeout;
+
+/**
  * Handle to our current configuration.
  */
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -178,6 +223,16 @@ static struct LocalAddressList *lal_head;
  */
 static struct LocalAddressList *lal_tail;
 
+/**
+ * Kept in a DLL.
+ */ 
+static struct StunExternalIP *se_head;
+
+/**
+ * Kept in a DLL.
+ */ 
+static struct StunExternalIP *se_tail;
+
 
 /**
  * Free the DLL starting at #lal_head.
@@ -353,6 +408,43 @@ check_stun (void *cls,
 
 
 /**
+ * Notify all clients about our external IP address
+ * as reported by the STUN server.
+ *
+ * @param ip the external IP
+ * @param add #GNUNET_YES to add, #GNUNET_NO to remove
+ */
+static void
+notify_clients_stun_change (const struct sockaddr_in *ip,
+                           int add)
+{
+  /* FIXME: notify clients about add/drop */
+}
+
+
+/**
+ * Function to be called when we decide that an
+ * external IP address as told to us by a STUN
+ * server has gone stale.
+ *
+ * @param cls the `struct StunExternalIP` to drop
+ */
+static void
+stun_ip_timeout (void *cls)
+{
+  struct StunExternalIP *se = cls;
+
+  se->timeout_task = NULL;
+  notify_clients_stun_change (&se->external_addr,
+                             GNUNET_NO);
+  GNUNET_CONTAINER_DLL_remove (se_head,
+                              se_tail,
+                              se);
+  GNUNET_free (se);
+}
+
+
+/**
  * Handler for #GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN message from
  * client.
  *
@@ -401,8 +493,7 @@ handle_stun (void *cls,
                                      payload_size,
                                      &external_addr))
   {     
-    /* FIXME: do something with "external_addr"! We 
-       now know that a server at "sa" claims that
+    /* We now know that a server at "sa" claims that
        we are visible at IP "external_addr". 
 
        We should (for some fixed period of time) tell
@@ -416,7 +507,50 @@ handle_stun (void *cls,
        (with a sane default), so that the UDP plugin can tell how
        often to re-request STUN.
     */
-    
+    struct StunExternalIP *se;
+
+    /* Check if we had a prior response from this STUN server */
+    for (se = se_head; NULL != se; se = se->next)
+    {
+      if ( (se->stun_server_addr_len != sa_len) ||
+          (0 != memcmp (sa,
+                        &se->stun_server_addr,
+                        sa_len)) )
+       continue; /* different STUN server */
+      if (0 != memcmp (&external_addr,
+                      &se->external_addr,
+                      sizeof (struct sockaddr_in)))
+      {
+       /* external IP changed, update! */
+       notify_clients_stun_change (&se->external_addr,
+                                   GNUNET_NO);
+       se->external_addr = external_addr;
+       notify_clients_stun_change (&se->external_addr,
+                                   GNUNET_YES);
+      }
+      /* update timeout */
+      GNUNET_SCHEDULER_cancel (se->timeout_task);
+      se->timeout_task
+       = GNUNET_SCHEDULER_add_delayed (stun_stale_timeout,
+                                       &stun_ip_timeout,
+                                       se);
+      return;
+    }
+    /* STUN server is completely new, create fresh entry */
+    se = GNUNET_new (struct StunExternalIP);
+    se->external_addr = external_addr;
+    GNUNET_memcpy (&se->stun_server_addr,
+                  sa,
+                  sa_len);
+    se->stun_server_addr_len = sa_len;
+    se->timeout_task = GNUNET_SCHEDULER_add_delayed (stun_stale_timeout,
+                                                    &stun_ip_timeout,
+                                                    se);
+    GNUNET_CONTAINER_DLL_insert (se_head,
+                                se_tail,
+                                se);
+    notify_clients_stun_change (&se->external_addr,
+                               GNUNET_NO);
   }
   GNUNET_SERVICE_client_continue (ch->client);
 }
@@ -579,6 +713,16 @@ handle_autoconfig_request (void *cls,
 static void
 shutdown_task (void *cls)
 {
+  struct StunExternalIP *se;
+
+  while (NULL != (se = se_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (se_head,
+                                se_tail,
+                                se);
+    GNUNET_SCHEDULER_cancel (se->timeout_task);
+    GNUNET_free (se);
+  }
   if (NULL != scan_task)
   {
     GNUNET_SCHEDULER_cancel (scan_task);
@@ -979,6 +1123,12 @@ run (void *cls,
      struct GNUNET_SERVICE_Handle *service)
 {
   cfg = c;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_time (cfg,
+                                          "NAT",
+                                          "STUN_STALE",
+                                          &stun_stale_timeout))
+    stun_stale_timeout = GNUNET_TIME_UNIT_HOURS;
   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
                                 NULL);
   stats = GNUNET_STATISTICS_create ("nat",
diff --git a/src/nat/nat.conf b/src/nat/nat.conf
index 4b1add1..4493a6e 100644
--- a/src/nat/nat.conf
+++ b/src/nat/nat.conf
@@ -54,6 +54,9 @@ STUN_FREQUENCY = 5 min
 # Default list of stun servers
 STUN_SERVERS = stun.gnunet.org stun.services.mozilla.com:3478 
stun.ekiga.net:3478
 
+# After how long do we consider STUN data stale?
+STUN_STALE = 60 min
+
 
 [gnunet-nat-server]
 HOSTNAME = gnunet.org
diff --git a/src/nat/nat_api_stun.c b/src/nat/nat_api_stun.c
index 0d4ba86..8f5a5f8 100644
--- a/src/nat/nat_api_stun.c
+++ b/src/nat/nat_api_stun.c
@@ -229,7 +229,8 @@ GNUNET_NAT_stun_make_request (const char *server,
   rh->dns_active = GNUNET_RESOLVER_ip_get (rh->stun_server,
                                            AF_INET,
                                            TIMEOUT,
-                                           &stun_dns_callback, rh);
+                                           &stun_dns_callback,
+                                          rh);
   if (NULL == rh->dns_active)
   {
     GNUNET_NAT_stun_make_request_cancel (rh);

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



reply via email to

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