fixed coverity bug #10042
[oweals/gnunet.git] / src / transport / plugin_transport_tcp.c
index 35103e58715b4df51ea6a596510e0bc64eeba3b6..ba07fcb48ad23bf29497c2c91b909d38bc74618e 100644 (file)
@@ -34,7 +34,7 @@
 #include "gnunet_signatures.h"
 #include "gnunet_statistics_service.h"
 #include "gnunet_transport_service.h"
-#include "plugin_transport.h"
+#include "gnunet_transport_plugin.h"
 #include "transport.h"
 
 #define DEBUG_TCP GNUNET_NO
@@ -345,7 +345,7 @@ struct Plugin
   /**
    * The process id of the server process (if behind NAT)
    */
-  pid_t server_pid;
+  struct GNUNET_OS_Process *server_proc;
 
   /**
    * List of open TCP sessions.
@@ -697,7 +697,7 @@ do_transmit (void *cls, size_t size, void *buf)
       ret = 0;
       now = GNUNET_TIME_absolute_get ();
       while ( (NULL != (pos = session->pending_messages_head)) &&
-             (pos->timeout.value <= now.value) )
+             (pos->timeout.abs_value <= now.abs_value) )
        {
          GNUNET_CONTAINER_DLL_remove (session->pending_messages_head,
                                       session->pending_messages_tail,
@@ -892,8 +892,7 @@ disconnect_session (struct Session *session)
   GNUNET_break (session->client != NULL);
   if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK)
     {
-      GNUNET_SCHEDULER_cancel (session->plugin->env->sched,
-                              session->receive_delay_task);
+      GNUNET_SCHEDULER_cancel (session->receive_delay_task);
       if (session->client != NULL)
        GNUNET_SERVER_receive_done (session->client,
                                    GNUNET_SYSERR);     
@@ -930,9 +929,9 @@ select_better_session (struct Session *s1,
   if ( (s1->expecting_welcome == GNUNET_YES) &&
        (s2->expecting_welcome == GNUNET_NO) )
     return s2;
-  if (s1->last_activity.value < s2->last_activity.value)
+  if (s1->last_activity.abs_value < s2->last_activity.abs_value)
     return s2;
-  if (s1->last_activity.value > s2->last_activity.value)
+  if (s1->last_activity.abs_value > s2->last_activity.abs_value)
     return s1;
   if ( (GNUNET_YES == s1->inbound) &&
        (GNUNET_NO  == s2->inbound) )
@@ -958,7 +957,7 @@ run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen)
   char inet4[INET_ADDRSTRLEN];
   char *address_as_string;
   char *port_as_string;
-  pid_t pid;
+  struct GNUNET_OS_Process *proc;
   const struct sockaddr *sa = (const struct sockaddr *)addr;
 
 #if DEBUG_TCP_NAT
@@ -995,10 +994,12 @@ run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen)
 #endif
 
   /* Start the client process */
-  pid = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
+  proc = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
   GNUNET_free(address_as_string);
   GNUNET_free(port_as_string);
-  GNUNET_OS_process_wait (pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 }
 
 
@@ -1226,8 +1227,7 @@ tcp_plugin_send (void *cls,
           /* Only do one NAT punch attempt per peer identity */
           return -1;
         }
-      sa = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched,
-                                                  af, sb, sbs);
+      sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs);
       if (sa == NULL)
        {
 #if DEBUG_TCP
@@ -1454,8 +1454,7 @@ tcp_plugin_address_pretty_printer (void *cls,
   ppc->asc = asc;
   ppc->asc_cls = asc_cls;
   ppc->port = port;
-  GNUNET_RESOLVER_hostname_get (plugin->env->sched,
-                                plugin->env->cfg,
+  GNUNET_RESOLVER_hostname_get (plugin->env->cfg,
                                 sb,
                                 sbs,
                                 !numeric, timeout, &append_port, ppc);
@@ -1806,12 +1805,11 @@ delayed_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                                         NULL, 0,
                                         session,
                                         NULL, 0);
-  if (delay.value == 0)
+  if (delay.rel_value == 0)
     GNUNET_SERVER_receive_done (session->client, GNUNET_OK);
   else
     session->receive_delay_task =
-      GNUNET_SCHEDULER_add_delayed (session->plugin->env->sched,
-                                   delay, &delayed_done, session);
+      GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session);
 }
 
 
@@ -1860,12 +1858,11 @@ handle_tcp_data (void *cls,
                                session,
                                (GNUNET_YES == session->inbound) ? NULL : session->connect_addr,
                                (GNUNET_YES == session->inbound) ? 0 : session->connect_alen);
-  if (delay.value == 0)
+  if (delay.rel_value == 0)
     GNUNET_SERVER_receive_done (client, GNUNET_OK);
   else
     session->receive_delay_task =
-      GNUNET_SCHEDULER_add_delayed (session->plugin->env->sched,
-                                   delay, &delayed_done, session);
+      GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session);
 }
 
 
@@ -2113,8 +2110,7 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
   else
     {
       plugin->server_read_task =
-           GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
-                                           GNUNET_TIME_UNIT_FOREVER_REL,
+           GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                            plugin->server_stdout_handle, &tcp_plugin_server_read, plugin);
       return;
     }
@@ -2132,8 +2128,7 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
                   _("nat-server-read malformed address\n"), &mybuf, port);
 
       plugin->server_read_task =
-          GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
-                                          GNUNET_TIME_UNIT_FOREVER_REL,
+          GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                           plugin->server_stdout_handle, &tcp_plugin_server_read, plugin);
       return;
     }
