Merge branch 'split_mainloop_onion'

This commit is contained in:
Nick Mathewson 2018-09-21 09:37:23 -04:00
commit 9399c579e5
65 changed files with 2437 additions and 2239 deletions

View file

@ -1,4 +1,3 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
@ -96,7 +95,8 @@
#include "lib/log/git_revision.h"
#include "feature/stats/geoip.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/main.h"
#include "app/main/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"

View file

@ -33,11 +33,11 @@
#include "core/or/circuitstats.h"
#include "app/config/config.h"
#include "app/config/confparse.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/connection.h"
#include "feature/control/control.h"
#include "feature/client/entrynodes.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/main.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "lib/sandbox/sandbox.h"

1515
src/app/main/main.c Normal file

File diff suppressed because it is too large Load diff

29
src/app/main/main.h Normal file
View file

@ -0,0 +1,29 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file main.h
* \brief Header file for main.c.
**/
#ifndef TOR_MAIN_H
#define TOR_MAIN_H
void handle_signals(void);
void activate_signal(int signal_num);
int try_locking(const or_options_t *options, int err_if_locked);
int have_lockfile(void);
void release_lockfile(void);
void tor_remove_file(const char *filename);
void tor_cleanup(void);
void tor_free_all(int postfork);
int tor_init(int argc, char **argv);
#endif /* !defined(TOR_MAIN_H) */

View file

@ -21,7 +21,7 @@
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/main.h"
#include "app/main/main.h"
#include "app/main/ntmain.h"
#include "lib/log/win32err.h"
#include "lib/fs/winlib.h"

View file

@ -0,0 +1,311 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file onion_crypto.c
* \brief Functions to handle different kinds of circuit extension crypto.
*
* In this module, we provide a set of abstractions to create a uniform
* interface over the three circuit extension handshakes that Tor has used
* over the years (TAP, CREATE_FAST, and ntor). These handshakes are
* implemented in onion_tap.c, onion_fast.c, and onion_ntor.c respectively.
*
* All[*] of these handshakes follow a similar pattern: a client, knowing
* some key from the relay it wants to extend through, generates the
* first part of a handshake. A relay receives that handshake, and sends
* a reply. Once the client handles the reply, it knows that it is
* talking to the right relay, and it shares some freshly negotiated key
* material with that relay.
*
* We sometimes call the client's part of the handshake an "onionskin".
* We do this because historically, Onion Routing used a multi-layer
* structure called an "onion" to construct circuits. Each layer of the
* onion contained key material chosen by the client, the identity of
* the next relay in the circuit, and a smaller onion, encrypted with
* the key of the next relay. When we changed Tor to use a telescoping
* circuit extension design, it corresponded to sending each layer of the
* onion separately -- as a series of onionskins.
**/
#include "core/or/or.h"
#include "core/or/circuitbuild.h"
#include "core/crypto/onion_crypto.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_ntor.h"
#include "core/crypto/onion_tap.h"
#include "feature/relay/router.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_util.h"
#include "core/or/crypt_path_st.h"
#include "core/or/extend_info_st.h"
/** Return a new server_onion_keys_t object with all of the keys
* and other info we might need to do onion handshakes. (We make a copy of
* our keys for each cpuworker to avoid race conditions with the main thread,
* and to avoid locking) */
server_onion_keys_t *
server_onion_keys_new(void)
{
server_onion_keys_t *keys = tor_malloc_zero(sizeof(server_onion_keys_t));
memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN);
dup_onion_keys(&keys->onion_key, &keys->last_onion_key);
keys->curve25519_key_map = construct_ntor_key_map();
keys->junk_keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));
curve25519_keypair_generate(keys->junk_keypair, 0);
return keys;
}
/** Release all storage held in <b>keys</b>. */
void
server_onion_keys_free_(server_onion_keys_t *keys)
{
if (! keys)
return;
crypto_pk_free(keys->onion_key);
crypto_pk_free(keys->last_onion_key);
ntor_key_map_free(keys->curve25519_key_map);
tor_free(keys->junk_keypair);
memwipe(keys, 0, sizeof(server_onion_keys_t));
tor_free(keys);
}
/** Release whatever storage is held in <b>state</b>, depending on its
* type, and clear its pointer. */
void
onion_handshake_state_release(onion_handshake_state_t *state)
{
switch (state->tag) {
case ONION_HANDSHAKE_TYPE_TAP:
crypto_dh_free(state->u.tap);
state->u.tap = NULL;
break;
case ONION_HANDSHAKE_TYPE_FAST:
fast_handshake_state_free(state->u.fast);
state->u.fast = NULL;
break;
case ONION_HANDSHAKE_TYPE_NTOR:
ntor_handshake_state_free(state->u.ntor);
state->u.ntor = NULL;
break;
default:
/* LCOV_EXCL_START
* This state should not even exist. */
log_warn(LD_BUG, "called with unknown handshake state type %d",
(int)state->tag);
tor_fragile_assert();
/* LCOV_EXCL_STOP */
}
}
/** Perform the first step of a circuit-creation handshake of type <b>type</b>
* (one of ONION_HANDSHAKE_TYPE_*): generate the initial "onion skin" in
* <b>onion_skin_out</b>, and store any state information in <b>state_out</b>.
* Return -1 on failure, and the length of the onionskin on acceptance.
*/
int
onion_skin_create(int type,
const extend_info_t *node,
onion_handshake_state_t *state_out,
uint8_t *onion_skin_out)
{
int r = -1;
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
if (!node->onion_key)
return -1;
if (onion_skin_TAP_create(node->onion_key,
&state_out->u.tap,
(char*)onion_skin_out) < 0)
return -1;
r = TAP_ONIONSKIN_CHALLENGE_LEN;
break;
case ONION_HANDSHAKE_TYPE_FAST:
if (fast_onionskin_create(&state_out->u.fast, onion_skin_out) < 0)
return -1;
r = CREATE_FAST_LEN;
break;
case ONION_HANDSHAKE_TYPE_NTOR:
if (!extend_info_supports_ntor(node))
return -1;
if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
&node->curve25519_onion_key,
&state_out->u.ntor,
onion_skin_out) < 0)
return -1;
r = NTOR_ONIONSKIN_LEN;
break;
default:
/* LCOV_EXCL_START
* We should never try to create an impossible handshake type. */
log_warn(LD_BUG, "called with unknown handshake state type %d", type);
tor_fragile_assert();
r = -1;
/* LCOV_EXCL_STOP */
}
if (r > 0)
state_out->tag = (uint16_t) type;
return r;
}
/* This is the maximum value for keys_out_len passed to
* onion_skin_server_handshake, plus 16. We can make it bigger if needed:
* It just defines how many bytes to stack-allocate. */
#define MAX_KEYS_TMP_LEN 128
/** Perform the second (server-side) step of a circuit-creation handshake of
* type <b>type</b>, responding to the client request in <b>onion_skin</b>
* using the keys in <b>keys</b>. On success, write our response into
* <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
* in <b>keys_out_len</b>, a hidden service nonce to <b>rend_nonce_out</b>,
* and return the length of the reply. On failure, return -1.
*/
int
onion_skin_server_handshake(int type,
const uint8_t *onion_skin, size_t onionskin_len,
const server_onion_keys_t *keys,
uint8_t *reply_out,
uint8_t *keys_out, size_t keys_out_len,
uint8_t *rend_nonce_out)
{
int r = -1;
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
if (onionskin_len != TAP_ONIONSKIN_CHALLENGE_LEN)
return -1;
if (onion_skin_TAP_server_handshake((const char*)onion_skin,
keys->onion_key, keys->last_onion_key,
(char*)reply_out,
(char*)keys_out, keys_out_len)<0)
return -1;
r = TAP_ONIONSKIN_REPLY_LEN;
memcpy(rend_nonce_out, reply_out+DH1024_KEY_LEN, DIGEST_LEN);
break;
case ONION_HANDSHAKE_TYPE_FAST:
if (onionskin_len != CREATE_FAST_LEN)
return -1;
if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
return -1;
r = CREATED_FAST_LEN;
memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN);
break;
case ONION_HANDSHAKE_TYPE_NTOR:
if (onionskin_len < NTOR_ONIONSKIN_LEN)
return -1;
{
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
if (onion_skin_ntor_server_handshake(
onion_skin, keys->curve25519_key_map,
keys->junk_keypair,
keys->my_identity,
reply_out, keys_tmp, keys_tmp_len)<0) {
/* no need to memwipe here, since the output will never be used */
return -1;
}
memcpy(keys_out, keys_tmp, keys_out_len);
memcpy(rend_nonce_out, keys_tmp+keys_out_len, DIGEST_LEN);
memwipe(keys_tmp, 0, sizeof(keys_tmp));
r = NTOR_REPLY_LEN;
}
break;
default:
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "called with unknown handshake state type %d", type);
tor_fragile_assert();
return -1;
/* LCOV_EXCL_STOP */
}
return r;
}
/** Perform the final (client-side) step of a circuit-creation handshake of
* type <b>type</b>, using our state in <b>handshake_state</b> and the
* server's response in <b>reply</b>. On success, generate <b>keys_out_len</b>
* bytes worth of key material in <b>keys_out_len</b>, set
* <b>rend_authenticator_out</b> to the "KH" field that can be used to
* establish introduction points at this hop, and return 0. On failure,
* return -1, and set *msg_out to an error message if this is worth
* complaining to the user about. */
int
onion_skin_client_handshake(int type,
const onion_handshake_state_t *handshake_state,
const uint8_t *reply, size_t reply_len,
uint8_t *keys_out, size_t keys_out_len,
uint8_t *rend_authenticator_out,
const char **msg_out)
{
if (handshake_state->tag != type)
return -1;
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
if (reply_len != TAP_ONIONSKIN_REPLY_LEN) {
if (msg_out)
*msg_out = "TAP reply was not of the correct length.";
return -1;
}
if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
(const char*)reply,
(char *)keys_out, keys_out_len,
msg_out) < 0)
return -1;
memcpy(rend_authenticator_out, reply+DH1024_KEY_LEN, DIGEST_LEN);
return 0;
case ONION_HANDSHAKE_TYPE_FAST:
if (reply_len != CREATED_FAST_LEN) {
if (msg_out)
*msg_out = "TAP reply was not of the correct length.";
return -1;
}
if (fast_client_handshake(handshake_state->u.fast, reply,
keys_out, keys_out_len, msg_out) < 0)
return -1;
memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN);
return 0;
case ONION_HANDSHAKE_TYPE_NTOR:
if (reply_len < NTOR_REPLY_LEN) {
if (msg_out)
*msg_out = "ntor reply was not of the correct length.";
return -1;
}
{
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
if (onion_skin_ntor_client_handshake(handshake_state->u.ntor,
reply,
keys_tmp, keys_tmp_len, msg_out) < 0) {
tor_free(keys_tmp);
return -1;
}
memcpy(keys_out, keys_tmp, keys_out_len);
memcpy(rend_authenticator_out, keys_tmp + keys_out_len, DIGEST_LEN);
memwipe(keys_tmp, 0, keys_tmp_len);
tor_free(keys_tmp);
}
return 0;
default:
log_warn(LD_BUG, "called with unknown handshake state type %d", type);
tor_fragile_assert();
return -1;
}
}

