aboutsummaryrefslogtreecommitdiff
path: root/src/feature/api
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-09-04 11:04:21 -0400
committerNick Mathewson <nickm@torproject.org>2018-09-04 11:04:21 -0400
commit3507fead10ef4f990c0373f4405bd235c0f0b35c (patch)
tree2eda3631bd503be2731f320f8ca46d60d2b86a16 /src/feature/api
parent94b04d6c64ec998a9117d65a156888fa3af188e5 (diff)
parent820aba70efcc6f50f23cf676832412852a01141a (diff)
downloadtor-3507fead10ef4f990c0373f4405bd235c0f0b35c.tar.gz
tor-3507fead10ef4f990c0373f4405bd235c0f0b35c.zip
Merge branch 'tor_api_owning_control'
Diffstat (limited to 'src/feature/api')
-rw-r--r--src/feature/api/tor_api.c77
-rw-r--r--src/feature/api/tor_api.h12
-rw-r--r--src/feature/api/tor_api_internal.h11
3 files changed, 98 insertions, 2 deletions
diff --git a/src/feature/api/tor_api.c b/src/feature/api/tor_api.c
index a53ade1f3e..efc4fdf8d9 100644
--- a/src/feature/api/tor_api.c
+++ b/src/feature/api/tor_api.c
@@ -8,12 +8,19 @@
* \file tor_api.c
**/
+#ifdef _WIN32
+#include <winsock2.h>
+#include <windows.h>
+#endif
+
#include "feature/api/tor_api.h"
-#include "feature/api/tor_api_internal.h"
// Include this after the above headers, to insure that they don't
// depend on anything else.
#include "orconfig.h"
+#include "feature/api/tor_api_internal.h"
+#include "lib/cc/torint.h"
+#include "lib/cc/compat_compiler.h"
#include <stdio.h>
#include <stdlib.h>
@@ -25,6 +32,42 @@
#define raw_malloc malloc
#define raw_free free
+#define raw_realloc realloc
+#define raw_strdup strdup
+
+#ifdef _WIN32
+#include "lib/net/socketpair.h"
+#define raw_socketpair tor_ersatz_socketpair
+#define raw_closesocket closesocket
+#define snprintf _snprintf
+#else
+#define raw_socketpair socketpair
+#define raw_closesocket close
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/**
+ * Helper: Add a copy of <b>arg</b> to the owned arguments of <b>cfg</b>.
+ * Return 0 on success, -1 on failure.
+ */
+static int
+cfg_add_owned_arg(tor_main_configuration_t *cfg, const char *arg)
+{
+ /* We aren't using amortized realloc here, because libc should do it for us,
+ * and because this function is not critical-path. */
+ char **new_argv = raw_realloc(cfg->argv_owned,
+ sizeof(char*) * (cfg->argc_owned+1));
+ if (new_argv == NULL)
+ return -1;
+ cfg->argv_owned = new_argv;
+ if (NULL == (cfg->argv_owned[cfg->argc_owned] = raw_strdup(arg)))
+ return -1;
+ ++cfg->argc_owned;
+ return 0;
+}
tor_main_configuration_t *
tor_main_configuration_new(void)
@@ -39,6 +82,8 @@ tor_main_configuration_new(void)
cfg->argc = 1;
cfg->argv = (char **) fake_argv;
+ cfg->owning_controller_socket = TOR_INVALID_SOCKET;
+
return cfg;
}
@@ -53,11 +98,41 @@ tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
return 0;
}
+tor_control_socket_t
+tor_main_configuration_setup_control_socket(tor_main_configuration_t *cfg)
+{
+ if (SOCKET_OK(cfg->owning_controller_socket))
+ return INVALID_TOR_CONTROL_SOCKET;
+
+ tor_socket_t fds[2];
+ if (raw_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
+ return INVALID_TOR_CONTROL_SOCKET;
+ }
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%"PRIu64, (uint64_t)fds[1]);
+
+ cfg_add_owned_arg(cfg, "__OwningControllerFD");
+ cfg_add_owned_arg(cfg, buf);
+
+ cfg->owning_controller_socket = fds[1];
+ return fds[0];
+}
+
void
tor_main_configuration_free(tor_main_configuration_t *cfg)
{
if (cfg == NULL)
return;
+ if (cfg->argv_owned) {
+ int i;
+ for (i = 0; i < cfg->argc_owned; ++i) {
+ raw_free(cfg->argv_owned[i]);
+ }
+ raw_free(cfg->argv_owned);
+ }
+ if (SOCKET_OK(cfg->owning_controller_socket)) {
+ raw_closesocket(cfg->owning_controller_socket);
+ }
raw_free(cfg);
}
diff --git a/src/feature/api/tor_api.h b/src/feature/api/tor_api.h
index ad2d3166c1..1ac9d892f2 100644
--- a/src/feature/api/tor_api.h
+++ b/src/feature/api/tor_api.h
@@ -49,6 +49,18 @@ tor_main_configuration_t *tor_main_configuration_new(void);
int tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
int argc, char *argv[]);
+#ifdef _WIN32
+typedef SOCKET tor_control_socket_t;
+#define INVALID_TOR_CONTROL_SOCKET INVALID_SOCKET
+#else
+typedef int tor_control_socket_t;
+#define INVALID_TOR_CONTROL_SOCKET (-1)
+#endif
+
+/** DOCDOC */
+tor_control_socket_t tor_main_configuration_setup_control_socket(
+ tor_main_configuration_t *cfg);
+
/**
* Release all storage held in <b>cfg</b>.
*
diff --git a/src/feature/api/tor_api_internal.h b/src/feature/api/tor_api_internal.h
index 2c392a68de..1e32012d01 100644
--- a/src/feature/api/tor_api_internal.h
+++ b/src/feature/api/tor_api_internal.h
@@ -7,6 +7,8 @@
#ifndef TOR_API_INTERNAL_H
#define TOR_API_INTERNAL_H
+#include "lib/net/nettypes.h"
+
/* The contents of this type are private; don't mess with them from outside
* Tor. */
struct tor_main_configuration_t {
@@ -14,7 +16,14 @@ struct tor_main_configuration_t {
int argc;
/** As in main(). This pointer is owned by the caller */
char **argv;
+
+ /** As argc, but describes the number of elements in argv_owned */
+ int argc_owned;
+ /** As argv, but is owned by the tor_main_configuration_t object. */
+ char **argv_owned;
+
+ /** Socket that Tor will use as an owning control socket. Owned. */
+ tor_socket_t owning_controller_socket;
};
#endif /* !defined(TOR_API_INTERNAL_H) */
-