gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r36463 - in gnunet/src: include nat util


From: gnunet
Subject: [GNUnet-SVN] r36463 - in gnunet/src: include nat util
Date: Wed, 7 Oct 2015 12:11:29 +0200

Author: grothoff
Date: 2015-10-07 12:11:29 +0200 (Wed, 07 Oct 2015)
New Revision: 36463

Modified:
   gnunet/src/include/gnunet_dnsstub_lib.h
   gnunet/src/include/gnunet_nat_lib.h
   gnunet/src/nat/nat.c
   gnunet/src/nat/nat_stun.c
   gnunet/src/util/connection.c
Log:
enable clean up of NAT STUN state, prevents test_plugin_udp from segfaulting

Modified: gnunet/src/include/gnunet_dnsstub_lib.h
===================================================================
--- gnunet/src/include/gnunet_dnsstub_lib.h     2015-10-07 09:51:46 UTC (rev 
36462)
+++ gnunet/src/include/gnunet_dnsstub_lib.h     2015-10-07 10:11:29 UTC (rev 
36463)
@@ -65,12 +65,13 @@
  * @param cls closure
  * @param rs socket that received the response
  * @param dns dns response, never NULL
- * @param dns_len number of bytes in 'dns'
+ * @param dns_len number of bytes in @a dns
  */
-typedef void (*GNUNET_DNSSTUB_ResultCallback)(void *cls,
-                                             struct 
GNUNET_DNSSTUB_RequestSocket *rs,
-                                             const struct GNUNET_TUN_DnsHeader 
*dns,
-                                             size_t dns_len);
+typedef void
+(*GNUNET_DNSSTUB_ResultCallback)(void *cls,
+                                 struct GNUNET_DNSSTUB_RequestSocket *rs,
+                                 const struct GNUNET_TUN_DnsHeader *dns,
+                                 size_t dns_len);
 
 
 /**
@@ -82,7 +83,7 @@
  * @param request DNS request to transmit
  * @param request_len number of bytes in msg
  * @param rc function to call with result
- * @param rc_cls closure for 'rc'
+ * @param rc_cls closure for @a rc
  * @return socket used for the request, NULL on error
  */
 struct GNUNET_DNSSTUB_RequestSocket *
@@ -102,7 +103,7 @@
  * @param request DNS request to transmit
  * @param request_len number of bytes in msg
  * @param rc function to call with result
- * @param rc_cls closure for 'rc'
+ * @param rc_cls closure for @a rc
  * @return socket used for the request, NULL on error
  */
 struct GNUNET_DNSSTUB_RequestSocket *

Modified: gnunet/src/include/gnunet_nat_lib.h
===================================================================
--- gnunet/src/include/gnunet_nat_lib.h 2015-10-07 09:51:46 UTC (rev 36462)
+++ gnunet/src/include/gnunet_nat_lib.h 2015-10-07 10:11:29 UTC (rev 36463)
@@ -506,46 +506,65 @@
 
 
 /**
- * Make Generic STUN request and
- * Send a generic stun request to the server specified using the specified 
socket.
- * possibly waiting for a reply and filling the 'reply' field with
- * the externally visible address.
+ * Handle to a request given to the resolver.  Can be used to cancel
+ * the request prior to the timeout or successful execution.  Also
+ * used to track our internal state for the request.
+ */
+struct GNUNET_NAT_STUN_Handle;
+
+
+/**
+ * Make generic STUN request.  Sends a generic stun request to the
+ * server specified using the specified socket.  The caller must
+ * wait for a reply on the @a sock and call
+ * #GNUNET_NAT_stun_handle_packet() if a reply is received.
  *
-
- * @param server, the address of the stun server
- * @param port, port of the stun server
+ * @param server the address of the stun server
+ * @param port port of the stun server
  * @param sock the socket used to send the request
- * @param cb callback in case of error
- * @return #GNUNET_OK success, #GNUNET_NO on error.
+ * @param cb callback in case of error (or completion)
+ * @param cb_cls closure for @a cb
+ * @return NULL on error
  */