View file

@ -0,0 +1,47 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file onion_crypto.h
* \brief Header file for onion_crypto.c.
**/
#ifndef TOR_ONION_CRYPTO_H
#define TOR_ONION_CRYPTO_H
typedef struct server_onion_keys_t {
uint8_t my_identity[DIGEST_LEN];
crypto_pk_t *onion_key;
crypto_pk_t *last_onion_key;
struct di_digest256_map_t *curve25519_key_map;
struct curve25519_keypair_t *junk_keypair;
} server_onion_keys_t;
void onion_handshake_state_release(onion_handshake_state_t *state);
int onion_skin_create(int type,
const extend_info_t *node,
onion_handshake_state_t *state_out,
uint8_t *onion_skin_out);
int onion_skin_server_handshake(int type,
const uint8_t *onion_skin, size_t onionskin_len,
const server_onion_keys_t *keys,
uint8_t *reply_out,
uint8_t *keys_out, size_t key_out_len,
uint8_t *rend_nonce_out);
int onion_skin_client_handshake(int type,
const onion_handshake_state_t *handshake_state,
const uint8_t *reply, size_t reply_len,
uint8_t *keys_out, size_t key_out_len,
uint8_t *rend_authenticator_out,
const char **msg_out);
server_onion_keys_t *server_onion_keys_new(void);
void server_onion_keys_free_(server_onion_keys_t *keys);
#define server_onion_keys_free(keys) \
FREE_AND_NULL(server_onion_keys_t, server_onion_keys_free_, (keys))
#endif

View file

@ -10,15 +10,16 @@ LIBTOR_APP_A_SOURCES = \
src/app/config/config.c \
src/app/config/confparse.c \
src/app/config/statefile.c \
src/app/main/main.c \
src/core/crypto/hs_ntor.c \
src/core/crypto/onion.c \
src/core/crypto/onion_crypto.c \
src/core/crypto/onion_fast.c \
src/core/crypto/onion_ntor.c \
src/core/crypto/onion_tap.c \
src/core/crypto/relay_crypto.c \
src/core/mainloop/connection.c \
src/core/mainloop/cpuworker.c \
src/core/mainloop/main.c \
src/core/mainloop/mainloop.c \
src/core/mainloop/periodic.c \
src/core/or/address_set.c \
src/core/or/channel.c \
@ -34,6 +35,7 @@ LIBTOR_APP_A_SOURCES = \
src/core/or/connection_edge.c \
src/core/or/connection_or.c \
src/core/or/dos.c \
src/core/or/onion.c \
src/core/or/policies.c \
src/core/or/protover.c \
src/core/or/reasons.c \
@ -95,6 +97,7 @@ LIBTOR_APP_A_SOURCES = \
src/feature/nodelist/torcert.c \
src/feature/relay/dns.c \
src/feature/relay/ext_orport.c \
src/feature/relay/onion_queue.c \
src/feature/relay/router.c \
src/feature/relay/routerkeys.c \
src/feature/rend/rendcache.c \
@ -162,16 +165,17 @@ noinst_HEADERS += \
src/app/config/or_options_st.h \
src/app/config/or_state_st.h \
src/app/config/statefile.h \
src/app/main/main.h \
src/app/main/ntmain.h \
src/core/crypto/hs_ntor.h \
src/core/crypto/onion.h \
src/core/crypto/onion_crypto.h \
src/core/crypto/onion_fast.h \
src/core/crypto/onion_ntor.h \
src/core/crypto/onion_tap.h \
src/core/crypto/relay_crypto.h \
src/core/mainloop/connection.h \
src/core/mainloop/cpuworker.h \
src/core/mainloop/main.h \
src/core/mainloop/mainloop.h \
src/core/mainloop/periodic.h \
src/core/or/addr_policy_st.h \
src/core/or/address_set.h \
@ -202,6 +206,7 @@ noinst_HEADERS += \
src/core/or/entry_port_cfg_st.h \
src/core/or/extend_info_st.h \
src/core/or/listener_connection_st.h \
src/core/or/onion.h \
src/core/or/or.h \
src/core/or/or_circuit_st.h \
src/core/or/or_connection_st.h \
@ -307,6 +312,7 @@ noinst_HEADERS += \
src/feature/relay/dns.h \
src/feature/relay/dns_structs.h \
src/feature/relay/ext_orport.h \
src/feature/relay/onion_queue.h \
src/feature/relay/router.h \
src/feature/relay/routerkeys.h \
src/feature/rend/rend_authorized_client_st.h \

View file

@ -85,7 +85,7 @@
#include "feature/client/entrynodes.h"
#include "feature/relay/ext_orport.h"
#include "feature/stats/geoip.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/hibernate/hibernate.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_ident.h"

View file

@ -26,11 +26,12 @@
#include "core/mainloop/cpuworker.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "core/mainloop/main.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "feature/relay/onion_queue.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "lib/evloop/workqueue.h"
#include "core/crypto/onion_crypto.h"
#include "core/or/or_circuit_st.h"
#include "lib/intmath/weakrng.h"

File diff suppressed because it is too large Load diff

View file

