[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r19141 - gnunet/src/exit
From: |
gnunet |
Subject: |
[GNUnet-SVN] r19141 - gnunet/src/exit |
Date: |
Sat, 14 Jan 2012 21:58:36 +0100 |
Author: grothoff
Date: 2012-01-14 21:58:36 +0100 (Sat, 14 Jan 2012)
New Revision: 19141
Modified:
gnunet/src/exit/exit.conf
gnunet/src/exit/gnunet-daemon-exit.c
gnunet/src/exit/gnunet-helper-exit.c
Log:
changing exit helper code to automatically do the network configuration for an
exit node (by running sysctl/iptables commands as necessary)
Modified: gnunet/src/exit/exit.conf
===================================================================
--- gnunet/src/exit/exit.conf 2012-01-14 18:31:25 UTC (rev 19140)
+++ gnunet/src/exit/exit.conf 2012-01-14 20:58:36 UTC (rev 19141)
@@ -1,12 +1,43 @@
[exit]
CONFIG = $DEFAULTCONFIG
BINARY = gnunet-daemon-exit
+
+# IPv6 address for the TUN interface (must be changed as this
+# must be within the global IPv6 range of your system!)
IPV6ADDR = 1234:1::1
+
+# Prefix for our IPv6 subnet on the TUN interface.
IPV6PREFIX = 32
+
+# IPv4 address to use on our TUN interface (may need to be
+# changed to avoid conflicts with existing addresses on your system).
IPV4ADDR = 10.10.1.1
+
+# Netmask for the IPv4 subnet on the TUN interface.
IPV4MASK = 255.255.0.0
-IFNAME = exit-gnunet
-ENABLE_UDP = NO
-ENABLE_TCP = NO
-# MAX_CONNECTIONS = 256
+
+# Name of the (virtual) tunnel interface the exit daemon will manage
+TUN_IFNAME = exit-gnunet
+
+# Name of the "real" interface that IPv4 traffic from this system will
+# leave from; this is the name of the interface where we need to
+# enable NAT on postrouting (typically something like 'eth0' or 'eth1'
+# or 'wlan0'). Not needed if EXIT_IPv4 is disabled.
+EXIT_IFNAME = eth0
+
+# Set this to YES to allow exiting this system via IPv4 to the Internet
+EXIT_IPV4 = NO
+
+# Set this to YES to allow exiting this system via IPv6 to the Internet
+EXIT_IPV6 = NO
+
+# For IPv4-services offered by this peer, we need to at least enable IPv4
+ENABLE_IPV4 = NO
+
+# For IPv6-services offered by this peer, we need to at least enable IPv6
+ENABLE_IPV6 = NO
+
+
+# Maximum number of concurrent connections this exit supports.
+MAX_CONNECTIONS = 256
Modified: gnunet/src/exit/gnunet-daemon-exit.c
===================================================================
--- gnunet/src/exit/gnunet-daemon-exit.c 2012-01-14 18:31:25 UTC (rev
19140)
+++ gnunet/src/exit/gnunet-daemon-exit.c 2012-01-14 20:58:36 UTC (rev
19141)
@@ -278,6 +278,17 @@
static int ipv6_exit;
/**
+ * Do we support IPv4 at all on the TUN interface?
+ */
+static int ipv4_enabled;
+
+/**
+ * Do we support IPv6 at all on the TUN interface?
+ */
+static int ipv6_enabled;
+
+
+/**
* Given IP information about a connection, calculate the respective
* hash we would use for the 'connections_map'.
*
@@ -1954,7 +1965,8 @@
GNUNET_APPLICATION_TYPE_END
};
unsigned int app_idx;
- char *ifname;
+ char *exit_ifname;
+ char *tun_ifname;
char *ipv6addr;
char *ipv6prefix_s;
char *ipv4addr;
@@ -1963,8 +1975,29 @@
struct in6_addr v6;
cfg = cfg_;
- ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit",
"ENABLE_IPV4");
- ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit",
"ENABLE_IPV6");
+ ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
+ ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6");
+ ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit",
"ENABLE_IPV4");
+ ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit",
"ENABLE_IPV6");
+ if (ipv4_exit && (! ipv4_enabled))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Cannot enable IPv4 exit but disable IPv4 on TUN interface,
will use ENABLE_IPv4=YES\n"));
+ ipv4_enabled = GNUNET_YES;
+ }
+ if (ipv6_exit && (! ipv6_enabled))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Cannot enable IPv6 exit but disable IPv6 on TUN interface,
will use ENABLE_IPv6=YES\n"));
+ ipv6_enabled = GNUNET_YES;
+ }
+ if (! (ipv4_enabled || ipv6_enabled))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("No useful service enabled. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
app_idx = 0;
if (GNUNET_YES == ipv4_exit)
{
@@ -1985,68 +2018,101 @@
max_connections = 1024;
exit_argv[0] = GNUNET_strdup ("exit-gnunet");
if (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IFNAME", &ifname))
+ GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "TUN_IFNAME",
&tun_ifname))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No entry 'IFNAME' in configuration!\n");
+ "No entry 'TUN_IFNAME' in configuration!\n");
GNUNET_SCHEDULER_shutdown ();
return;
}
- exit_argv[1] = ifname;
- if ( (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
- &ipv6addr) ||
- (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
+ exit_argv[1] = tun_ifname;
+ if (ipv4_exit)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid entry 'IPV6ADDR' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "EXIT_IFNAME",
&exit_ifname))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No entry 'EXIT_IFNAME' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ exit_argv[2] = exit_ifname;
}
- exit_argv[2] = ipv6addr;
- if (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
- &ipv6prefix_s))
+ else
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No entry 'IPV6PREFIX' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ exit_argv[2] = GNUNET_strdup ("%");
}
- exit_argv[3] = ipv6prefix_s;
- if ( (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
- "IPV6PREFIX",
- &ipv6prefix)) ||
- (ipv6prefix >= 127) )
+ if (GNUNET_YES == ipv6_enabled)
{
- GNUNET_SCHEDULER_shutdown ();
- return;
+ if ( (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR",
+ &ipv6addr) ||
+ (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid entry 'IPV6ADDR' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ exit_argv[3] = ipv6addr;
+ if (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX",
+ &ipv6prefix_s))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No entry 'IPV6PREFIX' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ exit_argv[4] = ipv6prefix_s;
+ if ( (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg, "exit",
+ "IPV6PREFIX",
+ &ipv6prefix)) ||
+ (ipv6prefix >= 127) )
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ }
+ else
+ {
+ /* IPv6 explicitly disabled */
+ exit_argv[3] = GNUNET_strdup ("-");
+ exit_argv[4] = GNUNET_strdup ("-");
}
-
- if ( (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
- &ipv4addr) ||
- (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
+ if (GNUNET_YES == ipv4_enabled)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid entry for 'IPV4ADDR' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ if ( (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR",
+ &ipv4addr) ||
+ (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid entry for 'IPV4ADDR' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ exit_argv[5] = ipv4addr;
+ if ( (GNUNET_SYSERR ==
+ GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
+ &ipv4mask) ||
+ (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No valid entry 'IPV4MASK' in configuration!\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ exit_argv[6] = ipv4mask;
}
- exit_argv[4] = ipv4addr;
- if ( (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK",
- &ipv4mask) ||
- (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
+ else
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "No valid entry 'IPV4MASK' in configuration!\n");
- GNUNET_SCHEDULER_shutdown ();
- return;
+ /* IPv4 explicitly disabled */
+ exit_argv[5] = GNUNET_strdup ("-");
+ exit_argv[6] = GNUNET_strdup ("-");
}
- exit_argv[5] = ipv4mask;
- exit_argv[6] = NULL;
+ exit_argv[7] = NULL;
udp_services = GNUNET_CONTAINER_multihashmap_create (65536);
tcp_services = GNUNET_CONTAINER_multihashmap_create (65536);
Modified: gnunet/src/exit/gnunet-helper-exit.c
===================================================================
--- gnunet/src/exit/gnunet-helper-exit.c 2012-01-14 18:31:25 UTC (rev
19140)
+++ gnunet/src/exit/gnunet-helper-exit.c 2012-01-14 20:58:36 UTC (rev
19141)
@@ -19,17 +19,22 @@
*/
/**
- * @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 data received on stdin to the
- * interface
+ * @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
+ * data received on stdin to the interface. The code also enables
+ * IPv4/IPv6 forwarding and NAT on the current system (the latter on
+ * an interface specified on the command-line); these changes to the
+ * network configuration are NOT automatically undone when the program
+ * is stopped (this is because we cannot be sure that some other
+ * application didn't enable them before or after us; also, these
+ * changes should be mostly harmless as it simply turns the system
+ * into a router).
+ *
* @author Philipp Tölke
+ * @author Christian Grothoff
*
- * TODO:
- * - need to add code to setup ip_forwarding and NAT (for IPv4) so that
- * users don't need to ALSO do admin work; this is what will set
- * gnunet-helper-exit.c apart from gnunet-helper-vpn.c
- *
* The following list of people have reviewed this code and considered
* it safe since the last modification (if you reviewed it, please
* have your name added to the list):
@@ -54,6 +59,17 @@
*/
#define MAX_SIZE 65536
+/**
+ * Path to 'sysctl' binary.
+ */
+#define SBIN_SYSCTL "/sbin/sysctl"
+
+/**
+ * Path to 'iptables' binary.
+ */
+#define SBIN_IPTABLES "/sbin/iptables"
+
+
#ifndef _LINUX_IN6_H
/**
* This is in linux/include/net/ipv6.h, but not always exported...
@@ -67,7 +83,59 @@
#endif
+
/**
+ * 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,
+ char *const cmd[])
+{
+ int status;
+ pid_t pid;
+ pid_t ret;
+
+ pid = fork ();
+ if (-1 == pid)
+ {
+ fprintf (stderr,
+ "fork failed: %s\n",
+ strerror (errno));
+ return 1;
+ }
+ if (0 == pid)
+ {
+ /* we are the child process */
+ (void) execv (file, cmd);
+ /* can only get here on error */
+ 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) );
+ if (-1 == ret)
+ {
+ fprintf (stderr,
+ "waitpid failed: %s\n",
+ strerror (errno));
+ return 1;
+ }
+ if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status))))
+ return 1;
+ /* child process completed and returned success, we're happy */
+ return 0;
+}
+
+
+/**
* Creates a tun-interface called dev;
*
* @param dev is asumed to point to a char[IFNAMSIZ]
@@ -521,12 +589,13 @@
* Open VPN tunnel interface.
*
* @param argc must be 6
- * @param argv 0: binary name (gnunet-helper-vpn)
- * 1: tunnel interface name (gnunet-vpn)
- * 2: IPv6 address (::1)
- * 3: IPv6 netmask length in bits (64)
- * 4: IPv4 address (1.2.3.4)
- * 5: IPv4 netmask (255.255.0.0)
+ * @param argv 0: binary name ("gnunet-helper-vpn")
+ * 1: tunnel interface name ("gnunet-vpn")
+ * 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
+ * 6: IPv4 netmask ("255.255.0.0") [ignored if #4 is "-"]
*/
int
main (int argc, char **argv)
@@ -535,11 +604,17 @@
int fd_tun;
int global_ret;
- if (6 != argc)
+ if (7 != argc)
{
fprintf (stderr, "Fatal: must supply 5 arguments!\n");
return 1;
}
+ if ( (0 == strcmp (argv[3], "-")) &&
+ (0 == strcmp (argv[5], "-")) )
+ {
+ fprintf (stderr, "Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
+ return 1;
+ }
strncpy (dev, argv[1], IFNAMSIZ);
dev[IFNAMSIZ - 1] = '\0';
@@ -550,24 +625,66 @@
return 1;
}
+ if (0 != strcmp (argv[3], "-"))
{
- const char *address = argv[2];
- long prefix_len = atol (argv[3]);
-
- if ((prefix_len < 1) || (prefix_len > 127))
{
- fprintf (stderr, "Fatal: prefix_len out of range\n");
- return 1;
+ 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[] =
+ {
+ "sysctl", "-w", "net.ipv6.conf.all.forwarding=1", NULL
+ };
+ if (0 != fork_and_exec (SBIN_SYSCTL,
+ sysctl_args))
+ {
+ fprintf (stderr,
+ "Failed to enable IPv6 forwarding. Will continue anyway.\n");
+ }
+ }
}
+ if (0 != strcmp (argv[5], "-"))
{
- const char *address = argv[4];
- const char *mask = argv[5];
-
- set_address4 (dev, address, mask);
+ {
+ const char *address = argv[5];
+ const char *mask = argv[6];
+
+ set_address4 (dev, address, mask);
+ }
+ {
+ char *const sysctl_args[] =
+ {
+ "sysctl", "-w", "net.ipv4.ip_forward=1", NULL
+ };
+ if (0 != fork_and_exec (SBIN_SYSCTL,
+ sysctl_args))
+ {
+ fprintf (stderr,
+ "Failed to enable IPv4 forwarding. Will continue anyway.\n");
+ }
+ }
+ if (0 != strcmp (argv[2], "%"))
+ {
+ char *const iptables_args[] =
+ {
+ "iptables", "-t", "nat", "-A", "POSTROUTING", "-o", argv[2], "-j",
"MASQUERADE", NULL
+ };
+ if (0 != fork_and_exec (SBIN_IPTABLES,
+ iptables_args))
+ {
+ fprintf (stderr,
+ "Failed to enable IPv4 masquerading (NAT). Will continue
anyway.\n");
+ }
+ }
}
uid_t uid = getuid ();
@@ -599,3 +716,5 @@
close (fd_tun);
return global_ret;
}
+
+/* end of gnunet-helper-exit.c */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r19141 - gnunet/src/exit,
gnunet <=