-int
-GNUNET_NAT_stun_make_request(char * server,
-                             int port,
-                             struct GNUNET_NETWORK_Handle * sock, 
GNUNET_NAT_STUN_ErrorCallback cb,
-                             void *cb_cls);
+struct GNUNET_NAT_STUN_Handle *
+GNUNET_NAT_stun_make_request (const char *server,
+                              uint16_t port,
+                              struct GNUNET_NETWORK_Handle *sock,
+                              GNUNET_NAT_STUN_ErrorCallback cb,
+                              void *cb_cls);
 
 
 /**
+ * Cancel active STUN request. Frees associated resources
+ * and ensures that the callback is no longer invoked.
  *
- * Handle an incoming STUN message, Do some basic sanity checks on packet size 
and content,
- * try to extract a bit of information, and possibly reply.
- * At the moment this only processes BIND requests, and returns
- * the externally visible address of the request.
- * If a callback is specified, invoke it with the attribute.
+ * @param rh request to cancel
+ */
+void
+GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh);
+
+
+/**
+ * Handle an incoming STUN message. Do some basic sanity checks on
+ * packet size and content, try to extract a bit of information, and
+ * possibly reply.  At the moment this only processes BIND requests,
+ * and returns the externally visible address of the request.  If a
+ * callback is specified, invoke it with the attribute.
  *
- * @param data, the packet
- * @param len, the length of the packet
- * @param arg, sockaddr_in where we will set our discovered packet
- *
- * @return, #GNUNET_OK on OK, #GNUNET_NO if the packet is invalid ( not a stun 
packet)
+ * @param data the packet
+ * @param len the length of the packet
+ * @param arg sockaddr_in where we will set our discovered packet
+ * @return #GNUNET_OK on OK,
+ *          #GNUNET_NO if the packet is not a stun packet
  */
 int
-GNUNET_NAT_stun_handle_packet(const void *data,
-                              size_t len,
-                              struct sockaddr_in *arg);
+GNUNET_NAT_stun_handle_packet (const void *data,
+                               size_t len,
+                               struct sockaddr_in *arg);
 
+
 /**
- * CHECK if is a valid STUN packet sending to GNUNET_NAT_stun_handle_packet.
+ * CHECK if is a valid STUN packet sending to #GNUNET_NAT_stun_handle_packet().
  * It also check if it can handle the packet based on the NAT handler.
  * You don't need to call anything else to check if the packet is valid,
  *
@@ -553,12 +572,12 @@
  * @param data, packet
  * @param len, packet length
  *
- * @return #GNUNET_NO if it can't decode,# GNUNET_YES if is a packet
+ * @return #GNUNET_NO if it can't decode, #GNUNET_YES if is a packet
  */
 int
-GNUNET_NAT_is_valid_stun_packet(void *cls,
-                                  const void *data,
-                                  size_t len);
+GNUNET_NAT_is_valid_stun_packet (void *cls,
+                                 const void *data,
+                                 size_t len);
 
 
 

Modified: gnunet/src/nat/nat.c
===================================================================
--- gnunet/src/nat/nat.c        2015-10-07 09:51:46 UTC (rev 36462)
+++ gnunet/src/nat/nat.c        2015-10-07 10:11:29 UTC (rev 36463)
@@ -270,17 +270,17 @@
   /**
    * ID of select gnunet-helper-nat-server stdout read task
    */
-  struct GNUNET_SCHEDULER_Task * server_read_task;
+  struct GNUNET_SCHEDULER_Task *server_read_task;
 
   /**
    * ID of interface IP-scan task
    */
-  struct GNUNET_SCHEDULER_Task * ifc_task;
+  struct GNUNET_SCHEDULER_Task *ifc_task;
 
   /**
    * ID of hostname DNS lookup task
    */
-  struct GNUNET_SCHEDULER_Task * hostname_task;
+  struct GNUNET_SCHEDULER_Task *hostname_task;
 
   /**
    * ID of DynDNS lookup task
@@ -288,6 +288,11 @@
   struct GNUNET_SCHEDULER_Task *dns_task;
 
   /**
+   * Active STUN request, if any.
+   */
+  struct GNUNET_NAT_STUN_Handle *stun_request;
+
+  /**
    * How often do we scan for changes in our IP address from our local
    * interfaces?
    */