@ -5,12 +5,12 @@
/* See LICENSE for licensing information */
/**
* \file main.h
* \brief Header file for main.c.
* \file mainloop.h
* \brief Header file for mainloop.c.
**/
#ifndef TOR_MAIN_H
#define TOR_MAIN_H
#ifndef TOR_MAINLOOP_H
#define TOR_MAINLOOP_H
int have_completed_a_circuit(void);
void note_that_we_completed_a_circuit(void);
@ -73,20 +73,7 @@ MOCK_DECL(void,reset_uptime,(void));
unsigned get_signewnym_epoch(void);
void handle_signals(void);
void activate_signal(int signal_num);
int try_locking(const or_options_t *options, int err_if_locked);
int have_lockfile(void);
void release_lockfile(void);
void tor_remove_file(const char *filename);
void tor_cleanup(void);
void tor_free_all(int postfork);
int do_main_loop(void);
int tor_init(int argc, char **argv);
void reset_main_loop_counters(void);
uint64_t get_main_loop_success_count(void);
@ -96,6 +83,12 @@ uint64_t get_main_loop_idle_count(void);
void periodic_events_on_new_options(const or_options_t *options);
void reschedule_per_second_timer(void);
void do_signewnym(time_t);
time_t get_last_signewnym_time(void);
void tor_init_connection_lists(void);
void tor_mainloop_free_all(void);
struct token_bucket_rw_t;
extern time_t time_of_process_start;
@ -103,13 +96,12 @@ extern int quiet_level;
extern struct token_bucket_rw_t global_bucket;
extern struct token_bucket_rw_t global_relayed_bucket;
#ifdef MAIN_PRIVATE
STATIC void init_connection_lists(void);
#ifdef MAINLOOP_PRIVATE
STATIC void initialize_mainloop_events(void);
STATIC void close_closeable_connections(void);
STATIC void initialize_periodic_events(void);
STATIC void teardown_periodic_events(void);
STATIC int get_my_roles(const or_options_t *options);
STATIC int get_my_roles(const or_options_t *);
#ifdef TOR_UNIT_TESTS
extern smartlist_t *connection_array;
@ -119,4 +111,4 @@ extern periodic_event_item_t periodic_events[];
#endif
#endif /* defined(MAIN_PRIVATE) */
#endif /* !defined(TOR_MAIN_H) */
#endif

View file

@ -14,7 +14,7 @@
#include "core/or/or.h"
#include "lib/evloop/compat_libevent.h"
#include "app/config/config.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/periodic.h"
#include "lib/evloop/compat_libevent.h"

View file

@ -69,7 +69,7 @@
#include "core/or/circuitmux.h"
#include "feature/client/entrynodes.h"
#include "feature/stats/geoip.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/relay.h"
#include "feature/stats/rephist.h"

View file

@ -17,7 +17,7 @@
#include "core/mainloop/connection.h"
#include "core/or/connection_or.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "lib/time/compat_time.h"

View file

@ -47,11 +47,12 @@
#include "feature/dircache/directory.h"
#include "feature/client/entrynodes.h"
#include "core/crypto/hs_ntor.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "core/crypto/onion_crypto.h"
#include "core/crypto/onion_tap.h"
#include "core/crypto/onion_fast.h"
#include "core/or/policies.h"

View file

@ -71,13 +71,14 @@
#include "lib/crypt_ops/crypto_dh.h"
#include "feature/dircache/directory.h"
#include "feature/client/entrynodes.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/hs/hs_circuit.h"
#include "feature/hs/hs_circuitmap.h"
#include "feature/hs/hs_ident.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/crypto/onion.h"
#include "feature/relay/onion_queue.h"
#include "core/crypto/onion_crypto.h"
#include "core/crypto/onion_fast.h"
#include "core/or/policies.h"
#include "core/or/relay.h"

View file

@ -32,7 +32,7 @@
#include "app/config/confparse.h"
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/rend/rendclient.h"
#include "feature/rend/rendservice.h"

View file

@ -50,7 +50,8 @@
#include "core/or/dos.h"
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/nodelist.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "core/crypto/onion_crypto.h"
#include "feature/stats/rephist.h"
#include "core/or/relay.h"
#include "feature/relay/router.h"
@ -699,4 +700,3 @@ command_setup_listener(channel_listener_t *listener)
channel_listener_set_listener_fn(listener, command_handle_incoming_channel);
}

View file

@ -80,7 +80,7 @@
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_circuit.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"

View file

@ -44,7 +44,7 @@
#include "feature/dirauth/reachability.h"
#include "feature/client/entrynodes.h"
#include "feature/stats/geoip.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "trunnel/link_handshake.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"

View file

@ -15,7 +15,7 @@
#include "core/or/connection_or.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/stats/geoip.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/relay.h"

View file