@@ -2144,15 +2139,14 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
    * We have received an ICMP response, ostensibly from a non-NAT'd peer
    *  that wants to connect to us! Send a message to establish a connection.
    */
-  sock = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched, AF_INET, (struct sockaddr *)&in_addr,
+  sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, (struct sockaddr *)&in_addr,
                                                  sizeof(in_addr));
 
 
   if (sock == NULL)
     {
       plugin->server_read_task =
-          GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
-                                          GNUNET_TIME_UNIT_FOREVER_REL,
+          GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                           plugin->server_stdout_handle, &tcp_plugin_server_read, plugin);
       return;
     }
@@ -2176,8 +2170,7 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
 
   /*GNUNET_SERVER_connect_socket(plugin->server, sock);*/
   plugin->server_read_task =
-      GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
-                                      GNUNET_TIME_UNIT_FOREVER_REL,
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                       plugin->server_stdout_handle, &tcp_plugin_server_read, plugin);
 }
 
@@ -2192,7 +2185,7 @@ static int
 tcp_transport_start_nat_server(struct Plugin *plugin)
 {
 
-  plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_YES);
+  plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES);
   if (plugin->server_stdout == NULL)
     return GNUNET_SYSERR;
 
@@ -2201,8 +2194,8 @@ tcp_transport_start_nat_server(struct Plugin *plugin)
                    "Starting gnunet-nat-server process cmd: %s %s\n", "gnunet-nat-server", plugin->internal_address);
 #endif
   /* Start the server process */
-  plugin->server_pid = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL);
-  if (plugin->server_pid == GNUNET_SYSERR)
+  plugin->server_proc = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL);
+  if (plugin->server_proc == NULL)
     {
 #if DEBUG_TCP_NAT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2215,12 +2208,12 @@ tcp_transport_start_nat_server(struct Plugin *plugin)
 
   plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ);
   plugin->server_read_task =
-      GNUNET_SCHEDULER_add_read_file (plugin->env->sched,
-                                      GNUNET_TIME_UNIT_FOREVER_REL,
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                       plugin->server_stdout_handle, &tcp_plugin_server_read, plugin);
   return GNUNET_YES;
 }
 
+
 /**
  * Return the actual path to a file found in the current
  * PATH environment variable.
@@ -2238,12 +2231,16 @@ get_path_from_PATH (char *binary)
 
   p = getenv ("PATH");
   if (p == NULL)
-    return NULL;
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("PATH environment variable is unset.\n"));
+      return NULL;
+    }
   path = GNUNET_strdup (p);     /* because we write on it */
   buf = GNUNET_malloc (strlen (path) + 20);
   pos = path;
 
-  while (NULL != (end = strchr (pos, ':')))
+  while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
     {
       *end = '\0';
       sprintf (buf, "%s/%s", pos, binary);
@@ -2277,20 +2274,52 @@ check_gnunet_nat_binary(char *binary)
 {
   struct stat statbuf;
   char *p;
+#ifdef MINGW
+  SOCKET rawsock;
+#endif
 
+#ifdef MINGW
+  char *binaryexe;
+  GNUNET_asprintf (&binaryexe, "%s.exe", binary);
+  p = get_path_from_PATH (binaryexe);
+  free (binaryexe);
+#else
   p = get_path_from_PATH (binary);
+#endif
   if (p == NULL)
-    return GNUNET_NO;
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("Could not find binary `%s' in PATH!\n"),
+                 binary);
+      return GNUNET_NO;
+    }
   if (0 != STAT (p, &statbuf))
     {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 
+                 _("stat (%s) failed: %s\n"), 
+                 p,
+                 STRERROR (errno));
       GNUNET_free (p);
       return GNUNET_SYSERR;
     }
   GNUNET_free (p);
+#ifndef MINGW
   if ( (0 != (statbuf.st_mode & S_ISUID)) &&
        (statbuf.st_uid == 0) )
     return GNUNET_YES;
   return GNUNET_NO;
+#else
+  rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == rawsock)
+    {
+      DWORD err = GetLastError ();
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 
+                 "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err);
+      return GNUNET_NO; /* not running as administrator */
+    }
+  closesocket (rawsock);
+  return GNUNET_YES;
+#endif
 }
 
 /**
@@ -2324,7 +2353,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
   struct sockaddr_in in_addr;
   struct IPv4TcpAddress t4;
 
-  service = GNUNET_SERVICE_start ("transport-tcp", env->sched, env->cfg);
+  service = GNUNET_SERVICE_start ("transport-tcp", env->cfg);
   if (service == NULL)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -2506,8 +2535,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
       GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
     }
 
-  plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->sched,
-                                                           env->cfg,
+  plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->cfg,
                                                            AF_UNSPEC,
                                                            HOSTNAME_RESOLVE_TIMEOUT,
                                                            &process_hostname_ips,
@@ -2566,9 +2594,11 @@ libgnunet_plugin_transport_tcp_done (void *cls)
 
   if (plugin->behind_nat == GNUNET_YES)
     {
-      if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM))
+      if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM))
         GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-      GNUNET_OS_process_wait (plugin->server_pid);
+      GNUNET_OS_process_wait (plugin->server_proc);
+      GNUNET_OS_process_close (plugin->server_proc);
+      plugin->server_proc = NULL;
     }
   GNUNET_free_non_null(plugin->bind_address);
   GNUNET_free (plugin);