@@ -1109,12 +1114,11 @@
 }
 
 
-
 /**
- * Callback if the STun request have a error
+ * Callback with the result from the STUN request.
  *
  * @param cls the NAT handle
- * @param result , the status
+ * @param result the status
  */
 static void
 stun_request_callback (void *cls,
@@ -1122,15 +1126,16 @@
 {
   struct GNUNET_NAT_Handle *h = cls;
 
-  if (NULL == h)
-    return;
-  h->waiting_stun = GNUNET_NO;
-
-  if(result != GNUNET_OK)
+  h->stun_request = NULL;
+  if (GNUNET_NAT_ERROR_SUCCESS != result)
   {
     LOG (GNUNET_ERROR_TYPE_WARNING,
-       "Error processing a STUN request");
+         "Error processing a STUN request");
   }
+  else
+  {
+    h->waiting_stun = GNUNET_YES;
+  }
 }
 
 
@@ -1153,7 +1158,7 @@
   struct sockaddr_in answer;
 
   /* We are not expecting a STUN message */
-  if (! h->waiting_stun)
+  if (GNUNET_YES != h->waiting_stun)
     return GNUNET_NO;
 
   /* We dont have STUN installed */
@@ -1166,14 +1171,14 @@
           sizeof(struct sockaddr_in));
 
   /*Lets handle the packet*/
-  int valid = GNUNET_NAT_stun_handle_packet (data,
-                                             len,
-                                             &answer);
-  if (! valid)
+  if (GNUNET_NO ==
+      GNUNET_NAT_stun_handle_packet (data,
+                                     len,
+                                     &answer))
     return GNUNET_NO;
 
   LOG (GNUNET_ERROR_TYPE_INFO,
-       "Stun server returned %s:%d\n",
+       "STUN server returned %s:%d\n",
        inet_ntoa (answer.sin_addr),
        ntohs (answer.sin_port));
   /* Remove old IPs from previous STUN calls */
@@ -1208,17 +1213,20 @@
        "I will request the stun server %s:%i\n",
        elem->address,
        elem->port);
-  if (GNUNET_OK ==
-      GNUNET_NAT_stun_make_request (elem->address,
+  if (NULL != h->stun_request)
+  {
+    GNUNET_NAT_stun_make_request_cancel (h->stun_request);
+    h->stun_request = NULL;
+  }
+  h->waiting_stun = GNUNET_NO;
+  h->stun_request
+    = GNUNET_NAT_stun_make_request (elem->address,
                                     elem->port,
                                     h->socket,
                                     &stun_request_callback,
-                                    NULL))
+                                    h);
+  if (NULL == h->stun_request)
   {
-    h->waiting_stun = GNUNET_YES;
-  }
-  else
-  {
     LOG (GNUNET_ERROR_TYPE_ERROR,
          "STUN request to %s:%i failed\n",
          elem->address,
@@ -1226,7 +1234,8 @@
   }
   h->stun_task =
     GNUNET_SCHEDULER_add_delayed (h->stun_frequency,
-                                  &process_stun, h);
+                                  &process_stun,
+                                  h);
 
   /* Set actual Server*/
   if (NULL != elem->next)
@@ -1709,7 +1718,6 @@
       /* Set the actual STUN server*/
       h->actual_stun_server = h->stun_servers_head;
     }
-
     h->stun_task = GNUNET_SCHEDULER_add_now (&process_stun,
                                              h);
   }
@@ -1821,10 +1829,18 @@
     GNUNET_SCHEDULER_cancel (h->stun_task);
     h->stun_task = NULL;
   }
+  if (NULL != h->stun_request)
+  {
+    GNUNET_NAT_stun_make_request_cancel (h->stun_request);
+    h->stun_request = NULL;
+  }
   if (NULL != h->server_proc)
   {
-    if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
-      GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill");
+    if (0 != GNUNET_OS_process_kill (h->server_proc,
+                                     GNUNET_TERM_SIG))
+      GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
+                                "nat",
+                                "kill");
     GNUNET_OS_process_wait (h->server_proc);
     GNUNET_OS_process_destroy (h->server_proc);
     h->server_proc = NULL;