@ -6,7 +6,7 @@
/**
* \file onion.c
* \brief Functions to queue create cells, wrap the various onionskin types,
* \brief Functions to queue create cells,
* and parse and create the CREATE cell and its allies.
*
* This module has a few functions, all related to the CREATE/CREATED
@ -14,27 +14,6 @@
* related EXTEND/EXTENDED handshake that we use over circuits in order to
* extend them an additional hop.
*
* In this module, we provide a set of abstractions to create a uniform
* interface over the three circuit extension handshakes that Tor has used
* over the years (TAP, CREATE_FAST, and ntor). These handshakes are
* implemented in onion_tap.c, onion_fast.c, and onion_ntor.c respectively.
*
* All[*] of these handshakes follow a similar pattern: a client, knowing
* some key from the relay it wants to extend through, generates the
* first part of a handshake. A relay receives that handshake, and sends
* a reply. Once the client handles the reply, it knows that it is
* talking to the right relay, and it shares some freshly negotiated key
* material with that relay.
*
* We sometimes call the client's part of the handshake an "onionskin".
* We do this because historically, Onion Routing used a multi-layer
* structure called an "onion" to construct circuits. Each layer of the
* onion contained key material chosen by the client, the identity of
* the next relay in the circuit, and a smaller onion, encrypted with
* the key of the next relay. When we changed Tor to use a telescoping
* circuit extension design, it corresponded to sending each layer of the
* onion separately -- as a series of onionskins.
*
* Clients invoke these functions when creating or extending a circuit,
* from circuitbuild.c.
*
@ -57,628 +36,23 @@
* <li>Encoding and decodign EXTEND, EXTENDED, EXTEND2, and EXTENDED2
* relay cells.
* </ul>
*
* [*] The CREATE_FAST handshake is weaker than described here; see
* onion_fast.c for more information.
**/
#include "core/or/or.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "app/config/config.h"
#include "core/mainloop/cpuworker.h"
#include "lib/crypt_ops/crypto_util.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "feature/nodelist/networkstatus.h"
#include "core/crypto/onion.h"
#include "core/crypto/onion_crypto.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_ntor.h"
#include "core/crypto/onion_tap.h"
#include "core/or/relay.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "core/or/onion.h"
#include "feature/nodelist/networkstatus.h"
#include "core/or/cell_st.h"
#include "core/or/extend_info_st.h"
#include "core/or/or_circuit_st.h"
// trunnel
#include "trunnel/ed25519_cert.h"
/** Type for a linked list of circuits that are waiting for a free CPU worker
* to process a waiting onion handshake. */
typedef struct onion_queue_t {
TOR_TAILQ_ENTRY(onion_queue_t) next;
or_circuit_t *circ;
uint16_t handshake_type;
create_cell_t *onionskin;
time_t when_added;
} onion_queue_t;
/** 5 seconds on the onion queue til we just send back a destroy */
#define ONIONQUEUE_WAIT_CUTOFF 5
/** Array of queues of circuits waiting for CPU workers. An element is NULL
* if that queue is empty.*/
static TOR_TAILQ_HEAD(onion_queue_head_t, onion_queue_t)
ol_list[MAX_ONION_HANDSHAKE_TYPE+1] =
{ TOR_TAILQ_HEAD_INITIALIZER(ol_list[0]), /* tap */
TOR_TAILQ_HEAD_INITIALIZER(ol_list[1]), /* fast */
TOR_TAILQ_HEAD_INITIALIZER(ol_list[2]), /* ntor */
};
/** Number of entries of each type currently in each element of ol_list[]. */
static int ol_entries[MAX_ONION_HANDSHAKE_TYPE+1];
static int num_ntors_per_tap(void);
static void onion_queue_entry_remove(onion_queue_t *victim);
/* XXXX Check lengths vs MAX_ONIONSKIN_{CHALLENGE,REPLY}_LEN.
*
* (By which I think I meant, "make sure that no
* X_ONIONSKIN_CHALLENGE/REPLY_LEN is greater than
* MAX_ONIONSKIN_CHALLENGE/REPLY_LEN." Also, make sure that we can pass
* over-large values via EXTEND2/EXTENDED2, for future-compatibility.*/
/** Return true iff we have room to queue another onionskin of type
* <b>type</b>. */
static int
have_room_for_onionskin(uint16_t type)
{
const or_options_t *options = get_options();
int num_cpus;
uint64_t tap_usec, ntor_usec;
uint64_t ntor_during_tap_usec, tap_during_ntor_usec;
/* If we've got fewer than 50 entries, we always have room for one more. */
if (ol_entries[type] < 50)
return 1;
num_cpus = get_num_cpus(options);
/* Compute how many microseconds we'd expect to need to clear all
* onionskins in various combinations of the queues. */
/* How long would it take to process all the TAP cells in the queue? */
tap_usec = estimated_usec_for_onionskins(
ol_entries[ONION_HANDSHAKE_TYPE_TAP],
ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
/* How long would it take to process all the NTor cells in the queue? */
ntor_usec = estimated_usec_for_onionskins(
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
/* How long would it take to process the tap cells that we expect to
* process while draining the ntor queue? */
tap_during_ntor_usec = estimated_usec_for_onionskins(
MIN(ol_entries[ONION_HANDSHAKE_TYPE_TAP],
ol_entries[ONION_HANDSHAKE_TYPE_NTOR] / num_ntors_per_tap()),
ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
/* How long would it take to process the ntor cells that we expect to
* process while draining the tap queue? */
ntor_during_tap_usec = estimated_usec_for_onionskins(
MIN(ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP] * num_ntors_per_tap()),
ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
/* See whether that exceeds MaxOnionQueueDelay. If so, we can't queue
* this. */
if (type == ONION_HANDSHAKE_TYPE_NTOR &&
(ntor_usec + tap_during_ntor_usec) / 1000 >
(uint64_t)options->MaxOnionQueueDelay)
return 0;
if (type == ONION_HANDSHAKE_TYPE_TAP &&
(tap_usec + ntor_during_tap_usec) / 1000 >
(uint64_t)options->MaxOnionQueueDelay)
return 0;
/* If we support the ntor handshake, then don't let TAP handshakes use
* more than 2/3 of the space on the queue. */
if (type == ONION_HANDSHAKE_TYPE_TAP &&
tap_usec / 1000 > (uint64_t)options->MaxOnionQueueDelay * 2 / 3)
return 0;
return 1;
}
/** Add <b>circ</b> to the end of ol_list and return 0, except
* if ol_list is too long, in which case do nothing and return -1.
*/
int
onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
{
onion_queue_t *tmp;
time_t now = time(NULL);
if (onionskin->handshake_type > MAX_ONION_HANDSHAKE_TYPE) {
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "Handshake %d out of range! Dropping.",
onionskin->handshake_type);
return -1;
/* LCOV_EXCL_STOP */
}
tmp = tor_malloc_zero(sizeof(onion_queue_t));
tmp->circ = circ;
tmp->handshake_type = onionskin->handshake_type;
tmp->onionskin = onionskin;
tmp->when_added = now;
if (!have_room_for_onionskin(onionskin->handshake_type)) {
#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
static ratelim_t last_warned =
RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
char *m;
if (onionskin->handshake_type == ONION_HANDSHAKE_TYPE_NTOR &&
(m = rate_limit_log(&last_warned, approx_time()))) {
log_warn(LD_GENERAL,
"Your computer is too slow to handle this many circuit "
"creation requests! Please consider using the "
"MaxAdvertisedBandwidth config option or choosing a more "
"restricted exit policy.%s",m);
tor_free(m);
}
tor_free(tmp);
return -1;
}
++ol_entries[onionskin->handshake_type];
log_info(LD_OR, "New create (%s). Queues now ntor=%d and tap=%d.",
onionskin->handshake_type == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP]);
circ->onionqueue_entry = tmp;
TOR_TAILQ_INSERT_TAIL(&ol_list[onionskin->handshake_type], tmp, next);
/* cull elderly requests. */
while (1) {
onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[onionskin->handshake_type]);
if (now - head->when_added < (time_t)ONIONQUEUE_WAIT_CUTOFF)
break;
circ = head->circ;
circ->onionqueue_entry = NULL;
onion_queue_entry_remove(head);
log_info(LD_CIRC,
"Circuit create request is too old; canceling due to overload.");
if (! TO_CIRCUIT(circ)->marked_for_close) {
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
}
}
return 0;
}
/** Return a fairness parameter, to prefer processing NTOR style
* handshakes but still slowly drain the TAP queue so we don't starve
* it entirely. */
static int
num_ntors_per_tap(void)
{
#define DEFAULT_NUM_NTORS_PER_TAP 10
#define MIN_NUM_NTORS_PER_TAP 1
#define MAX_NUM_NTORS_PER_TAP 100000
return networkstatus_get_param(NULL, "NumNTorsPerTAP",
DEFAULT_NUM_NTORS_PER_TAP,
MIN_NUM_NTORS_PER_TAP,
MAX_NUM_NTORS_PER_TAP);
}
/** Choose which onion queue we'll pull from next. If one is empty choose
* the other; if they both have elements, load balance across them but
* favoring NTOR. */
static uint16_t
decide_next_handshake_type(void)
{
/* The number of times we've chosen ntor lately when both were available. */
static int recently_chosen_ntors = 0;
if (!ol_entries[ONION_HANDSHAKE_TYPE_NTOR])
return ONION_HANDSHAKE_TYPE_TAP; /* no ntors? try tap */
if (!ol_entries[ONION_HANDSHAKE_TYPE_TAP]) {
/* Nick wants us to prioritize new tap requests when there aren't
* any in the queue and we've processed k ntor cells since the last
* tap cell. This strategy is maybe a good idea, since it starves tap
* less in the case where tap is rare, or maybe a poor idea, since it
* makes the new tap cell unfairly jump in front of ntor cells that
* got here first. In any case this edge case will only become relevant
* once tap is rare. We should reevaluate whether we like this decision
* once tap gets more rare. */
if (ol_entries[ONION_HANDSHAKE_TYPE_NTOR] &&
recently_chosen_ntors <= num_ntors_per_tap())
++recently_chosen_ntors;
return ONION_HANDSHAKE_TYPE_NTOR; /* no taps? try ntor */
}
/* They both have something queued. Pick ntor if we haven't done that
* too much lately. */
if (++recently_chosen_ntors <= num_ntors_per_tap()) {
return ONION_HANDSHAKE_TYPE_NTOR;
}
/* Else, it's time to let tap have its turn. */
recently_chosen_ntors = 0;
return ONION_HANDSHAKE_TYPE_TAP;
}
/** Remove the highest priority item from ol_list[] and return it, or
* return NULL if the lists are empty.
*/
or_circuit_t *
onion_next_task(create_cell_t **onionskin_out)
{
or_circuit_t *circ;
uint16_t handshake_to_choose = decide_next_handshake_type();
onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[handshake_to_choose]);
if (!head)
return NULL; /* no onions pending, we're done */
tor_assert(head->circ);
tor_assert(head->handshake_type <= MAX_ONION_HANDSHAKE_TYPE);
// tor_assert(head->circ->p_chan); /* make sure it's still valid */
/* XXX I only commented out the above line to make the unit tests
* more manageable. That's probably not good long-term. -RD */
circ = head->circ;
if (head->onionskin)
--ol_entries[head->handshake_type];
log_info(LD_OR, "Processing create (%s). Queues now ntor=%d and tap=%d.",
head->handshake_type == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP]);
*onionskin_out = head->onionskin;
head->onionskin = NULL; /* prevent free. */
circ->onionqueue_entry = NULL;
onion_queue_entry_remove(head);
return circ;
}
/** Return the number of <b>handshake_type</b>-style create requests pending.
*/
int
onion_num_pending(uint16_t handshake_type)
{
return ol_entries[handshake_type];
}
/** Go through ol_list, find the onion_queue_t element which points to
* circ, remove and free that element. Leave circ itself alone.
*/
void
onion_pending_remove(or_circuit_t *circ)
{
onion_queue_t *victim;
if (!circ)
return;
victim = circ->onionqueue_entry;
if (victim)
onion_queue_entry_remove(victim);
cpuworker_cancel_circ_handshake(circ);
}
/** Remove a queue entry <b>victim</b> from the queue, unlinking it from
* its circuit and freeing it and any structures it owns.*/
static void
onion_queue_entry_remove(onion_queue_t *victim)
{
if (victim->handshake_type > MAX_ONION_HANDSHAKE_TYPE) {
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "Handshake %d out of range! Dropping.",
victim->handshake_type);
/* XXX leaks */
return;
/* LCOV_EXCL_STOP */
}
TOR_TAILQ_REMOVE(&ol_list[victim->handshake_type], victim, next);
if (victim->circ)
victim->circ->onionqueue_entry = NULL;
if (victim->onionskin)
--ol_entries[victim->handshake_type];
tor_free(victim->onionskin);
tor_free(victim);
}
/** Remove all circuits from the pending list. Called from tor_free_all. */
void
clear_pending_onions(void)
{
onion_queue_t *victim, *next;
int i;
for (i=0; i<=MAX_ONION_HANDSHAKE_TYPE; i++) {
for (victim = TOR_TAILQ_FIRST(&ol_list[i]); victim; victim = next) {
next = TOR_TAILQ_NEXT(victim,next);
onion_queue_entry_remove(victim);
}
tor_assert(TOR_TAILQ_EMPTY(&ol_list[i]));
}
memset(ol_entries, 0, sizeof(ol_entries));
}
/* ============================================================ */
/** Return a new server_onion_keys_t object with all of the keys
* and other info we might need to do onion handshakes. (We make a copy of
* our keys for each cpuworker to avoid race conditions with the main thread,
* and to avoid locking) */
server_onion_keys_t *
server_onion_keys_new(void)
{
server_onion_keys_t *keys = tor_malloc_zero(sizeof(server_onion_keys_t));
memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN);
dup_onion_keys(&keys->onion_key, &keys->last_onion_key);
keys->curve25519_key_map = construct_ntor_key_map();
keys->junk_keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));
curve25519_keypair_generate(keys->junk_keypair, 0);
return keys;
}
/** Release all storage held in <b>keys</b>. */
void
server_onion_keys_free_(server_onion_keys_t *keys)
{
if (! keys)
return;
crypto_pk_free(keys->onion_key);
crypto_pk_free(keys->last_onion_key);
ntor_key_map_free(keys->curve25519_key_map);
tor_free(keys->junk_keypair);
memwipe(keys, 0, sizeof(server_onion_keys_t));
tor_free(keys);
}
/** Release whatever storage is held in <b>state</b>, depending on its
* type, and clear its pointer. */
void
onion_handshake_state_release(onion_handshake_state_t *state)
{
switch (state->tag) {
case ONION_HANDSHAKE_TYPE_TAP:
crypto_dh_free(state->u.tap);
state->u.tap = NULL;
break;
case ONION_HANDSHAKE_TYPE_FAST:
fast_handshake_state_free(state->u.fast);
state->u.fast = NULL;
break;
case ONION_HANDSHAKE_TYPE_NTOR:
ntor_handshake_state_free(state->u.ntor);
state->u.ntor = NULL;
break;
default:
/* LCOV_EXCL_START
* This state should not even exist. */
log_warn(LD_BUG, "called with unknown handshake state type %d",
(int)state->tag);
tor_fragile_assert();
/* LCOV_EXCL_STOP */
}
}
/** Perform the first step of a circuit-creation handshake of type <b>type</b>
* (one of ONION_HANDSHAKE_TYPE_*): generate the initial "onion skin" in
* <b>onion_skin_out</b>, and store any state information in <b>state_out</b>.
* Return -1 on failure, and the length of the onionskin on acceptance.
*/
int
onion_skin_create(int type,
const extend_info_t *node,
onion_handshake_state_t *state_out,
uint8_t *onion_skin_out)
{
int r = -1;
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
if (!node->onion_key)
return -1;
if (onion_skin_TAP_create(node->onion_key,
&state_out->u.tap,
(char*)onion_skin_out) < 0)
return -1;
r = TAP_ONIONSKIN_CHALLENGE_LEN;
break;
case ONION_HANDSHAKE_TYPE_FAST:
if (fast_onionskin_create(&state_out->u.fast, onion_skin_out) < 0)
return -1;
r = CREATE_FAST_LEN;
break;
case ONION_HANDSHAKE_TYPE_NTOR:
if (!extend_info_supports_ntor(node))
return -1;
if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
&node->curve25519_onion_key,
&state_out->u.ntor,
onion_skin_out) < 0)
return -1;
r = NTOR_ONIONSKIN_LEN;
break;
default:
/* LCOV_EXCL_START
* We should never try to create an impossible handshake type. */
log_warn(LD_BUG, "called with unknown handshake state type %d", type);
tor_fragile_assert();
r = -1;
/* LCOV_EXCL_STOP */
}
if (r > 0)
state_out->tag = (uint16_t) type;
return r;
}
/* This is the maximum value for keys_out_len passed to
* onion_skin_server_handshake, plus 16. We can make it bigger if needed:
* It just defines how many bytes to stack-allocate. */
#define MAX_KEYS_TMP_LEN 128
/** Perform the second (server-side) step of a circuit-creation handshake of
* type <b>type</b>, responding to the client request in <b>onion_skin</b>
* using the keys in <b>keys</b>. On success, write our response into
* <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
* in <b>keys_out_len</b>, a hidden service nonce to <b>rend_nonce_out</b>,
* and return the length of the reply. On failure, return -1.
*/
int
onion_skin_server_handshake(int type,
const uint8_t *onion_skin, size_t onionskin_len,
const server_onion_keys_t *keys,
uint8_t *reply_out,
uint8_t *keys_out, size_t keys_out_len,
uint8_t *rend_nonce_out)
{
int r = -1;
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
if (onionskin_len != TAP_ONIONSKIN_CHALLENGE_LEN)
return -1;
if (onion_skin_TAP_server_handshake((const char*)onion_skin,
keys->onion_key, keys->last_onion_key,
(char*)reply_out,
(char*)keys_out, keys_out_len)<0)
return -1;
r = TAP_ONIONSKIN_REPLY_LEN;
memcpy(rend_nonce_out, reply_out+DH1024_KEY_LEN, DIGEST_LEN);
break;
case ONION_HANDSHAKE_TYPE_FAST:
if (onionskin_len != CREATE_FAST_LEN)
return -1;
if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
return -1;
r = CREATED_FAST_LEN;
memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN);
break;
case ONION_HANDSHAKE_TYPE_NTOR:
if (onionskin_len < NTOR_ONIONSKIN_LEN)
return -1;
{
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
if (onion_skin_ntor_server_handshake(
onion_skin, keys->curve25519_key_map,
keys->junk_keypair,
keys->my_identity,
reply_out, keys_tmp, keys_tmp_len)<0) {
/* no need to memwipe here, since the output will never be used */
return -1;
}
memcpy(keys_out, keys_tmp, keys_out_len);
memcpy(rend_nonce_out, keys_tmp+keys_out_len, DIGEST_LEN);
memwipe(keys_tmp, 0, sizeof(keys_tmp));
r = NTOR_REPLY_LEN;
}
break;
default:
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "called with unknown handshake state type %d", type);
tor_fragile_assert();
return -1;
/* LCOV_EXCL_STOP */
}
return r;
}
/** Perform the final (client-side) step of a circuit-creation handshake of
* type <b>type</b>, using our state in <b>handshake_state</b> and the
* server's response in <b>reply</b>. On success, generate <b>keys_out_len</b>
* bytes worth of key material in <b>keys_out_len</b>, set
* <b>rend_authenticator_out</b> to the "KH" field that can be used to
* establish introduction points at this hop, and return 0. On failure,
* return -1, and set *msg_out to an error message if this is worth
* complaining to the user about. */
int
onion_skin_client_handshake(int type,
const onion_handshake_state_t *handshake_state,
const uint8_t *reply, size_t reply_len,
uint8_t *keys_out, size_t keys_out_len,
uint8_t *rend_authenticator_out,
const char **msg_out)
{
if (handshake_state->tag != type)
return -1;
switch (type) {
case ONION_HANDSHAKE_TYPE_TAP:
if (reply_len != TAP_ONIONSKIN_REPLY_LEN) {
if (msg_out)
*msg_out = "TAP reply was not of the correct length.";
return -1;
}
if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
(const char*)reply,
(char *)keys_out, keys_out_len,
msg_out) < 0)
return -1;
memcpy(rend_authenticator_out, reply+DH1024_KEY_LEN, DIGEST_LEN);
return 0;
case ONION_HANDSHAKE_TYPE_FAST:
if (reply_len != CREATED_FAST_LEN) {
if (msg_out)
*msg_out = "TAP reply was not of the correct length.";
return -1;
}
if (fast_client_handshake(handshake_state->u.fast, reply,
keys_out, keys_out_len, msg_out) < 0)
return -1;
memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN);
return 0;
case ONION_HANDSHAKE_TYPE_NTOR:
if (reply_len < NTOR_REPLY_LEN) {
if (msg_out)
*msg_out = "ntor reply was not of the correct length.";
return -1;
}
{
size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
if (onion_skin_ntor_client_handshake(handshake_state->u.ntor,
reply,
keys_tmp, keys_tmp_len, msg_out) < 0) {
tor_free(keys_tmp);
return -1;
}
memcpy(keys_out, keys_tmp, keys_out_len);
memcpy(rend_authenticator_out, keys_tmp + keys_out_len, DIGEST_LEN);
memwipe(keys_tmp, 0, keys_tmp_len);
tor_free(keys_tmp);
}
return 0;
default:
log_warn(LD_BUG, "called with unknown handshake state type %d", type);
tor_fragile_assert();
return -1;
}
}
/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. If
* <b>unknown_ok</b> is true, allow cells with handshake types we don't
* recognize. */

