Merge branch 'tor_api_squashed'

This commit is contained in:
Nick Mathewson
2017-11-01 13:22:16 -04:00
18 changed files with 374 additions and 36 deletions
+1
View File
@@ -211,6 +211,7 @@ uptime-*.json
/src/test/fuzz/lf-fuzz-*
# /src/tools/
/src/tools/libtorrunner.a
/src/tools/tor-checkkey
/src/tools/tor-resolve
/src/tools/tor-cov-resolve
+9
View File
@@ -0,0 +1,9 @@
o Major features (embedding):
- There is now a documented stable API for programs that need to
embed Tor. See tor_api.h for full documentation and known bugs.
Closes ticket 23684.
o Code simplification and refactoring:
- The tor_git_revision[] constant no longer needs to be redeclared
by everything that links against the rest of Tor. Done as part
of ticket 23845, to simplify our external API.
+1
View File
@@ -375,6 +375,7 @@ AH_BOTTOM([
AM_CONDITIONAL(BUILD_NT_SERVICES, test "x$bwin32" = "xtrue")
AM_CONDITIONAL(BUILD_LIBTORRUNNER, test "x$bwin32" != "xtrue")
dnl Enable C99 when compiling with MIPSpro
AC_MSG_CHECKING([for MIPSpro compiler])
+1 -2
View File
@@ -82,6 +82,7 @@
#include "dirvote.h"
#include "dns.h"
#include "entrynodes.h"
#include "git_revision.h"
#include "geoip.h"
#include "hibernate.h"
#include "main.h"
@@ -883,8 +884,6 @@ set_options(or_options_t *new_val, char **msg)
return 0;
}
extern const char tor_git_revision[]; /* from tor_main.c */
/** The version of this Tor process, as parsed. */
static char *the_tor_version = NULL;
/** A shorter version of this Tor process's version, for export in our router
+17
View File
@@ -0,0 +1,17 @@
/* Copyright 2001-2004 Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "git_revision.h"
/** String describing which Tor Git repository version the source was
* built from. This string is generated by a bit of shell kludging in
* src/or/include.am, and is usually right.
*/
const char tor_git_revision[] =
#ifndef _MSC_VER
#include "micro-revision.i"
#endif
"";
+12
View File
@@ -0,0 +1,12 @@
/* Copyright 2001-2004 Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_GIT_REVISION_H
#define TOR_GIT_REVISION_H
extern const char tor_git_revision[];
#endif
+9 -2
View File
@@ -51,6 +51,7 @@ LIBTOR_A_SOURCES = \
src/or/geoip.c \
src/or/entrynodes.c \
src/or/ext_orport.c \
src/or/git_revision.c \
src/or/hibernate.c \
src/or/hs_cache.c \
src/or/hs_cell.c \
@@ -105,6 +106,7 @@ LIBTOR_A_SOURCES = \
src/or/statefile.c \
src/or/status.c \
src/or/torcert.c \
src/or/tor_api.c \
src/or/onion_ntor.c \
$(tor_platform_source)
@@ -190,6 +192,7 @@ ORHEADERS = \
src/or/fp_pair.h \
src/or/geoip.h \
src/or/entrynodes.h \
src/or/git_revision.h \
src/or/hibernate.h \
src/or/hs_cache.h \
src/or/hs_cell.h \
@@ -244,9 +247,13 @@ ORHEADERS = \
src/or/scheduler.h \
src/or/statefile.h \
src/or/status.h \
src/or/torcert.h
src/or/torcert.h \
src/or/tor_api_internal.h
noinst_HEADERS+= $(ORHEADERS) micro-revision.i
# This may someday want to be an installed file?
noinst_HEADERS += src/or/tor_api.h
noinst_HEADERS += $(ORHEADERS) micro-revision.i
micro-revision.i: FORCE
$(AM_V_at)rm -f micro-revision.tmp; \
+8 -4
View File
@@ -105,6 +105,8 @@
#include "shared_random.h"
#include "statefile.h"
#include "status.h"
#include "tor_api.h"
#include "tor_api_internal.h"
#include "util_process.h"
#include "ext_orport.h"
#ifdef USE_DMALLOC
@@ -3795,14 +3797,16 @@ sandbox_init_filter(void)
return cfg;
}
/** Main entry point for the Tor process. Called from main(). */
/* This function is distinct from main() only so we can link main.c into
* the unittest binary without conflicting with the unittests' main. */
/* Main entry point for the Tor process. Called from tor_main(), and by
* anybody embedding Tor. */
int
tor_main(int argc, char *argv[])
tor_run_main(const tor_main_configuration_t *tor_cfg)
{
int result = 0;
int argc = tor_cfg->argc;
char **argv = tor_cfg->argv;
#ifdef _WIN32
#ifndef HeapEnableTerminationOnCorruption
#define HeapEnableTerminationOnCorruption 1
-2
View File
@@ -76,8 +76,6 @@ void release_lockfile(void);
void tor_cleanup(void);
void tor_free_all(int postfork);
int tor_main(int argc, char *argv[]);
int do_main_loop(void);
int tor_init(int argc, char **argv);
+88
View File
@@ -0,0 +1,88 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file tor_api.c
**/
#include "tor_api.h"
#include "tor_api_internal.h"
// Include this after the above headers, to insure that they don't
// depend on anything else.
#include "orconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// We don't want to use tor_malloc and tor_free here, since this needs
// to run before anything is initialized at all, and ought to run when
// we're not linked to anything at all.
#define raw_malloc malloc
#define raw_free free
tor_main_configuration_t *
tor_main_configuration_new(void)
{
static const char *fake_argv[] = { "tor" };
tor_main_configuration_t *cfg = raw_malloc(sizeof(*cfg));
if (cfg == NULL)
return NULL;
memset(cfg, 0, sizeof(*cfg));
cfg->argc = 1;
cfg->argv = (char **) fake_argv;
return cfg;
}
int
tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
int argc, char *argv[])
{
if (cfg == NULL)
return -1;
cfg->argc = argc;
cfg->argv = argv;
return 0;
}
void
tor_main_configuration_free(tor_main_configuration_t *cfg)
{
if (cfg == NULL)
return;
raw_free(cfg);
}
/* Main entry point for the Tor process. Called from main().
*
* This function is distinct from main() only so we can link main.c into
* the unittest binary without conflicting with the unittests' main.
*
* Some embedders have historically called this function; but that usage is
* deprecated: they should use tor_run_main() instead.
*/
int
tor_main(int argc, char *argv[])
{
tor_main_configuration_t *cfg = tor_main_configuration_new();
if (!cfg) {
puts("INTERNAL ERROR: Allocation failure. Cannot proceed");
return 1;
}
if (tor_main_configuration_set_command_line(cfg, argc, argv) < 0) {
puts("INTERNAL ERROR: Can't set command line. Cannot proceed.");
return 1;
}
int rv = tor_run_main(cfg);
tor_main_configuration_free(cfg);
return rv;
}
+102
View File
@@ -0,0 +1,102 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file tor_api.h
* \brief Public C API for the Tor network service.
*
* This interface is intended for use by programs that need to link Tor as
* a library, and launch it in a separate thread. If you have the ability
* to run Tor as a separate executable, you should probably do that instead
* of embedding it as a library.
*
* To use this API, first construct a tor_main_configuration_t object using
* tor_main_configuration_new(). Then, you use one or more other function
* calls (such as tor_main_configuration_set_command_line() to configure how
* Tor should be run. Finally, you pass the configuration object to
* tor_run_main().
*
* At this point, tor_run_main() will block its thread to run a Tor daemon;
* when the Tor daemon exits, it will return. See notes on bugs and
* limitations below.
*
* There is no other public C API to Tor: calling any C Tor function not
* documented in this file is not guaranteed to be stable.
**/
#ifndef TOR_API_H
#define TOR_API_H
typedef struct tor_main_configuration_t tor_main_configuration_t;
/**
* Create and return a new tor_main_configuration().
*/
tor_main_configuration_t *tor_main_configuration_new(void);
/**
* Set the command-line arguments in <b>cfg</b>.
*
* The <b>argc</b> and <b>argv</b> values here are as for main(). The
* contents of the argv pointer must remain unchanged until tor_run_main() has
* finished and you call tor_main_configuration_free().
*
* Return 0 on success, -1 on failure.
*/
int tor_main_configuration_set_command_line(tor_main_configuration_t *cfg,
int argc, char *argv[]);
/**
* Release all storage held in <b>cfg</b>.
*
* Once you have passed a tor_main_configuration_t to tor_run_main(), you
* must not free it until tor_run_main() has finished.
*/
void tor_main_configuration_free(tor_main_configuration_t *cfg);
/**
* Run the tor process, as if from the command line.
*
* The command line arguments from tor_main_configuration_set_command_line()
* are taken as if they had been passed to main().
*
* This function will not return until Tor is done running. It returns zero
* on success, and nonzero on failure.
*
* BUG 23848: In many cases, tor_main will call exit() or abort() instead of
* returning. This is not the intended long-term behavior; we are trying to
* fix it.
*
* BUG 23847: You can only call tor_main() once in a single process; if it
* returns and you call it again, you may crash. This is not intended
* long-term behavior; we are trying to fix it.
*
* LIMITATION: You cannot run more than one instance of Tor in the same
* process at the same time. Concurrent calls will cause undefined behavior.
* We do not currently have plans to change this.
*
* LIMITATION: While we will try to fix any problems found here, you
* should be aware that Tor was originally written to run as its own
* process, and that the functionality of this file was added later. If
* you find any bugs or strange behavior, please report them, and we'll
* try to straighten them out.
*/
int tor_run_main(const tor_main_configuration_t *);
/**
* Run the tor process, as if from the command line.
*
* @deprecated Using this function from outside Tor is deprecated; you should
* use use tor_run_main() instead.
*
* BUGS: This function has all the same bugs as tor_run_main().
*
* LIMITATIONS: This function has all the limitations of tor_run_main().
*/
int tor_main(int argc, char **argv);
#endif /* !defined(TOR_API_H) */
+20
View File
@@ -0,0 +1,20 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_API_INTERNAL_H
#define TOR_API_INTERNAL_H
/* The contents of this type are private; don't mess with them from outside
* Tor. */
struct tor_main_configuration_t {
/** As in main() */
int argc;
/** As in main(). This pointer is owned by the caller */
char **argv;
};
#endif
-12
View File
@@ -3,18 +3,6 @@
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
extern const char tor_git_revision[];
/** String describing which Tor Git repository version the source was
* built from. This string is generated by a bit of shell kludging in
* src/or/include.am, and is usually right.
*/
const char tor_git_revision[] =
#ifndef _MSC_VER
#include "micro-revision.i"
#endif
"";
/**
* \file tor_main.c
* \brief Stub module containing a main() function.
-5
View File
@@ -3,11 +3,6 @@
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
extern const char tor_git_revision[];
/* Ordinarily defined in tor_main.c; this bit is just here to provide one
* since we're not linking to tor_main.c */
const char tor_git_revision[] = "";
/**
* \file bench.c
* \brief Benchmarks for lower level Tor modules.
-3
View File
@@ -9,9 +9,6 @@
#include "crypto.h"
#include "crypto_ed25519.h"
extern const char tor_git_revision[];
const char tor_git_revision[] = "";
static or_options_t *mock_options = NULL;
static const or_options_t *
mock_get_options(void)
-6
View File
@@ -3,12 +3,6 @@
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
extern const char tor_git_revision[];
/* Ordinarily defined in tor_main.c; this bit is just here to provide one
* since we're not linking to tor_main.c */
const char tor_git_revision[] = "";
/**
* \file test_common.c
* \brief Common pieces to implement unit tests.
+5
View File
@@ -45,3 +45,8 @@ src_tools_tor_cov_gencert_LDADD = src/common/libor-testing.a \
endif
EXTRA_DIST += src/tools/tor-fw-helper/README
if BUILD_LIBTORRUNNER
noinst_LIBRARIES += src/tools/libtorrunner.a
src_tools_libtorrunner_a_SOURCES = src/tools/tor_runner.c src/or/tor_api.c
endif
+101
View File
@@ -0,0 +1,101 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* @file tor_runner.c
* @brief Experimental module to emulate tor_run_main() API with fork+exec
*
* The functions here are meant to allow the application developer to
* use the tor_run_main() API without having to care whether Tor is
* running in-process or out-of-process. For in-process usage, the
* developer can link Tor as a library and call tor_run_main(); for
* out-of-process usage, the developer can link this library instead.
*
* This interface is EXPERIMENTAL; please let us know if you would like
* to depend on it. We don't know yet whether it will be reliable in
* practice.
*/
/* NOTE: This module is supposed to work without the standard Tor utility
* functions. Don't add more dependencies!
*/
#include "tor_api.h"
#include "tor_api_internal.h"
#include "orconfig.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <stdlib.h>
#include <string.h>
#ifndef __GNUC__
#define __attribute__(x)
#endif
static void child(const tor_main_configuration_t *cfg)
__attribute__((noreturn));
int
tor_run_main(const tor_main_configuration_t *cfg)
{
pid_t pid = fork();
if (pid == 0) {
child(cfg);
exit(0); /* Unreachable */
}
pid_t stopped_pid;
int status = 0;
do {
stopped_pid = waitpid(pid, &status, 0);
} while (stopped_pid == -1);
/* Note: these return values are not documented. No return value is
* documented! */
if (stopped_pid != pid) {
return -99999;
}
if (WIFSTOPPED(status)) {
return WEXITSTATUS(status);
}
if (WIFSIGNALED(status)) {
return -WTERMSIG(status);
}
return -999988;
}
/* circumlocution to avoid getting warned about calling calloc instead of
* tor_calloc. */
#define real_calloc calloc
static void
child(const tor_main_configuration_t *cfg)
{
/* XXXX Close unused file descriptors. */
char **args = real_calloc(cfg->argc+1, sizeof(char *));
memcpy(args, cfg->argv, cfg->argc * sizeof(char *));
args[cfg->argc] = NULL;
int rv = execv(BINDIR "/tor", args);
if (rv < 0) {
exit(254);
} else {
abort(); /* Unreachable */
}
}