Modified: gnunet/src/nat/nat_stun.c
===================================================================
--- gnunet/src/nat/nat_stun.c   2015-10-07 09:51:46 UTC (rev 36462)
+++ gnunet/src/nat/nat_stun.c   2015-10-07 10:11:29 UTC (rev 36463)
@@ -154,7 +154,10 @@
 static const char *
 stun_msg2str(int msg)
 {
-  static const struct { enum StunClasses value; const char *name; } classes[] 
= {
+  static const struct {
+    enum StunClasses value;
+    const char *name;
+  } classes[] = {
     { STUN_REQUEST, "Request" },
     { STUN_INDICATION, "Indication" },
     { STUN_RESPONSE, "Response" },
@@ -161,7 +164,10 @@
     { STUN_ERROR_RESPONSE, "Error Response" },
     { 0, NULL }
   };
-  static const struct { enum StunMethods value; const char *name; } methods[] 
= {
+  static const struct {
+    enum StunMethods value;
+    const char *name;
+  } methods[] = {
     { STUN_BINDING, "Binding" },
     { 0, NULL }
   };
@@ -201,9 +207,12 @@
  * @return string with the attribute name
  */
 static const char *
-stun_attr2str(int msg)
+stun_attr2str (int msg)
 {
-  const struct { enum StunAttributes value; const char *name; } attrs[] = {
+  static const struct {
+    enum StunAttributes value;
+    const char *name;
+  } attrs[] = {
     { STUN_MAPPED_ADDRESS, "Mapped Address" },
     { STUN_RESPONSE_ADDRESS, "Response Address" },
     { STUN_CHANGE_ADDRESS, "Change Address" },
@@ -242,7 +251,7 @@
  * @param req, stun header to be filled
  */
 static void
-generate_request_id(struct stun_header *req)
+generate_request_id (struct stun_header *req)
 {
   unsigned int x;
 
@@ -292,7 +301,8 @@
   default:
     return 1;
   }
-  if (ntohs(attr->len) < 8 && returned_addr->family != 1)
+  if ( (ntohs(attr->len) < 8) &&
+       (returned_addr->family != 1) )
   {
     return 1;
   }
@@ -371,10 +381,7 @@
          (int)len);
     return GNUNET_NO;
   }
-  else
-  {
-    len = advertised_message_size;
-  }
+  len = advertised_message_size;
   memset (&st,0, sizeof(st));
 
   while (len > 0)
@@ -415,15 +422,21 @@
 
 
 /**
- * Clean-up used memory
+ * Cancel active STUN request. Frees associated resources
+ * and ensures that the callback is no longer invoked.
  *
- * @param handle handle to release memory for
+ * @param rh request to cancel
  */
-static void
-clean (struct GNUNET_NAT_STUN_Handle *handle)
+void
+GNUNET_NAT_stun_make_request_cancel (struct GNUNET_NAT_STUN_Handle *rh)
 {
-  GNUNET_free (handle->stun_server);
-  GNUNET_free (handle);
+  if (NULL != rh->dns_active)
+  {
+    GNUNET_RESOLVER_request_cancel (rh->dns_active);
+    rh->dns_active = NULL;
+  }
+  GNUNET_free (rh->stun_server);
+  GNUNET_free (rh);
 }
 
 
@@ -439,32 +452,35 @@
                    const struct sockaddr *addr,
                    socklen_t addrlen)
 {
-  struct GNUNET_NAT_STUN_Handle *request = cls;
+  struct GNUNET_NAT_STUN_Handle *rh = cls;
   struct stun_header *req;
   uint8_t reqdata[1024];
   int reqlen;
   struct sockaddr_in server;
 
+  rh->dns_active = NULL;
   if (NULL == addr)
   {
-    request->dns_active = NULL;
-    if (GNUNET_NO == request->dns_success)
+    if (GNUNET_NO == rh->dns_success)
     {
       LOG (GNUNET_ERROR_TYPE_INFO,
            "Error resolving host %s\n",
-           request->stun_server);
-      request->cb (request->cb_cls,
-                   GNUNET_NAT_ERROR_NOT_ONLINE);
-      clean (request);
+           rh->stun_server);
+      rh->cb (rh->cb_cls,
+              GNUNET_NAT_ERROR_NOT_ONLINE);
+      GNUNET_NAT_stun_make_request_cancel (rh);
     }
     return;
   }
 
-  request->dns_success= GNUNET_YES;
-  memset(&server,0, sizeof(server));
+  rh->dns_success = GNUNET_YES;
+  memset (&server,0, sizeof(server));
   server.sin_family = AF_INET;
   server.sin_addr = ((struct sockaddr_in *)addr)->sin_addr;
-  server.sin_port = htons(request->stun_port);
+  server.sin_port = htons(rh->stun_port);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+  server.sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
 
   /*Craft the simplest possible STUN packet. A request binding*/
   req = (struct stun_header *)reqdata;
@@ -476,7 +492,7 @@
   req->msgtype = htons(encode_message(STUN_REQUEST, STUN_BINDING));
 
   /* Send the packet */
-  if (-1 == GNUNET_NETWORK_socket_sendto (request->sock,
+  if (-1 == GNUNET_NETWORK_socket_sendto (rh->sock,
                                           req,
                                           ntohs(req->msglen) + sizeof(*req),
                                           (const struct sockaddr *) &server,
@@ -484,11 +500,14 @@
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
                          "Fail to sendto");
-    request->cb (request->cb_cls,
-                 GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
-    clean (request);
+    rh->cb (rh->cb_cls,
+            GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR);
+    GNUNET_NAT_stun_make_request_cancel (rh);
     return;
   }
+  /* sending STUN request done, let's wait for replies... */
+  rh->cb (rh->cb_cls,
+          GNUNET_NAT_ERROR_SUCCESS);
 }
 
 
@@ -503,9 +522,9 @@
  * @param sock the socket used to send the request
  * @param cb callback in case of error
  * @param cb_cls closure for @a cb
- * @return #GNUNET_OK success, #GNUNET_NO on error.
+ * @return NULL on error
  */
-int
+struct GNUNET_NAT_STUN_Handle *
 GNUNET_NAT_stun_make_request (const char *server,
                               uint16_t port,
                               struct GNUNET_NETWORK_Handle *sock,
@@ -529,8 +548,10 @@
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
                          "Failed DNS");
-    clean (rh);
-    return GNUNET_NO;
+    GNUNET_NAT_stun_make_request_cancel (rh);
+    return NULL;
   }
-  return GNUNET_OK;
+  return rh;
 }
+
+/* end of nat_stun.c */

Modified: gnunet/src/util/connection.c
===================================================================
--- gnunet/src/util/connection.c        2015-10-07 09:51:46 UTC (rev 36462)
+++ gnunet/src/util/connection.c        2015-10-07 10:11:29 UTC (rev 36463)
@@ -738,9 +738,9 @@
   if (NULL == addr)
   {
     connection->dns_active = NULL;
-    if ((NULL == connection->ap_head) && 
+    if ((NULL == connection->ap_head) &&
         (NULL == connection->sock) &&
-        (NULL == connection->proxy_handshake)) 
+        (NULL == connection->proxy_handshake))
       connect_fail_continuation (connection);
     return;
   }
@@ -991,8 +991,8 @@
 int
 GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
 {
-  if ((NULL != connection->ap_head) || 
-      (NULL != connection->dns_active) || 
+  if ((NULL != connection->ap_head) ||
+      (NULL != connection->dns_active) ||
       (NULL != connection->proxy_handshake))
     return GNUNET_YES;          /* still trying to connect */
   if ( (0 != connection->destroy_later) ||
@@ -1588,7 +1588,7 @@
 
 
 /**
- * Activate proxied connection and destroy initial proxy handshake connection. 
+ * Activate proxied connection and destroy initial proxy handshake connection.
  * There must not be any pending requests for reading or writing to the
  * proxy hadshake connection at this time.
  *




reply via email to

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