View file

@ -17,47 +17,9 @@ struct curve25519_keypair_t;
struct curve25519_public_key_t;
#include "lib/crypt_ops/crypto_ed25519.h"
int onion_pending_add(or_circuit_t *circ, struct create_cell_t *onionskin);
or_circuit_t *onion_next_task(struct create_cell_t **onionskin_out);
int onion_num_pending(uint16_t handshake_type);
void onion_pending_remove(or_circuit_t *circ);
void clear_pending_onions(void);
typedef struct server_onion_keys_t {
uint8_t my_identity[DIGEST_LEN];
crypto_pk_t *onion_key;
crypto_pk_t *last_onion_key;
struct di_digest256_map_t *curve25519_key_map;
struct curve25519_keypair_t *junk_keypair;
} server_onion_keys_t;
#define MAX_ONIONSKIN_CHALLENGE_LEN 255
#define MAX_ONIONSKIN_REPLY_LEN 255
server_onion_keys_t *server_onion_keys_new(void);
void server_onion_keys_free_(server_onion_keys_t *keys);
#define server_onion_keys_free(keys) \
FREE_AND_NULL(server_onion_keys_t, server_onion_keys_free_, (keys))
void onion_handshake_state_release(onion_handshake_state_t *state);
int onion_skin_create(int type,
const extend_info_t *node,
onion_handshake_state_t *state_out,
uint8_t *onion_skin_out);
int onion_skin_server_handshake(int type,
const uint8_t *onion_skin, size_t onionskin_len,
const server_onion_keys_t *keys,
uint8_t *reply_out,
uint8_t *keys_out, size_t key_out_len,
uint8_t *rend_nonce_out);
int onion_skin_client_handshake(int type,
const onion_handshake_state_t *handshake_state,
const uint8_t *reply, size_t reply_len,
uint8_t *keys_out, size_t key_out_len,
uint8_t *rend_authenticator_out,
const char **msg_out);
/** A parsed CREATE, CREATE_FAST, or CREATE2 cell. */
typedef struct create_cell_t {
/** The cell command. One of CREATE{,_FAST,2} */

View file

@ -67,10 +67,10 @@
#include "feature/relay/dns.h"
#include "feature/stats/geoip.h"
#include "feature/hs/hs_cache.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "core/or/policies.h"
#include "core/or/reasons.h"
#include "core/or/relay.h"

View file

@ -8,7 +8,7 @@
#define SCHEDULER_PRIVATE_
#define SCHEDULER_KIST_PRIVATE
#include "core/or/scheduler.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "lib/container/buffers.h"
#define TOR_CHANNEL_INTERNAL_
#include "core/or/channeltls.h"

View file

@ -22,7 +22,7 @@
#include "core/or/relay.h"
#include "feature/relay/router.h"
#include "core/or/circuitlist.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/stats/rephist.h"
#include "feature/hibernate/hibernate.h"
#include "app/config/statefile.h"

View file

@ -27,7 +27,7 @@
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "feature/control/control.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "feature/control/control_connection_st.h"

View file

@ -127,7 +127,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/dircache/directory.h"
#include "feature/client/entrynodes.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"

View file

@ -65,7 +65,8 @@
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_control.h"
#include "core/mainloop/main.h"
#include "app/main/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"

View file

@ -14,7 +14,7 @@
#include "feature/dirauth/voteflags.h"
#include "app/config/config.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "feature/dirauth/bwauth.h"
#include "feature/dirauth/reachability.h"

View file

@ -30,7 +30,7 @@
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_control.h"
#include "feature/hs/hs_client.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"

View file

@ -38,7 +38,7 @@ hibernating, phase 2:
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/relay/router.h"
#include "app/config/statefile.h"
#include "lib/evloop/compat_libevent.h"

View file

@ -20,7 +20,7 @@
#include "lib/crypt_ops/crypto_ope.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/dircache/directory.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/relay.h"

View file

@ -20,7 +20,7 @@
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "feature/client/bridges.h"
#include "feature/dircache/directory.h"

View file

@ -29,7 +29,7 @@
/* #include "feature/dircache/dirserv.h" */
/* #include "feature/hibernate/hibernate.h" */
/* #include "feature/dirauth/keypin.h" */
/* #include "core/mainloop/main.h" */
/* #include "core/mainloop/mainloop.h" */
/* #include "feature/nodelist/microdesc.h" */
/* #include "feature/nodelist/networkstatus.h" */
/* #include "feature/nodelist/nodelist.h" */

View file

@ -57,7 +57,7 @@
#include "core/or/dos.h"
#include "feature/client/entrynodes.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"

View file

@ -52,7 +52,7 @@
#include "feature/stats/geoip.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_client.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"

View file

@ -64,7 +64,7 @@
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "feature/client/bridges.h"
#include "feature/control/control.h"

View file

@ -58,7 +58,7 @@
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/relay/dns.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/or/policies.h"
#include "core/or/relay.h"
#include "feature/relay/router.h"

View file

@ -25,7 +25,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "feature/relay/ext_orport.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/proto/proto_ext_or.h"
#include "core/or/or_connection_st.h"

View file

@ -0,0 +1,361 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file onion_queue.c
* \brief Functions to queue create cells for processing.
*
* Relays invoke these functions when they receive a CREATE or EXTEND
* cell in command.c or relay.c, in order to queue the pending request.
* They also invoke them from cpuworker.c, which handles dispatching
* onionskin requests to different worker threads.
*
* <br>
*
* This module also handles:
* <ul>
* <li> Queueing incoming onionskins on the relay side before passing
* them to worker threads.
* <li>Expiring onionskins on the relay side if they have waited for
* too long.
* </ul>
**/
#include "core/or/or.h"
#include "feature/relay/onion_queue.h"
#include "app/config/config.h"
#include "core/mainloop/cpuworker.h"
#include "core/or/circuitlist.h"
#include "core/or/onion.h"
#include "feature/nodelist/networkstatus.h"
#include "core/or/or_circuit_st.h"
/** Type for a linked list of circuits that are waiting for a free CPU worker
* to process a waiting onion handshake. */
typedef struct onion_queue_t {
TOR_TAILQ_ENTRY(onion_queue_t) next;
or_circuit_t *circ;
uint16_t handshake_type;
create_cell_t *onionskin;
time_t when_added;
} onion_queue_t;
/** 5 seconds on the onion queue til we just send back a destroy */
#define ONIONQUEUE_WAIT_CUTOFF 5
/** Array of queues of circuits waiting for CPU workers. An element is NULL
* if that queue is empty.*/
static TOR_TAILQ_HEAD(onion_queue_head_t, onion_queue_t)
ol_list[MAX_ONION_HANDSHAKE_TYPE+1] =
{ TOR_TAILQ_HEAD_INITIALIZER(ol_list[0]), /* tap */
TOR_TAILQ_HEAD_INITIALIZER(ol_list[1]), /* fast */
TOR_TAILQ_HEAD_INITIALIZER(ol_list[2]), /* ntor */
};
/** Number of entries of each type currently in each element of ol_list[]. */
static int ol_entries[MAX_ONION_HANDSHAKE_TYPE+1];
static int num_ntors_per_tap(void);
static void onion_queue_entry_remove(onion_queue_t *victim);
/* XXXX Check lengths vs MAX_ONIONSKIN_{CHALLENGE,REPLY}_LEN.
*
* (By which I think I meant, "make sure that no
* X_ONIONSKIN_CHALLENGE/REPLY_LEN is greater than
* MAX_ONIONSKIN_CHALLENGE/REPLY_LEN." Also, make sure that we can pass
* over-large values via EXTEND2/EXTENDED2, for future-compatibility.*/
/** Return true iff we have room to queue another onionskin of type
* <b>type</b>. */
static int
have_room_for_onionskin(uint16_t type)
{
const or_options_t *options = get_options();
int num_cpus;
uint64_t tap_usec, ntor_usec;
uint64_t ntor_during_tap_usec, tap_during_ntor_usec;
/* If we've got fewer than 50 entries, we always have room for one more. */
if (ol_entries[type] < 50)
return 1;
num_cpus = get_num_cpus(options);
/* Compute how many microseconds we'd expect to need to clear all
* onionskins in various combinations of the queues. */
/* How long would it take to process all the TAP cells in the queue? */
tap_usec = estimated_usec_for_onionskins(
ol_entries[ONION_HANDSHAKE_TYPE_TAP],
ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
/* How long would it take to process all the NTor cells in the queue? */
ntor_usec = estimated_usec_for_onionskins(
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
/* How long would it take to process the tap cells that we expect to
* process while draining the ntor queue? */
tap_during_ntor_usec = estimated_usec_for_onionskins(
MIN(ol_entries[ONION_HANDSHAKE_TYPE_TAP],
ol_entries[ONION_HANDSHAKE_TYPE_NTOR] / num_ntors_per_tap()),
ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
/* How long would it take to process the ntor cells that we expect to
* process while draining the tap queue? */
ntor_during_tap_usec = estimated_usec_for_onionskins(
MIN(ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP] * num_ntors_per_tap()),
ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
/* See whether that exceeds MaxOnionQueueDelay. If so, we can't queue
* this. */
if (type == ONION_HANDSHAKE_TYPE_NTOR &&
(ntor_usec + tap_during_ntor_usec) / 1000 >
(uint64_t)options->MaxOnionQueueDelay)
return 0;
if (type == ONION_HANDSHAKE_TYPE_TAP &&
(tap_usec + ntor_during_tap_usec) / 1000 >
(uint64_t)options->MaxOnionQueueDelay)
return 0;
/* If we support the ntor handshake, then don't let TAP handshakes use
* more than 2/3 of the space on the queue. */
if (type == ONION_HANDSHAKE_TYPE_TAP &&
tap_usec / 1000 > (uint64_t)options->MaxOnionQueueDelay * 2 / 3)
return 0;
return 1;
}
/** Add <b>circ</b> to the end of ol_list and return 0, except
* if ol_list is too long, in which case do nothing and return -1.
*/
int
onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
{
onion_queue_t *tmp;
time_t now = time(NULL);
if (onionskin->handshake_type > MAX_ONION_HANDSHAKE_TYPE) {
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "Handshake %d out of range! Dropping.",
onionskin->handshake_type);
return -1;
/* LCOV_EXCL_STOP */
}
tmp = tor_malloc_zero(sizeof(onion_queue_t));
tmp->circ = circ;
tmp->handshake_type = onionskin->handshake_type;
tmp->onionskin = onionskin;
tmp->when_added = now;
if (!have_room_for_onionskin(onionskin->handshake_type)) {
#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
static ratelim_t last_warned =
RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
char *m;
if (onionskin->handshake_type == ONION_HANDSHAKE_TYPE_NTOR &&
(m = rate_limit_log(&last_warned, approx_time()))) {
log_warn(LD_GENERAL,
"Your computer is too slow to handle this many circuit "
"creation requests! Please consider using the "
"MaxAdvertisedBandwidth config option or choosing a more "
"restricted exit policy.%s",m);
tor_free(m);
}
tor_free(tmp);
return -1;
}
++ol_entries[onionskin->handshake_type];
log_info(LD_OR, "New create (%s). Queues now ntor=%d and tap=%d.",
onionskin->handshake_type == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP]);
circ->onionqueue_entry = tmp;
TOR_TAILQ_INSERT_TAIL(&ol_list[onionskin->handshake_type], tmp, next);
/* cull elderly requests. */
while (1) {
onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[onionskin->handshake_type]);
if (now - head->when_added < (time_t)ONIONQUEUE_WAIT_CUTOFF)
break;
circ = head->circ;
circ->onionqueue_entry = NULL;
onion_queue_entry_remove(head);
log_info(LD_CIRC,
"Circuit create request is too old; canceling due to overload.");
if (! TO_CIRCUIT(circ)->marked_for_close) {
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
}
}
return 0;
}
/** Return a fairness parameter, to prefer processing NTOR style
* handshakes but still slowly drain the TAP queue so we don't starve
* it entirely. */
static int
num_ntors_per_tap(void)
{
#define DEFAULT_NUM_NTORS_PER_TAP 10
#define MIN_NUM_NTORS_PER_TAP 1
#define MAX_NUM_NTORS_PER_TAP 100000
return networkstatus_get_param(NULL, "NumNTorsPerTAP",
DEFAULT_NUM_NTORS_PER_TAP,
MIN_NUM_NTORS_PER_TAP,
MAX_NUM_NTORS_PER_TAP);
}
/** Choose which onion queue we'll pull from next. If one is empty choose
* the other; if they both have elements, load balance across them but
* favoring NTOR. */
static uint16_t
decide_next_handshake_type(void)
{
/* The number of times we've chosen ntor lately when both were available. */
static int recently_chosen_ntors = 0;
if (!ol_entries[ONION_HANDSHAKE_TYPE_NTOR])
return ONION_HANDSHAKE_TYPE_TAP; /* no ntors? try tap */
if (!ol_entries[ONION_HANDSHAKE_TYPE_TAP]) {
/* Nick wants us to prioritize new tap requests when there aren't
* any in the queue and we've processed k ntor cells since the last
* tap cell. This strategy is maybe a good idea, since it starves tap
* less in the case where tap is rare, or maybe a poor idea, since it
* makes the new tap cell unfairly jump in front of ntor cells that
* got here first. In any case this edge case will only become relevant
* once tap is rare. We should reevaluate whether we like this decision
* once tap gets more rare. */
if (ol_entries[ONION_HANDSHAKE_TYPE_NTOR] &&
recently_chosen_ntors <= num_ntors_per_tap())
++recently_chosen_ntors;
return ONION_HANDSHAKE_TYPE_NTOR; /* no taps? try ntor */
}
/* They both have something queued. Pick ntor if we haven't done that
* too much lately. */
if (++recently_chosen_ntors <= num_ntors_per_tap()) {
return ONION_HANDSHAKE_TYPE_NTOR;
}
/* Else, it's time to let tap have its turn. */
recently_chosen_ntors = 0;
return ONION_HANDSHAKE_TYPE_TAP;
}
/** Remove the highest priority item from ol_list[] and return it, or
* return NULL if the lists are empty.
*/
or_circuit_t *
onion_next_task(create_cell_t **onionskin_out)
{
or_circuit_t *circ;
uint16_t handshake_to_choose = decide_next_handshake_type();
onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list[handshake_to_choose]);
if (!head)
return NULL; /* no onions pending, we're done */
tor_assert(head->circ);
tor_assert(head->handshake_type <= MAX_ONION_HANDSHAKE_TYPE);
// tor_assert(head->circ->p_chan); /* make sure it's still valid */
/* XXX I only commented out the above line to make the unit tests
* more manageable. That's probably not good long-term. -RD */
circ = head->circ;
if (head->onionskin)
--ol_entries[head->handshake_type];
log_info(LD_OR, "Processing create (%s). Queues now ntor=%d and tap=%d.",
head->handshake_type == ONION_HANDSHAKE_TYPE_NTOR ? "ntor" : "tap",
ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
ol_entries[ONION_HANDSHAKE_TYPE_TAP]);
*onionskin_out = head->onionskin;
head->onionskin = NULL; /* prevent free. */
circ->onionqueue_entry = NULL;
onion_queue_entry_remove(head);
return circ;
}
/** Return the number of <b>handshake_type</b>-style create requests pending.
*/
int
onion_num_pending(uint16_t handshake_type)
{
return ol_entries[handshake_type];
}
/** Go through ol_list, find the onion_queue_t element which points to
* circ, remove and free that element. Leave circ itself alone.
*/
void
onion_pending_remove(or_circuit_t *circ)
{
onion_queue_t *victim;
if (!circ)
return;
victim = circ->onionqueue_entry;
if (victim)
onion_queue_entry_remove(victim);
cpuworker_cancel_circ_handshake(circ);
}
/** Remove a queue entry <b>victim</b> from the queue, unlinking it from
* its circuit and freeing it and any structures it owns.*/
static void
onion_queue_entry_remove(onion_queue_t *victim)
{
if (victim->handshake_type > MAX_ONION_HANDSHAKE_TYPE) {
/* LCOV_EXCL_START
* We should have rejected this far before this point */
log_warn(LD_BUG, "Handshake %d out of range! Dropping.",
victim->handshake_type);
/* XXX leaks */
return;
/* LCOV_EXCL_STOP */
}
TOR_TAILQ_REMOVE(&ol_list[victim->handshake_type], victim, next);
if (victim->circ)
victim->circ->onionqueue_entry = NULL;
if (victim->onionskin)
--ol_entries[victim->handshake_type];
tor_free(victim->onionskin);
tor_free(victim);
}
/** Remove all circuits from the pending list. Called from tor_free_all. */
void
clear_pending_onions(void)
{
onion_queue_t *victim, *next;
int i;
for (i=0; i<=MAX_ONION_HANDSHAKE_TYPE; i++) {
for (victim = TOR_TAILQ_FIRST(&ol_list[i]); victim; victim = next) {
next = TOR_TAILQ_NEXT(victim,next);
onion_queue_entry_remove(victim);
}
tor_assert(TOR_TAILQ_EMPTY(&ol_list[i]));
}
memset(ol_entries, 0, sizeof(ol_entries));
}

