Support normal socket (non-NSP) name lookups in resolver (for testing)
[oweals/gnunet.git] / src / exit / gnunet-helper-exit.c
index df52183a77af28e3c1d27ab6ed14f31760c76f8d..e87aac5599401365e51581d4c2944b199e0070e2 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 /**
- * @file exit/gnunet-helper-exit.c 
+ * @file exit/gnunet-helper-exit.c
  *
  * @brief the helper for exit nodes. Opens a virtual
  * network-interface, sends data received on the if to stdout, sends
@@ -47,6 +47,7 @@
 /**
  * Need 'struct GNUNET_MessageHeader'.
  */
+#include "gnunet_crypto_lib.h"
 #include "gnunet_common.h"
 
 /**
@@ -83,22 +84,48 @@ static const char *sbin_iptables;
 struct in6_ifreq
 {
   struct in6_addr ifr6_addr;
-  __u32 ifr6_prefixlen;
+  uint32_t ifr6_prefixlen; /* __u32 in the original */
   int ifr6_ifindex;
 };
 #endif
 
 
+/**
+ * Open '/dev/null' and make the result the given
+ * file descriptor.
+ *
+ * @param target_fd desired FD to point to /dev/null
+ * @param flags open flags (O_RDONLY, O_WRONLY)
+ */
+static void
+open_dev_null (int target_fd,
+              int flags)
+{
+  int fd;
+
+  fd = open ("/dev/null", flags);
+  if (-1 == fd)
+    abort ();
+  if (fd == target_fd)
+    return;
+  if (-1 == dup2 (fd, target_fd))
+  {
+    (void) close (fd);
+    abort ();
+  }
+  (void) close (fd);
+}
+
 
 /**
  * Run the given command and wait for it to complete.
- * 
+ *
  * @param file name of the binary to run
  * @param cmd command line arguments (as given to 'execv')
  * @return 0 on success, 1 on any error
  */
 static int
-fork_and_exec (const char *file, 
+fork_and_exec (const char *file,
               char *const cmd[])
 {
   int status;
@@ -108,8 +135,8 @@ fork_and_exec (const char *file,
   pid = fork ();
   if (-1 == pid)
   {
-    fprintf (stderr, 
-            "fork failed: %s\n", 
+    fprintf (stderr,
+            "fork failed: %s\n",
             strerror (errno));
     return 1;
   }
@@ -118,23 +145,25 @@ fork_and_exec (const char *file,
     /* we are the child process */
     /* close stdin/stdout to not cause interference
        with the helper's main protocol! */
-    (void) close (0); 
-    (void) close (1); 
+    (void) close (0);
+    open_dev_null (0, O_RDONLY);
+    (void) close (1);
+    open_dev_null (1, O_WRONLY);
     (void) execv (file, cmd);
     /* can only get here on error */
-    fprintf (stderr, 
-            "exec `%s' failed: %s\n", 
+    fprintf (stderr,
+            "exec `%s' failed: %s\n",
             file,
             strerror (errno));
     _exit (1);
   }
   /* keep running waitpid as long as the only error we get is 'EINTR' */
   while ( (-1 == (ret = waitpid (pid, &status, 0))) &&
-         (errno == EINTR) ); 
+         (errno == EINTR) );
   if (-1 == ret)
   {
-    fprintf (stderr, 
-            "waitpid failed: %s\n", 
+    fprintf (stderr,
+            "waitpid failed: %s\n",
             strerror (errno));
     return 1;
   }
@@ -186,7 +215,7 @@ init_tun (char *dev)
 
   if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr))
   {
-    fprintf (stderr, 
+    fprintf (stderr,
             "Error with ioctl on `%s': %s\n", "/dev/net/tun",
              strerror (errno));
     (void) close (fd);
@@ -610,7 +639,7 @@ PROCESS_BUFFER:
  * @param argc must be 6
  * @param argv 0: binary name ("gnunet-helper-exit")
  *             1: tunnel interface name ("gnunet-exit")
- *             2: IPv4 "physical" interface name ("eth0"), or "%" to not do IPv4 NAT
+ *             2: IPv4 "physical" interface name ("eth0"), or "-" to not do IPv4 NAT
  *             3: IPv6 address ("::1"), or "-" to skip IPv6
  *             4: IPv6 netmask length in bits ("64") [ignored if #4 is "-"]
  *             5: IPv4 address ("1.2.3.4"), or "-" to skip IPv4
@@ -640,7 +669,7 @@ main (int argc, char **argv)
     sbin_iptables = "/usr/sbin/iptables";
   else
   {
-    fprintf (stderr, 
+    fprintf (stderr,
             "Fatal: executable iptables not found in approved directories: %s\n",
             strerror (errno));
     return 1;
@@ -662,7 +691,13 @@ main (int argc, char **argv)
 
   if (-1 == (fd_tun = init_tun (dev)))
   {
-    fprintf (stderr, "Fatal: could not initialize tun-interface\n");
+    fprintf (stderr,
+            "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
+            dev,
+            argv[3],
+            argv[4],
+            argv[5],
+            argv[6]);
     return 1;
   }
 
@@ -671,13 +706,13 @@ main (int argc, char **argv)
     {
       const char *address = argv[3];
       long prefix_len = atol (argv[4]);
-      
+
       if ((prefix_len < 1) || (prefix_len > 127))
       {
        fprintf (stderr, "Fatal: prefix_len out of range\n");
        return 1;
-      }      
-      set_address6 (dev, address, prefix_len);    
+      }
+      set_address6 (dev, address, prefix_len);
     }
     {
       char *const sysctl_args[] =
@@ -689,7 +724,7 @@ main (int argc, char **argv)
       {
        fprintf (stderr,
                 "Failed to enable IPv6 forwarding.  Will continue anyway.\n");
-      }    
+      }
     }
   }
 
@@ -698,7 +733,7 @@ main (int argc, char **argv)
     {
       const char *address = argv[5];
       const char *mask = argv[6];
-      
+
       set_address4 (dev, address, mask);
     }
     {
@@ -711,9 +746,9 @@ main (int argc, char **argv)
       {
        fprintf (stderr,
                 "Failed to enable IPv4 forwarding.  Will continue anyway.\n");
-      }    
+      }
     }
-    if (0 != strcmp (argv[2], "%"))
+    if (0 != strcmp (argv[2], "-"))
     {
       char *const iptables_args[] =
        {
@@ -724,10 +759,10 @@ main (int argc, char **argv)
       {
        fprintf (stderr,
                 "Failed to enable IPv4 masquerading (NAT).  Will continue anyway.\n");
-      }    
+      }
     }
   }
-  
+
   uid_t uid = getuid ();
 #ifdef HAVE_SETRESUID
   if (0 != setresuid (uid, uid, uid))
@@ -754,7 +789,7 @@ main (int argc, char **argv)
   run (fd_tun);
   global_ret = 0;
  cleanup:
-  close (fd_tun);
+  (void) close (fd_tun);
   return global_ret;
 }