fix #4546
[oweals/gnunet.git] / src / nat / nat_auto.c
index dc7eecb3e22e2e647cc8b7e8dd40dd4eb7269ae6..6d5b82cc961801ef4533edac797020b29d27500a 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2015 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2015 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -236,16 +236,21 @@ process_stun_reply(struct sockaddr_in* answer, struct GNUNET_NAT_AutoHandle *ah)
 static void
 stop_stun ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping STUN and quitting...\n");
 
-  //Clean task
+  /* Clean task */
   if(NULL != ltask4)
+  {
     GNUNET_SCHEDULER_cancel (ltask4);
+    ltask4 = NULL;
+  }
 
-  //Clean socket
-  if(NULL != ltask4)
+  /* Clean socket */
+  if(NULL != lsock4)
+  {
     GNUNET_NETWORK_socket_close (lsock4);
-
+    lsock4 = NULL;
+  }
 }
 
 /**
@@ -253,69 +258,61 @@ stop_stun ()
  * incoming connection.
  *
  * @param cls
- * @param tc scheduler context
  */
 static void
-do_udp_read (void *cls,
-             const struct GNUNET_SCHEDULER_TaskContext *tc)
+do_udp_read (void *cls)
 {
   struct GNUNET_NAT_AutoHandle *ah = cls;
   unsigned char reply_buf[1024];
   ssize_t rlen;
   struct sockaddr_in answer;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
 
-
+  tc = GNUNET_SCHEDULER_get_task_context ();
   if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
       (GNUNET_NETWORK_fdset_isset (tc->read_ready,
                                    lsock4)))
   {
-    rlen = GNUNET_NETWORK_socket_recv (lsock4, reply_buf, sizeof (reply_buf));
-
+    rlen = GNUNET_NETWORK_socket_recv (lsock4,
+                                      reply_buf,
+                                      sizeof (reply_buf));
 
     //Lets handle the packet
     memset(&answer, 0, sizeof(struct sockaddr_in));
-
-
-
-
-
     if(ah->phase == AUTO_NAT_PUNCHED)
     {
       //Destroy the connection
       GNUNET_NETWORK_socket_close (lsock4);
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO, "The external server was able to connect back");
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "The external server was able to connect back");
       ah->connected_back = GNUNET_YES;
       next_phase (ah);
     }
     else
     {
-      if(GNUNET_OK == GNUNET_NAT_stun_handle_packet(reply_buf,rlen, &answer))
+      if (GNUNET_OK ==
+         GNUNET_NAT_stun_handle_packet (reply_buf, rlen, &answer))
       {
         //Process the answer
-        process_stun_reply(&answer, ah);
-
+        process_stun_reply (&answer, ah);
       }
       else
       {
         next_phase (ah);
       }
     }
-
-
   }
   else
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "TIMEOUT while aiting for an answer");
-    if(ah->phase == AUTO_NAT_PUNCHED)
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "TIMEOUT while waiting for an answer\n");
+    if (ah->phase == AUTO_NAT_PUNCHED)
     {
       stop_stun();
     }
 
-    next_phase(ah);
+    next_phase (ah);
   }
-
-
-
 }
 
 
@@ -355,20 +352,17 @@ bind_v4 ()
 }
 
 
-
-
-static void request_callback(void *cls,
-                             enum GNUNET_NAT_StatusCode result)
+static void
+request_callback (void *cls,
+                 enum GNUNET_NAT_StatusCode result)
 {
-  struct GNUNET_NAT_AutoHandle *ah = cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n");
-  stop_stun();
-
-  next_phase(ah);
-};
-
+  // struct GNUNET_NAT_AutoHandle *ah = cls;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Request callback: stop and quit\n");
+  stop_stun ();
 
+  // next_phase (ah); FIXME this always will be NULL, as called in test_stun()
+}
 
 
 /**
@@ -403,11 +397,9 @@ result_callback (void *cls,
  * Main function for the connection reversal test.
  *
  * @param cls the `struct GNUNET_NAT_AutoHandle`
- * @param tc scheduler context
  */
 static void