View file

@ -0,0 +1,23 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file onion_queue.h
* \brief Header file for onion_queue.c.
**/
#ifndef TOR_ONION_QUEUE_H
#define TOR_ONION_QUEUE_H
struct create_cell_t;
int onion_pending_add(or_circuit_t *circ, struct create_cell_t *onionskin);
or_circuit_t *onion_next_task(struct create_cell_t **onionskin_out);
int onion_num_pending(uint16_t handshake_type);
void onion_pending_remove(or_circuit_t *circ);
void clear_pending_onions(void);
#endif

View file

@ -22,7 +22,8 @@
#include "feature/relay/dns.h"
#include "feature/stats/geoip.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/main.h"
#include "app/main/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"

View file

@ -23,7 +23,7 @@
#include "feature/hs/hs_circuit.h"
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_common.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/relay.h"

View file

@ -22,7 +22,7 @@
#include "feature/dircache/directory.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_config.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"

View file

@ -11,7 +11,6 @@
#include "orconfig.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "app/config/or_state_st.h"
#include <stdio.h>
@ -33,7 +32,7 @@
#define ROUTER_PRIVATE
#define CIRCUITSTATS_PRIVATE
#define CIRCUITLIST_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#define STATEFILE_PRIVATE
#include "core/or/or.h"
@ -47,9 +46,9 @@
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendcache.h"
#include "test/test.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "lib/memarea/memarea.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "core/crypto/onion_ntor.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_tap.h"
@ -64,6 +63,7 @@
#include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
#include "feature/rend/rend_intro_point_st.h"
#include "feature/rend/rend_service_descriptor_st.h"
#include "feature/relay/onion_queue.h"
/** Run unit tests for the onion handshake code. */
static void

