aboutsummaryrefslogtreecommitdiff
path: root/src/tools/tor-fw-helper/tor-fw-helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/tor-fw-helper/tor-fw-helper.c')
-rw-r--r--src/tools/tor-fw-helper/tor-fw-helper.c208
1 files changed, 151 insertions, 57 deletions
diff --git a/src/tools/tor-fw-helper/tor-fw-helper.c b/src/tools/tor-fw-helper/tor-fw-helper.c
index c7cc577e1..968f19f7f 100644
--- a/src/tools/tor-fw-helper/tor-fw-helper.c
+++ b/src/tools/tor-fw-helper/tor-fw-helper.c
@@ -2,6 +2,11 @@
* Copyright (c) 2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+/**
+ * \file tor-fw-helper.c
+ * \brief The main wrapper around our firewall helper logic.
+ **/
+
/*
* tor-fw-helper is a tool for opening firewalls with NAT-PMP and UPnP; this
* tool is designed to be called by hand or by Tor by way of a exec() at a
@@ -13,12 +18,76 @@
#include <stdlib.h>
#include <getopt.h>
#include <time.h>
+#include <string.h>
#include "orconfig.h"
#include "tor-fw-helper.h"
+#ifdef NAT_PMP
#include "tor-fw-helper-natpmp.h"
+#endif
+#ifdef MINIUPNPC
#include "tor-fw-helper-upnp.h"
+#endif
+
+/** This is our meta storage type - it holds information about each helper
+ including the total number of helper backends, function pointers, and helper
+ state. */
+typedef struct backends_t {
+ /** The total number of backends */
+ int n_backends;
+ /** The backend functions as an array */
+ tor_fw_backend_t backend_ops[MAX_BACKENDS];
+ /** The internal backend state */
+ void *backend_state[MAX_BACKENDS];
+} backends_t;
+
+int
+init_backends(tor_fw_options_t *options, backends_t *backends);
+/** Initalize each backend helper with the user input stored in <b>options</b>
+ * and put the results in the <b>backends</b> struct. */
+int
+init_backends(tor_fw_options_t *options, backends_t *backends)
+{
+ int n_available = 0;
+ int i, r, n;
+ tor_fw_backend_t *backend_ops_list[MAX_BACKENDS];
+ void *data = NULL;
+ /* First, build a list of the working backends. */
+ n = 0;
+#ifdef MINIUPNPC
+ backend_ops_list[n++] = (tor_fw_backend_t *) tor_fw_get_miniupnp_backend();
+#endif
+#ifdef NAT_PMP
+ backend_ops_list[n++] = (tor_fw_backend_t *) tor_fw_get_natpmp_backend();
+#endif
+ n_available = n;
+
+ /* Now, for each backend that might work, try to initialize it.
+ * That's how we roll, initialized.
+ */
+ n = 0;
+ for (i=0; i<n_available; ++i) {
+ data = calloc(1, backend_ops_list[i]->state_len);
+ if (!data) {
+ perror("calloc");
+ exit(1);
+ }
+ r = backend_ops_list[i]->init(options, data);
+ if (r == 0) {
+ backends->backend_ops[n] = *backend_ops_list[i];
+ backends->backend_state[n] = data;
+ n++;
+ } else {
+ free(data);
+ }
+ }
+ backends->n_backends = n;
+
+ return n;
+}
+
+/** Return the proper commandline switches when the user needs information. */
static void
usage(void)
{
@@ -33,9 +102,10 @@ usage(void)
" [-p|--external-dir-port [TCP port]]]\n");
}
-/* Log commandline options */
+/** Log commandline options to a hardcoded file <b>tor-fw-helper.log</b> in the
+ * current working directory. */
static int
-test_commandline_options(int argc, char **argv)
+log_commandline_options(int argc, char **argv)
{
int i, retval;
FILE *logfile;
@@ -71,71 +141,88 @@ test_commandline_options(int argc, char **argv)
return -1;
}
+/** Iterate over over each of the supported <b>backends</b> and attempt to
+ * fetch the public ip. */
static void
tor_fw_fetch_public_ip(tor_fw_options_t *tor_fw_options,
- miniupnpc_state_t *miniupnpc_state)
+ backends_t *backends)
{
+ int i;
int r = 0;
- r = tor_natpmp_fetch_public_ip(tor_fw_options);
- if (tor_fw_options->verbose)
- fprintf(stdout, "V: Attempts to fetch public ip (natpmp) resulted in: "
- "%d\n", r);
-
- if (r == 0)
- tor_fw_options->public_ip_status = 1;
- r = tor_upnp_fetch_public_ip(miniupnpc_state);
if (tor_fw_options->verbose)
- fprintf(stdout, "V: Attempts to fetch public ip (upnp) resulted in: "
- "%d\n", r);
-
- if (r == 0)
- tor_fw_options->public_ip_status = 1;
+ fprintf(stdout, "V: tor_fw_fetch_public_ip\n");
+
+ for (i=0; i<backends->n_backends; ++i) {
+ if (tor_fw_options->verbose)
+ {
+ fprintf(stdout, "V: running backend_state now: %i\n", i);
+ fprintf(stdout, "V: size of backend state: %u\n",
+ (int)(backends->backend_ops)[i].state_len);
+ fprintf(stdout, "V: backend state name: %s\n",
+ (char *)(backends->backend_ops)[i].name);
+ }
+ r = ((backends->backend_ops)[i].fetch_public_ip(tor_fw_options,
+ (backends->backend_state)[i]));
+ fprintf(stdout, "tor-fw-helper: tor_fw_fetch_public_ip backend %s "
+ " returned: %i\n", (char *)(backends->backend_ops)[i].name, r);
+ }
}
+/** Iterate over each of the supported <b>backends</b> and attempt to add a
+ * port forward for the OR port stored in <b>tor_fw_options</b>. */
static void
-tor_fw_add_or_port(tor_fw_options_t *tor_fw_options, miniupnpc_state_t
- *miniupnpc_state)
+tor_fw_add_or_port(tor_fw_options_t *tor_fw_options,
+ backends_t *backends)
{
+ int i;
int r = 0;
- tor_fw_options->internal_port = tor_fw_options->private_or_port;
- tor_fw_options->external_port = tor_fw_options->public_or_port;
-
- r = tor_natpmp_add_tcp_mapping(tor_fw_options);
- fprintf(stdout, "tor-fw-helper: Attempts to add ORPort mapping (natpmp)"
- "resulted in: %d\n", r);
-
- if (r == 0)
- tor_fw_options->nat_pmp_status = 1;
- r = tor_upnp_add_tcp_mapping(miniupnpc_state,
- tor_fw_options->private_or_port,
- tor_fw_options->public_or_port);
- fprintf(stdout, "tor-fw-helper: Attempts to add ORPort mapping (upnp)"
- "resulted in: %d\n", r);
-
- if (r == 0)
- tor_fw_options->upnp_status = 1;
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: tor_fw_add_or_port\n");
+
+ for (i=0; i<backends->n_backends; ++i) {
+ if (tor_fw_options->verbose)
+ {
+ fprintf(stdout, "V: running backend_state now: %i\n", i);
+ fprintf(stdout, "V: size of backend state: %u\n",
+ (int)(backends->backend_ops)[i].state_len);
+ fprintf(stdout, "V: backend state name: %s\n",
+ (char *)(backends->backend_ops)[i].name);
+ }
+ r = ((backends->backend_ops)[i].add_tcp_mapping(tor_fw_options,
+ (backends->backend_state)[i]));
+ fprintf(stdout, "tor-fw-helper: tor_fw_add_or_port backend %s "
+ "returned: %i\n", (char *)(backends->backend_ops)[i].name, r);
+ }
}
+/** Iterate over each of the supported <b>backends</b> and attempt to add a
+ * port forward for the Dir port stored in <b>tor_fw_options</b>. */
static void
-tor_fw_add_dir_port(tor_fw_options_t *tor_fw_options, miniupnpc_state_t
- *miniupnpc_state)
+tor_fw_add_dir_port(tor_fw_options_t *tor_fw_options,
+ backends_t *backends)
{
+ int i;
int r = 0;
- tor_fw_options->internal_port = tor_fw_options->private_dir_port;
- tor_fw_options->external_port = tor_fw_options->public_dir_port;
-
- r = tor_natpmp_add_tcp_mapping(tor_fw_options);
- fprintf(stdout, "V: Attempts to add DirPort mapping (natpmp) resulted in: "
- "%d\n", r);
-
- r = tor_upnp_add_tcp_mapping(miniupnpc_state,
- tor_fw_options->private_or_port,
- tor_fw_options->public_or_port);
- fprintf(stdout, "V: Attempts to add DirPort mapping (upnp) resulted in: "
- "%d\n",
- r);
+
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: tor_fw_add_dir_port\n");
+
+ for (i=0; i<backends->n_backends; ++i) {
+ if (tor_fw_options->verbose)
+ {
+ fprintf(stdout, "V: running backend_state now: %i\n", i);
+ fprintf(stdout, "V: size of backend state: %u\n",
+ (int)(backends->backend_ops)[i].state_len);
+ fprintf(stdout, "V: backend state name: %s\n",
+ (char *)(backends->backend_ops)[i].name);
+ }
+ r=((backends->backend_ops)[i].add_tcp_mapping(tor_fw_options,
+ (backends->backend_state)[i]));
+ fprintf(stdout, "tor-fw-helper: tor_fw_add_dir_port backend %s "
+ "returned: %i\n", (char *)(backends->backend_ops)[i].name, r);
+ }
}
int
@@ -145,9 +232,7 @@ main(int argc, char **argv)
int c = 0;
tor_fw_options_t tor_fw_options = {0,0,0,0,0,0,0,0,0,0,0,0,0};
- miniupnpc_state_t miniupnpc_state;
-
- miniupnpc_state.init = 0;
+ backends_t backend_state;
while (1)
{
@@ -204,7 +289,7 @@ main(int argc, char **argv)
}
if (tor_fw_options.test_commandline) {
- return test_commandline_options(argc, argv);
+ return log_commandline_options(argc, argv);
}
/* At the very least, we require an ORPort;
@@ -256,19 +341,28 @@ main(int argc, char **argv)
tor_fw_options.public_dir_port);
}
+ // Initalize the various fw-helper backend helpers
+ r = init_backends(&tor_fw_options, &backend_state);
+ if (r)
+ printf("tor-fw-helper: %i NAT traversal helper(s) loaded\n", r);
+
if (tor_fw_options.fetch_public_ip)
{
- tor_fw_fetch_public_ip(&tor_fw_options, &miniupnpc_state);
+ tor_fw_fetch_public_ip(&tor_fw_options, &backend_state);
}
if (tor_fw_options.private_or_port)
{
- tor_fw_add_or_port(&tor_fw_options, &miniupnpc_state);
+ tor_fw_options.internal_port = tor_fw_options.private_or_port;
+ tor_fw_options.external_port = tor_fw_options.private_or_port;
+ tor_fw_add_or_port(&tor_fw_options, &backend_state);
}
if (tor_fw_options.private_dir_port)
{
- tor_fw_add_dir_port(&tor_fw_options, &miniupnpc_state);
+ tor_fw_options.internal_port = tor_fw_options.private_dir_port;
+ tor_fw_options.external_port = tor_fw_options.private_dir_port;
+ tor_fw_add_dir_port(&tor_fw_options, &backend_state);
}
r = (((tor_fw_options.nat_pmp_status | tor_fw_options.upnp_status)