Fix: Cast closure to proper type
[oweals/gnunet.git] / src / nat / gnunet-service-nat_helper.c
index e476da12d2ebb076d7affe0d23376c8f33da412b..35b3dd9999177aa9b78d59494cb4ab1a55b90601 100644 (file)
@@ -2,20 +2,18 @@
      This file is part of GNUnet.
      Copyright (C) 2009, 2010, 2011, 2016 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
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
@@ -28,7 +26,6 @@
 #include "gnunet_util_lib.h"
 #include "gnunet-service-nat_helper.h"
 
-#define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__)
 
 /**
  * Information we keep per NAT helper process.
@@ -39,7 +36,7 @@ struct HelperContext
   /**
    * IP address we pass to the NAT helper.
    */
-  const char *internal_address;
+  struct in_addr internal_address;
 
   /**
    * Function to call if we receive a reversal request.
@@ -50,7 +47,7 @@ struct HelperContext
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * How long do we wait for restarting a crashed gnunet-helper-nat-server?
    */
@@ -127,17 +124,17 @@ nat_server_read (void *cls)
   memset (mybuf,
          0,
          sizeof (mybuf));
-  bytes 
+  bytes
     = GNUNET_DISK_file_read (h->server_stdout_handle,
                             mybuf,
                             sizeof (mybuf));
   if (bytes < 1)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Finished reading from server stdout with code: %d\n",
-         bytes);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Finished reading from server stdout with code: %d\n",
+               (int) bytes);
     if (0 != GNUNET_OS_process_kill (h->server_proc,
--                                   GNUNET_TERM_SIG))
+                                    GNUNET_TERM_SIG))
       GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
                                "nat",
                                "kill");
@@ -183,11 +180,10 @@ nat_server_read (void *cls)
                         &sin_addr.sin_addr)))
   {
     /* should we restart gnunet-helper-nat-server? */
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "nat",
-         _("gnunet-helper-nat-server generated malformed address `%s'\n"),
-         mybuf);
-    h->server_read_task 
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("gnunet-helper-nat-server generated malformed address `%s'\n"),
+               mybuf);
+    h->server_read_task
       = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                         h->server_stdout_handle,
                                         &nat_server_read,
@@ -195,13 +191,13 @@ nat_server_read (void *cls)
     return;
   }
   sin_addr.sin_port = htons ((uint16_t) port);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "gnunet-helper-nat-server read: %s:%d\n",
-       mybuf,
-       port);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "gnunet-helper-nat-server read: %s:%d\n",
+             mybuf,
+             port);
   h->cb (h->cb_cls,
         &sin_addr);
-  h->server_read_task 
+  h->server_read_task
     = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                       h->server_stdout_handle,
                                      &nat_server_read,
@@ -220,26 +216,45 @@ restart_nat_server (void *cls)
 {
   struct HelperContext *h = cls;
   char *binary;
-  
+  char ia[INET_ADDRSTRLEN];
+
   h->server_read_task = NULL;
-  h->server_stdout 
+  GNUNET_assert (NULL !=
+                inet_ntop (AF_INET,
+                           &h->internal_address,
+                           ia,
+                           sizeof (ia)));
+  /* Start the server process */
+  binary
+    = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
+  if (GNUNET_YES !=
+      GNUNET_OS_check_helper_binary (binary,
+                                     GNUNET_YES,
+                                     ia))
+  {
+    /* move instantly to max delay, as this is unlikely to be fixed */
+    h->server_retry_delay
+      = GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD;
+    GNUNET_free (binary);
+    try_again (h);
+    return;
+  }
+  h->server_stdout
     = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES,
                        GNUNET_NO, GNUNET_YES);
   if (NULL == h->server_stdout)
   {
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
                         "pipe");
+    GNUNET_free (binary);
     try_again (h);
     return;
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Starting `%s' at `%s'\n",
-       "gnunet-helper-nat-server",
-       h->internal_address);
-  /* Start the server process */
-  binary
-    = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server");
-  h->server_proc 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Starting `%s' at `%s'\n",
+             "gnunet-helper-nat-server",
+             ia);
+  h->server_proc
     = GNUNET_OS_start_process (GNUNET_NO,
                               0,
                               NULL,
@@ -247,15 +262,14 @@ restart_nat_server (void *cls)
                               NULL,
                               binary,
                               "gnunet-helper-nat-server",
-                              h->internal_address,
+                              ia,
                               NULL);
   GNUNET_free (binary);
   if (NULL == h->server_proc)
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "nat",
-        _("Failed to start %s\n"),
-        "gnunet-helper-nat-server");
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("Failed to start %s\n"),
+               "gnunet-helper-nat-server");
     GNUNET_DISK_pipe_close (h->server_stdout);
     h->server_stdout = NULL;
     try_again (h);
@@ -264,10 +278,10 @@ restart_nat_server (void *cls)
   /* Close the write end of the read pipe */
   GNUNET_DISK_pipe_close_end (h->server_stdout,
                              GNUNET_DISK_PIPE_END_WRITE);
-  h->server_stdout_handle 
+  h->server_stdout_handle
     = GNUNET_DISK_pipe_handle (h->server_stdout,
                               GNUNET_DISK_PIPE_END_READ);
-  h->server_read_task 
+  h->server_read_task
     = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                      h->server_stdout_handle,
                                      &nat_server_read,
@@ -285,7 +299,7 @@ restart_nat_server (void *cls)
  * @return NULL on error
  */
 struct HelperContext *
-GN_start_gnunet_nat_server_ (const char *internal_address,
+GN_start_gnunet_nat_server_ (const struct in_addr *internal_address,
                             GN_ReversalCallback cb,
                             void *cb_cls)
 {
@@ -294,8 +308,8 @@ GN_start_gnunet_nat_server_ (const char *internal_address,
   h = GNUNET_new (struct HelperContext);
   h->cb = cb;
   h->cb_cls = cb_cls;
-  h->internal_address
-    = internal_address;
+  h->internal_address = *internal_address;
+  restart_nat_server (h);
   if (NULL == h->server_stdout)
   {
     GN_stop_gnunet_nat_server_ (h);
@@ -313,19 +327,18 @@ GN_start_gnunet_nat_server_ (const char *internal_address,
  */
 void
 GN_stop_gnunet_nat_server_ (struct HelperContext *h)
-{  
+{
   if (NULL != h->server_read_task)
   {
     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))
-      GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
-                                "nat",
-                                "kill");
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                          "kill");
     GNUNET_OS_process_wait (h->server_proc);
     GNUNET_OS_process_destroy (h->server_proc);
     h->server_proc = NULL;
@@ -349,39 +362,49 @@ 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_strerror (GNUNET_ERROR_TYPE_WARNING,
+                        "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");
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                        "inet_ntop");
     return GNUNET_SYSERR;
   }
   GNUNET_snprintf (port_as_string,
                    sizeof (port_as_string),
                    "%d",
-                   ntohs (sa->sin_port));
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       _("Running gnunet-helper-nat-client %s %s %u\n"),
-       internal_address,
-       inet4,
-       ntohs (sa->sin_port));
+                   internal_port);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Running gnunet-helper-nat-client %s %s %u\n",
+             intv4,
+             remv4,
+             internal_port);
   binary
     = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client");
   proc
@@ -392,8 +415,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);