View file

@ -13,7 +13,7 @@
#include "core/or/connection_or.h"
#include "app/config/config.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "core/crypto/onion_tap.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_ntor.h"

View file

@ -2,7 +2,7 @@
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define TOR_TIMERS_PRIVATE
#include "core/or/or.h"
@ -16,7 +16,7 @@
#include "lib/evloop/compat_libevent.h"
#include "app/config/config.h"
#include "lib/time/compat_time.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "test/log_test_helpers.h"
#include "lib/tls/tortls.h"

View file

@ -31,7 +31,7 @@
#include "feature/relay/ext_orport.h"
#include "feature/stats/geoip.h"
#include "feature/hibernate/hibernate.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"

View file

@ -4,7 +4,7 @@
#include "orconfig.h"
#define CONNECTION_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#define CONNECTION_OR_PRIVATE
#include "core/or/or.h"
@ -13,7 +13,7 @@
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "feature/hs/hs_common.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/networkstatus.h"

View file

@ -3,7 +3,7 @@
#define CONNECTION_PRIVATE
#define EXT_ORPORT_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#include "core/or/or.h"
#include "lib/container/buffers.h"
#include "core/mainloop/connection.h"
@ -12,7 +12,7 @@
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/relay/ext_orport.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/or/or_connection_st.h"
@ -463,7 +463,7 @@ test_ext_or_handshake(void *arg)
memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
ext_or_auth_cookie_is_set = 1;
init_connection_lists();
tor_init_connection_lists();
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));

