Add a public tor_api.h with an implementation in tor_api.c

The main effect of this change is to commit to an extensible
long-term API.

Closes ticket 23684.
This commit is contained in:
Nick Mathewson 2017-10-18 14:26:29 -04:00
parent 72b5e4a2db
commit fa02ea102e
7 changed files with 210 additions and 8 deletions

View File

@ -1,3 +1,8 @@
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

View File

@ -105,6 +105,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)
@ -245,9 +246,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; \

View File

@ -106,6 +106,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
@ -3703,14 +3705,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

View File

@ -74,8 +74,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
src/or/tor_api.c Normal file
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;
}

82
src/or/tor_api.h Normal file
View File

@ -0,0 +1,82 @@
/* 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.
**/
#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.
*/
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
src/or/tor_api_internal.h Normal file
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