-reversal_test (void *cls,
-               const struct GNUNET_SCHEDULER_TaskContext *tc)
+reversal_test (void *cls)
 {
   struct GNUNET_NAT_AutoHandle *ah = cls;
 
@@ -457,7 +449,7 @@ set_external_ipv4 (void *cls,
   {
     GNUNET_break (0);
     /* actually, this should never happen, as the caller already executed just
-     * this check, but for consistency (eg: future changes in the caller) 
+     * this check, but for consistency (eg: future changes in the caller)
      * we still need to report this error...
      */
     ah->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID;
@@ -481,7 +473,7 @@ test_external_ip (struct GNUNET_NAT_AutoHandle *ah)
 {
   if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
     next_phase (ah);
-  
+
   // FIXME: CPS?
   /* try to detect external IP */
   ah->eh = GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT,
@@ -498,7 +490,7 @@ static void
 test_stun (struct GNUNET_NAT_AutoHandle *ah)
 {
 
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,"Running STUN test");
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running STUN test\n");
 
   /* Get port from the configuration */
   if (GNUNET_OK !=
@@ -522,26 +514,29 @@ test_stun (struct GNUNET_NAT_AutoHandle *ah)
   {
     //Lets call our function now when it accepts
     ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT,
-                                            lsock4, &do_udp_read, ah);
-
+                                            lsock4,
+                                           &do_udp_read,
+                                           ah);
   }
 
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "STUN service listens on port %u\n",
-              port);
-  if( GNUNET_NO == GNUNET_NAT_stun_make_request(stun_server, stun_port, lsock4, &request_callback, NULL))
+              (unsigned int) port);
+  if (GNUNET_NO ==
+      GNUNET_NAT_stun_make_request (stun_server, stun_port,
+                                   lsock4,
+                                   &request_callback,
+                                   NULL))
   {
     /*An error happened*/
-    stop_stun();
-    next_phase(ah);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN error, stopping\n");
+    stop_stun ();
+    next_phase (ah);
   }
-
-
 }
 
 
-
 /**
  * Process list of local IP addresses.  Find and set the
  * one of the default interface.
@@ -553,16 +548,16 @@ test_stun (struct GNUNET_NAT_AutoHandle *ah)
  * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned)
  * @param netmask the network mask (can be NULL for unknown or unassigned))
  * @param addrlen length of the @a addr and @a broadcast_addr
- * @return GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
+ * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
  */
 static int
 process_if (void *cls,
-      const char *name,
-      int isDefault,
-      const struct sockaddr *addr,
-      const struct sockaddr *broadcast_addr,
-      const struct sockaddr *netmask,
-      socklen_t addrlen)
+           const char *name,
+           int isDefault,
+           const struct sockaddr *addr,
+           const struct sockaddr *broadcast_addr,
+           const struct sockaddr *netmask,
+           socklen_t addrlen)
 {
   struct GNUNET_NAT_AutoHandle *ah = cls;
   const struct sockaddr_in *in;
@@ -628,7 +623,7 @@ test_local_ip (struct GNUNET_NAT_AutoHandle *ah)
   ah->have_v6 = GNUNET_NO;
   ah->ret = GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO; // reset to success if any of the IFs in below iterator has a valid IP
   GNUNET_OS_network_interfaces_list (&process_if, ah);
-  
+
   GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "DISABLEV6",
                                         (GNUNET_YES == ah->have_v6) ? "NO" : "YES");
   next_phase (ah);
@@ -643,12 +638,10 @@ test_local_ip (struct GNUNET_NAT_AutoHandle *ah)
 static void
 test_nat_punched (struct GNUNET_NAT_AutoHandle *ah)
 {
-
   struct GNUNET_CLIENT_Connection *client;
   struct GNUNET_NAT_TestMessage msg;
 
-
-  if(ah->stun_ip)
+  if (ah->stun_ip)
   {
     LOG (GNUNET_ERROR_TYPE_INFO,
          "Asking gnunet-nat-server to connect to `%s'\n",
@@ -675,9 +668,14 @@ test_nat_punched (struct GNUNET_NAT_AutoHandle *ah)
                                                            NAT_SERVER_TIMEOUT,
                                                            GNUNET_YES, NULL,
                                                            NULL));
-    ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT,
-                                            lsock4, &do_udp_read, ah);
-
+    if (NULL != ltask4)
+    {
+      GNUNET_SCHEDULER_cancel (ltask4);
+      ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT,
+                                              lsock4,
+                                             &do_udp_read,
+                                             ah);
+    }
   }
   else
   {
@@ -685,13 +683,9 @@ test_nat_punched (struct GNUNET_NAT_AutoHandle *ah)
          "We don't have a STUN IP");
     next_phase(ah);
   }
-
-
 }
 
 