View file

@ -9,7 +9,7 @@
#define ROUTERLIST_PRIVATE
#define CONFIG_PRIVATE
#define CONNECTION_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#include "orconfig.h"
#include "core/or/or.h"
@ -19,7 +19,7 @@
#include "app/config/confparse.h"
#include "core/mainloop/connection.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/relay.h"
#include "feature/nodelist/routerlist.h"
@ -217,7 +217,7 @@ test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose)
mock_connection_connect_sockaddr);
MOCK(tor_close_socket, fake_close_socket);
init_connection_lists();
tor_init_connection_lists();
conn = connection_new(type, TEST_CONN_FAMILY);
tt_assert(conn);

View file

@ -8,7 +8,7 @@
#define CONFIG_PRIVATE
#define CRYPTO_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#define HS_CLIENT_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITBUILD_PRIVATE
@ -26,7 +26,7 @@
#include "lib/crypt_ops/crypto_dh.h"
#include "core/or/channeltls.h"
#include "feature/dircache/directory.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"

View file

@ -15,7 +15,7 @@
#define HS_SERVICE_PRIVATE
#define HS_INTROPOINT_PRIVATE
#define HS_CIRCUIT_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define STATEFILE_PRIVATE
#define TOR_CHANNEL_INTERNAL_
@ -49,7 +49,7 @@
#include "feature/hs/hs_circuitmap.h"
#include "feature/hs/hs_service.h"
#include "feature/hs/hs_client.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/rend/rendservice.h"
#include "app/config/statefile.h"
#include "feature/dirauth/shared_random_state.h"

View file

@ -10,7 +10,7 @@
#include "test/log_test_helpers.h"
#include "core/or/or.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
static const uint64_t BILLION = 1000000000;

View file

@ -10,7 +10,7 @@
#include "core/mainloop/connection.h"
#include "core/or/connection_or.h"
#include "feature/dircache/directory.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "test/test.h"
#include "feature/dircommon/dir_connection_st.h"

View file

@ -12,7 +12,7 @@
#define ROUTERSET_PRIVATE
#include "feature/nodelist/routerset.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "test/log_test_helpers.h"
#include "lib/sandbox/sandbox.h"

View file

@ -9,7 +9,7 @@
#define CONFIG_PRIVATE
#define HS_SERVICE_PRIVATE
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#include "test/test.h"
#include "test/test_helpers.h"
@ -18,7 +18,7 @@
#include "app/config/config.h"
#include "feature/hibernate/hibernate.h"
#include "feature/hs/hs_service.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/periodic.h"
/** Helper function: This is replaced in some tests for the event callbacks so

View file

@ -6,7 +6,7 @@
#define RELAY_PRIVATE
#define CIRCUITLIST_PRIVATE
#include "core/or/or.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "lib/crypt_ops/crypto_cipher.h"

View file

@ -9,7 +9,7 @@
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist.h"

View file

@ -21,7 +21,7 @@
#include "feature/stats/rephist.h"
#include "core/or/relay.h"
#include "feature/relay/router.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "app/config/statefile.h"
#include "lib/tls/tortls.h"

View file

@ -5,7 +5,7 @@
#include "core/or/or.h"
#include "lib/thread/threads.h"
#include "core/crypto/onion.h"
#include "core/or/onion.h"
#include "lib/evloop/workqueue.h"
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_rand.h"

View file

@ -8,7 +8,7 @@
* \brief Common pieces to implement unit tests.
**/
#define MAIN_PRIVATE
#define MAINLOOP_PRIVATE
#include "orconfig.h"
#include "core/or/or.h"
#include "feature/control/control.h"
@ -20,7 +20,7 @@
#include "lib/err/backtrace.h"
#include "test/test.h"
#include "core/or/channelpadding.h"
#include "core/mainloop/main.h"
#include "core/mainloop/mainloop.h"
#include "lib/compress/compress.h"
#include "lib/evloop/compat_libevent.h"
#include "lib/crypt_ops/crypto_init.h"

View file

@ -6,7 +6,7 @@
#include <string.h>
#include <time.h>
#include "ed25519_cert.h"
#include "trunnel/ed25519_cert.h"
#include "lib/cc/torint.h" /* TOR_PRIdSZ */
#include "lib/crypt_ops/crypto_format.h"
#include "lib/malloc/malloc.h"