-
-
 /**
  * Test if UPnPC works.
  *
@@ -705,7 +699,7 @@ test_upnpc (struct GNUNET_NAT_AutoHandle *ah)
 
   if (GNUNET_NAT_ERROR_SUCCESS != ah->ret)
     next_phase (ah);
-  
+
   // test if upnpc is available
   have_upnpc = (GNUNET_SYSERR !=
                GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL));
@@ -738,7 +732,7 @@ test_icmp_server (struct GNUNET_NAT_AutoHandle *ah)
   ext_ip = GNUNET_NO;
   nated = GNUNET_NO;
   binary = GNUNET_NO;
-  
+
   tmp = NULL;
   helper = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
   if ((GNUNET_OK ==
@@ -749,7 +743,7 @@ test_icmp_server (struct GNUNET_NAT_AutoHandle *ah)
   }
   else
     goto err;
-    
+
   if (GNUNET_YES ==
         GNUNET_CONFIGURATION_get_value_yesno (ah->cfg, "nat", "BEHIND_NAT")){
     nated = GNUNET_YES;
@@ -757,7 +751,7 @@ test_icmp_server (struct GNUNET_NAT_AutoHandle *ah)
   }
   else
     goto err;
-  
+
   if (GNUNET_YES ==
         GNUNET_OS_check_helper_binary (helper, GNUNET_YES, "-d 127.0.0.1" )){
     binary = GNUNET_OK; // use localhost as source for that one udp-port, ok for testing
@@ -771,7 +765,6 @@ err:
     ah->task = GNUNET_SCHEDULER_add_now (&reversal_test, ah);
   else
     next_phase (ah);
-
 }
 
 
@@ -783,8 +776,6 @@ err:
 static void
 test_icmp_client (struct GNUNET_NAT_AutoHandle *ah)
 {
-
-
   char *tmp;
   char *helper;
 
@@ -798,25 +789,26 @@ test_icmp_client (struct GNUNET_NAT_AutoHandle *ah)
   }
   else
     goto err;
-  
+
   if (GNUNET_YES !=
       GNUNET_CONFIGURATION_get_value_yesno (ah->cfg, "nat", "BEHIND_NAT")){
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("test_icmp_server not possible, as we are not behind NAT\n"));
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+               _("test_icmp_server not possible, as we are not behind NAT\n"));
   }
   else
     goto err;
-  
+
   if (GNUNET_YES ==
       GNUNET_OS_check_helper_binary (helper, GNUNET_YES, "-d 127.0.0.1 127.0.0.2 42")){
           // none of these parameters are actually used in privilege testing mode
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("No working gnunet-helper-nat-server found\n"));
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+               _("No working gnunet-helper-nat-server found\n"));
   }
 err:
   GNUNET_free_non_null (tmp);
   GNUNET_free (helper);
 
   next_phase (ah);
-
 }
 
 
@@ -847,7 +839,7 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
     test_local_ip (ah);
     break;
   case AUTO_NAT_PUNCHED:
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run GNUNET_ERROR_TYPE_DEBUG\n");
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Will run AUTO_NAT_PUNCHED\n");
     test_nat_punched (ah);
     break;
   case AUTO_UPNPC:
@@ -864,11 +856,11 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
     break;
   case AUTO_DONE:
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Done with tests\n");
-    if(!ah->internal_ip_is_public)
+    if (!ah->internal_ip_is_public)
     {
       GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "YES");
 
-      if(ah->connected_back)
+      if (ah->connected_back)
       {
         GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "PUNCHED_NAT", "YES");
       }
@@ -881,7 +873,7 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
       {
         GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
                                                ah->stun_ip);
-        if(ah->connected_back)
+        if (ah->connected_back)
         {
           ah->type = GNUNET_NAT_TYPE_STUN_PUNCHED_NAT;
           GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "USE_STUN", "YES");
@@ -893,7 +885,7 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
         }
 
       }
-      if(ah->stun_port)
+      if (ah->stun_port)
       {
         GNUNET_CONFIGURATION_set_value_number (ah->cfg, "transport-udp",
                                                "ADVERTISED_PORT",
@@ -904,7 +896,7 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
     else
     {
       //The internal IP is the same as public, but we didn't got a incoming connection
-      if(ah->connected_back)
+      if (ah->connected_back)
       {
         ah->type = GNUNET_NAT_TYPE_NO_NAT;
         GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "BEHIND_NAT", "NO");
@@ -918,7 +910,7 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
           GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS",
                                                  ah->stun_ip);
         }
-        if(ah->stun_port)
+        if (ah->stun_port)
         {
           GNUNET_CONFIGURATION_set_value_number (ah->cfg, "transport-udp",
                                                  "ADVERTISED_PORT",
@@ -939,11 +931,7 @@ next_phase (struct GNUNET_NAT_AutoHandle *ah)
     GNUNET_CONFIGURATION_destroy (diff);
     GNUNET_NAT_autoconfig_cancel (ah);
     return;
-
   }
-
-
-
 }