diff --git a/changes/split_or_h b/changes/split_or_h new file mode 100644 index 0000000000..53d54ca6dd --- /dev/null +++ b/changes/split_or_h @@ -0,0 +1,5 @@ + o Code simplification and refactoring: + - Many structures have been removed from the centralized "or.h" header, + and moved into their own headers. This will allow us to reduce + the number of places in the code that rely on each structure's + contents and layout. Closes ticket 26383. diff --git a/src/or/addressmap.c b/src/or/addressmap.c index 7f861e4d24..9808b7bdd7 100644 --- a/src/or/addressmap.c +++ b/src/or/addressmap.c @@ -26,6 +26,8 @@ #include "nodelist.h" #include "routerset.h" +#include "entry_connection_st.h" + /** A client-side struct to remember requests to rewrite addresses * to new addresses. These structs are stored in the hash table * "addressmap" below. diff --git a/src/or/authority_cert_st.h b/src/or/authority_cert_st.h new file mode 100644 index 0000000000..bc274a1c62 --- /dev/null +++ b/src/or/authority_cert_st.h @@ -0,0 +1,32 @@ +/* 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 AUTHORITY_CERT_ST_H +#define AUTHORITY_CERT_ST_H + +#include "signed_descriptor_st.h" + +/** Certificate for v3 directory protocol: binds long-term authority identity + * keys to medium-term authority signing keys. */ +struct authority_cert_t { + /** Information relating to caching this cert on disk and looking it up. */ + signed_descriptor_t cache_info; + /** This authority's long-term authority identity key. */ + crypto_pk_t *identity_key; + /** This authority's medium-term signing key. */ + crypto_pk_t *signing_key; + /** The digest of signing_key */ + char signing_key_digest[DIGEST_LEN]; + /** The listed expiration time of this certificate. */ + time_t expires; + /** This authority's IPv4 address, in host order. */ + uint32_t addr; + /** This authority's directory port. */ + uint16_t dir_port; +}; + +#endif + diff --git a/src/or/bridges.c b/src/or/bridges.c index 699e030e6c..793f292a54 100644 --- a/src/or/bridges.c +++ b/src/or/bridges.c @@ -27,6 +27,11 @@ #include "routerset.h" #include "transports.h" +#include "extend_info_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + /** Information about a configured bridge. Currently this just matches the * ones in the torrc file, but one day we may be able to learn about new * bridges on our own, and remember them in the state file. */ diff --git a/src/or/cached_dir_st.h b/src/or/cached_dir_st.h new file mode 100644 index 0000000000..4f930b6fb9 --- /dev/null +++ b/src/or/cached_dir_st.h @@ -0,0 +1,25 @@ +/* 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 CACHED_DIR_ST_H +#define CACHED_DIR_ST_H + +/** A cached_dir_t represents a cacheable directory object, along with its + * compressed form. */ +struct cached_dir_t { + char *dir; /**< Contents of this object, NUL-terminated. */ + char *dir_compressed; /**< Compressed contents of this object. */ + size_t dir_len; /**< Length of dir (not counting its NUL). */ + size_t dir_compressed_len; /**< Length of dir_compressed. */ + time_t published; /**< When was this object published. */ + common_digests_t digests; /**< Digests of this object (networkstatus only) */ + /** Sha3 digest (also ns only) */ + uint8_t digest_sha3_as_signed[DIGEST256_LEN]; + int refcnt; /**< Reference count for this cached_dir_t. */ +}; + +#endif + diff --git a/src/or/cell_queue_st.h b/src/or/cell_queue_st.h new file mode 100644 index 0000000000..6c429eacce --- /dev/null +++ b/src/or/cell_queue_st.h @@ -0,0 +1,28 @@ +/* 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 PACKED_CELL_ST_H +#define PACKED_CELL_ST_H + +/** A cell as packed for writing to the network. */ +struct packed_cell_t { + /** Next cell queued on this circuit. */ + TOR_SIMPLEQ_ENTRY(packed_cell_t) next; + char body[CELL_MAX_NETWORK_SIZE]; /**< Cell as packed for network. */ + uint32_t inserted_timestamp; /**< Time (in timestamp units) when this cell + * was inserted */ +}; + +/** A queue of cells on a circuit, waiting to be added to the + * or_connection_t's outbuf. */ +struct cell_queue_t { + /** Linked list of packed_cell_t*/ + TOR_SIMPLEQ_HEAD(cell_simpleq, packed_cell_t) head; + int n; /**< The number of cells in the queue. */ +}; + +#endif + diff --git a/src/or/cell_st.h b/src/or/cell_st.h new file mode 100644 index 0000000000..08ed290871 --- /dev/null +++ b/src/or/cell_st.h @@ -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 CELL_ST_H +#define CELL_ST_H + +/** Parsed onion routing cell. All communication between nodes + * is via cells. */ +struct cell_t { + circid_t circ_id; /**< Circuit which received the cell. */ + uint8_t command; /**< Type of the cell: one of CELL_PADDING, CELL_CREATE, + * CELL_DESTROY, etc */ + uint8_t payload[CELL_PAYLOAD_SIZE]; /**< Cell body. */ +}; + +#endif + diff --git a/src/or/channel.c b/src/or/channel.c index c30e508018..d53e0d2e3f 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -80,6 +80,8 @@ #include "networkstatus.h" #include "rendservice.h" +#include "cell_queue_st.h" + /* Global lists of channels */ /* All channel_t instances */ diff --git a/src/or/channelpadding.c b/src/or/channelpadding.c index a8b9a2b47b..e3aa2dc103 100644 --- a/src/or/channelpadding.c +++ b/src/or/channelpadding.c @@ -23,6 +23,9 @@ #include "compat_time.h" #include "rendservice.h" +#include "cell_st.h" +#include "or_connection_st.h" + STATIC int32_t channelpadding_get_netflow_inactive_timeout_ms( const channel_t *); STATIC int channelpadding_send_disable_command(channel_t *); diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 54d94f6109..c345364cde 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -60,6 +60,15 @@ #include "channelpadding_negotiation.h" #include "channelpadding.h" +#include "cell_st.h" +#include "cell_queue_st.h" +#include "extend_info_st.h" +#include "or_connection_st.h" +#include "or_handshake_certs_st.h" +#include "or_handshake_state_st.h" +#include "routerinfo_st.h" +#include "var_cell_st.h" + /** How many CELL_PADDING cells have we received, ever? */ uint64_t stats_n_padding_cells_processed = 0; /** How many CELL_VERSIONS cells have we received, ever? */ diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c index ff42bf91e4..6586fe4472 100644 --- a/src/or/circpathbias.c +++ b/src/or/circpathbias.c @@ -35,6 +35,12 @@ #include "networkstatus.h" #include "relay.h" +#include "cell_st.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "extend_info_st.h" +#include "origin_circuit_st.h" + static void pathbias_count_successful_close(origin_circuit_t *circ); static void pathbias_count_collapse(origin_circuit_t *circ); static void pathbias_count_use_failed(origin_circuit_t *circ); diff --git a/src/or/circuit_st.h b/src/or/circuit_st.h new file mode 100644 index 0000000000..f977d542dd --- /dev/null +++ b/src/or/circuit_st.h @@ -0,0 +1,172 @@ +/* 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 CIRCUIT_ST_H +#define CIRCUIT_ST_H + +#include "or.h" + +#include "cell_queue_st.h" + +/** + * A circuit is a path over the onion routing + * network. Applications can connect to one end of the circuit, and can + * create exit connections at the other end of the circuit. AP and exit + * connections have only one circuit associated with them (and thus these + * connection types are closed when the circuit is closed), whereas + * OR connections multiplex many circuits at once, and stay standing even + * when there are no circuits running over them. + * + * A circuit_t structure can fill one of two roles. First, a or_circuit_t + * links two connections together: either an edge connection and an OR + * connection, or two OR connections. (When joined to an OR connection, a + * circuit_t affects only cells sent to a particular circID on that + * connection. When joined to an edge connection, a circuit_t affects all + * data.) + + * Second, an origin_circuit_t holds the cipher keys and state for sending data + * along a given circuit. At the OP, it has a sequence of ciphers, each + * of which is shared with a single OR along the circuit. Separate + * ciphers are used for data going "forward" (away from the OP) and + * "backward" (towards the OP). At the OR, a circuit has only two stream + * ciphers: one for data going forward, and one for data going backward. + */ +struct circuit_t { + uint32_t magic; /**< For memory and type debugging: must equal + * ORIGIN_CIRCUIT_MAGIC or OR_CIRCUIT_MAGIC. */ + + /** The channel that is next in this circuit. */ + channel_t *n_chan; + + /** + * The circuit_id used in the next (forward) hop of this circuit; + * this is unique to n_chan, but this ordered pair is globally + * unique: + * + * (n_chan->global_identifier, n_circ_id) + */ + circid_t n_circ_id; + + /** + * Circuit mux associated with n_chan to which this circuit is attached; + * NULL if we have no n_chan. + */ + circuitmux_t *n_mux; + + /** Queue of cells waiting to be transmitted on n_chan */ + cell_queue_t n_chan_cells; + + /** + * The hop to which we want to extend this circuit. Should be NULL if + * the circuit has attached to a channel. + */ + extend_info_t *n_hop; + + /** True iff we are waiting for n_chan_cells to become less full before + * allowing p_streams to add any more cells. (Origin circuit only.) */ + unsigned int streams_blocked_on_n_chan : 1; + /** True iff we are waiting for p_chan_cells to become less full before + * allowing n_streams to add any more cells. (OR circuit only.) */ + unsigned int streams_blocked_on_p_chan : 1; + + /** True iff we have queued a delete backwards on this circuit, but not put + * it on the output buffer. */ + unsigned int p_delete_pending : 1; + /** True iff we have queued a delete forwards on this circuit, but not put + * it on the output buffer. */ + unsigned int n_delete_pending : 1; + + /** True iff this circuit has received a DESTROY cell in either direction */ + unsigned int received_destroy : 1; + + uint8_t state; /**< Current status of this circuit. */ + uint8_t purpose; /**< Why are we creating this circuit? */ + + /** How many relay data cells can we package (read from edge streams) + * on this circuit before we receive a circuit-level sendme cell asking + * for more? */ + int package_window; + /** How many relay data cells will we deliver (write to edge streams) + * on this circuit? When deliver_window gets low, we send some + * circuit-level sendme cells to indicate that we're willing to accept + * more. */ + int deliver_window; + + /** Temporary field used during circuits_handle_oom. */ + uint32_t age_tmp; + + /** For storage while n_chan is pending (state CIRCUIT_STATE_CHAN_WAIT). */ + struct create_cell_t *n_chan_create_cell; + + /** When did circuit construction actually begin (ie send the + * CREATE cell or begin cannibalization). + * + * Note: This timer will get reset if we decide to cannibalize + * a circuit. It may also get reset during certain phases of hidden + * service circuit use. + * + * We keep this timestamp with a higher resolution than most so that the + * circuit-build-time tracking code can get millisecond resolution. + */ + struct timeval timestamp_began; + + /** This timestamp marks when the init_circuit_base constructor ran. */ + struct timeval timestamp_created; + + /** When the circuit was first used, or 0 if the circuit is clean. + * + * XXXX Note that some code will artificially adjust this value backward + * in time in order to indicate that a circuit shouldn't be used for new + * streams, but that it can stay alive as long as it has streams on it. + * That's a kludge we should fix. + * + * XXX The CBT code uses this field to record when HS-related + * circuits entered certain states. This usage probably won't + * interfere with this field's primary purpose, but we should + * document it more thoroughly to make sure of that. + * + * XXX The SocksPort option KeepaliveIsolateSOCKSAuth will artificially + * adjust this value forward each time a suitable stream is attached to an + * already constructed circuit, potentially keeping the circuit alive + * indefinitely. + */ + time_t timestamp_dirty; + + uint16_t marked_for_close; /**< Should we close this circuit at the end of + * the main loop? (If true, holds the line number + * where this circuit was marked.) */ + const char *marked_for_close_file; /**< For debugging: in which file was this + * circuit marked for close? */ + /** For what reason (See END_CIRC_REASON...) is this circuit being closed? + * This field is set in circuit_mark_for_close and used later in + * circuit_about_to_free. */ + int marked_for_close_reason; + /** As marked_for_close_reason, but reflects the underlying reason for + * closing this circuit. + */ + int marked_for_close_orig_reason; + + /** Unique ID for measuring tunneled network status requests. */ + uint64_t dirreq_id; + + /** Index in smartlist of all circuits (global_circuitlist). */ + int global_circuitlist_idx; + + /** Various statistics about cells being added to or removed from this + * circuit's queues; used only if CELL_STATS events are enabled and + * cleared after being sent to control port. */ + smartlist_t *testing_cell_stats; + + /** If set, points to an HS token that this circuit might be carrying. + * Used by the HS circuitmap. */ + hs_token_t *hs_token; + /** Hashtable node: used to look up the circuit by its HS token using the HS + circuitmap. */ + HT_ENTRY(circuit_t) hs_circuitmap_node; +}; + +#endif + diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 3d1c9c1abf..dfe293d4e7 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -65,6 +65,17 @@ #include "routerset.h" #include "transports.h" +#include "cell_st.h" +#include "cpath_build_state_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "node_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" +#include "microdesc_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + static channel_t * channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port, const char *id_digest, diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 45fff7cc17..95463fde38 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -67,6 +67,7 @@ #include "control.h" #include "crypto_rand.h" #include "crypto_util.h" +#include "directory.h" #include "entrynodes.h" #include "main.h" #include "hs_circuit.h" @@ -91,6 +92,14 @@ #include "ht.h" +#include "cpath_build_state_st.h" +#include "crypt_path_reference_st.h" +#include "dir_connection_st.h" +#include "edge_connection_st.h" +#include "extend_info_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + /********* START VARIABLES **********/ /** A global list of all circuits at this hop. */ @@ -126,6 +135,31 @@ static int any_opened_circs_cached_val = 0; /********* END VARIABLES ************/ +or_circuit_t * +TO_OR_CIRCUIT(circuit_t *x) +{ + tor_assert(x->magic == OR_CIRCUIT_MAGIC); + return DOWNCAST(or_circuit_t, x); +} +const or_circuit_t * +CONST_TO_OR_CIRCUIT(const circuit_t *x) +{ + tor_assert(x->magic == OR_CIRCUIT_MAGIC); + return DOWNCAST(or_circuit_t, x); +} +origin_circuit_t * +TO_ORIGIN_CIRCUIT(circuit_t *x) +{ + tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC); + return DOWNCAST(origin_circuit_t, x); +} +const origin_circuit_t * +CONST_TO_ORIGIN_CIRCUIT(const circuit_t *x) +{ + tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC); + return DOWNCAST(origin_circuit_t, x); +} + /** A map from channel and circuit ID to circuit. (Lookup performance is * very important here, since we need to do it every time a cell arrives.) */ typedef struct chan_circid_circuit_map_t { diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index 246f0c8815..8eb6fefbfe 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -15,6 +15,15 @@ #include "testsupport.h" #include "hs_ident.h" +/** Convert a circuit_t* to a pointer to the enclosing or_circuit_t. Assert + * if the cast is impossible. */ +or_circuit_t *TO_OR_CIRCUIT(circuit_t *); +const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *); +/** Convert a circuit_t* to a pointer to the enclosing origin_circuit_t. + * Assert if the cast is impossible. */ +origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *); +const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT(const circuit_t *); + MOCK_DECL(smartlist_t *, circuit_get_global_list, (void)); smartlist_t *circuit_get_global_origin_circuit_list(void); int circuit_any_opened_circuits(void); diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c index f9f5faa057..e073311753 100644 --- a/src/or/circuitmux.c +++ b/src/or/circuitmux.c @@ -75,6 +75,10 @@ #include "circuitmux.h" #include "relay.h" +#include "cell_queue_st.h" +#include "destroy_cell_queue_st.h" +#include "or_circuit_st.h" + /* * Private typedefs for circuitmux.c */ diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c index 94f75c590f..f1660090f0 100644 --- a/src/or/circuitstats.c +++ b/src/or/circuitstats.c @@ -41,6 +41,9 @@ #include "circuitlist.h" #include "circuituse.h" +#include "crypt_path_st.h" +#include "origin_circuit_st.h" + #undef log #include diff --git a/src/or/circuitstats.h b/src/or/circuitstats.h index 86116cb7f8..5fe80acfea 100644 --- a/src/or/circuitstats.h +++ b/src/or/circuitstats.h @@ -73,6 +73,21 @@ int circuit_build_times_network_check_live(const circuit_build_times_t *cbt); void circuit_build_times_network_circ_success(circuit_build_times_t *cbt); #ifdef CIRCUITSTATS_PRIVATE +/** Information about the state of our local network connection */ +typedef struct { + /** The timestamp we last completed a TLS handshake or received a cell */ + time_t network_last_live; + /** If the network is not live, how many timeouts has this caused? */ + int nonlive_timeouts; + /** Circular array of circuits that have made it to the first hop. Slot is + * 1 if circuit timed out, 0 if circuit succeeded */ + int8_t *timeouts_after_firsthop; + /** Number of elements allocated for the above array */ + int num_recent_circs; + /** Index into circular array. */ + int after_firsthop_idx; +} network_liveness_t; + /** Structure for circuit build times history */ struct circuit_build_times_s { /** The circular array of recorded build times in milliseconds */ diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 8e007ce920..60ffe95b1b 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -40,6 +40,7 @@ #include "connection.h" #include "connection_edge.h" #include "control.h" +#include "directory.h" #include "entrynodes.h" #include "hs_common.h" #include "hs_client.h" @@ -56,6 +57,14 @@ #include "router.h" #include "routerlist.h" +#include "cpath_build_state_st.h" +#include "dir_connection_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" +#include "socks_request_st.h" + static void circuit_expire_old_circuits_clientside(void); static void circuit_increment_failure_count(void); diff --git a/src/or/command.c b/src/or/command.c index 39950f41bf..39136966ec 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -56,6 +56,11 @@ #include "router.h" #include "routerlist.h" +#include "cell_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" +#include "var_cell_st.h" + /** How many CELL_CREATE cells have we received, ever? */ uint64_t stats_n_create_cells_processed = 0; /** How many CELL_CREATED cells have we received, ever? */ diff --git a/src/or/config.c b/src/or/config.c index 94a58f3488..ca495aa974 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -116,6 +116,9 @@ #include "dirauth/dirvote.h" #include "dirauth/mode.h" +#include "connection_st.h" +#include "port_cfg_st.h" + #ifdef HAVE_SYSTEMD # if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse diff --git a/src/or/connection.c b/src/or/connection.c index 5185b45b14..6e133f8d4d 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -113,6 +113,15 @@ #include #endif +#include "dir_connection_st.h" +#include "control_connection_st.h" +#include "entry_connection_st.h" +#include "listener_connection_st.h" +#include "or_connection_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" +#include "socks_request_st.h" + static connection_t *connection_listener_new( const struct sockaddr *listensockaddr, socklen_t listensocklen, int type, @@ -167,6 +176,27 @@ static smartlist_t *outgoing_addrs = NULL; /**************************************************************/ +/** Convert a connection_t* to an listener_connection_t*; assert if the cast + * is invalid. */ +listener_connection_t * +TO_LISTENER_CONN(connection_t *c) +{ + tor_assert(c->magic == LISTENER_CONNECTION_MAGIC); + return DOWNCAST(listener_connection_t, c); +} + +size_t +connection_get_inbuf_len(connection_t *conn) +{ + return conn->inbuf ? buf_datalen(conn->inbuf) : 0; +} + +size_t +connection_get_outbuf_len(connection_t *conn) +{ + return conn->outbuf ? buf_datalen(conn->outbuf) : 0; +} + /** * Return the human-readable name for the connection type type */ @@ -4108,6 +4138,13 @@ connection_write_to_buf_impl_,(const char *string, size_t len, connection_write_to_buf_commit(conn, written); } +void +connection_buf_add_compress(const char *string, size_t len, + dir_connection_t *conn, int done) +{ + connection_write_to_buf_impl_(string, len, TO_CONN(conn), done ? -1 : 1); +} + /** * Add all bytes from buf to conn's outbuf, draining them * from buf. (If the connection is marked and will soon be closed, @@ -4812,6 +4849,20 @@ kill_conn_list_for_oos, (smartlist_t *conns)) smartlist_len(conns)); } +/** Check if a connection is on the way out so the OOS handler doesn't try + * to kill more than it needs. */ +int +connection_is_moribund(connection_t *conn) +{ + if (conn != NULL && + (conn->conn_array_index < 0 || + conn->marked_for_close)) { + return 1; + } else { + return 0; + } +} + /** Out-of-Sockets handler; n_socks is the current number of open * sockets, and failed is non-zero if a socket exhaustion related * error immediately preceded this call. This is where to do diff --git a/src/or/connection.h b/src/or/connection.h index ad3129c9d8..0ab8962b41 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -12,6 +12,8 @@ #ifndef TOR_CONNECTION_H #define TOR_CONNECTION_H +listener_connection_t *TO_LISTENER_CONN(connection_t *); + /* XXXX For buf_datalen in inline function */ #include "buffers.h" @@ -150,39 +152,17 @@ MOCK_DECL(void, connection_write_to_buf_impl_, /* DOCDOC connection_write_to_buf */ static void connection_buf_add(const char *string, size_t len, connection_t *conn); -/* DOCDOC connection_write_to_buf_compress */ -static void connection_buf_add_compress(const char *string, size_t len, - dir_connection_t *conn, int done); static inline void connection_buf_add(const char *string, size_t len, connection_t *conn) { connection_write_to_buf_impl_(string, len, conn, 0); } -static inline void -connection_buf_add_compress(const char *string, size_t len, - dir_connection_t *conn, int done) -{ - connection_write_to_buf_impl_(string, len, TO_CONN(conn), done ? -1 : 1); -} +void connection_buf_add_compress(const char *string, size_t len, + dir_connection_t *conn, int done); void connection_buf_add_buf(connection_t *conn, buf_t *buf); -/* DOCDOC connection_get_inbuf_len */ -static size_t connection_get_inbuf_len(connection_t *conn); -/* DOCDOC connection_get_outbuf_len */ -static size_t connection_get_outbuf_len(connection_t *conn); - -static inline size_t -connection_get_inbuf_len(connection_t *conn) -{ - return conn->inbuf ? buf_datalen(conn->inbuf) : 0; -} - -static inline size_t -connection_get_outbuf_len(connection_t *conn) -{ - return conn->outbuf ? buf_datalen(conn->outbuf) : 0; -} - +size_t connection_get_inbuf_len(connection_t *conn); +size_t connection_get_outbuf_len(connection_t *conn); connection_t *connection_get_by_global_id(uint64_t id); connection_t *connection_get_by_type(int type); @@ -259,20 +239,7 @@ MOCK_DECL(void, clock_skew_warning, log_domain_mask_t domain, const char *received, const char *source)); -/** Check if a connection is on the way out so the OOS handler doesn't try - * to kill more than it needs. */ -static inline int -connection_is_moribund(connection_t *conn) -{ - if (conn != NULL && - (conn->conn_array_index < 0 || - conn->marked_for_close)) { - return 1; - } else { - return 0; - } -} - +int connection_is_moribund(connection_t *conn); void connection_check_oos(int n_socks, int failed); #ifdef CONNECTION_PRIVATE diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 046369af60..7ceb97e7cc 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -97,6 +97,16 @@ #include "routerset.h" #include "circuitbuild.h" +#include "cell_st.h" +#include "cpath_build_state_st.h" +#include "dir_connection_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "node_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" +#include "socks_request_st.h" + #ifdef HAVE_LINUX_TYPES_H #include #endif @@ -137,6 +147,30 @@ static int connection_exit_connect_dir(edge_connection_t *exitconn); static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port); static int connection_ap_supports_optimistic_data(const entry_connection_t *); +/** Convert a connection_t* to an edge_connection_t*; assert if the cast is + * invalid. */ +edge_connection_t * +TO_EDGE_CONN(connection_t *c) +{ + tor_assert(c->magic == EDGE_CONNECTION_MAGIC || + c->magic == ENTRY_CONNECTION_MAGIC); + return DOWNCAST(edge_connection_t, c); +} + +entry_connection_t * +TO_ENTRY_CONN(connection_t *c) +{ + tor_assert(c->magic == ENTRY_CONNECTION_MAGIC); + return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_.base_); +} + +entry_connection_t * +EDGE_TO_ENTRY_CONN(edge_connection_t *c) +{ + tor_assert(c->base_.magic == ENTRY_CONNECTION_MAGIC); + return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_); +} + /** An AP stream has failed/finished. If it hasn't already sent back * a socks reply, send one now (based on endreason). Also set * has_sent_end to 1, and mark the conn. diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index c6583d3845..27d2c8614f 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -14,7 +14,11 @@ #include "testsupport.h" -#define connection_mark_unattached_ap(conn, endreason) \ +edge_connection_t *TO_EDGE_CONN(connection_t *); +entry_connection_t *TO_ENTRY_CONN(connection_t *); +entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *); + +#define connection_mark_unattached_ap(conn, endreason) \ connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__) MOCK_DECL(void,connection_mark_unattached_ap_, diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 7898fbd42e..bbd6fa0edc 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -61,6 +61,14 @@ #include "torcert.h" #include "channelpadding.h" +#include "cell_st.h" +#include "cell_queue_st.h" +#include "or_connection_st.h" +#include "or_handshake_certs_st.h" +#include "or_handshake_state_st.h" +#include "routerinfo_st.h" +#include "var_cell_st.h" + static int connection_tls_finish_handshake(or_connection_t *conn); static int connection_or_launch_v3_or_handshake(or_connection_t *conn); static int connection_or_process_cells_from_inbuf(or_connection_t *conn); @@ -86,6 +94,15 @@ static void connection_or_check_canonicity(or_connection_t *conn, /**************************************************************/ +/** Convert a connection_t* to an or_connection_t*; assert if the cast is + * invalid. */ +or_connection_t * +TO_OR_CONN(connection_t *c) +{ + tor_assert(c->magic == OR_CONNECTION_MAGIC); + return DOWNCAST(or_connection_t, c); +} + /** Global map between Extended ORPort identifiers and OR * connections. */ static digestmap_t *orconn_ext_or_id_map = NULL; diff --git a/src/or/connection_or.h b/src/or/connection_or.h index 158eb1fdad..4251aacab7 100644 --- a/src/or/connection_or.h +++ b/src/or/connection_or.h @@ -12,6 +12,8 @@ #ifndef TOR_CONNECTION_OR_H #define TOR_CONNECTION_OR_H +or_connection_t *TO_OR_CONN(connection_t *); + void connection_or_clear_identity(or_connection_t *conn); void connection_or_clear_identity_map(void); void clear_broken_connection_map(int disable); diff --git a/src/or/connection_st.h b/src/or/connection_st.h new file mode 100644 index 0000000000..b65238693f --- /dev/null +++ b/src/or/connection_st.h @@ -0,0 +1,132 @@ +/* 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 CONNECTION_ST_H +#define CONNECTION_ST_H + +struct buf_t; + +/** Description of a connection to another host or process, and associated + * data. + * + * A connection is named based on what it's connected to -- an "OR + * connection" has a Tor node on the other end, an "exit + * connection" has a website or other server on the other end, and an + * "AP connection" has an application proxy (and thus a user) on the + * other end. + * + * Every connection has a type and a state. Connections never change + * their type, but can go through many state changes in their lifetime. + * + * Every connection has two associated input and output buffers. + * Listeners don't use them. For non-listener connections, incoming + * data is appended to conn->inbuf, and outgoing data is taken from + * conn->outbuf. Connections differ primarily in the functions called + * to fill and drain these buffers. + */ +typedef struct connection_t { + uint32_t magic; /**< For memory debugging: must equal one of + * *_CONNECTION_MAGIC. */ + + uint8_t state; /**< Current state of this connection. */ + unsigned int type:5; /**< What kind of connection is this? */ + unsigned int purpose:5; /**< Only used for DIR and EXIT types currently. */ + + /* The next fields are all one-bit booleans. Some are only applicable to + * connection subtypes, but we hold them here anyway, to save space. + */ + unsigned int read_blocked_on_bw:1; /**< Boolean: should we start reading + * again once the bandwidth throttler allows it? */ + unsigned int write_blocked_on_bw:1; /**< Boolean: should we start writing + * again once the bandwidth throttler allows + * writes? */ + unsigned int hold_open_until_flushed:1; /**< Despite this connection's being + * marked for close, do we flush it + * before closing it? */ + unsigned int inbuf_reached_eof:1; /**< Boolean: did read() return 0 on this + * conn? */ + /** Set to 1 when we're inside connection_flushed_some to keep us from + * calling connection_handle_write() recursively. */ + unsigned int in_flushed_some:1; + /** True if connection_handle_write is currently running on this connection. + */ + unsigned int in_connection_handle_write:1; + + /* For linked connections: + */ + unsigned int linked:1; /**< True if there is, or has been, a linked_conn. */ + /** True iff we'd like to be notified about read events from the + * linked conn. */ + unsigned int reading_from_linked_conn:1; + /** True iff we're willing to write to the linked conn. */ + unsigned int writing_to_linked_conn:1; + /** True iff we're currently able to read on the linked conn, and our + * read_event should be made active with libevent. */ + unsigned int active_on_link:1; + /** True iff we've called connection_close_immediate() on this linked + * connection. */ + unsigned int linked_conn_is_closed:1; + + /** CONNECT/SOCKS proxy client handshake state (for outgoing connections). */ + unsigned int proxy_state:4; + + /** Our socket; set to TOR_INVALID_SOCKET if this connection is closed, + * or has no socket. */ + tor_socket_t s; + int conn_array_index; /**< Index into the global connection array. */ + + struct event *read_event; /**< Libevent event structure. */ + struct event *write_event; /**< Libevent event structure. */ + struct buf_t *inbuf; /**< Buffer holding data read over this connection. */ + struct buf_t *outbuf; /**< Buffer holding data to write over this + * connection. */ + size_t outbuf_flushlen; /**< How much data should we try to flush from the + * outbuf? */ + time_t timestamp_last_read_allowed; /**< When was the last time libevent said + * we could read? */ + time_t timestamp_last_write_allowed; /**< When was the last time libevent + * said we could write? */ + + time_t timestamp_created; /**< When was this connection_t created? */ + + int socket_family; /**< Address family of this connection's socket. Usually + * AF_INET, but it can also be AF_UNIX, or AF_INET6 */ + tor_addr_t addr; /**< IP that socket "s" is directly connected to; + * may be the IP address for a proxy or pluggable transport, + * see "address" for the address of the final destination. + */ + uint16_t port; /**< If non-zero, port that socket "s" is directly connected + * to; may be the port for a proxy or pluggable transport, + * see "address" for the port at the final destination. */ + uint16_t marked_for_close; /**< Should we close this conn on the next + * iteration of the main loop? (If true, holds + * the line number where this connection was + * marked.) */ + const char *marked_for_close_file; /**< For debugging: in which file were + * we marked for close? */ + char *address; /**< FQDN (or IP) and port of the final destination for this + * connection; this is always the remote address, it is + * passed to a proxy or pluggable transport if one in use. + * See "addr" and "port" for the address that socket "s" is + * directly connected to. + * strdup into this, because free_connection() frees it. */ + /** Another connection that's connected to this one in lieu of a socket. */ + struct connection_t *linked_conn; + + /** Unique identifier for this connection on this Tor instance. */ + uint64_t global_identifier; + + /** Bytes read since last call to control_event_conn_bandwidth_used(). + * Only used if we're configured to emit CONN_BW events. */ + uint32_t n_read_conn_bw; + + /** Bytes written since last call to control_event_conn_bandwidth_used(). + * Only used if we're configured to emit CONN_BW events. */ + uint32_t n_written_conn_bw; +} connection_t; + +#endif + diff --git a/src/or/consdiffmgr.c b/src/or/consdiffmgr.c index 323f4f9ca0..f1b7601ca6 100644 --- a/src/or/consdiffmgr.c +++ b/src/or/consdiffmgr.c @@ -23,6 +23,9 @@ #include "routerparse.h" #include "workqueue.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" + /** * Labels to apply to items in the conscache object. * diff --git a/src/or/control.c b/src/or/control.c index 72d4ff3189..fa9bd05136 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -81,6 +81,24 @@ #include "routerparse.h" #include "shared_random_client.h" +#include "cached_dir_st.h" +#include "control_connection_st.h" +#include "cpath_build_state_st.h" +#include "entry_connection_st.h" +#include "extrainfo_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "or_connection_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" +#include "microdesc_st.h" +#include "rend_authorized_client_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "rend_service_descriptor_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "socks_request_st.h" + #ifndef _WIN32 #include #include @@ -226,6 +244,15 @@ static void flush_queued_events_cb(mainloop_event_t *event, void *arg); static char * download_status_to_string(const download_status_t *dl); static void control_get_bytes_rw_last_sec(uint64_t *r, uint64_t *w); +/** Convert a connection_t* to an control_connection_t*; assert if the cast is + * invalid. */ +control_connection_t * +TO_CONTROL_CONN(connection_t *c) +{ + tor_assert(c->magic == CONTROL_CONNECTION_MAGIC); + return DOWNCAST(control_connection_t, c); +} + /** Given a control event code for a message event, return the corresponding * log severity. */ static inline int diff --git a/src/or/control.h b/src/or/control.h index 92cbf866dd..a499e4533d 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -12,6 +12,8 @@ #ifndef TOR_CONTROL_H #define TOR_CONTROL_H +control_connection_t *TO_CONTROL_CONN(connection_t *); + void control_initialize_event_queue(void); void control_update_global_event_mask(void); diff --git a/src/or/control_connection_st.h b/src/or/control_connection_st.h new file mode 100644 index 0000000000..7770b54d5f --- /dev/null +++ b/src/or/control_connection_st.h @@ -0,0 +1,46 @@ +/* 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 CONTROL_CONNECTION_ST_H +#define CONTROL_CONNECTION_ST_H + +#include "or.h" +#include "connection_st.h" + +/** Subtype of connection_t for an connection to a controller. */ +struct control_connection_t { + connection_t base_; + + uint64_t event_mask; /**< Bitfield: which events does this controller + * care about? + * EVENT_MAX_ is >31, so we need a 64 bit mask */ + + /** True if we have sent a protocolinfo reply on this connection. */ + unsigned int have_sent_protocolinfo:1; + /** True if we have received a takeownership command on this + * connection. */ + unsigned int is_owning_control_connection:1; + + /** List of ephemeral onion services belonging to this connection. */ + smartlist_t *ephemeral_onion_services; + + /** If we have sent an AUTHCHALLENGE reply on this connection and + * have not received a successful AUTHENTICATE command, points to + * the value which the client must send to authenticate itself; + * otherwise, NULL. */ + char *safecookie_client_hash; + + /** Amount of space allocated in incoming_cmd. */ + uint32_t incoming_cmd_len; + /** Number of bytes currently stored in incoming_cmd. */ + uint32_t incoming_cmd_cur_len; + /** A control command that we're reading from the inbuf, but which has not + * yet arrived completely. */ + char *incoming_cmd; +}; + +#endif + diff --git a/src/or/cpath_build_state_st.h b/src/or/cpath_build_state_st.h new file mode 100644 index 0000000000..504f638dbf --- /dev/null +++ b/src/or/cpath_build_state_st.h @@ -0,0 +1,38 @@ +/* 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 CIRCUIT_BUILD_STATE_ST_ST_H +#define CIRCUIT_BUILD_STATE_ST_ST_H + +/** Information used to build a circuit. */ +struct cpath_build_state_t { + /** Intended length of the final circuit. */ + int desired_path_len; + /** How to extend to the planned exit node. */ + extend_info_t *chosen_exit; + /** Whether every node in the circ must have adequate uptime. */ + unsigned int need_uptime : 1; + /** Whether every node in the circ must have adequate capacity. */ + unsigned int need_capacity : 1; + /** Whether the last hop was picked with exiting in mind. */ + unsigned int is_internal : 1; + /** Did we pick this as a one-hop tunnel (not safe for other streams)? + * These are for encrypted dir conns that exit to this router, not + * for arbitrary exits from the circuit. */ + unsigned int onehop_tunnel : 1; + /** The crypt_path_t to append after rendezvous: used for rendezvous. */ + crypt_path_t *pending_final_cpath; + /** A ref-counted reference to the crypt_path_t to append after + * rendezvous; used on the service side. */ + crypt_path_reference_t *service_pending_final_cpath_ref; + /** How many times has building a circuit for this task failed? */ + int failure_count; + /** At what time should we give up on this task? */ + time_t expiry_time; +}; + +#endif + diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index 15ef6869cf..ad66268c3a 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -32,6 +32,8 @@ #include "router.h" #include "workqueue.h" +#include "or_circuit_st.h" + static void queue_pending_tasks(void); typedef struct worker_state_s { diff --git a/src/or/crypt_path_reference_st.h b/src/or/crypt_path_reference_st.h new file mode 100644 index 0000000000..2758a281c0 --- /dev/null +++ b/src/or/crypt_path_reference_st.h @@ -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-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef CRYPT_PATH_REFERENCE_ST_H +#define CRYPT_PATH_REFERENCE_ST_H + +/** A reference-counted pointer to a crypt_path_t, used only to share + * the final rendezvous cpath to be used on a service-side rendezvous + * circuit among multiple circuits built in parallel to the same + * destination rendezvous point. */ +struct crypt_path_reference_t { + /** The reference count. */ + unsigned int refcount; + /** The pointer. Set to NULL when the crypt_path_t is put into use + * on an opened rendezvous circuit. */ + crypt_path_t *cpath; +}; + +#endif + diff --git a/src/or/crypt_path_st.h b/src/or/crypt_path_st.h new file mode 100644 index 0000000000..ebad872172 --- /dev/null +++ b/src/or/crypt_path_st.h @@ -0,0 +1,56 @@ +/* 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 */ + +#ifndef CRYPT_PATH_ST_H +#define CRYPT_PATH_ST_H + +#include "relay_crypto_st.h" + +/** Holds accounting information for a single step in the layered encryption + * performed by a circuit. Used only at the client edge of a circuit. */ +struct crypt_path_t { + uint32_t magic; + + /** Cryptographic state used for encrypting and authenticating relay + * cells to and from this hop. */ + relay_crypto_t crypto; + + /** Current state of the handshake as performed with the OR at this + * step. */ + onion_handshake_state_t handshake_state; + /** Diffie-hellman handshake state for performing an introduction + * operations */ + crypto_dh_t *rend_dh_handshake_state; + + /** Negotiated key material shared with the OR at this step. */ + char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */ + + /** Information to extend to the OR at this step. */ + extend_info_t *extend_info; + + /** Is the circuit built to this step? Must be one of: + * - CPATH_STATE_CLOSED (The circuit has not been extended to this step) + * - CPATH_STATE_AWAITING_KEYS (We have sent an EXTEND/CREATE to this step + * and not received an EXTENDED/CREATED) + * - CPATH_STATE_OPEN (The circuit has been extended to this step) */ + uint8_t state; +#define CPATH_STATE_CLOSED 0 +#define CPATH_STATE_AWAITING_KEYS 1 +#define CPATH_STATE_OPEN 2 + struct crypt_path_t *next; /**< Link to next crypt_path_t in the circuit. + * (The list is circular, so the last node + * links to the first.) */ + struct crypt_path_t *prev; /**< Link to previous crypt_path_t in the + * circuit. */ + + int package_window; /**< How many cells are we allowed to originate ending + * at this step? */ + int deliver_window; /**< How many cells are we willing to deliver originating + * at this step? */ +}; + +#endif + diff --git a/src/or/desc_store_st.h b/src/or/desc_store_st.h new file mode 100644 index 0000000000..40238f4ce1 --- /dev/null +++ b/src/or/desc_store_st.h @@ -0,0 +1,34 @@ +/* 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 DESC_STORE_ST_H +#define DESC_STORE_ST_H + +/** A 'store' is a set of descriptors saved on disk, with accompanying + * journal, mmaped as needed, rebuilt as needed. */ +struct desc_store_t { + /** Filename (within DataDir) for the store. We append .tmp to this + * filename for a temporary file when rebuilding the store, and .new to this + * filename for the journal. */ + const char *fname_base; + /** Human-readable description of what this store contains. */ + const char *description; + + tor_mmap_t *mmap; /**< A mmap for the main file in the store. */ + + store_type_t type; /**< What's stored in this store? */ + + /** The size of the router log, in bytes. */ + size_t journal_len; + /** The size of the router store, in bytes. */ + size_t store_len; + /** Total bytes dropped since last rebuild: this is space currently + * used in the cache and the journal that could be freed by a rebuild. */ + size_t bytes_dropped; +}; + +#endif + diff --git a/src/or/destroy_cell_queue_st.h b/src/or/destroy_cell_queue_st.h new file mode 100644 index 0000000000..67c25935e4 --- /dev/null +++ b/src/or/destroy_cell_queue_st.h @@ -0,0 +1,27 @@ +/* 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 DESTROY_CELL_QUEUE_ST_H +#define DESTROY_CELL_QUEUE_ST_H + +/** A single queued destroy cell. */ +struct destroy_cell_t { + TOR_SIMPLEQ_ENTRY(destroy_cell_t) next; + circid_t circid; + uint32_t inserted_timestamp; /**< Time (in timestamp units) when this cell + * was inserted */ + uint8_t reason; +}; + +/** A queue of destroy cells on a channel. */ +struct destroy_cell_queue_t { + /** Linked list of packed_cell_t */ + TOR_SIMPLEQ_HEAD(dcell_simpleq, destroy_cell_t) head; + int n; /**< The number of cells in the queue. */ +}; + +#endif + diff --git a/src/or/dir_connection_st.h b/src/or/dir_connection_st.h new file mode 100644 index 0000000000..379f787df4 --- /dev/null +++ b/src/or/dir_connection_st.h @@ -0,0 +1,66 @@ +/* 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 DIR_CONNECTION_ST_H +#define DIR_CONNECTION_ST_H + +#include "connection_st.h" + +/** Subtype of connection_t for an "directory connection" -- that is, an HTTP + * connection to retrieve or serve directory material. */ +struct dir_connection_t { + connection_t base_; + + /** Which 'resource' did we ask the directory for? This is typically the part + * of the URL string that defines, relative to the directory conn purpose, + * what thing we want. For example, in router descriptor downloads by + * descriptor digest, it contains "d/", then one or more +-separated + * fingerprints. + **/ + char *requested_resource; + unsigned int dirconn_direct:1; /**< Is this dirconn direct, or via Tor? */ + + /** If we're fetching descriptors, what router purpose shall we assign + * to them? */ + uint8_t router_purpose; + + /** List of spooled_resource_t for objects that we're spooling. We use + * it from back to front. */ + smartlist_t *spool; + /** The compression object doing on-the-fly compression for spooled data. */ + tor_compress_state_t *compress_state; + + /** What rendezvous service are we querying for? */ + rend_data_t *rend_data; + + /* Hidden service connection identifier for dir connections: Used by HS + client-side code to fetch HS descriptors, and by the service-side code to + upload descriptors. */ + struct hs_ident_dir_conn_t *hs_ident; + + /** If this is a one-hop connection, tracks the state of the directory guard + * for this connection (if any). */ + struct circuit_guard_state_t *guard_state; + + char identity_digest[DIGEST_LEN]; /**< Hash of the public RSA key for + * the directory server's signing key. */ + + /** Unique ID for directory requests; this used to be in connection_t, but + * that's going away and being used on channels instead. The dirserver still + * needs this for the incoming side, so it's moved here. */ + uint64_t dirreq_id; + +#ifdef MEASUREMENTS_21206 + /** Number of RELAY_DATA cells received. */ + uint32_t data_cells_received; + + /** Number of RELAY_DATA cells sent. */ + uint32_t data_cells_sent; +#endif /* defined(MEASUREMENTS_21206) */ +}; + +#endif + diff --git a/src/or/dir_server_st.h b/src/or/dir_server_st.h new file mode 100644 index 0000000000..b9d3f1c556 --- /dev/null +++ b/src/or/dir_server_st.h @@ -0,0 +1,55 @@ +/* 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 DIR_SERVER_ST_H +#define DIR_SERVER_ST_H + +#include "torint.h" +#include "or.h" +#include "routerstatus_st.h" + +/** Represents information about a single trusted or fallback directory + * server. */ +typedef struct dir_server_t { + char *description; + char *nickname; + char *address; /**< Hostname. */ + /* XX/teor - why do we duplicate the address and port fields here and in + * fake_status? Surely we could just use fake_status (#17867). */ + tor_addr_t ipv6_addr; /**< IPv6 address if present; AF_UNSPEC if not */ + uint32_t addr; /**< IPv4 address. */ + uint16_t dir_port; /**< Directory port. */ + uint16_t or_port; /**< OR port: Used for tunneling connections. */ + uint16_t ipv6_orport; /**< OR port corresponding to ipv6_addr. */ + double weight; /** Weight used when selecting this node at random */ + char digest[DIGEST_LEN]; /**< Digest of identity key. */ + char v3_identity_digest[DIGEST_LEN]; /**< Digest of v3 (authority only, + * high-security) identity key. */ + + unsigned int is_running:1; /**< True iff we think this server is running. */ + unsigned int is_authority:1; /**< True iff this is a directory authority + * of some kind. */ + + /** True iff this server has accepted the most recent server descriptor + * we tried to upload to it. */ + unsigned int has_accepted_serverdesc:1; + + /** What kind of authority is this? (Bitfield.) */ + dirinfo_type_t type; + + time_t addr_current_at; /**< When was the document that we derived the + * address information from published? */ + + routerstatus_t fake_status; /**< Used when we need to pass this trusted + * dir_server_t to + * directory_request_set_routerstatus. + * as a routerstatus_t. Not updated by the + * router-status management code! + **/ +} dir_server_t; + +#endif + diff --git a/src/or/dirauth/dircollate.c b/src/or/dirauth/dircollate.c index dec6f75154..81f0bf31eb 100644 --- a/src/or/dirauth/dircollate.c +++ b/src/or/dirauth/dircollate.c @@ -25,6 +25,9 @@ #include "dircollate.h" #include "dirvote.h" +#include "networkstatus_st.h" +#include "vote_routerstatus_st.h" + static void dircollator_collate_by_ed25519(dircollator_t *dc); /** Hashtable entry mapping a pair of digests (actually an ed25519 key and an diff --git a/src/or/dirauth/dirvote.c b/src/or/dirauth/dirvote.c index b097b10cf9..c39708f4e4 100644 --- a/src/or/dirauth/dirvote.c +++ b/src/or/dirauth/dirvote.c @@ -28,6 +28,21 @@ #include "dirauth/mode.h" #include "dirauth/shared_random_state.h" +#include "authority_cert_st.h" +#include "cached_dir_st.h" +#include "dir_server_st.h" +#include "document_signature_st.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" +#include "node_st.h" +#include "ns_detached_signatures_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "vote_microdesc_hash_st.h" +#include "vote_routerstatus_st.h" +#include "vote_timing_st.h" + /** * \file dirvote.c * \brief Functions to compute directory consensus, and schedule voting. diff --git a/src/or/dirauth/shared_random.c b/src/or/dirauth/shared_random.c index 6dd1f330e0..c042acda1b 100644 --- a/src/or/dirauth/shared_random.c +++ b/src/or/dirauth/shared_random.c @@ -105,6 +105,9 @@ #include "dirauth/dirvote.h" #include "dirauth/mode.h" +#include "authority_cert_st.h" +#include "networkstatus_st.h" + /* String prefix of shared random values in votes/consensuses. */ static const char previous_srv_str[] = "shared-rand-previous-value"; static const char current_srv_str[] = "shared-rand-current-value"; diff --git a/src/or/directory.c b/src/or/directory.c index c7da804909..2394b75b2e 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -23,6 +23,7 @@ #include "directory.h" #include "dirserv.h" #include "entrynodes.h" +#include "fp_pair.h" #include "geoip.h" #include "hs_cache.h" #include "hs_common.h" @@ -53,6 +54,16 @@ #include "dirauth/mode.h" #include "dirauth/shared_random.h" +#include "authority_cert_st.h" +#include "cached_dir_st.h" +#include "dir_connection_st.h" +#include "dir_server_st.h" +#include "entry_connection_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "rend_service_descriptor_st.h" +#include "routerinfo_st.h" + /** * \file directory.c * \brief Code to send and fetch information from directory authorities and @@ -151,6 +162,15 @@ static void connection_dir_close_consensus_fetches( /********* END VARIABLES ************/ +/** Convert a connection_t* to a dir_connection_t*; assert if the cast is + * invalid. */ +dir_connection_t * +TO_DIR_CONN(connection_t *c) +{ + tor_assert(c->magic == DIR_CONNECTION_MAGIC); + return DOWNCAST(dir_connection_t, c); +} + /** Return false if the directory purpose dir_purpose * does not require an anonymous (three-hop) connection. * @@ -5613,6 +5633,27 @@ download_status_reset(download_status_t *dls) /* Don't reset dls->want_authority or dls->increment_on */ } +/** Return true iff, as of now, the resource tracked by dls is + * ready to get its download reattempted. */ +int +download_status_is_ready(download_status_t *dls, time_t now) +{ + /* dls wasn't reset before it was used */ + if (dls->next_attempt_at == 0) { + download_status_reset(dls); + } + + return download_status_get_next_attempt_at(dls) <= now; +} + +/** Mark dl as never downloadable. */ +void +download_status_mark_impossible(download_status_t *dl) +{ + dl->n_download_failures = IMPOSSIBLE_TO_DOWNLOAD; + dl->n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD; +} + /** Return the number of failures on dls since the last success (if * any). */ int diff --git a/src/or/directory.h b/src/or/directory.h index 5f5ff7eca6..27dc986a02 100644 --- a/src/or/directory.h +++ b/src/or/directory.h @@ -14,6 +14,7 @@ #include "hs_ident.h" +dir_connection_t *TO_DIR_CONN(connection_t *c); int directories_have_accepted_server_descriptor(void); void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, dirinfo_type_t type, const char *payload, @@ -60,6 +61,7 @@ void directory_request_set_dir_addr_port(directory_request_t *req, const tor_addr_port_t *p); void directory_request_set_directory_id_digest(directory_request_t *req, const char *digest); +struct circuit_guard_state_t; void directory_request_set_guard_state(directory_request_t *req, struct circuit_guard_state_t *state); void directory_request_set_router_purpose(directory_request_t *req, @@ -132,30 +134,9 @@ time_t download_status_increment_attempt(download_status_t *dls, time(NULL)) void download_status_reset(download_status_t *dls); -static int download_status_is_ready(download_status_t *dls, time_t now); +int download_status_is_ready(download_status_t *dls, time_t now); time_t download_status_get_next_attempt_at(const download_status_t *dls); - -/** Return true iff, as of now, the resource tracked by dls is - * ready to get its download reattempted. */ -static inline int -download_status_is_ready(download_status_t *dls, time_t now) -{ - /* dls wasn't reset before it was used */ - if (dls->next_attempt_at == 0) { - download_status_reset(dls); - } - - return download_status_get_next_attempt_at(dls) <= now; -} - -static void download_status_mark_impossible(download_status_t *dl); -/** Mark dl as never downloadable. */ -static inline void -download_status_mark_impossible(download_status_t *dl) -{ - dl->n_download_failures = IMPOSSIBLE_TO_DOWNLOAD; - dl->n_download_attempts = IMPOSSIBLE_TO_DOWNLOAD; -} +void download_status_mark_impossible(download_status_t *dl); int download_status_get_n_failures(const download_status_t *dls); int download_status_get_n_attempts(const download_status_t *dls); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index c01234e0b9..68f411b486 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -36,6 +36,16 @@ #include "dirauth/dirvote.h" +#include "cached_dir_st.h" +#include "dir_connection_st.h" +#include "extrainfo_st.h" +#include "microdesc_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "tor_version_st.h" +#include "vote_routerstatus_st.h" + /** * \file dirserv.c * \brief Directory server core implementation. Manages directory diff --git a/src/or/dirserv.h b/src/or/dirserv.h index f0b8913c5c..b79963cf8e 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -87,6 +87,14 @@ typedef struct spooled_resource_t { off_t cached_dir_offset; } spooled_resource_t; +#ifdef DIRSERV_PRIVATE +typedef struct measured_bw_line_t { + char node_id[DIGEST_LEN]; + char node_hex[MAX_HEX_NICKNAME_LEN+1]; + long int bw_kb; +} measured_bw_line_t; +#endif /* defined(DIRSERV_PRIVATE) */ + int connection_dirserv_flushed_some(dir_connection_t *conn); int dirserv_add_own_fingerprint(crypto_pk_t *pk); diff --git a/src/or/dns.c b/src/or/dns.c index ba734ed900..defc86bc93 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -64,6 +64,10 @@ #include "router.h" #include "ht.h" #include "sandbox.h" + +#include "edge_connection_st.h" +#include "or_circuit_st.h" + #include #include diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 7e344deeab..c286d4f93b 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -29,6 +29,12 @@ #include "control.h" #include "main.h" #include "policies.h" + +#include "control_connection_st.h" +#include "entry_connection_st.h" +#include "listener_connection_st.h" +#include "socks_request_st.h" + #include #include /* XXXX this implies we want an improved evdns */ diff --git a/src/or/document_signature_st.h b/src/or/document_signature_st.h new file mode 100644 index 0000000000..ec0b1ba1b0 --- /dev/null +++ b/src/or/document_signature_st.h @@ -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-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef DOCUMENT_SIGNATURE_ST_H +#define DOCUMENT_SIGNATURE_ST_H + +/** A signature of some document by an authority. */ +struct document_signature_t { + /** Declared SHA-1 digest of this voter's identity key */ + char identity_digest[DIGEST_LEN]; + /** Declared SHA-1 digest of signing key used by this voter. */ + char signing_key_digest[DIGEST_LEN]; + /** Algorithm used to compute the digest of the document. */ + digest_algorithm_t alg; + /** Signature of the signed thing. */ + char *signature; + /** Length of signature */ + int signature_len; + unsigned int bad_signature : 1; /**< Set to true if we've tried to verify + * the sig, and we know it's bad. */ + unsigned int good_signature : 1; /**< Set to true if we've verified the sig + * as good. */ +}; + +#endif + diff --git a/src/or/dos.c b/src/or/dos.c index ee731accea..8367db4ef5 100644 --- a/src/or/dos.c +++ b/src/or/dos.c @@ -11,6 +11,7 @@ #include "or.h" #include "channel.h" #include "config.h" +#include "connection_or.h" #include "crypto_rand.h" #include "geoip.h" #include "main.h" @@ -21,6 +22,8 @@ #include "dos.h" +#include "or_connection_st.h" + /* * Circuit creation denial of service mitigation. * diff --git a/src/or/download_status_st.h b/src/or/download_status_st.h new file mode 100644 index 0000000000..8ed77aaa7b --- /dev/null +++ b/src/or/download_status_st.h @@ -0,0 +1,65 @@ +/* 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 DOWNLOAD_STATUS_ST_H +#define DOWNLOAD_STATUS_ST_H + +/** Information about our plans for retrying downloads for a downloadable + * directory object. + * Each type of downloadable directory object has a corresponding retry + * schedule, which can be different depending on whether the object is + * being downloaded from an authority or a mirror (want_authority). + * next_attempt_at contains the next time we will attempt to download + * the object. + * For schedules that increment_on failure, n_download_failures + * is used to determine the position in the schedule. (Each schedule is a + * smartlist of integer delays, parsed from a CSV option.) Every time a + * connection attempt fails, n_download_failures is incremented, + * the new delay value is looked up from the schedule, and + * next_attempt_at is set delay seconds from the time the previous + * connection failed. Therefore, at most one failure-based connection can be + * in progress for each download_status_t. + * For schedules that increment_on attempt, n_download_attempts + * is used to determine the position in the schedule. Every time a + * connection attempt is made, n_download_attempts is incremented, + * the new delay value is looked up from the schedule, and + * next_attempt_at is set delay seconds from the time the previous + * connection was attempted. Therefore, multiple concurrent attempted-based + * connections can be in progress for each download_status_t. + * After an object is successfully downloaded, any other concurrent connections + * are terminated. A new schedule which starts at position 0 is used for + * subsequent downloads of the same object. + */ +struct download_status_t { + time_t next_attempt_at; /**< When should we try downloading this object + * again? */ + uint8_t n_download_failures; /**< Number of failed downloads of the most + * recent object, since the last success. */ + uint8_t n_download_attempts; /**< Number of (potentially concurrent) attempts + * to download the most recent object, since + * the last success. */ + download_schedule_bitfield_t schedule : 8; /**< What kind of object is being + * downloaded? This determines the + * schedule used for the download. + */ + download_want_authority_bitfield_t want_authority : 1; /**< Is the download + * happening from an authority + * or a mirror? This determines + * the schedule used for the + * download. */ + download_schedule_increment_bitfield_t increment_on : 1; /**< does this + * schedule increment on each attempt, + * or after each failure? */ + uint8_t last_backoff_position; /**< number of attempts/failures, depending + * on increment_on, when we last recalculated + * the delay. Only updated if backoff + * == 1. */ + int last_delay_used; /**< last delay used for random exponential backoff; + * only updated if backoff == 1 */ +}; + +#endif + diff --git a/src/or/edge_connection_st.h b/src/or/edge_connection_st.h new file mode 100644 index 0000000000..7ef56bf060 --- /dev/null +++ b/src/or/edge_connection_st.h @@ -0,0 +1,77 @@ +/* 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 EDGE_CONNECTION_ST_H +#define EDGE_CONNECTION_ST_H + +#include "or.h" + +#include "connection_st.h" + +/** Subtype of connection_t for an "edge connection" -- that is, an entry (ap) + * connection, or an exit. */ +struct edge_connection_t { + connection_t base_; + + struct edge_connection_t *next_stream; /**< Points to the next stream at this + * edge, if any */ + int package_window; /**< How many more relay cells can I send into the + * circuit? */ + int deliver_window; /**< How many more relay cells can end at me? */ + + struct circuit_t *on_circuit; /**< The circuit (if any) that this edge + * connection is using. */ + + /** A pointer to which node in the circ this conn exits at. Set for AP + * connections and for hidden service exit connections. */ + struct crypt_path_t *cpath_layer; + /** What rendezvous service are we querying for (if an AP) or providing (if + * an exit)? */ + rend_data_t *rend_data; + + /* Hidden service connection identifier for edge connections. Used by the HS + * client-side code to identify client SOCKS connections and by the + * service-side code to match HS circuits with their streams. */ + struct hs_ident_edge_conn_t *hs_ident; + + uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit + * connection. Exit connections only. */ + uint32_t begincell_flags; /** Flags sent or received in the BEGIN cell + * for this connection */ + + streamid_t stream_id; /**< The stream ID used for this edge connection on its + * circuit */ + + /** The reason why this connection is closing; passed to the controller. */ + uint16_t end_reason; + + /** Bytes read since last call to control_event_stream_bandwidth_used() */ + uint32_t n_read; + + /** Bytes written since last call to control_event_stream_bandwidth_used() */ + uint32_t n_written; + + /** True iff this connection is for a DNS request only. */ + unsigned int is_dns_request:1; + /** True iff this connection is for a PTR DNS request. (exit only) */ + unsigned int is_reverse_dns_lookup:1; + + unsigned int edge_has_sent_end:1; /**< For debugging; only used on edge + * connections. Set once we've set the stream end, + * and check in connection_about_to_close_connection(). + */ + /** True iff we've blocked reading until the circuit has fewer queued + * cells. */ + unsigned int edge_blocked_on_circ:1; + + /** Unique ID for directory requests; this used to be in connection_t, but + * that's going away and being used on channels instead. We still tag + * edge connections with dirreq_id from circuits, so it's copied here. */ + uint64_t dirreq_id; +}; + +#endif + diff --git a/src/or/entry_connection_st.h b/src/or/entry_connection_st.h new file mode 100644 index 0000000000..c3b1ad2ab3 --- /dev/null +++ b/src/or/entry_connection_st.h @@ -0,0 +1,100 @@ +/* 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 ENTRY_CONNECTION_ST_H +#define ENTRY_CONNECTION_ST_H + +#include "edge_connection_st.h" + +/** Subtype of edge_connection_t for an "entry connection" -- that is, a SOCKS + * connection, a DNS request, a TransPort connection or a NATD connection */ +struct entry_connection_t { + struct edge_connection_t edge_; + + /** Nickname of planned exit node -- used with .exit support. */ + /* XXX prop220: we need to make chosen_exit_name able to encode Ed IDs too. + * That's logically part of the UI parts for prop220 though. */ + char *chosen_exit_name; + + socks_request_t *socks_request; /**< SOCKS structure describing request (AP + * only.) */ + + /* === Isolation related, AP only. === */ + entry_port_cfg_t entry_cfg; + /** AP only: The newnym epoch in which we created this connection. */ + unsigned nym_epoch; + + /** AP only: The original requested address before we rewrote it. */ + char *original_dest_address; + /* Other fields to isolate on already exist. The ClientAddr is addr. The + ClientProtocol is a combination of type and socks_request-> + socks_version. SocksAuth is socks_request->username/password. + DestAddr is in socks_request->address. */ + + /** Number of times we've reassigned this application connection to + * a new circuit. We keep track because the timeout is longer if we've + * already retried several times. */ + uint8_t num_socks_retries; + + /** For AP connections only: buffer for data that we have sent + * optimistically, which we might need to re-send if we have to + * retry this connection. */ + struct buf_t *pending_optimistic_data; + /* For AP connections only: buffer for data that we previously sent + * optimistically which we are currently re-sending as we retry this + * connection. */ + struct buf_t *sending_optimistic_data; + + /** If this is a DNSPort connection, this field holds the pending DNS + * request that we're going to try to answer. */ + struct evdns_server_request *dns_server_request; + +#define DEBUGGING_17659 + +#ifdef DEBUGGING_17659 + uint16_t marked_pending_circ_line; + const char *marked_pending_circ_file; +#endif + +#define NUM_CIRCUITS_LAUNCHED_THRESHOLD 10 + /** Number of times we've launched a circuit to handle this stream. If + * it gets too high, that could indicate an inconsistency between our + * "launch a circuit to handle this stream" logic and our "attach our + * stream to one of the available circuits" logic. */ + unsigned int num_circuits_launched:4; + + /** True iff this stream must attach to a one-hop circuit (e.g. for + * begin_dir). */ + unsigned int want_onehop:1; + /** True iff this stream should use a BEGIN_DIR relay command to establish + * itself rather than BEGIN (either via onehop or via a whole circuit). */ + unsigned int use_begindir:1; + + /** For AP connections only. If 1, and we fail to reach the chosen exit, + * stop requiring it. */ + unsigned int chosen_exit_optional:1; + /** For AP connections only. If non-zero, this exit node was picked as + * a result of the TrackHostExit, and the value decrements every time + * we fail to complete a circuit to our chosen exit -- if it reaches + * zero, abandon the associated mapaddress. */ + unsigned int chosen_exit_retries:3; + + /** True iff this is an AP connection that came from a transparent or + * NATd connection */ + unsigned int is_transparent_ap:1; + + /** For AP connections only: Set if this connection's target exit node + * allows optimistic data (that is, data sent on this stream before + * the exit has sent a CONNECTED cell) and we have chosen to use it. + */ + unsigned int may_use_optimistic_data : 1; +}; + +/** Cast a entry_connection_t subtype pointer to a edge_connection_t **/ +#define ENTRY_TO_EDGE_CONN(c) (&(((c))->edge_)) + +#endif + diff --git a/src/or/entry_port_cfg_st.h b/src/or/entry_port_cfg_st.h new file mode 100644 index 0000000000..0563f2e9fb --- /dev/null +++ b/src/or/entry_port_cfg_st.h @@ -0,0 +1,54 @@ +/* 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 ENTRY_PORT_CFG_ST_H +#define ENTRY_PORT_CFG_ST_H + +#include "torint.h" +#include "or.h" + +struct entry_port_cfg_t { + /* Client port types (socks, dns, trans, natd) only: */ + uint8_t isolation_flags; /**< Zero or more isolation flags */ + int session_group; /**< A session group, or -1 if this port is not in a + * session group. */ + + /* Socks only: */ + /** When both no-auth and user/pass are advertised by a SOCKS client, select + * no-auth. */ + unsigned int socks_prefer_no_auth : 1; + /** When ISO_SOCKSAUTH is in use, Keep-Alive circuits indefinitely. */ + unsigned int socks_iso_keep_alive : 1; + + /* Client port types only: */ + unsigned int ipv4_traffic : 1; + unsigned int ipv6_traffic : 1; + unsigned int prefer_ipv6 : 1; + unsigned int dns_request : 1; + unsigned int onion_traffic : 1; + + /** For a socks listener: should we cache IPv4/IPv6 DNS information that + * exit nodes tell us? + * + * @{ */ + unsigned int cache_ipv4_answers : 1; + unsigned int cache_ipv6_answers : 1; + /** @} */ + /** For a socks listeners: if we find an answer in our client-side DNS cache, + * should we use it? + * + * @{ */ + unsigned int use_cached_ipv4_answers : 1; + unsigned int use_cached_ipv6_answers : 1; + /** @} */ + /** For socks listeners: When we can automap an address to IPv4 or IPv6, + * do we prefer IPv6? */ + unsigned int prefer_ipv6_virtaddr : 1; + +}; + +#endif + diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 27d760f1a8..62a65f2494 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -139,6 +139,9 @@ #include "transports.h" #include "statefile.h" +#include "node_st.h" +#include "origin_circuit_st.h" + /** A list of existing guard selection contexts. */ static smartlist_t *guard_contexts = NULL; /** The currently enabled guard selection context. */ diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c index b842442caf..acbc900ade 100644 --- a/src/or/ext_orport.c +++ b/src/or/ext_orport.c @@ -29,6 +29,8 @@ #include "proto_ext_or.h" #include "util.h" +#include "or_connection_st.h" + /** Allocate and return a structure capable of holding an Extended * ORPort message of body length len. */ ext_or_cmd_t * diff --git a/src/or/extend_info_st.h b/src/or/extend_info_st.h new file mode 100644 index 0000000000..42c638d6d5 --- /dev/null +++ b/src/or/extend_info_st.h @@ -0,0 +1,28 @@ +/* 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 EXTEND_INFO_ST_H +#define EXTEND_INFO_ST_H + +/** Information on router used when extending a circuit. We don't need a + * full routerinfo_t to extend: we only need addr:port:keyid to build an OR + * connection, and onion_key to create the onionskin. Note that for onehop + * general-purpose tunnels, the onion_key is NULL. */ +struct extend_info_t { + char nickname[MAX_HEX_NICKNAME_LEN+1]; /**< This router's nickname for + * display. */ + /** Hash of this router's RSA identity key. */ + char identity_digest[DIGEST_LEN]; + /** Ed25519 identity for this router, if any. */ + ed25519_public_key_t ed_identity; + uint16_t port; /**< OR port. */ + tor_addr_t addr; /**< IP address. */ + crypto_pk_t *onion_key; /**< Current onionskin key. */ + curve25519_public_key_t curve25519_onion_key; +}; + +#endif + diff --git a/src/or/extrainfo_st.h b/src/or/extrainfo_st.h new file mode 100644 index 0000000000..c4d84b8eec --- /dev/null +++ b/src/or/extrainfo_st.h @@ -0,0 +1,30 @@ +/* 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 EXTRAINFO_ST_H +#define EXTRAINFO_ST_H + +#include "signed_descriptor_st.h" + +/** Information needed to keep and cache a signed extra-info document. */ +struct extrainfo_t { + signed_descriptor_t cache_info; + /** SHA256 digest of this document */ + uint8_t digest256[DIGEST256_LEN]; + /** The router's nickname. */ + char nickname[MAX_NICKNAME_LEN+1]; + /** True iff we found the right key for this extra-info, verified the + * signature, and found it to be bad. */ + unsigned int bad_sig : 1; + /** If present, we didn't have the right key to verify this extra-info, + * so this is a copy of the signature in the document. */ + char *pending_sig; + /** Length of pending_sig. */ + size_t pending_sig_len; +}; + +#endif + diff --git a/src/or/fp_pair.h b/src/or/fp_pair.h index 4498a16101..3c5c33bcbe 100644 --- a/src/or/fp_pair.h +++ b/src/or/fp_pair.h @@ -9,6 +9,12 @@ #ifndef _TOR_FP_PAIR_H #define _TOR_FP_PAIR_H +/** A pair of digests created by dir_split_resource_info_fingerprint_pairs() */ +typedef struct { + char first[DIGEST_LEN]; + char second[DIGEST_LEN]; +} fp_pair_t; + /* * Declare fp_pair_map_t functions and structs */ diff --git a/src/or/hibernate.c b/src/or/hibernate.c index d7d259470f..e2e53b3530 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -42,6 +42,8 @@ hibernating, phase 2: #include "router.h" #include "statefile.h" +#include "or_connection_st.h" + /** Are we currently awake, asleep, running out of bandwidth, or shutting * down? */ static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL; diff --git a/src/or/hs_cache.c b/src/or/hs_cache.c index ecc845d17f..092d944b86 100644 --- a/src/or/hs_cache.c +++ b/src/or/hs_cache.c @@ -21,6 +21,8 @@ #include "hs_cache.h" +#include "networkstatus_st.h" + static int cached_client_descriptor_has_expired(time_t now, const hs_cache_client_descriptor_t *cached_desc); diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c index 03273a44f9..f5ed3df571 100644 --- a/src/or/hs_cell.c +++ b/src/or/hs_cell.c @@ -16,6 +16,8 @@ #include "hs_cell.h" #include "hs_ntor.h" +#include "origin_circuit_st.h" + /* Trunnel. */ #include "ed25519_cert.h" #include "hs/cell_common.h" diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c index a35d2af8ba..761edd6210 100644 --- a/src/or/hs_circuit.c +++ b/src/or/hs_circuit.c @@ -33,6 +33,11 @@ #include "hs/cell_common.h" #include "hs/cell_establish_intro.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" + /* A circuit is about to become an e2e rendezvous circuit. Check * circ_purpose and ensure that it's properly set. Return true iff * circuit purpose is properly set, otherwise return false. */ diff --git a/src/or/hs_circuitmap.c b/src/or/hs_circuitmap.c index 112c8bdced..fd0a01f8ba 100644 --- a/src/or/hs_circuitmap.c +++ b/src/or/hs_circuitmap.c @@ -18,6 +18,9 @@ #include "circuitlist.h" #include "hs_circuitmap.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + /************************** HS circuitmap code *******************************/ /* This is the hidden service circuitmap. It's a hash table that maps diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 26e8785d9f..2237699bc7 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -35,6 +35,12 @@ #include "router.h" #include "routerset.h" +#include "cpath_build_state_st.h" +#include "dir_connection_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "origin_circuit_st.h" + /* Return a human-readable string for the client fetch status code. */ static const char * fetch_status_to_string(hs_client_fetch_status_t status) diff --git a/src/or/hs_common.c b/src/or/hs_common.c index 3081ad216c..c63d4330d6 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -33,6 +33,12 @@ #include "shared_random_client.h" #include "dirauth/shared_random_state.h" +#include "edge_connection_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" +#include "routerstatus_st.h" + /* Trunnel */ #include "ed25519_cert.h" diff --git a/src/or/hs_control.c b/src/or/hs_control.c index 6b9b95c6d8..3ad7fb151f 100644 --- a/src/or/hs_control.c +++ b/src/or/hs_control.c @@ -15,6 +15,9 @@ #include "hs_service.h" #include "nodelist.h" +#include "node_st.h" +#include "routerstatus_st.h" + /* Send on the control port the "HS_DESC REQUESTED [...]" event. * * The onion_pk is the onion service public key, base64_blinded_pk is the diff --git a/src/or/hs_descriptor.c b/src/or/hs_descriptor.c index 096122392d..bda4dd64b7 100644 --- a/src/or/hs_descriptor.c +++ b/src/or/hs_descriptor.c @@ -67,6 +67,8 @@ #include "hs_config.h" #include "torcert.h" /* tor_cert_encode_ed22519() */ +#include "extend_info_st.h" + /* Constant string value used for the descriptor format. */ #define str_hs_desc "hs-descriptor" #define str_desc_cert "descriptor-signing-key-cert" diff --git a/src/or/hs_intropoint.c b/src/or/hs_intropoint.c index 3274e8e9c0..58416fbe93 100644 --- a/src/or/hs_intropoint.c +++ b/src/or/hs_intropoint.c @@ -27,6 +27,8 @@ #include "hs_intropoint.h" #include "hs_common.h" +#include "or_circuit_st.h" + /** Extract the authentication key from an ESTABLISH_INTRO or INTRODUCE1 using * the given cell_type from cell and place it in * auth_key_out. */ diff --git a/src/or/hs_service.c b/src/or/hs_service.c index f1f26954ae..46fb3bf682 100644 --- a/src/or/hs_service.c +++ b/src/or/hs_service.c @@ -39,6 +39,14 @@ #include "hs_service.h" #include "hs_stats.h" +#include "dir_connection_st.h" +#include "edge_connection_st.h" +#include "extend_info_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" +#include "routerstatus_st.h" + /* Trunnel */ #include "ed25519_cert.h" #include "hs/cell_common.h" diff --git a/src/or/hsdir_index_st.h b/src/or/hsdir_index_st.h new file mode 100644 index 0000000000..9d9ce66bd9 --- /dev/null +++ b/src/or/hsdir_index_st.h @@ -0,0 +1,24 @@ +/* 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 HSDIR_INDEX_ST_H +#define HSDIR_INDEX_ST_H + +/* Hidden service directory index used in a node_t which is set once we set + * the consensus. */ +struct hsdir_index_t { + /* HSDir index to use when fetching a descriptor. */ + uint8_t fetch[DIGEST256_LEN]; + + /* HSDir index used by services to store their first and second + * descriptor. The first descriptor is chronologically older than the second + * one and uses older TP and SRV values. */ + uint8_t store_first[DIGEST256_LEN]; + uint8_t store_second[DIGEST256_LEN]; +}; + +#endif + diff --git a/src/or/include.am b/src/or/include.am index 0e2aac4aae..af525f35cf 100644 --- a/src/or/include.am +++ b/src/or/include.am @@ -181,8 +181,11 @@ endif ORHEADERS = \ src/or/addressmap.h \ + src/or/authority_cert_st.h \ src/or/auth_dirs.inc \ src/or/bridges.h \ + src/or/cell_st.h \ + src/or/cell_queue_st.h \ src/or/channel.h \ src/or/channelpadding.h \ src/or/channeltls.h \ @@ -193,24 +196,42 @@ ORHEADERS = \ src/or/circuitmux_ewma.h \ src/or/circuitstats.h \ src/or/circuituse.h \ + src/or/circuit_st.h \ + src/or/cached_dir_st.h \ src/or/command.h \ src/or/config.h \ src/or/confparse.h \ src/or/connection.h \ + src/or/connection_st.h \ src/or/connection_edge.h \ src/or/connection_or.h \ src/or/conscache.h \ src/or/consdiff.h \ src/or/consdiffmgr.h \ + src/or/control_connection_st.h \ src/or/control.h \ + src/or/cpath_build_state_st.h \ + src/or/crypt_path_st.h \ + src/or/crypt_path_reference_st.h \ src/or/cpuworker.h \ + src/or/desc_store_st.h \ + src/or/destroy_cell_queue_st.h \ src/or/directory.h \ src/or/dirserv.h \ + src/or/dir_connection_st.h \ + src/or/dir_server_st.h \ + src/or/document_signature_st.h \ + src/or/download_status_st.h \ src/or/dns.h \ src/or/dns_structs.h \ src/or/dnsserv.h \ src/or/dos.h \ + src/or/edge_connection_st.h \ + src/or/entry_connection_st.h \ + src/or/entry_port_cfg_st.h \ src/or/ext_orport.h \ + src/or/extend_info_st.h \ + src/or/extrainfo_st.h \ src/or/fallback_dirs.inc \ src/or/fp_pair.h \ src/or/geoip.h \ @@ -231,20 +252,34 @@ ORHEADERS = \ src/or/hs_ntor.h \ src/or/hs_stats.h \ src/or/hs_service.h \ + src/or/hsdir_index_st.h \ src/or/keypin.h \ + src/or/listener_connection_st.h \ src/or/main.h \ src/or/microdesc.h \ + src/or/microdesc_st.h \ src/or/networkstatus.h \ + src/or/networkstatus_st.h \ + src/or/networkstatus_sr_info_st.h \ + src/or/networkstatus_voter_info_st.h \ src/or/nodelist.h \ + src/or/node_st.h \ + src/or/ns_detached_signatures_st.h \ src/or/ntmain.h \ src/or/onion.h \ src/or/onion_fast.h \ src/or/onion_ntor.h \ src/or/onion_tap.h \ src/or/or.h \ + src/or/or_circuit_st.h \ + src/or/or_connection_st.h \ + src/or/or_handshake_certs_st.h \ + src/or/or_handshake_state_st.h \ + src/or/origin_circuit_st.h \ src/or/transports.h \ - src/or/parsecommon.h \ + src/or/parsecommon.h \ src/or/periodic.h \ + src/or/port_cfg_st.h \ src/or/policies.h \ src/or/protover.h \ src/or/proto_cell.h \ @@ -255,25 +290,41 @@ ORHEADERS = \ src/or/reasons.h \ src/or/relay.h \ src/or/relay_crypto.h \ + src/or/relay_crypto_st.h \ src/or/rendcache.h \ src/or/rendclient.h \ src/or/rendcommon.h \ src/or/rendmid.h \ src/or/rendservice.h \ + src/or/rend_authorized_client_st.h \ + src/or/rend_encoded_v2_service_descriptor_st.h \ + src/or/rend_intro_point_st.h \ + src/or/rend_service_descriptor_st.h \ src/or/rephist.h \ src/or/replaycache.h \ src/or/router.h \ + src/or/routerinfo_st.h \ src/or/routerkeys.h \ src/or/routerlist.h \ + src/or/routerlist_st.h \ src/or/routerkeys.h \ src/or/routerset.h \ src/or/routerparse.h \ + src/or/routerstatus_st.h \ src/or/scheduler.h \ + src/or/server_port_cfg_st.h \ src/or/shared_random_client.h \ + src/or/signed_descriptor_st.h \ + src/or/socks_request_st.h \ src/or/statefile.h \ src/or/status.h \ src/or/torcert.h \ src/or/tor_api_internal.h \ + src/or/tor_version_st.h \ + src/or/var_cell_st.h \ + src/or/vote_microdesc_hash_st.h \ + src/or/vote_routerstatus_st.h \ + src/or/vote_timing_st.h \ src/or/voting_schedule.h # We add the headers of the modules even though they are disabled so we can diff --git a/src/or/listener_connection_st.h b/src/or/listener_connection_st.h new file mode 100644 index 0000000000..63588c99ab --- /dev/null +++ b/src/or/listener_connection_st.h @@ -0,0 +1,25 @@ +/* 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 LISTENER_CONNECTION_ST_H +#define LISTENER_CONNECTION_ST_H + +#include "connection_st.h" + +/** Subtype of connection_t; used for a listener socket. */ +struct listener_connection_t { + connection_t base_; + + /** If the connection is a CONN_TYPE_AP_DNS_LISTENER, this field points + * to the evdns_server_port it uses to listen to and answer connections. */ + struct evdns_server_port *dns_server_port; + + entry_port_cfg_t entry_cfg; + +}; + +#endif + diff --git a/src/or/main.c b/src/or/main.c index 9dce158b33..bb5aaaf608 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -122,6 +122,14 @@ #include "dirauth/mode.h" #include "dirauth/shared_random.h" +#include "cell_st.h" +#include "entry_connection_st.h" +#include "networkstatus_st.h" +#include "or_connection_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" +#include "socks_request_st.h" + #ifdef HAVE_SYSTEMD # if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse diff --git a/src/or/microdesc.c b/src/or/microdesc.c index b4a934e095..a194fb3b0b 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -22,6 +22,11 @@ #include "routerlist.h" #include "routerparse.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "routerstatus_st.h" + /** A data structure to hold a bunch of cached microdescriptors. There are * two active files in the cache: a "cache file" that we mmap, and a "journal * file" that we append to. Periodically, we rebuild the cache file to hold diff --git a/src/or/microdesc_st.h b/src/or/microdesc_st.h new file mode 100644 index 0000000000..f10a9ed7f5 --- /dev/null +++ b/src/or/microdesc_st.h @@ -0,0 +1,71 @@ +/* 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 MICRODESC_ST_H +#define MICRODESC_ST_H + +/** A microdescriptor is the smallest amount of information needed to build a + * circuit through a router. They are generated by the directory authorities, + * using information from the uploaded routerinfo documents. They are not + * self-signed, but are rather authenticated by having their hash in a signed + * networkstatus document. */ +struct microdesc_t { + /** Hashtable node, used to look up the microdesc by its digest. */ + HT_ENTRY(microdesc_t) node; + + /* Cache information */ + + /** When was this microdescriptor last listed in a consensus document? + * Once a microdesc has been unlisted long enough, we can drop it. + */ + time_t last_listed; + /** Where is this microdescriptor currently stored? */ + saved_location_bitfield_t saved_location : 3; + /** If true, do not attempt to cache this microdescriptor on disk. */ + unsigned int no_save : 1; + /** If true, this microdesc has an entry in the microdesc_map */ + unsigned int held_in_map : 1; + /** Reference count: how many node_ts have a reference to this microdesc? */ + unsigned int held_by_nodes; + + /** If saved_location == SAVED_IN_CACHE, this field holds the offset of the + * microdescriptor in the cache. */ + off_t off; + + /* The string containing the microdesc. */ + + /** A pointer to the encoded body of the microdescriptor. If the + * saved_location is SAVED_IN_CACHE, then the body is a pointer into an + * mmap'd region. Otherwise, it is a malloc'd string. The string might not + * be NUL-terminated; take the length from bodylen. */ + char *body; + /** The length of the microdescriptor in body. */ + size_t bodylen; + /** A SHA256-digest of the microdescriptor. */ + char digest[DIGEST256_LEN]; + + /* Fields in the microdescriptor. */ + + /** As routerinfo_t.onion_pkey */ + crypto_pk_t *onion_pkey; + /** As routerinfo_t.onion_curve25519_pkey */ + curve25519_public_key_t *onion_curve25519_pkey; + /** Ed25519 identity key, if included. */ + ed25519_public_key_t *ed25519_identity_pkey; + /** As routerinfo_t.ipv6_addr */ + tor_addr_t ipv6_addr; + /** As routerinfo_t.ipv6_orport */ + uint16_t ipv6_orport; + /** As routerinfo_t.family */ + smartlist_t *family; + /** IPv4 exit policy summary */ + short_policy_t *exit_policy; + /** IPv6 exit policy summary */ + short_policy_t *ipv6_exit_policy; +}; + +#endif + diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 998eaf74e6..dd994f0852 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -74,6 +74,19 @@ #include "dirauth/mode.h" #include "dirauth/shared_random.h" +#include "authority_cert_st.h" +#include "dir_connection_st.h" +#include "dir_server_st.h" +#include "document_signature_st.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" +#include "ns_detached_signatures_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "vote_microdesc_hash_st.h" +#include "vote_routerstatus_st.h" + /** Most recently received and validated v3 "ns"-flavored consensus network * status. */ STATIC networkstatus_t *current_ns_consensus = NULL; diff --git a/src/or/networkstatus_sr_info_st.h b/src/or/networkstatus_sr_info_st.h new file mode 100644 index 0000000000..3b2690f0ae --- /dev/null +++ b/src/or/networkstatus_sr_info_st.h @@ -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-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef NETWORKSTATUS_SR_INFO_ST_H +#define NETWORKSTATUS_SR_INFO_ST_H + +struct networkstatus_sr_info_t { + /* Indicate if the dirauth partitipates in the SR protocol with its vote. + * This is tied to the SR flag in the vote. */ + unsigned int participate:1; + /* Both vote and consensus: Current and previous SRV. If list is empty, + * this means none were found in either the consensus or vote. */ + struct sr_srv_t *previous_srv; + struct sr_srv_t *current_srv; + /* Vote only: List of commitments. */ + smartlist_t *commits; +}; + +#endif + diff --git a/src/or/networkstatus_st.h b/src/or/networkstatus_st.h new file mode 100644 index 0000000000..81965395a2 --- /dev/null +++ b/src/or/networkstatus_st.h @@ -0,0 +1,95 @@ +/* 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 NETWORKSTATUS_ST_H +#define NETWORKSTATUS_ST_H + +#include "networkstatus_sr_info_st.h" + +/** A common structure to hold a v3 network status vote, or a v3 network + * status consensus. */ +struct networkstatus_t { + networkstatus_type_t type; /**< Vote, consensus, or opinion? */ + consensus_flavor_t flavor; /**< If a consensus, what kind? */ + unsigned int has_measured_bws : 1;/**< True iff this networkstatus contains + * measured= bandwidth values. */ + + time_t published; /**< Vote only: Time when vote was written. */ + time_t valid_after; /**< Time after which this vote or consensus applies. */ + time_t fresh_until; /**< Time before which this is the most recent vote or + * consensus. */ + time_t valid_until; /**< Time after which this vote or consensus should not + * be used. */ + + /** Consensus only: what method was used to produce this consensus? */ + int consensus_method; + /** Vote only: what methods is this voter willing to use? */ + smartlist_t *supported_methods; + + /** List of 'package' lines describing hashes of downloadable packages */ + smartlist_t *package_lines; + + /** How long does this vote/consensus claim that authorities take to + * distribute their votes to one another? */ + int vote_seconds; + /** How long does this vote/consensus claim that authorities take to + * distribute their consensus signatures to one another? */ + int dist_seconds; + + /** Comma-separated list of recommended client software, or NULL if this + * voter has no opinion. */ + char *client_versions; + char *server_versions; + + /** Lists of subprotocol versions which are _recommended_ for relays and + * clients, or which are _require_ for relays and clients. Tor shouldn't + * make any more network connections if a required protocol is missing. + */ + char *recommended_relay_protocols; + char *recommended_client_protocols; + char *required_relay_protocols; + char *required_client_protocols; + + /** List of flags that this vote/consensus applies to routers. If a flag is + * not listed here, the voter has no opinion on what its value should be. */ + smartlist_t *known_flags; + + /** List of key=value strings for the parameters in this vote or + * consensus, sorted by key. */ + smartlist_t *net_params; + + /** List of key=value strings for the bw weight parameters in the + * consensus. */ + smartlist_t *weight_params; + + /** List of networkstatus_voter_info_t. For a vote, only one element + * is included. For a consensus, one element is included for every voter + * whose vote contributed to the consensus. */ + smartlist_t *voters; + + struct authority_cert_t *cert; /**< Vote only: the voter's certificate. */ + + /** Digests of this document, as signed. */ + common_digests_t digests; + /** A SHA3-256 digest of the document, not including signatures: used for + * consensus diffs */ + uint8_t digest_sha3_as_signed[DIGEST256_LEN]; + + /** List of router statuses, sorted by identity digest. For a vote, + * the elements are vote_routerstatus_t; for a consensus, the elements + * are routerstatus_t. */ + smartlist_t *routerstatus_list; + + /** If present, a map from descriptor digest to elements of + * routerstatus_list. */ + digestmap_t *desc_digest_map; + + /** Contains the shared random protocol data from a vote or consensus. */ + networkstatus_sr_info_t sr_info; +}; + +#endif + diff --git a/src/or/networkstatus_voter_info_st.h b/src/or/networkstatus_voter_info_st.h new file mode 100644 index 0000000000..32ea597bd8 --- /dev/null +++ b/src/or/networkstatus_voter_info_st.h @@ -0,0 +1,31 @@ +/* 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 NETWORKSTATUS_VOTER_INFO_ST_H +#define NETWORKSTATUS_VOTER_INFO_ST_H + +/** Information about a single voter in a vote or a consensus. */ +typedef struct networkstatus_voter_info_t { + /** Declared SHA-1 digest of this voter's identity key */ + char identity_digest[DIGEST_LEN]; + char *nickname; /**< Nickname of this voter */ + /** Digest of this voter's "legacy" identity key, if any. In vote only; for + * consensuses, we treat legacy keys as additional signers. */ + char legacy_id_digest[DIGEST_LEN]; + char *address; /**< Address of this voter, in string format. */ + uint32_t addr; /**< Address of this voter, in IPv4, in host order. */ + uint16_t dir_port; /**< Directory port of this voter */ + uint16_t or_port; /**< OR port of this voter */ + char *contact; /**< Contact information for this voter. */ + char vote_digest[DIGEST_LEN]; /**< Digest of this voter's vote, as signed. */ + + /* Nothing from here on is signed. */ + /** The signature of the document and the signature's status. */ + smartlist_t *sigs; +} networkstatus_voter_info_t; + +#endif + diff --git a/src/or/node_st.h b/src/or/node_st.h new file mode 100644 index 0000000000..43206f662f --- /dev/null +++ b/src/or/node_st.h @@ -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 */ + +#ifndef NODE_ST_H +#define NODE_ST_H + +#include "hsdir_index_st.h" + +/** A node_t represents a Tor router. + * + * Specifically, a node_t is a Tor router as we are using it: a router that + * we are considering for circuits, connections, and so on. A node_t is a + * thin wrapper around the routerstatus, routerinfo, and microdesc for a + * single router, and provides a consistent interface for all of them. + * + * Also, a node_t has mutable state. While a routerinfo, a routerstatus, + * and a microdesc have[*] only the information read from a router + * descriptor, a consensus entry, and a microdescriptor (respectively)... + * a node_t has flags based on *our own current opinion* of the node. + * + * [*] Actually, there is some leftover information in each that is mutable. + * We should try to excise that. + */ +struct node_t { + /* Indexing information */ + + /** Used to look up the node_t by its identity digest. */ + HT_ENTRY(node_t) ht_ent; + /** Used to look up the node_t by its ed25519 identity digest. */ + HT_ENTRY(node_t) ed_ht_ent; + /** Position of the node within the list of nodes */ + int nodelist_idx; + + /** The identity digest of this node_t. No more than one node_t per + * identity may exist at a time. */ + char identity[DIGEST_LEN]; + + /** The ed25519 identity of this node_t. This field is nonzero iff we + * currently have an ed25519 identity for this node in either md or ri, + * _and_ this node has been inserted to the ed25519-to-node map in the + * nodelist. + */ + ed25519_public_key_t ed25519_id; + + microdesc_t *md; + routerinfo_t *ri; + routerstatus_t *rs; + + /* local info: copied from routerstatus, then possibly frobbed based + * on experience. Authorities set this stuff directly. Note that + * these reflect knowledge of the primary (IPv4) OR port only. */ + + unsigned int is_running:1; /**< As far as we know, is this OR currently + * running? */ + unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR? + * (For Authdir: Have we validated this OR?) */ + unsigned int is_fast:1; /** Do we think this is a fast OR? */ + unsigned int is_stable:1; /** Do we think this is a stable OR? */ + unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */ + unsigned int is_exit:1; /**< Do we think this is an OK exit? */ + unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked, + * or otherwise nasty? */ + unsigned int is_hs_dir:1; /**< True iff this router is a hidden service + * directory according to the authorities. */ + + /* Local info: warning state. */ + + unsigned int name_lookup_warned:1; /**< Have we warned the user for referring + * to this (unnamed) router by nickname? + */ + + /** Local info: we treat this node as if it rejects everything */ + unsigned int rejects_all:1; + + /* Local info: derived. */ + + /** True if the IPv6 OR port is preferred over the IPv4 OR port. + * XX/teor - can this become out of date if the torrc changes? */ + unsigned int ipv6_preferred:1; + + /** According to the geoip db what country is this router in? */ + /* XXXprop186 what is this suppose to mean with multiple OR ports? */ + country_t country; + + /* The below items are used only by authdirservers for + * reachability testing. */ + + /** When was the last time we could reach this OR? */ + time_t last_reachable; /* IPv4. */ + time_t last_reachable6; /* IPv6. */ + + /* Hidden service directory index data. This is used by a service or client + * in order to know what's the hs directory index for this node at the time + * the consensus is set. */ + struct hsdir_index_t hsdir_index; +}; + +#endif + diff --git a/src/or/nodelist.c b/src/or/nodelist.c index bc9a79940b..5e575e9a83 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -68,6 +68,14 @@ #include "dirauth/mode.h" +#include "dir_server_st.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "routerstatus_st.h" + static void nodelist_drop_node(node_t *node, int remove_from_ht); #define node_free(val) \ FREE_AND_NULL(node_t, node_free_, (val)) @@ -632,6 +640,15 @@ nodelist_set_consensus(networkstatus_t *ns) } } +/** Return 1 iff node has Exit flag and no BadExit flag. + * Otherwise, return 0. + */ +int +node_is_good_exit(const node_t *node) +{ + return node->is_exit && ! node->is_bad_exit; +} + /** Helper: return true iff a node has a usable amount of information*/ static inline int node_is_usable(const node_t *node) diff --git a/src/or/nodelist.h b/src/or/nodelist.h index 1ffba2e8df..fd91a26832 100644 --- a/src/or/nodelist.h +++ b/src/or/nodelist.h @@ -46,6 +46,7 @@ void node_get_verbose_nickname(const node_t *node, void node_get_verbose_nickname_by_id(const char *id_digest, char *verbose_name_out); int node_is_dir(const node_t *node); +int node_is_good_exit(const node_t *node); int node_has_any_descriptor(const node_t *node); int node_has_preferred_descriptor(const node_t *node, int for_direct_connect); diff --git a/src/or/ns_detached_signatures_st.h b/src/or/ns_detached_signatures_st.h new file mode 100644 index 0000000000..4cb37de632 --- /dev/null +++ b/src/or/ns_detached_signatures_st.h @@ -0,0 +1,22 @@ +/* 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 NS_DETACHED_SIGNATURES_ST_H +#define NS_DETACHED_SIGNATURES_ST_H + +/** A set of signatures for a networkstatus consensus. Unless otherwise + * noted, all fields are as for networkstatus_t. */ +struct ns_detached_signatures_t { + time_t valid_after; + time_t fresh_until; + time_t valid_until; + strmap_t *digests; /**< Map from flavor name to digestset_t */ + strmap_t *signatures; /**< Map from flavor name to list of + * document_signature_t */ +}; + +#endif + diff --git a/src/or/onion.c b/src/or/onion.c index 829be12bae..c84cb13ade 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -77,6 +77,10 @@ #include "rephist.h" #include "router.h" +#include "cell_st.h" +#include "extend_info_st.h" +#include "or_circuit_st.h" + // trunnel #include "ed25519_cert.h" diff --git a/src/or/or.h b/src/or/or.h index 345aa6bed8..014704768a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -86,6 +86,10 @@ #include "util_format.h" #include "hs_circuitmap.h" +// These, more than other includes, are for keeping the other struct +// definitions working. We should remove them when we minimize our includes. +#include "entry_port_cfg_st.h" + /* These signals are defined to help handle_control_signal work. */ #ifndef SIGHUP @@ -897,18 +901,7 @@ struct hs_ident_edge_conn_t; struct hs_ident_dir_conn_t; struct hs_ident_circuit_t; -/* Hidden service directory index used in a node_t which is set once we set - * the consensus. */ -typedef struct hsdir_index_t { - /* HSDir index to use when fetching a descriptor. */ - uint8_t fetch[DIGEST256_LEN]; - - /* HSDir index used by services to store their first and second - * descriptor. The first descriptor is chronologically older than the second - * one and uses older TP and SRV values. */ - uint8_t store_first[DIGEST256_LEN]; - uint8_t store_second[DIGEST256_LEN]; -} hsdir_index_t; +typedef struct hsdir_index_t hsdir_index_t; /** Time interval for tracking replays of DH public keys received in * INTRODUCE2 cells. Used only to avoid launching multiple @@ -1174,26 +1167,12 @@ typedef struct channel_tls_s channel_tls_t; typedef struct circuitmux_s circuitmux_t; -/** Parsed onion routing cell. All communication between nodes - * is via cells. */ -typedef struct cell_t { - circid_t circ_id; /**< Circuit which received the cell. */ - uint8_t command; /**< Type of the cell: one of CELL_PADDING, CELL_CREATE, - * CELL_DESTROY, etc */ - uint8_t payload[CELL_PAYLOAD_SIZE]; /**< Cell body. */ -} cell_t; - -/** Parsed variable-length onion routing cell. */ -typedef struct var_cell_t { - /** Type of the cell: CELL_VERSIONS, etc. */ - uint8_t command; - /** Circuit thich received the cell */ - circid_t circ_id; - /** Number of bytes actually stored in payload */ - uint16_t payload_len; - /** Payload of this cell */ - uint8_t payload[FLEXIBLE_ARRAY_MEMBER]; -} var_cell_t; +typedef struct cell_t cell_t; +typedef struct var_cell_t var_cell_t; +typedef struct packed_cell_t packed_cell_t; +typedef struct cell_queue_t cell_queue_t; +typedef struct destroy_cell_t destroy_cell_t; +typedef struct destroy_cell_queue_t destroy_cell_queue_t; /** A parsed Extended ORPort message. */ typedef struct ext_or_cmd_t { @@ -1202,39 +1181,6 @@ typedef struct ext_or_cmd_t { char body[FLEXIBLE_ARRAY_MEMBER]; /** Message body */ } ext_or_cmd_t; -/** A cell as packed for writing to the network. */ -typedef struct packed_cell_t { - /** Next cell queued on this circuit. */ - TOR_SIMPLEQ_ENTRY(packed_cell_t) next; - char body[CELL_MAX_NETWORK_SIZE]; /**< Cell as packed for network. */ - uint32_t inserted_timestamp; /**< Time (in timestamp units) when this cell - * was inserted */ -} packed_cell_t; - -/** A queue of cells on a circuit, waiting to be added to the - * or_connection_t's outbuf. */ -typedef struct cell_queue_t { - /** Linked list of packed_cell_t*/ - TOR_SIMPLEQ_HEAD(cell_simpleq, packed_cell_t) head; - int n; /**< The number of cells in the queue. */ -} cell_queue_t; - -/** A single queued destroy cell. */ -typedef struct destroy_cell_t { - TOR_SIMPLEQ_ENTRY(destroy_cell_t) next; - circid_t circid; - uint32_t inserted_timestamp; /**< Time (in timestamp units) when this cell - * was inserted */ - uint8_t reason; -} destroy_cell_t; - -/** A queue of destroy cells on a channel. */ -typedef struct destroy_cell_queue_t { - /** Linked list of packed_cell_t */ - TOR_SIMPLEQ_HEAD(dcell_simpleq, destroy_cell_t) head; - int n; /**< The number of cells in the queue. */ -} destroy_cell_queue_t; - /** Beginning of a RELAY cell payload. */ typedef struct { uint8_t command; /**< The end-to-end relay command. */ @@ -1245,55 +1191,8 @@ typedef struct { } relay_header_t; typedef struct socks_request_t socks_request_t; - -typedef struct entry_port_cfg_t { - /* Client port types (socks, dns, trans, natd) only: */ - uint8_t isolation_flags; /**< Zero or more isolation flags */ - int session_group; /**< A session group, or -1 if this port is not in a - * session group. */ - - /* Socks only: */ - /** When both no-auth and user/pass are advertised by a SOCKS client, select - * no-auth. */ - unsigned int socks_prefer_no_auth : 1; - /** When ISO_SOCKSAUTH is in use, Keep-Alive circuits indefinitely. */ - unsigned int socks_iso_keep_alive : 1; - - /* Client port types only: */ - unsigned int ipv4_traffic : 1; - unsigned int ipv6_traffic : 1; - unsigned int prefer_ipv6 : 1; - unsigned int dns_request : 1; - unsigned int onion_traffic : 1; - - /** For a socks listener: should we cache IPv4/IPv6 DNS information that - * exit nodes tell us? - * - * @{ */ - unsigned int cache_ipv4_answers : 1; - unsigned int cache_ipv6_answers : 1; - /** @} */ - /** For a socks listeners: if we find an answer in our client-side DNS cache, - * should we use it? - * - * @{ */ - unsigned int use_cached_ipv4_answers : 1; - unsigned int use_cached_ipv6_answers : 1; - /** @} */ - /** For socks listeners: When we can automap an address to IPv4 or IPv6, - * do we prefer IPv6? */ - unsigned int prefer_ipv6_virtaddr : 1; - -} entry_port_cfg_t; - -typedef struct server_port_cfg_t { - /* Server port types (or, dir) only: */ - unsigned int no_advertise : 1; - unsigned int no_listen : 1; - unsigned int all_addrs : 1; - unsigned int bind_ipv4_only : 1; - unsigned int bind_ipv6_only : 1; -} server_port_cfg_t; +typedef struct entry_port_cfg_t entry_port_cfg_t; +typedef struct server_port_cfg_t server_port_cfg_t; /* Values for connection_t.magic: used to make sure that downcasts (casts from * connection_t to foo_connection_t) are safe. */ @@ -1305,139 +1204,6 @@ typedef struct server_port_cfg_t { #define CONTROL_CONNECTION_MAGIC 0x8abc765du #define LISTENER_CONNECTION_MAGIC 0x1a1ac741u -struct buf_t; - -/** Description of a connection to another host or process, and associated - * data. - * - * A connection is named based on what it's connected to -- an "OR - * connection" has a Tor node on the other end, an "exit - * connection" has a website or other server on the other end, and an - * "AP connection" has an application proxy (and thus a user) on the - * other end. - * - * Every connection has a type and a state. Connections never change - * their type, but can go through many state changes in their lifetime. - * - * Every connection has two associated input and output buffers. - * Listeners don't use them. For non-listener connections, incoming - * data is appended to conn->inbuf, and outgoing data is taken from - * conn->outbuf. Connections differ primarily in the functions called - * to fill and drain these buffers. - */ -typedef struct connection_t { - uint32_t magic; /**< For memory debugging: must equal one of - * *_CONNECTION_MAGIC. */ - - uint8_t state; /**< Current state of this connection. */ - unsigned int type:5; /**< What kind of connection is this? */ - unsigned int purpose:5; /**< Only used for DIR and EXIT types currently. */ - - /* The next fields are all one-bit booleans. Some are only applicable to - * connection subtypes, but we hold them here anyway, to save space. - */ - unsigned int read_blocked_on_bw:1; /**< Boolean: should we start reading - * again once the bandwidth throttler allows it? */ - unsigned int write_blocked_on_bw:1; /**< Boolean: should we start writing - * again once the bandwidth throttler allows - * writes? */ - unsigned int hold_open_until_flushed:1; /**< Despite this connection's being - * marked for close, do we flush it - * before closing it? */ - unsigned int inbuf_reached_eof:1; /**< Boolean: did read() return 0 on this - * conn? */ - /** Set to 1 when we're inside connection_flushed_some to keep us from - * calling connection_handle_write() recursively. */ - unsigned int in_flushed_some:1; - /** True if connection_handle_write is currently running on this connection. - */ - unsigned int in_connection_handle_write:1; - - /* For linked connections: - */ - unsigned int linked:1; /**< True if there is, or has been, a linked_conn. */ - /** True iff we'd like to be notified about read events from the - * linked conn. */ - unsigned int reading_from_linked_conn:1; - /** True iff we're willing to write to the linked conn. */ - unsigned int writing_to_linked_conn:1; - /** True iff we're currently able to read on the linked conn, and our - * read_event should be made active with libevent. */ - unsigned int active_on_link:1; - /** True iff we've called connection_close_immediate() on this linked - * connection. */ - unsigned int linked_conn_is_closed:1; - - /** CONNECT/SOCKS proxy client handshake state (for outgoing connections). */ - unsigned int proxy_state:4; - - /** Our socket; set to TOR_INVALID_SOCKET if this connection is closed, - * or has no socket. */ - tor_socket_t s; - int conn_array_index; /**< Index into the global connection array. */ - - struct event *read_event; /**< Libevent event structure. */ - struct event *write_event; /**< Libevent event structure. */ - struct buf_t *inbuf; /**< Buffer holding data read over this connection. */ - struct buf_t *outbuf; /**< Buffer holding data to write over this - * connection. */ - size_t outbuf_flushlen; /**< How much data should we try to flush from the - * outbuf? */ - time_t timestamp_last_read_allowed; /**< When was the last time libevent said - * we could read? */ - time_t timestamp_last_write_allowed; /**< When was the last time libevent - * said we could write? */ - - time_t timestamp_created; /**< When was this connection_t created? */ - - int socket_family; /**< Address family of this connection's socket. Usually - * AF_INET, but it can also be AF_UNIX, or AF_INET6 */ - tor_addr_t addr; /**< IP that socket "s" is directly connected to; - * may be the IP address for a proxy or pluggable transport, - * see "address" for the address of the final destination. - */ - uint16_t port; /**< If non-zero, port that socket "s" is directly connected - * to; may be the port for a proxy or pluggable transport, - * see "address" for the port at the final destination. */ - uint16_t marked_for_close; /**< Should we close this conn on the next - * iteration of the main loop? (If true, holds - * the line number where this connection was - * marked.) */ - const char *marked_for_close_file; /**< For debugging: in which file were - * we marked for close? */ - char *address; /**< FQDN (or IP) and port of the final destination for this - * connection; this is always the remote address, it is - * passed to a proxy or pluggable transport if one in use. - * See "addr" and "port" for the address that socket "s" is - * directly connected to. - * strdup into this, because free_connection() frees it. */ - /** Another connection that's connected to this one in lieu of a socket. */ - struct connection_t *linked_conn; - - /** Unique identifier for this connection on this Tor instance. */ - uint64_t global_identifier; - - /** Bytes read since last call to control_event_conn_bandwidth_used(). - * Only used if we're configured to emit CONN_BW events. */ - uint32_t n_read_conn_bw; - - /** Bytes written since last call to control_event_conn_bandwidth_used(). - * Only used if we're configured to emit CONN_BW events. */ - uint32_t n_written_conn_bw; -} connection_t; - -/** Subtype of connection_t; used for a listener socket. */ -typedef struct listener_connection_t { - connection_t base_; - - /** If the connection is a CONN_TYPE_AP_DNS_LISTENER, this field points - * to the evdns_server_port it uses to listen to and answer connections. */ - struct evdns_server_port *dns_server_port; - - entry_port_cfg_t entry_cfg; - -} listener_connection_t; - /** Minimum length of the random part of an AUTH_CHALLENGE cell. */ #define OR_AUTH_CHALLENGE_LEN 32 @@ -1497,100 +1263,8 @@ typedef struct listener_connection_t { * signs. */ #define V3_AUTH_BODY_LEN (V3_AUTH_FIXED_PART_LEN + 8 + 16) -/** Structure to hold all the certificates we've received on an OR connection - */ -typedef struct or_handshake_certs_t { - /** True iff we originated this connection. */ - int started_here; - /** The cert for the 'auth' RSA key that's supposed to sign the AUTHENTICATE - * cell. Signed with the RSA identity key. */ - tor_x509_cert_t *auth_cert; - /** The cert for the 'link' RSA key that was used to negotiate the TLS - * connection. Signed with the RSA identity key. */ - tor_x509_cert_t *link_cert; - /** A self-signed identity certificate: the RSA identity key signed - * with itself. */ - tor_x509_cert_t *id_cert; - /** The Ed25519 signing key, signed with the Ed25519 identity key. */ - struct tor_cert_st *ed_id_sign; - /** A digest of the X509 link certificate for the TLS connection, signed - * with the Ed25519 siging key. */ - struct tor_cert_st *ed_sign_link; - /** The Ed25519 authentication key (that's supposed to sign an AUTHENTICATE - * cell) , signed with the Ed25519 siging key. */ - struct tor_cert_st *ed_sign_auth; - /** The Ed25519 identity key, crosssigned with the RSA identity key. */ - uint8_t *ed_rsa_crosscert; - /** The length of ed_rsa_crosscert in bytes */ - size_t ed_rsa_crosscert_len; -} or_handshake_certs_t; - -/** Stores flags and information related to the portion of a v2/v3 Tor OR - * connection handshake that happens after the TLS handshake is finished. - */ -typedef struct or_handshake_state_t { - /** When was the VERSIONS cell sent on this connection? Used to get - * an estimate of the skew in the returning NETINFO reply. */ - time_t sent_versions_at; - /** True iff we originated this connection */ - unsigned int started_here : 1; - /** True iff we have received and processed a VERSIONS cell. */ - unsigned int received_versions : 1; - /** True iff we have received and processed an AUTH_CHALLENGE cell */ - unsigned int received_auth_challenge : 1; - /** True iff we have received and processed a CERTS cell. */ - unsigned int received_certs_cell : 1; - /** True iff we have received and processed an AUTHENTICATE cell */ - unsigned int received_authenticate : 1; - - /* True iff we've received valid authentication to some identity. */ - unsigned int authenticated : 1; - unsigned int authenticated_rsa : 1; - unsigned int authenticated_ed25519 : 1; - - /* True iff we have sent a netinfo cell */ - unsigned int sent_netinfo : 1; - - /** The signing->ed25519 link certificate corresponding to the x509 - * certificate we used on the TLS connection (if this is a server-side - * connection). We make a copy of this here to prevent a race condition - * caused by TLS context rotation. */ - struct tor_cert_st *own_link_cert; - - /** True iff we should feed outgoing cells into digest_sent and - * digest_received respectively. - * - * From the server's side of the v3 handshake, we want to capture everything - * from the VERSIONS cell through and including the AUTH_CHALLENGE cell. - * From the client's, we want to capture everything from the VERSIONS cell - * through but *not* including the AUTHENTICATE cell. - * - * @{ */ - unsigned int digest_sent_data : 1; - unsigned int digest_received_data : 1; - /**@}*/ - - /** Identity RSA digest that we have received and authenticated for our peer - * on this connection. */ - uint8_t authenticated_rsa_peer_id[DIGEST_LEN]; - /** Identity Ed25519 public key that we have received and authenticated for - * our peer on this connection. */ - ed25519_public_key_t authenticated_ed25519_peer_id; - - /** Digests of the cells that we have sent or received as part of a V3 - * handshake. Used for making and checking AUTHENTICATE cells. - * - * @{ - */ - crypto_digest_t *digest_sent; - crypto_digest_t *digest_received; - /** @} */ - - /** Certificates that a connection initiator sent us in a CERTS cell; we're - * holding on to them until we get an AUTHENTICATE cell. - */ - or_handshake_certs_t *certs; -} or_handshake_state_t; +typedef struct or_handshake_certs_t or_handshake_certs_t; +typedef struct or_handshake_state_t or_handshake_state_t; /** Length of Extended ORPort connection identifier. */ #define EXT_OR_CONN_ID_LEN DIGEST_LEN /* 20 */ @@ -1607,381 +1281,20 @@ typedef struct or_handshake_state_t { * drops below this size. */ #define OR_CONN_LOWWATER (16*1024) -/** Subtype of connection_t for an "OR connection" -- that is, one that speaks - * cells over TLS. */ -typedef struct or_connection_t { - connection_t base_; - - /** Hash of the public RSA key for the other side's identity key, or zeroes - * if the other side hasn't shown us a valid identity key. */ - char identity_digest[DIGEST_LEN]; - - /** Extended ORPort connection identifier. */ - char *ext_or_conn_id; - /** This is the ClientHash value we expect to receive from the - * client during the Extended ORPort authentication protocol. We - * compute it upon receiving the ClientNoce from the client, and we - * compare it with the acual ClientHash value sent by the - * client. */ - char *ext_or_auth_correct_client_hash; - /** String carrying the name of the pluggable transport - * (e.g. "obfs2") that is obfuscating this connection. If no - * pluggable transports are used, it's NULL. */ - char *ext_or_transport; - - char *nickname; /**< Nickname of OR on other side (if any). */ - - tor_tls_t *tls; /**< TLS connection state. */ - int tls_error; /**< Last tor_tls error code. */ - /** When we last used this conn for any client traffic. If not - * recent, we can rate limit it further. */ - - /* Channel using this connection */ - channel_tls_t *chan; - - tor_addr_t real_addr; /**< The actual address that this connection came from - * or went to. The addr field is prone to - * getting overridden by the address from the router - * descriptor matching identity_digest. */ - - /** Should this connection be used for extending circuits to the server - * matching the identity_digest field? Set to true if we're pretty - * sure we aren't getting MITMed, either because we're connected to an - * address listed in a server descriptor, or because an authenticated - * NETINFO cell listed the address we're connected to as recognized. */ - unsigned int is_canonical:1; - - /** True iff this is an outgoing connection. */ - unsigned int is_outgoing:1; - unsigned int proxy_type:2; /**< One of PROXY_NONE...PROXY_SOCKS5 */ - unsigned int wide_circ_ids:1; - /** True iff this connection has had its bootstrap failure logged with - * control_event_bootstrap_problem. */ - unsigned int have_noted_bootstrap_problem:1; - /** True iff this is a client connection and its address has been put in the - * geoip cache and handled by the DoS mitigation subsystem. We use this to - * insure we have a coherent count of concurrent connection. */ - unsigned int tracked_for_dos_mitigation : 1; - - uint16_t link_proto; /**< What protocol version are we using? 0 for - * "none negotiated yet." */ - uint16_t idle_timeout; /**< How long can this connection sit with no - * circuits on it before we close it? Based on - * IDLE_CIRCUIT_TIMEOUT_{NON,}CANONICAL and - * on is_canonical, randomized. */ - or_handshake_state_t *handshake_state; /**< If we are setting this connection - * up, state information to do so. */ - - time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/ - - token_bucket_rw_t bucket; /**< Used for rate limiting when the connection is - * in state CONN_OPEN. */ - - /* - * Count the number of bytes flushed out on this orconn, and the number of - * bytes TLS actually sent - used for overhead estimation for scheduling. - */ - uint64_t bytes_xmitted, bytes_xmitted_by_tls; -} or_connection_t; - -/** Subtype of connection_t for an "edge connection" -- that is, an entry (ap) - * connection, or an exit. */ -typedef struct edge_connection_t { - connection_t base_; - - struct edge_connection_t *next_stream; /**< Points to the next stream at this - * edge, if any */ - int package_window; /**< How many more relay cells can I send into the - * circuit? */ - int deliver_window; /**< How many more relay cells can end at me? */ - - struct circuit_t *on_circuit; /**< The circuit (if any) that this edge - * connection is using. */ - - /** A pointer to which node in the circ this conn exits at. Set for AP - * connections and for hidden service exit connections. */ - struct crypt_path_t *cpath_layer; - /** What rendezvous service are we querying for (if an AP) or providing (if - * an exit)? */ - rend_data_t *rend_data; - - /* Hidden service connection identifier for edge connections. Used by the HS - * client-side code to identify client SOCKS connections and by the - * service-side code to match HS circuits with their streams. */ - struct hs_ident_edge_conn_t *hs_ident; - - uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit - * connection. Exit connections only. */ - uint32_t begincell_flags; /** Flags sent or received in the BEGIN cell - * for this connection */ - - streamid_t stream_id; /**< The stream ID used for this edge connection on its - * circuit */ - - /** The reason why this connection is closing; passed to the controller. */ - uint16_t end_reason; - - /** Bytes read since last call to control_event_stream_bandwidth_used() */ - uint32_t n_read; - - /** Bytes written since last call to control_event_stream_bandwidth_used() */ - uint32_t n_written; - - /** True iff this connection is for a DNS request only. */ - unsigned int is_dns_request:1; - /** True iff this connection is for a PTR DNS request. (exit only) */ - unsigned int is_reverse_dns_lookup:1; - - unsigned int edge_has_sent_end:1; /**< For debugging; only used on edge - * connections. Set once we've set the stream end, - * and check in connection_about_to_close_connection(). - */ - /** True iff we've blocked reading until the circuit has fewer queued - * cells. */ - unsigned int edge_blocked_on_circ:1; - - /** Unique ID for directory requests; this used to be in connection_t, but - * that's going away and being used on channels instead. We still tag - * edge connections with dirreq_id from circuits, so it's copied here. */ - uint64_t dirreq_id; -} edge_connection_t; - -/** Subtype of edge_connection_t for an "entry connection" -- that is, a SOCKS - * connection, a DNS request, a TransPort connection or a NATD connection */ -typedef struct entry_connection_t { - edge_connection_t edge_; - - /** Nickname of planned exit node -- used with .exit support. */ - /* XXX prop220: we need to make chosen_exit_name able to encode Ed IDs too. - * That's logically part of the UI parts for prop220 though. */ - char *chosen_exit_name; - - socks_request_t *socks_request; /**< SOCKS structure describing request (AP - * only.) */ - - /* === Isolation related, AP only. === */ - entry_port_cfg_t entry_cfg; - /** AP only: The newnym epoch in which we created this connection. */ - unsigned nym_epoch; - - /** AP only: The original requested address before we rewrote it. */ - char *original_dest_address; - /* Other fields to isolate on already exist. The ClientAddr is addr. The - ClientProtocol is a combination of type and socks_request-> - socks_version. SocksAuth is socks_request->username/password. - DestAddr is in socks_request->address. */ - - /** Number of times we've reassigned this application connection to - * a new circuit. We keep track because the timeout is longer if we've - * already retried several times. */ - uint8_t num_socks_retries; - - /** For AP connections only: buffer for data that we have sent - * optimistically, which we might need to re-send if we have to - * retry this connection. */ - struct buf_t *pending_optimistic_data; - /* For AP connections only: buffer for data that we previously sent - * optimistically which we are currently re-sending as we retry this - * connection. */ - struct buf_t *sending_optimistic_data; - - /** If this is a DNSPort connection, this field holds the pending DNS - * request that we're going to try to answer. */ - struct evdns_server_request *dns_server_request; - -#define DEBUGGING_17659 - -#ifdef DEBUGGING_17659 - uint16_t marked_pending_circ_line; - const char *marked_pending_circ_file; -#endif - -#define NUM_CIRCUITS_LAUNCHED_THRESHOLD 10 - /** Number of times we've launched a circuit to handle this stream. If - * it gets too high, that could indicate an inconsistency between our - * "launch a circuit to handle this stream" logic and our "attach our - * stream to one of the available circuits" logic. */ - unsigned int num_circuits_launched:4; - - /** True iff this stream must attach to a one-hop circuit (e.g. for - * begin_dir). */ - unsigned int want_onehop:1; - /** True iff this stream should use a BEGIN_DIR relay command to establish - * itself rather than BEGIN (either via onehop or via a whole circuit). */ - unsigned int use_begindir:1; - - /** For AP connections only. If 1, and we fail to reach the chosen exit, - * stop requiring it. */ - unsigned int chosen_exit_optional:1; - /** For AP connections only. If non-zero, this exit node was picked as - * a result of the TrackHostExit, and the value decrements every time - * we fail to complete a circuit to our chosen exit -- if it reaches - * zero, abandon the associated mapaddress. */ - unsigned int chosen_exit_retries:3; - - /** True iff this is an AP connection that came from a transparent or - * NATd connection */ - unsigned int is_transparent_ap:1; - - /** For AP connections only: Set if this connection's target exit node - * allows optimistic data (that is, data sent on this stream before - * the exit has sent a CONNECTED cell) and we have chosen to use it. - */ - unsigned int may_use_optimistic_data : 1; -} entry_connection_t; - -/** Subtype of connection_t for an "directory connection" -- that is, an HTTP - * connection to retrieve or serve directory material. */ -typedef struct dir_connection_t { - connection_t base_; - - /** Which 'resource' did we ask the directory for? This is typically the part - * of the URL string that defines, relative to the directory conn purpose, - * what thing we want. For example, in router descriptor downloads by - * descriptor digest, it contains "d/", then one or more +-separated - * fingerprints. - **/ - char *requested_resource; - unsigned int dirconn_direct:1; /**< Is this dirconn direct, or via Tor? */ - - /** If we're fetching descriptors, what router purpose shall we assign - * to them? */ - uint8_t router_purpose; - - /** List of spooled_resource_t for objects that we're spooling. We use - * it from back to front. */ - smartlist_t *spool; - /** The compression object doing on-the-fly compression for spooled data. */ - tor_compress_state_t *compress_state; - - /** What rendezvous service are we querying for? */ - rend_data_t *rend_data; - - /* Hidden service connection identifier for dir connections: Used by HS - client-side code to fetch HS descriptors, and by the service-side code to - upload descriptors. */ - struct hs_ident_dir_conn_t *hs_ident; - - /** If this is a one-hop connection, tracks the state of the directory guard - * for this connection (if any). */ - struct circuit_guard_state_t *guard_state; - - char identity_digest[DIGEST_LEN]; /**< Hash of the public RSA key for - * the directory server's signing key. */ - - /** Unique ID for directory requests; this used to be in connection_t, but - * that's going away and being used on channels instead. The dirserver still - * needs this for the incoming side, so it's moved here. */ - uint64_t dirreq_id; - -#ifdef MEASUREMENTS_21206 - /** Number of RELAY_DATA cells received. */ - uint32_t data_cells_received; - - /** Number of RELAY_DATA cells sent. */ - uint32_t data_cells_sent; -#endif /* defined(MEASUREMENTS_21206) */ -} dir_connection_t; - -/** Subtype of connection_t for an connection to a controller. */ -typedef struct control_connection_t { - connection_t base_; - - uint64_t event_mask; /**< Bitfield: which events does this controller - * care about? - * EVENT_MAX_ is >31, so we need a 64 bit mask */ - - /** True if we have sent a protocolinfo reply on this connection. */ - unsigned int have_sent_protocolinfo:1; - /** True if we have received a takeownership command on this - * connection. */ - unsigned int is_owning_control_connection:1; - - /** List of ephemeral onion services belonging to this connection. */ - smartlist_t *ephemeral_onion_services; - - /** If we have sent an AUTHCHALLENGE reply on this connection and - * have not received a successful AUTHENTICATE command, points to - * the value which the client must send to authenticate itself; - * otherwise, NULL. */ - char *safecookie_client_hash; - - /** Amount of space allocated in incoming_cmd. */ - uint32_t incoming_cmd_len; - /** Number of bytes currently stored in incoming_cmd. */ - uint32_t incoming_cmd_cur_len; - /** A control command that we're reading from the inbuf, but which has not - * yet arrived completely. */ - char *incoming_cmd; -} control_connection_t; +typedef struct connection_t connection_t; +typedef struct control_connection_t control_connection_t; +typedef struct dir_connection_t dir_connection_t; +typedef struct edge_connection_t edge_connection_t; +typedef struct entry_connection_t entry_connection_t; +typedef struct listener_connection_t listener_connection_t; +typedef struct or_connection_t or_connection_t; /** Cast a connection_t subtype pointer to a connection_t **/ #define TO_CONN(c) (&(((c)->base_))) -/** Cast a entry_connection_t subtype pointer to a edge_connection_t **/ -#define ENTRY_TO_EDGE_CONN(c) (&(((c))->edge_)) /** Cast a entry_connection_t subtype pointer to a connection_t **/ #define ENTRY_TO_CONN(c) (TO_CONN(ENTRY_TO_EDGE_CONN(c))) -/** Convert a connection_t* to an or_connection_t*; assert if the cast is - * invalid. */ -static or_connection_t *TO_OR_CONN(connection_t *); -/** Convert a connection_t* to a dir_connection_t*; assert if the cast is - * invalid. */ -static dir_connection_t *TO_DIR_CONN(connection_t *); -/** Convert a connection_t* to an edge_connection_t*; assert if the cast is - * invalid. */ -static edge_connection_t *TO_EDGE_CONN(connection_t *); -/** Convert a connection_t* to an entry_connection_t*; assert if the cast is - * invalid. */ -static entry_connection_t *TO_ENTRY_CONN(connection_t *); -/** Convert a edge_connection_t* to an entry_connection_t*; assert if the cast - * is invalid. */ -static entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *); -/** Convert a connection_t* to an control_connection_t*; assert if the cast is - * invalid. */ -static control_connection_t *TO_CONTROL_CONN(connection_t *); -/** Convert a connection_t* to an listener_connection_t*; assert if the cast is - * invalid. */ -static listener_connection_t *TO_LISTENER_CONN(connection_t *); - -static inline or_connection_t *TO_OR_CONN(connection_t *c) -{ - tor_assert(c->magic == OR_CONNECTION_MAGIC); - return DOWNCAST(or_connection_t, c); -} -static inline dir_connection_t *TO_DIR_CONN(connection_t *c) -{ - tor_assert(c->magic == DIR_CONNECTION_MAGIC); - return DOWNCAST(dir_connection_t, c); -} -static inline edge_connection_t *TO_EDGE_CONN(connection_t *c) -{ - tor_assert(c->magic == EDGE_CONNECTION_MAGIC || - c->magic == ENTRY_CONNECTION_MAGIC); - return DOWNCAST(edge_connection_t, c); -} -static inline entry_connection_t *TO_ENTRY_CONN(connection_t *c) -{ - tor_assert(c->magic == ENTRY_CONNECTION_MAGIC); - return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_.base_); -} -static inline entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *c) -{ - tor_assert(c->base_.magic == ENTRY_CONNECTION_MAGIC); - return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_); -} -static inline control_connection_t *TO_CONTROL_CONN(connection_t *c) -{ - tor_assert(c->magic == CONTROL_CONNECTION_MAGIC); - return DOWNCAST(control_connection_t, c); -} -static inline listener_connection_t *TO_LISTENER_CONN(connection_t *c) -{ - tor_assert(c->magic == LISTENER_CONNECTION_MAGIC); - return DOWNCAST(listener_connection_t, c); -} - /** What action type does an address policy indicate: accept or reject? */ typedef enum { ADDR_POLICY_ACCEPT=1, @@ -2015,19 +1328,7 @@ typedef struct addr_policy_t { uint16_t prt_max; /**< Highest port number to accept/reject. */ } addr_policy_t; -/** A cached_dir_t represents a cacheable directory object, along with its - * compressed form. */ -typedef struct cached_dir_t { - char *dir; /**< Contents of this object, NUL-terminated. */ - char *dir_compressed; /**< Compressed contents of this object. */ - size_t dir_len; /**< Length of dir (not counting its NUL). */ - size_t dir_compressed_len; /**< Length of dir_compressed. */ - time_t published; /**< When was this object published. */ - common_digests_t digests; /**< Digests of this object (networkstatus only) */ - /** Sha3 digest (also ns only) */ - uint8_t digest_sha3_as_signed[DIGEST256_LEN]; - int refcnt; /**< Reference count for this cached_dir_t. */ -} cached_dir_t; +typedef struct cached_dir_t cached_dir_t; /** Enum used to remember where a signed_descriptor_t is stored and how to * manage the memory for signed_descriptor_body. */ @@ -2080,59 +1381,7 @@ typedef enum { #define download_schedule_increment_bitfield_t \ ENUM_BF(download_schedule_increment_t) -/** Information about our plans for retrying downloads for a downloadable - * directory object. - * Each type of downloadable directory object has a corresponding retry - * schedule, which can be different depending on whether the object is - * being downloaded from an authority or a mirror (want_authority). - * next_attempt_at contains the next time we will attempt to download - * the object. - * For schedules that increment_on failure, n_download_failures - * is used to determine the position in the schedule. (Each schedule is a - * smartlist of integer delays, parsed from a CSV option.) Every time a - * connection attempt fails, n_download_failures is incremented, - * the new delay value is looked up from the schedule, and - * next_attempt_at is set delay seconds from the time the previous - * connection failed. Therefore, at most one failure-based connection can be - * in progress for each download_status_t. - * For schedules that increment_on attempt, n_download_attempts - * is used to determine the position in the schedule. Every time a - * connection attempt is made, n_download_attempts is incremented, - * the new delay value is looked up from the schedule, and - * next_attempt_at is set delay seconds from the time the previous - * connection was attempted. Therefore, multiple concurrent attempted-based - * connections can be in progress for each download_status_t. - * After an object is successfully downloaded, any other concurrent connections - * are terminated. A new schedule which starts at position 0 is used for - * subsequent downloads of the same object. - */ -typedef struct download_status_t { - time_t next_attempt_at; /**< When should we try downloading this object - * again? */ - uint8_t n_download_failures; /**< Number of failed downloads of the most - * recent object, since the last success. */ - uint8_t n_download_attempts; /**< Number of (potentially concurrent) attempts - * to download the most recent object, since - * the last success. */ - download_schedule_bitfield_t schedule : 8; /**< What kind of object is being - * downloaded? This determines the - * schedule used for the download. - */ - download_want_authority_bitfield_t want_authority : 1; /**< Is the download - * happening from an authority - * or a mirror? This determines - * the schedule used for the - * download. */ - download_schedule_increment_bitfield_t increment_on : 1; /**< does this - * schedule increment on each attempt, - * or after each failure? */ - uint8_t last_backoff_position; /**< number of attempts/failures, depending - * on increment_on, when we last recalculated - * the delay. Only updated if backoff - * == 1. */ - int last_delay_used; /**< last delay used for random exponential backoff; - * only updated if backoff == 1 */ -} download_status_t; +typedef struct download_status_t download_status_t; /** If n_download_failures is this high, the download can never happen. */ #define IMPOSSIBLE_TO_DOWNLOAD 255 @@ -2142,53 +1391,7 @@ typedef struct download_status_t { * create any that are larger than this. */ #define ROUTER_ANNOTATION_BUF_LEN 256 -/** Information need to cache an onion router's descriptor. */ -typedef struct signed_descriptor_t { - /** Pointer to the raw server descriptor, preceded by annotations. Not - * necessarily NUL-terminated. If saved_location is SAVED_IN_CACHE, this - * pointer is null. */ - char *signed_descriptor_body; - /** Length of the annotations preceding the server descriptor. */ - size_t annotations_len; - /** Length of the server descriptor. */ - size_t signed_descriptor_len; - /** Digest of the server descriptor, computed as specified in - * dir-spec.txt. */ - char signed_descriptor_digest[DIGEST_LEN]; - /** Identity digest of the router. */ - char identity_digest[DIGEST_LEN]; - /** Declared publication time of the descriptor. */ - time_t published_on; - /** For routerdescs only: digest of the corresponding extrainfo. */ - char extra_info_digest[DIGEST_LEN]; - /** For routerdescs only: A SHA256-digest of the extrainfo (if any) */ - char extra_info_digest256[DIGEST256_LEN]; - /** Certificate for ed25519 signing key. */ - struct tor_cert_st *signing_key_cert; - /** For routerdescs only: Status of downloading the corresponding - * extrainfo. */ - download_status_t ei_dl_status; - /** Where is the descriptor saved? */ - saved_location_t saved_location; - /** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of - * this descriptor in the corresponding file. */ - off_t saved_offset; - /** What position is this descriptor within routerlist->routers or - * routerlist->old_routers? -1 for none. */ - int routerlist_index; - /** The valid-until time of the most recent consensus that listed this - * descriptor. 0 for "never listed in a consensus, so far as we know." */ - time_t last_listed_as_valid_until; - /* If true, we do not ever try to save this object in the cache. */ - unsigned int do_not_cache : 1; - /* If true, this item is meant to represent an extrainfo. */ - unsigned int is_extrainfo : 1; - /* If true, we got an extrainfo for this item, and the digest was right, - * but it was incompatible. */ - unsigned int extrainfo_is_bogus : 1; - /* If true, we are willing to transmit this item unencrypted. */ - unsigned int send_unencrypted : 1; -} signed_descriptor_t; +typedef struct signed_descriptor_t signed_descriptor_t; /** A signed integer representing a country code. */ typedef int16_t country_t; @@ -2230,183 +1433,9 @@ typedef struct protover_summary_flags_t { unsigned int supports_v3_rendezvous_point: 1; } protover_summary_flags_t; -/** Information about another onion router in the network. */ -typedef struct { - signed_descriptor_t cache_info; - char *nickname; /**< Human-readable OR name. */ - - uint32_t addr; /**< IPv4 address of OR, in host order. */ - uint16_t or_port; /**< Port for TLS connections. */ - uint16_t dir_port; /**< Port for HTTP directory connections. */ - - /** A router's IPv6 address, if it has one. */ - /* XXXXX187 Actually these should probably be part of a list of addresses, - * not just a special case. Use abstractions to access these; don't do it - * directly. */ - tor_addr_t ipv6_addr; - uint16_t ipv6_orport; - - crypto_pk_t *onion_pkey; /**< Public RSA key for onions. */ - crypto_pk_t *identity_pkey; /**< Public RSA key for signing. */ - /** Public curve25519 key for onions */ - curve25519_public_key_t *onion_curve25519_pkey; - /** What's the earliest expiration time on all the certs in this - * routerinfo? */ - time_t cert_expiration_time; - - char *platform; /**< What software/operating system is this OR using? */ - - char *protocol_list; /**< Encoded list of subprotocol versions supported - * by this OR */ - - /* link info */ - uint32_t bandwidthrate; /**< How many bytes does this OR add to its token - * bucket per second? */ - uint32_t bandwidthburst; /**< How large is this OR's token bucket? */ - /** How many bytes/s is this router known to handle? */ - uint32_t bandwidthcapacity; - smartlist_t *exit_policy; /**< What streams will this OR permit - * to exit on IPv4? NULL for 'reject *:*'. */ - /** What streams will this OR permit to exit on IPv6? - * NULL for 'reject *:*' */ - struct short_policy_t *ipv6_exit_policy; - long uptime; /**< How many seconds the router claims to have been up */ - smartlist_t *declared_family; /**< Nicknames of router which this router - * claims are its family. */ - char *contact_info; /**< Declared contact info for this router. */ - unsigned int is_hibernating:1; /**< Whether the router claims to be - * hibernating */ - unsigned int caches_extra_info:1; /**< Whether the router says it caches and - * serves extrainfo documents. */ - unsigned int allow_single_hop_exits:1; /**< Whether the router says - * it allows single hop exits. */ - - unsigned int wants_to_be_hs_dir:1; /**< True iff this router claims to be - * a hidden service directory. */ - unsigned int policy_is_reject_star:1; /**< True iff the exit policy for this - * router rejects everything. */ - /** True if, after we have added this router, we should re-launch - * tests for it. */ - unsigned int needs_retest_if_added:1; - - /** True iff this router included "tunnelled-dir-server" in its descriptor, - * implying it accepts tunnelled directory requests, or it advertised - * dir_port > 0. */ - unsigned int supports_tunnelled_dir_requests:1; - - /** Used during voting to indicate that we should not include an entry for - * this routerinfo. Used only during voting. */ - unsigned int omit_from_vote:1; - - /** Flags to summarize the protocol versions for this routerinfo_t. */ - protover_summary_flags_t pv; - -/** Tor can use this router for general positions in circuits; we got it - * from a directory server as usual, or we're an authority and a server - * uploaded it. */ -#define ROUTER_PURPOSE_GENERAL 0 -/** Tor should avoid using this router for circuit-building: we got it - * from a controller. If the controller wants to use it, it'll have to - * ask for it by identity. */ -#define ROUTER_PURPOSE_CONTROLLER 1 -/** Tor should use this router only for bridge positions in circuits: we got - * it via a directory request from the bridge itself, or a bridge - * authority. */ -#define ROUTER_PURPOSE_BRIDGE 2 -/** Tor should not use this router; it was marked in cached-descriptors with - * a purpose we didn't recognize. */ -#define ROUTER_PURPOSE_UNKNOWN 255 - - /** In what way did we find out about this router? One of ROUTER_PURPOSE_*. - * Routers of different purposes are kept segregated and used for different - * things; see notes on ROUTER_PURPOSE_* macros above. - */ - uint8_t purpose; -} routerinfo_t; - -/** Information needed to keep and cache a signed extra-info document. */ -typedef struct extrainfo_t { - signed_descriptor_t cache_info; - /** SHA256 digest of this document */ - uint8_t digest256[DIGEST256_LEN]; - /** The router's nickname. */ - char nickname[MAX_NICKNAME_LEN+1]; - /** True iff we found the right key for this extra-info, verified the - * signature, and found it to be bad. */ - unsigned int bad_sig : 1; - /** If present, we didn't have the right key to verify this extra-info, - * so this is a copy of the signature in the document. */ - char *pending_sig; - /** Length of pending_sig. */ - size_t pending_sig_len; -} extrainfo_t; - -/** Contents of a single router entry in a network status object. - */ -typedef struct routerstatus_t { - time_t published_on; /**< When was this router published? */ - char nickname[MAX_NICKNAME_LEN+1]; /**< The nickname this router says it - * has. */ - char identity_digest[DIGEST_LEN]; /**< Digest of the router's identity - * key. */ - /** Digest of the router's most recent descriptor or microdescriptor. - * If it's a descriptor, we only use the first DIGEST_LEN bytes. */ - char descriptor_digest[DIGEST256_LEN]; - uint32_t addr; /**< IPv4 address for this router, in host order. */ - uint16_t or_port; /**< IPv4 OR port for this router. */ - uint16_t dir_port; /**< Directory port for this router. */ - tor_addr_t ipv6_addr; /**< IPv6 address for this router. */ - uint16_t ipv6_orport; /**< IPv6 OR port for this router. */ - unsigned int is_authority:1; /**< True iff this router is an authority. */ - unsigned int is_exit:1; /**< True iff this router is a good exit. */ - unsigned int is_stable:1; /**< True iff this router stays up a long time. */ - unsigned int is_fast:1; /**< True iff this router has good bandwidth. */ - /** True iff this router is called 'running' in the consensus. We give it - * this funny name so that we don't accidentally use this bit as a view of - * whether we think the router is *currently* running. If that's what you - * want to know, look at is_running in node_t. */ - unsigned int is_flagged_running:1; - unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */ - unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another - * router. */ - unsigned int is_valid:1; /**< True iff this router isn't invalid. */ - unsigned int is_possible_guard:1; /**< True iff this router would be a good - * choice as an entry guard. */ - unsigned int is_bad_exit:1; /**< True iff this node is a bad choice for - * an exit node. */ - unsigned int is_hs_dir:1; /**< True iff this router is a v2-or-later hidden - * service directory. */ - unsigned int is_v2_dir:1; /** True iff this router publishes an open DirPort - * or it claims to accept tunnelled dir requests. - */ - - unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */ - unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */ - unsigned int bw_is_unmeasured:1; /**< This is a consensus entry, with - * the Unmeasured flag set. */ - - /** Flags to summarize the protocol versions for this routerstatus_t. */ - protover_summary_flags_t pv; - - uint32_t bandwidth_kb; /**< Bandwidth (capacity) of the router as reported in - * the vote/consensus, in kilobytes/sec. */ - - /** The consensus has guardfraction information for this router. */ - unsigned int has_guardfraction:1; - /** The guardfraction value of this router. */ - uint32_t guardfraction_percentage; - - char *exitsummary; /**< exit policy summary - - * XXX weasel: this probably should not stay a string. */ - - /* ---- The fields below aren't derived from the networkstatus; they - * hold local information only. */ - - time_t last_dir_503_at; /**< When did this router last tell us that it - * was too busy to serve directory info? */ - download_status_t dl_status; - -} routerstatus_t; +typedef struct routerinfo_t routerinfo_t; +typedef struct extrainfo_t extrainfo_t; +typedef struct routerstatus_t routerstatus_t; /** A single entry in a parsed policy summary, describing a range of ports. */ typedef struct short_policy_entry_t { @@ -2427,244 +1456,13 @@ typedef struct short_policy_t { short_policy_entry_t entries[FLEXIBLE_ARRAY_MEMBER]; } short_policy_t; -/** A microdescriptor is the smallest amount of information needed to build a - * circuit through a router. They are generated by the directory authorities, - * using information from the uploaded routerinfo documents. They are not - * self-signed, but are rather authenticated by having their hash in a signed - * networkstatus document. */ -typedef struct microdesc_t { - /** Hashtable node, used to look up the microdesc by its digest. */ - HT_ENTRY(microdesc_t) node; - - /* Cache information */ - - /** When was this microdescriptor last listed in a consensus document? - * Once a microdesc has been unlisted long enough, we can drop it. - */ - time_t last_listed; - /** Where is this microdescriptor currently stored? */ - saved_location_bitfield_t saved_location : 3; - /** If true, do not attempt to cache this microdescriptor on disk. */ - unsigned int no_save : 1; - /** If true, this microdesc has an entry in the microdesc_map */ - unsigned int held_in_map : 1; - /** Reference count: how many node_ts have a reference to this microdesc? */ - unsigned int held_by_nodes; - - /** If saved_location == SAVED_IN_CACHE, this field holds the offset of the - * microdescriptor in the cache. */ - off_t off; - - /* The string containing the microdesc. */ - - /** A pointer to the encoded body of the microdescriptor. If the - * saved_location is SAVED_IN_CACHE, then the body is a pointer into an - * mmap'd region. Otherwise, it is a malloc'd string. The string might not - * be NUL-terminated; take the length from bodylen. */ - char *body; - /** The length of the microdescriptor in body. */ - size_t bodylen; - /** A SHA256-digest of the microdescriptor. */ - char digest[DIGEST256_LEN]; - - /* Fields in the microdescriptor. */ - - /** As routerinfo_t.onion_pkey */ - crypto_pk_t *onion_pkey; - /** As routerinfo_t.onion_curve25519_pkey */ - curve25519_public_key_t *onion_curve25519_pkey; - /** Ed25519 identity key, if included. */ - ed25519_public_key_t *ed25519_identity_pkey; - /** As routerinfo_t.ipv6_addr */ - tor_addr_t ipv6_addr; - /** As routerinfo_t.ipv6_orport */ - uint16_t ipv6_orport; - /** As routerinfo_t.family */ - smartlist_t *family; - /** IPv4 exit policy summary */ - short_policy_t *exit_policy; - /** IPv6 exit policy summary */ - short_policy_t *ipv6_exit_policy; - -} microdesc_t; - -/** A node_t represents a Tor router. - * - * Specifically, a node_t is a Tor router as we are using it: a router that - * we are considering for circuits, connections, and so on. A node_t is a - * thin wrapper around the routerstatus, routerinfo, and microdesc for a - * single router, and provides a consistent interface for all of them. - * - * Also, a node_t has mutable state. While a routerinfo, a routerstatus, - * and a microdesc have[*] only the information read from a router - * descriptor, a consensus entry, and a microdescriptor (respectively)... - * a node_t has flags based on *our own current opinion* of the node. - * - * [*] Actually, there is some leftover information in each that is mutable. - * We should try to excise that. - */ -typedef struct node_t { - /* Indexing information */ - - /** Used to look up the node_t by its identity digest. */ - HT_ENTRY(node_t) ht_ent; - /** Used to look up the node_t by its ed25519 identity digest. */ - HT_ENTRY(node_t) ed_ht_ent; - /** Position of the node within the list of nodes */ - int nodelist_idx; - - /** The identity digest of this node_t. No more than one node_t per - * identity may exist at a time. */ - char identity[DIGEST_LEN]; - - /** The ed25519 identity of this node_t. This field is nonzero iff we - * currently have an ed25519 identity for this node in either md or ri, - * _and_ this node has been inserted to the ed25519-to-node map in the - * nodelist. - */ - ed25519_public_key_t ed25519_id; - - microdesc_t *md; - routerinfo_t *ri; - routerstatus_t *rs; - - /* local info: copied from routerstatus, then possibly frobbed based - * on experience. Authorities set this stuff directly. Note that - * these reflect knowledge of the primary (IPv4) OR port only. */ - - unsigned int is_running:1; /**< As far as we know, is this OR currently - * running? */ - unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR? - * (For Authdir: Have we validated this OR?) */ - unsigned int is_fast:1; /** Do we think this is a fast OR? */ - unsigned int is_stable:1; /** Do we think this is a stable OR? */ - unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */ - unsigned int is_exit:1; /**< Do we think this is an OK exit? */ - unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked, - * or otherwise nasty? */ - unsigned int is_hs_dir:1; /**< True iff this router is a hidden service - * directory according to the authorities. */ - - /* Local info: warning state. */ - - unsigned int name_lookup_warned:1; /**< Have we warned the user for referring - * to this (unnamed) router by nickname? - */ - - /** Local info: we treat this node as if it rejects everything */ - unsigned int rejects_all:1; - - /* Local info: derived. */ - - /** True if the IPv6 OR port is preferred over the IPv4 OR port. - * XX/teor - can this become out of date if the torrc changes? */ - unsigned int ipv6_preferred:1; - - /** According to the geoip db what country is this router in? */ - /* XXXprop186 what is this suppose to mean with multiple OR ports? */ - country_t country; - - /* The below items are used only by authdirservers for - * reachability testing. */ - - /** When was the last time we could reach this OR? */ - time_t last_reachable; /* IPv4. */ - time_t last_reachable6; /* IPv6. */ - - /* Hidden service directory index data. This is used by a service or client - * in order to know what's the hs directory index for this node at the time - * the consensus is set. */ - struct hsdir_index_t hsdir_index; -} node_t; - -/** Linked list of microdesc hash lines for a single router in a directory - * vote. - */ -typedef struct vote_microdesc_hash_t { - /** Next element in the list, or NULL. */ - struct vote_microdesc_hash_t *next; - /** The raw contents of the microdesc hash line, from the "m" through the - * newline. */ - char *microdesc_hash_line; -} vote_microdesc_hash_t; - -/** The claim about a single router, made in a vote. */ -typedef struct vote_routerstatus_t { - routerstatus_t status; /**< Underlying 'status' object for this router. - * Flags are redundant. */ - /** How many known-flags are allowed in a vote? This is the width of - * the flags field of vote_routerstatus_t */ -#define MAX_KNOWN_FLAGS_IN_VOTE 64 - uint64_t flags; /**< Bit-field for all recognized flags; index into - * networkstatus_t.known_flags. */ - char *version; /**< The version that the authority says this router is - * running. */ - char *protocols; /**< The protocols that this authority says this router - * provides. */ - unsigned int has_measured_bw:1; /**< The vote had a measured bw */ - /** True iff the vote included an entry for ed25519 ID, or included - * "id ed25519 none" to indicate that there was no ed25519 ID. */ - unsigned int has_ed25519_listing:1; - /** True if the Ed25519 listing here is the consensus-opinion for the - * Ed25519 listing; false if there was no consensus on Ed25519 key status, - * or if this VRS doesn't reflect it. */ - unsigned int ed25519_reflects_consensus:1; - uint32_t measured_bw_kb; /**< Measured bandwidth (capacity) of the router */ - /** The hash or hashes that the authority claims this microdesc has. */ - vote_microdesc_hash_t *microdesc; - /** Ed25519 identity for this router, or zero if it has none. */ - uint8_t ed25519_id[ED25519_PUBKEY_LEN]; -} vote_routerstatus_t; - -/** A signature of some document by an authority. */ -typedef struct document_signature_t { - /** Declared SHA-1 digest of this voter's identity key */ - char identity_digest[DIGEST_LEN]; - /** Declared SHA-1 digest of signing key used by this voter. */ - char signing_key_digest[DIGEST_LEN]; - /** Algorithm used to compute the digest of the document. */ - digest_algorithm_t alg; - /** Signature of the signed thing. */ - char *signature; - /** Length of signature */ - int signature_len; - unsigned int bad_signature : 1; /**< Set to true if we've tried to verify - * the sig, and we know it's bad. */ - unsigned int good_signature : 1; /**< Set to true if we've verified the sig - * as good. */ -} document_signature_t; - -/** Information about a single voter in a vote or a consensus. */ -typedef struct networkstatus_voter_info_t { - /** Declared SHA-1 digest of this voter's identity key */ - char identity_digest[DIGEST_LEN]; - char *nickname; /**< Nickname of this voter */ - /** Digest of this voter's "legacy" identity key, if any. In vote only; for - * consensuses, we treat legacy keys as additional signers. */ - char legacy_id_digest[DIGEST_LEN]; - char *address; /**< Address of this voter, in string format. */ - uint32_t addr; /**< Address of this voter, in IPv4, in host order. */ - uint16_t dir_port; /**< Directory port of this voter */ - uint16_t or_port; /**< OR port of this voter */ - char *contact; /**< Contact information for this voter. */ - char vote_digest[DIGEST_LEN]; /**< Digest of this voter's vote, as signed. */ - - /* Nothing from here on is signed. */ - /** The signature of the document and the signature's status. */ - smartlist_t *sigs; -} networkstatus_voter_info_t; - -typedef struct networkstatus_sr_info_t { - /* Indicate if the dirauth partitipates in the SR protocol with its vote. - * This is tied to the SR flag in the vote. */ - unsigned int participate:1; - /* Both vote and consensus: Current and previous SRV. If list is empty, - * this means none were found in either the consensus or vote. */ - struct sr_srv_t *previous_srv; - struct sr_srv_t *current_srv; - /* Vote only: List of commitments. */ - smartlist_t *commits; -} networkstatus_sr_info_t; +typedef struct microdesc_t microdesc_t; +typedef struct node_t node_t; +typedef struct vote_microdesc_hash_t vote_microdesc_hash_t; +typedef struct vote_routerstatus_t vote_routerstatus_t; +typedef struct document_signature_t document_signature_t; +typedef struct networkstatus_voter_info_t networkstatus_voter_info_t; +typedef struct networkstatus_sr_info_t networkstatus_sr_info_t; /** Enumerates the possible seriousness values of a networkstatus document. */ typedef enum { @@ -2684,98 +1482,8 @@ typedef enum { /** How many different consensus flavors are there? */ #define N_CONSENSUS_FLAVORS ((int)(FLAV_MICRODESC)+1) -/** A common structure to hold a v3 network status vote, or a v3 network - * status consensus. */ -typedef struct networkstatus_t { - networkstatus_type_t type; /**< Vote, consensus, or opinion? */ - consensus_flavor_t flavor; /**< If a consensus, what kind? */ - unsigned int has_measured_bws : 1;/**< True iff this networkstatus contains - * measured= bandwidth values. */ - - time_t published; /**< Vote only: Time when vote was written. */ - time_t valid_after; /**< Time after which this vote or consensus applies. */ - time_t fresh_until; /**< Time before which this is the most recent vote or - * consensus. */ - time_t valid_until; /**< Time after which this vote or consensus should not - * be used. */ - - /** Consensus only: what method was used to produce this consensus? */ - int consensus_method; - /** Vote only: what methods is this voter willing to use? */ - smartlist_t *supported_methods; - - /** List of 'package' lines describing hashes of downloadable packages */ - smartlist_t *package_lines; - - /** How long does this vote/consensus claim that authorities take to - * distribute their votes to one another? */ - int vote_seconds; - /** How long does this vote/consensus claim that authorities take to - * distribute their consensus signatures to one another? */ - int dist_seconds; - - /** Comma-separated list of recommended client software, or NULL if this - * voter has no opinion. */ - char *client_versions; - char *server_versions; - - /** Lists of subprotocol versions which are _recommended_ for relays and - * clients, or which are _require_ for relays and clients. Tor shouldn't - * make any more network connections if a required protocol is missing. - */ - char *recommended_relay_protocols; - char *recommended_client_protocols; - char *required_relay_protocols; - char *required_client_protocols; - - /** List of flags that this vote/consensus applies to routers. If a flag is - * not listed here, the voter has no opinion on what its value should be. */ - smartlist_t *known_flags; - - /** List of key=value strings for the parameters in this vote or - * consensus, sorted by key. */ - smartlist_t *net_params; - - /** List of key=value strings for the bw weight parameters in the - * consensus. */ - smartlist_t *weight_params; - - /** List of networkstatus_voter_info_t. For a vote, only one element - * is included. For a consensus, one element is included for every voter - * whose vote contributed to the consensus. */ - smartlist_t *voters; - - struct authority_cert_t *cert; /**< Vote only: the voter's certificate. */ - - /** Digests of this document, as signed. */ - common_digests_t digests; - /** A SHA3-256 digest of the document, not including signatures: used for - * consensus diffs */ - uint8_t digest_sha3_as_signed[DIGEST256_LEN]; - - /** List of router statuses, sorted by identity digest. For a vote, - * the elements are vote_routerstatus_t; for a consensus, the elements - * are routerstatus_t. */ - smartlist_t *routerstatus_list; - - /** If present, a map from descriptor digest to elements of - * routerstatus_list. */ - digestmap_t *desc_digest_map; - - /** Contains the shared random protocol data from a vote or consensus. */ - networkstatus_sr_info_t sr_info; -} networkstatus_t; - -/** A set of signatures for a networkstatus consensus. Unless otherwise - * noted, all fields are as for networkstatus_t. */ -typedef struct ns_detached_signatures_t { - time_t valid_after; - time_t fresh_until; - time_t valid_until; - strmap_t *digests; /**< Map from flavor name to digestset_t */ - strmap_t *signatures; /**< Map from flavor name to list of - * document_signature_t */ -} ns_detached_signatures_t; +typedef struct networkstatus_t networkstatus_t; +typedef struct ns_detached_signatures_t ns_detached_signatures_t; /** Allowable types of desc_store_t. */ typedef enum store_type_t { @@ -2783,91 +1491,10 @@ typedef enum store_type_t { EXTRAINFO_STORE = 1 } store_type_t; -/** A 'store' is a set of descriptors saved on disk, with accompanying - * journal, mmaped as needed, rebuilt as needed. */ -typedef struct desc_store_t { - /** Filename (within DataDir) for the store. We append .tmp to this - * filename for a temporary file when rebuilding the store, and .new to this - * filename for the journal. */ - const char *fname_base; - /** Human-readable description of what this store contains. */ - const char *description; - - tor_mmap_t *mmap; /**< A mmap for the main file in the store. */ - - store_type_t type; /**< What's stored in this store? */ - - /** The size of the router log, in bytes. */ - size_t journal_len; - /** The size of the router store, in bytes. */ - size_t store_len; - /** Total bytes dropped since last rebuild: this is space currently - * used in the cache and the journal that could be freed by a rebuild. */ - size_t bytes_dropped; -} desc_store_t; - -/** Contents of a directory of onion routers. */ -typedef struct { - /** Map from server identity digest to a member of routers. */ - struct digest_ri_map_t *identity_map; - /** Map from server descriptor digest to a signed_descriptor_t from - * routers or old_routers. */ - struct digest_sd_map_t *desc_digest_map; - /** Map from extra-info digest to an extrainfo_t. Only exists for - * routers in routers or old_routers. */ - struct digest_ei_map_t *extra_info_map; - /** Map from extra-info digests to a signed_descriptor_t for a router - * descriptor having that extra-info digest. Only exists for - * routers in routers or old_routers. */ - struct digest_sd_map_t *desc_by_eid_map; - /** List of routerinfo_t for all currently live routers we know. */ - smartlist_t *routers; - /** List of signed_descriptor_t for older router descriptors we're - * caching. */ - smartlist_t *old_routers; - /** Store holding server descriptors. If present, any router whose - * cache_info.saved_location == SAVED_IN_CACHE is stored in this file - * starting at cache_info.saved_offset */ - desc_store_t desc_store; - /** Store holding extra-info documents. */ - desc_store_t extrainfo_store; -} routerlist_t; - -/** Information on router used when extending a circuit. We don't need a - * full routerinfo_t to extend: we only need addr:port:keyid to build an OR - * connection, and onion_key to create the onionskin. Note that for onehop - * general-purpose tunnels, the onion_key is NULL. */ -typedef struct extend_info_t { - char nickname[MAX_HEX_NICKNAME_LEN+1]; /**< This router's nickname for - * display. */ - /** Hash of this router's RSA identity key. */ - char identity_digest[DIGEST_LEN]; - /** Ed25519 identity for this router, if any. */ - ed25519_public_key_t ed_identity; - uint16_t port; /**< OR port. */ - tor_addr_t addr; /**< IP address. */ - crypto_pk_t *onion_key; /**< Current onionskin key. */ - curve25519_public_key_t curve25519_onion_key; -} extend_info_t; - -/** Certificate for v3 directory protocol: binds long-term authority identity - * keys to medium-term authority signing keys. */ -typedef struct authority_cert_t { - /** Information relating to caching this cert on disk and looking it up. */ - signed_descriptor_t cache_info; - /** This authority's long-term authority identity key. */ - crypto_pk_t *identity_key; - /** This authority's medium-term signing key. */ - crypto_pk_t *signing_key; - /** The digest of signing_key */ - char signing_key_digest[DIGEST_LEN]; - /** The listed expiration time of this certificate. */ - time_t expires; - /** This authority's IPv4 address, in host order. */ - uint32_t addr; - /** This authority's directory port. */ - uint16_t dir_port; -} authority_cert_t; +typedef struct desc_store_t desc_store_t; +typedef struct routerlist_t routerlist_t; +typedef struct extend_info_t extend_info_t; +typedef struct authority_cert_t authority_cert_t; /** Bitfield enum type listing types of information that directory authorities * can be authoritative about, and that directory caches may or may not cache. @@ -2909,107 +1536,15 @@ typedef struct { } u; } onion_handshake_state_t; -typedef struct relay_crypto_t { - /* crypto environments */ - /** Encryption key and counter for cells heading towards the OR at this - * step. */ - crypto_cipher_t *f_crypto; - /** Encryption key and counter for cells heading back from the OR at this - * step. */ - crypto_cipher_t *b_crypto; - - /** Digest state for cells heading towards the OR at this step. */ - crypto_digest_t *f_digest; /* for integrity checking */ - /** Digest state for cells heading away from the OR at this step. */ - crypto_digest_t *b_digest; - -} relay_crypto_t; - -/** Holds accounting information for a single step in the layered encryption - * performed by a circuit. Used only at the client edge of a circuit. */ -typedef struct crypt_path_t { - uint32_t magic; - - /** Cryptographic state used for encrypting and authenticating relay - * cells to and from this hop. */ - relay_crypto_t crypto; - - /** Current state of the handshake as performed with the OR at this - * step. */ - onion_handshake_state_t handshake_state; - /** Diffie-hellman handshake state for performing an introduction - * operations */ - crypto_dh_t *rend_dh_handshake_state; - - /** Negotiated key material shared with the OR at this step. */ - char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */ - - /** Information to extend to the OR at this step. */ - extend_info_t *extend_info; - - /** Is the circuit built to this step? Must be one of: - * - CPATH_STATE_CLOSED (The circuit has not been extended to this step) - * - CPATH_STATE_AWAITING_KEYS (We have sent an EXTEND/CREATE to this step - * and not received an EXTENDED/CREATED) - * - CPATH_STATE_OPEN (The circuit has been extended to this step) */ - uint8_t state; -#define CPATH_STATE_CLOSED 0 -#define CPATH_STATE_AWAITING_KEYS 1 -#define CPATH_STATE_OPEN 2 - struct crypt_path_t *next; /**< Link to next crypt_path_t in the circuit. - * (The list is circular, so the last node - * links to the first.) */ - struct crypt_path_t *prev; /**< Link to previous crypt_path_t in the - * circuit. */ - - int package_window; /**< How many cells are we allowed to originate ending - * at this step? */ - int deliver_window; /**< How many cells are we willing to deliver originating - * at this step? */ -} crypt_path_t; - -/** A reference-counted pointer to a crypt_path_t, used only to share - * the final rendezvous cpath to be used on a service-side rendezvous - * circuit among multiple circuits built in parallel to the same - * destination rendezvous point. */ -typedef struct { - /** The reference count. */ - unsigned int refcount; - /** The pointer. Set to NULL when the crypt_path_t is put into use - * on an opened rendezvous circuit. */ - crypt_path_t *cpath; -} crypt_path_reference_t; +typedef struct relay_crypto_t relay_crypto_t; +typedef struct crypt_path_t crypt_path_t; +typedef struct crypt_path_reference_t crypt_path_reference_t; #define CPATH_KEY_MATERIAL_LEN (20*2+16*2) #define DH_KEY_LEN DH_BYTES -/** Information used to build a circuit. */ -typedef struct { - /** Intended length of the final circuit. */ - int desired_path_len; - /** How to extend to the planned exit node. */ - extend_info_t *chosen_exit; - /** Whether every node in the circ must have adequate uptime. */ - unsigned int need_uptime : 1; - /** Whether every node in the circ must have adequate capacity. */ - unsigned int need_capacity : 1; - /** Whether the last hop was picked with exiting in mind. */ - unsigned int is_internal : 1; - /** Did we pick this as a one-hop tunnel (not safe for other streams)? - * These are for encrypted dir conns that exit to this router, not - * for arbitrary exits from the circuit. */ - unsigned int onehop_tunnel : 1; - /** The crypt_path_t to append after rendezvous: used for rendezvous. */ - crypt_path_t *pending_final_cpath; - /** A ref-counted reference to the crypt_path_t to append after - * rendezvous; used on the service side. */ - crypt_path_reference_t *service_pending_final_cpath_ref; - /** How many times has building a circuit for this task failed? */ - int failure_count; - /** At what time should we give up on this task? */ - time_t expiry_time; -} cpath_build_state_t; +typedef struct cpath_build_state_t cpath_build_state_t; /** "magic" value for an origin_circuit_t */ #define ORIGIN_CIRCUIT_MAGIC 0x35315243u @@ -3035,162 +1570,9 @@ typedef struct testing_cell_stats_entry_t { unsigned int exitward:1; /**< 0 for app-ward, 1 for exit-ward. */ } testing_cell_stats_entry_t; -/** - * A circuit is a path over the onion routing - * network. Applications can connect to one end of the circuit, and can - * create exit connections at the other end of the circuit. AP and exit - * connections have only one circuit associated with them (and thus these - * connection types are closed when the circuit is closed), whereas - * OR connections multiplex many circuits at once, and stay standing even - * when there are no circuits running over them. - * - * A circuit_t structure can fill one of two roles. First, a or_circuit_t - * links two connections together: either an edge connection and an OR - * connection, or two OR connections. (When joined to an OR connection, a - * circuit_t affects only cells sent to a particular circID on that - * connection. When joined to an edge connection, a circuit_t affects all - * data.) - - * Second, an origin_circuit_t holds the cipher keys and state for sending data - * along a given circuit. At the OP, it has a sequence of ciphers, each - * of which is shared with a single OR along the circuit. Separate - * ciphers are used for data going "forward" (away from the OP) and - * "backward" (towards the OP). At the OR, a circuit has only two stream - * ciphers: one for data going forward, and one for data going backward. - */ -typedef struct circuit_t { - uint32_t magic; /**< For memory and type debugging: must equal - * ORIGIN_CIRCUIT_MAGIC or OR_CIRCUIT_MAGIC. */ - - /** The channel that is next in this circuit. */ - channel_t *n_chan; - - /** - * The circuit_id used in the next (forward) hop of this circuit; - * this is unique to n_chan, but this ordered pair is globally - * unique: - * - * (n_chan->global_identifier, n_circ_id) - */ - circid_t n_circ_id; - - /** - * Circuit mux associated with n_chan to which this circuit is attached; - * NULL if we have no n_chan. - */ - circuitmux_t *n_mux; - - /** Queue of cells waiting to be transmitted on n_chan */ - cell_queue_t n_chan_cells; - - /** - * The hop to which we want to extend this circuit. Should be NULL if - * the circuit has attached to a channel. - */ - extend_info_t *n_hop; - - /** True iff we are waiting for n_chan_cells to become less full before - * allowing p_streams to add any more cells. (Origin circuit only.) */ - unsigned int streams_blocked_on_n_chan : 1; - /** True iff we are waiting for p_chan_cells to become less full before - * allowing n_streams to add any more cells. (OR circuit only.) */ - unsigned int streams_blocked_on_p_chan : 1; - - /** True iff we have queued a delete backwards on this circuit, but not put - * it on the output buffer. */ - unsigned int p_delete_pending : 1; - /** True iff we have queued a delete forwards on this circuit, but not put - * it on the output buffer. */ - unsigned int n_delete_pending : 1; - - /** True iff this circuit has received a DESTROY cell in either direction */ - unsigned int received_destroy : 1; - - uint8_t state; /**< Current status of this circuit. */ - uint8_t purpose; /**< Why are we creating this circuit? */ - - /** How many relay data cells can we package (read from edge streams) - * on this circuit before we receive a circuit-level sendme cell asking - * for more? */ - int package_window; - /** How many relay data cells will we deliver (write to edge streams) - * on this circuit? When deliver_window gets low, we send some - * circuit-level sendme cells to indicate that we're willing to accept - * more. */ - int deliver_window; - - /** Temporary field used during circuits_handle_oom. */ - uint32_t age_tmp; - - /** For storage while n_chan is pending (state CIRCUIT_STATE_CHAN_WAIT). */ - struct create_cell_t *n_chan_create_cell; - - /** When did circuit construction actually begin (ie send the - * CREATE cell or begin cannibalization). - * - * Note: This timer will get reset if we decide to cannibalize - * a circuit. It may also get reset during certain phases of hidden - * service circuit use. - * - * We keep this timestamp with a higher resolution than most so that the - * circuit-build-time tracking code can get millisecond resolution. - */ - struct timeval timestamp_began; - - /** This timestamp marks when the init_circuit_base constructor ran. */ - struct timeval timestamp_created; - - /** When the circuit was first used, or 0 if the circuit is clean. - * - * XXXX Note that some code will artificially adjust this value backward - * in time in order to indicate that a circuit shouldn't be used for new - * streams, but that it can stay alive as long as it has streams on it. - * That's a kludge we should fix. - * - * XXX The CBT code uses this field to record when HS-related - * circuits entered certain states. This usage probably won't - * interfere with this field's primary purpose, but we should - * document it more thoroughly to make sure of that. - * - * XXX The SocksPort option KeepaliveIsolateSOCKSAuth will artificially - * adjust this value forward each time a suitable stream is attached to an - * already constructed circuit, potentially keeping the circuit alive - * indefinitely. - */ - time_t timestamp_dirty; - - uint16_t marked_for_close; /**< Should we close this circuit at the end of - * the main loop? (If true, holds the line number - * where this circuit was marked.) */ - const char *marked_for_close_file; /**< For debugging: in which file was this - * circuit marked for close? */ - /** For what reason (See END_CIRC_REASON...) is this circuit being closed? - * This field is set in circuit_mark_for_close and used later in - * circuit_about_to_free. */ - int marked_for_close_reason; - /** As marked_for_close_reason, but reflects the underlying reason for - * closing this circuit. - */ - int marked_for_close_orig_reason; - - /** Unique ID for measuring tunneled network status requests. */ - uint64_t dirreq_id; - - /** Index in smartlist of all circuits (global_circuitlist). */ - int global_circuitlist_idx; - - /** Various statistics about cells being added to or removed from this - * circuit's queues; used only if CELL_STATS events are enabled and - * cleared after being sent to control port. */ - smartlist_t *testing_cell_stats; - - /** If set, points to an HS token that this circuit might be carrying. - * Used by the HS circuitmap. */ - hs_token_t *hs_token; - /** Hashtable node: used to look up the circuit by its HS token using the HS - circuitmap. */ - HT_ENTRY(circuit_t) hs_circuitmap_node; -} circuit_t; +typedef struct circuit_t circuit_t; +typedef struct origin_circuit_t origin_circuit_t; +typedef struct or_circuit_t or_circuit_t; /** Largest number of relay_early cells that we can send on a given * circuit. */ @@ -3253,288 +1635,6 @@ typedef enum { } path_state_t; #define path_state_bitfield_t ENUM_BF(path_state_t) -/** An origin_circuit_t holds data necessary to build and use a circuit. - */ -typedef struct origin_circuit_t { - circuit_t base_; - - /** Linked list of AP streams (or EXIT streams if hidden service) - * associated with this circuit. */ - edge_connection_t *p_streams; - - /** Bytes read on this circuit since last call to - * control_event_circ_bandwidth_used(). Only used if we're configured - * to emit CIRC_BW events. */ - uint32_t n_read_circ_bw; - - /** Bytes written to on this circuit since last call to - * control_event_circ_bandwidth_used(). Only used if we're configured - * to emit CIRC_BW events. */ - uint32_t n_written_circ_bw; - - /** Total known-valid relay cell bytes since last call to - * control_event_circ_bandwidth_used(). Only used if we're configured - * to emit CIRC_BW events. */ - uint32_t n_delivered_read_circ_bw; - - /** Total written relay cell bytes since last call to - * control_event_circ_bandwidth_used(). Only used if we're configured - * to emit CIRC_BW events. */ - uint32_t n_delivered_written_circ_bw; - - /** Total overhead data in all known-valid relay data cells since last - * call to control_event_circ_bandwidth_used(). Only used if we're - * configured to emit CIRC_BW events. */ - uint32_t n_overhead_read_circ_bw; - - /** Total written overhead data in all relay data cells since last call to - * control_event_circ_bandwidth_used(). Only used if we're configured - * to emit CIRC_BW events. */ - uint32_t n_overhead_written_circ_bw; - - /** Build state for this circuit. It includes the intended path - * length, the chosen exit router, rendezvous information, etc. - */ - cpath_build_state_t *build_state; - /** The doubly-linked list of crypt_path_t entries, one per hop, - * for this circuit. This includes ciphers for each hop, - * integrity-checking digests for each hop, and package/delivery - * windows for each hop. - */ - crypt_path_t *cpath; - - /** Holds all rendezvous data on either client or service side. */ - rend_data_t *rend_data; - - /** Holds hidden service identifier on either client or service side. This - * is for both introduction and rendezvous circuit. */ - struct hs_ident_circuit_t *hs_ident; - - /** Holds the data that the entry guard system uses to track the - * status of the guard this circuit is using, and thereby to determine - * whether this circuit can be used. */ - struct circuit_guard_state_t *guard_state; - - /** Index into global_origin_circuit_list for this circuit. -1 if not - * present. */ - int global_origin_circuit_list_idx; - - /** How many more relay_early cells can we send on this circuit, according - * to the specification? */ - unsigned int remaining_relay_early_cells : 4; - - /** Set if this circuit is insanely old and we already informed the user */ - unsigned int is_ancient : 1; - - /** Set if this circuit has already been opened. Used to detect - * cannibalized circuits. */ - unsigned int has_opened : 1; - - /** - * Path bias state machine. Used to ensure integrity of our - * circuit building and usage accounting. See path_state_t - * for more details. - */ - path_state_bitfield_t path_state : 3; - - /* If this flag is set, we should not consider attaching any more - * connections to this circuit. */ - unsigned int unusable_for_new_conns : 1; - - /** - * Tristate variable to guard against pathbias miscounting - * due to circuit purpose transitions changing the decision - * of pathbias_should_count(). This variable is informational - * only. The current results of pathbias_should_count() are - * the official decision for pathbias accounting. - */ - uint8_t pathbias_shouldcount; -#define PATHBIAS_SHOULDCOUNT_UNDECIDED 0 -#define PATHBIAS_SHOULDCOUNT_IGNORED 1 -#define PATHBIAS_SHOULDCOUNT_COUNTED 2 - - /** For path probing. Store the temporary probe stream ID - * for response comparison */ - streamid_t pathbias_probe_id; - - /** For path probing. Store the temporary probe address nonce - * (in host byte order) for response comparison. */ - uint32_t pathbias_probe_nonce; - - /** Set iff this is a hidden-service circuit which has timed out - * according to our current circuit-build timeout, but which has - * been kept around because it might still succeed in connecting to - * its destination, and which is not a fully-connected rendezvous - * circuit. - * - * (We clear this flag for client-side rendezvous circuits when they - * are 'joined' to the other side's rendezvous circuit, so that - * connection_ap_handshake_attach_circuit can put client streams on - * the circuit. We also clear this flag for service-side rendezvous - * circuits when they are 'joined' to a client's rend circ, but only - * for symmetry with the client case. Client-side introduction - * circuits are closed when we get a joined rend circ, and - * service-side introduction circuits never have this flag set.) */ - unsigned int hs_circ_has_timed_out : 1; - - /** Set iff this circuit has been given a relaxed timeout because - * no circuits have opened. Used to prevent spamming logs. */ - unsigned int relaxed_timeout : 1; - - /** Set iff this is a service-side rendezvous circuit for which a - * new connection attempt has been launched. We consider launching - * a new service-side rend circ to a client when the previous one - * fails; now that we don't necessarily close a service-side rend - * circ when we launch a new one to the same client, this flag keeps - * us from launching two retries for the same failed rend circ. */ - unsigned int hs_service_side_rend_circ_has_been_relaunched : 1; - - /** What commands were sent over this circuit that decremented the - * RELAY_EARLY counter? This is for debugging task 878. */ - uint8_t relay_early_commands[MAX_RELAY_EARLY_CELLS_PER_CIRCUIT]; - - /** How many RELAY_EARLY cells have been sent over this circuit? This is - * for debugging task 878, too. */ - int relay_early_cells_sent; - - /** The next stream_id that will be tried when we're attempting to - * construct a new AP stream originating at this circuit. */ - streamid_t next_stream_id; - - /* The intro key replaces the hidden service's public key if purpose is - * S_ESTABLISH_INTRO or S_INTRO, provided that no unversioned rendezvous - * descriptor is used. */ - crypto_pk_t *intro_key; - - /** Quasi-global identifier for this circuit; used for control.c */ - /* XXXX NM This can get re-used after 2**32 circuits. */ - uint32_t global_identifier; - - /** True if we have associated one stream to this circuit, thereby setting - * the isolation parameters for this circuit. Note that this doesn't - * necessarily mean that we've attached any streams to the circuit: - * we may only have marked up this circuit during the launch process. - */ - unsigned int isolation_values_set : 1; - /** True iff any stream has ever been attached to this circuit. - * - * In a better world we could use timestamp_dirty for this, but - * timestamp_dirty is far too overloaded at the moment. - */ - unsigned int isolation_any_streams_attached : 1; - - /** A bitfield of ISO_* flags for every isolation field such that this - * circuit has had streams with more than one value for that field - * attached to it. */ - uint8_t isolation_flags_mixed; - - /** @name Isolation parameters - * - * If any streams have been associated with this circ (isolation_values_set - * == 1), and all streams associated with the circuit have had the same - * value for some field ((isolation_flags_mixed & ISO_FOO) == 0), then these - * elements hold the value for that field. - * - * Note again that "associated" is not the same as "attached": we - * preliminarily associate streams with a circuit while the circuit is being - * launched, so that we can tell whether we need to launch more circuits. - * - * @{ - */ - uint8_t client_proto_type; - uint8_t client_proto_socksver; - uint16_t dest_port; - tor_addr_t client_addr; - char *dest_address; - int session_group; - unsigned nym_epoch; - size_t socks_username_len; - uint8_t socks_password_len; - /* Note that the next two values are NOT NUL-terminated; see - socks_username_len and socks_password_len for their lengths. */ - char *socks_username; - char *socks_password; - /** Global identifier for the first stream attached here; used by - * ISO_STREAM. */ - uint64_t associated_isolated_stream_global_id; - /**@}*/ - /** A list of addr_policy_t for this circuit in particular. Used by - * adjust_exit_policy_from_exitpolicy_failure. - */ - smartlist_t *prepend_policy; - - /** How long do we wait before closing this circuit if it remains - * completely idle after it was built, in seconds? This value - * is randomized on a per-circuit basis from CircuitsAvailableTimoeut - * to 2*CircuitsAvailableTimoeut. */ - int circuit_idle_timeout; - -} origin_circuit_t; - -struct onion_queue_t; - -/** An or_circuit_t holds information needed to implement a circuit at an - * OR. */ -typedef struct or_circuit_t { - circuit_t base_; - - /** Pointer to an entry on the onion queue, if this circuit is waiting for a - * chance to give an onionskin to a cpuworker. Used only in onion.c */ - struct onion_queue_t *onionqueue_entry; - /** Pointer to a workqueue entry, if this circuit has given an onionskin to - * a cpuworker and is waiting for a response. Used to decide whether it is - * safe to free a circuit or if it is still in use by a cpuworker. */ - struct workqueue_entry_s *workqueue_entry; - - /** The circuit_id used in the previous (backward) hop of this circuit. */ - circid_t p_circ_id; - /** Queue of cells waiting to be transmitted on p_conn. */ - cell_queue_t p_chan_cells; - /** The channel that is previous in this circuit. */ - channel_t *p_chan; - /** - * Circuit mux associated with p_chan to which this circuit is attached; - * NULL if we have no p_chan. - */ - circuitmux_t *p_mux; - /** Linked list of Exit streams associated with this circuit. */ - edge_connection_t *n_streams; - /** Linked list of Exit streams associated with this circuit that are - * still being resolved. */ - edge_connection_t *resolving_streams; - - /** Cryptographic state used for encrypting and authenticating relay - * cells to and from this hop. */ - relay_crypto_t crypto; - - /** Points to spliced circuit if purpose is REND_ESTABLISHED, and circuit - * is not marked for close. */ - struct or_circuit_t *rend_splice; - - /** Stores KH for the handshake. */ - char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */ - - /** How many more relay_early cells can we send on this circuit, according - * to the specification? */ - unsigned int remaining_relay_early_cells : 4; - - /* We have already received an INTRODUCE1 cell on this circuit. */ - unsigned int already_received_introduce1 : 1; - - /** If set, this circuit carries HS traffic. Consider it in any HS - * statistics. */ - unsigned int circuit_carries_hs_traffic_stats : 1; - - /** Number of cells that were removed from circuit queue; reset every - * time when writing buffer stats to disk. */ - uint32_t processed_cells; - - /** Total time in milliseconds that cells spent in both app-ward and - * exit-ward queues of this circuit; reset every time when writing - * buffer stats to disk. */ - uint64_t total_cell_waiting_time; -} or_circuit_t; - #if REND_COOKIE_LEN != DIGEST_LEN #error "The REND_TOKEN_LEN macro assumes REND_COOKIE_LEN == DIGEST_LEN" #endif @@ -3543,45 +1643,6 @@ typedef struct or_circuit_t { /** Convert a circuit subtype to a circuit_t. */ #define TO_CIRCUIT(x) (&((x)->base_)) -/** Convert a circuit_t* to a pointer to the enclosing or_circuit_t. Assert - * if the cast is impossible. */ -static or_circuit_t *TO_OR_CIRCUIT(circuit_t *); -static const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *); -/** Convert a circuit_t* to a pointer to the enclosing origin_circuit_t. - * Assert if the cast is impossible. */ -static origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *); -static const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT(const circuit_t *); - -/** Return 1 iff node has Exit flag and no BadExit flag. - * Otherwise, return 0. - */ -static inline int node_is_good_exit(const node_t *node) -{ - return node->is_exit && ! node->is_bad_exit; -} - -static inline or_circuit_t *TO_OR_CIRCUIT(circuit_t *x) -{ - tor_assert(x->magic == OR_CIRCUIT_MAGIC); - return DOWNCAST(or_circuit_t, x); -} -static inline const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *x) -{ - tor_assert(x->magic == OR_CIRCUIT_MAGIC); - return DOWNCAST(or_circuit_t, x); -} -static inline origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *x) -{ - tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC); - return DOWNCAST(origin_circuit_t, x); -} -static inline const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT( - const circuit_t *x) -{ - tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC); - return DOWNCAST(origin_circuit_t, x); -} - /* limits for TCP send and recv buffer size used for constrained sockets */ #define MIN_CONSTRAINED_TCP_BUFFER 2048 #define MAX_CONSTRAINED_TCP_BUFFER 262144 /* 256k */ @@ -3622,27 +1683,7 @@ static inline const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT( /** First automatically allocated session group number */ #define SESSION_GROUP_FIRST_AUTO -4 -/** Configuration for a single port that we're listening on. */ -typedef struct port_cfg_t { - tor_addr_t addr; /**< The actual IP to listen on, if !is_unix_addr. */ - int port; /**< The configured port, or CFG_AUTO_PORT to tell Tor to pick its - * own port. */ - uint8_t type; /**< One of CONN_TYPE_*_LISTENER */ - unsigned is_unix_addr : 1; /**< True iff this is an AF_UNIX address. */ - - unsigned is_group_writable : 1; - unsigned is_world_writable : 1; - unsigned relax_dirmode_check : 1; - - entry_port_cfg_t entry_cfg; - - server_port_cfg_t server_cfg; - - /* Unix sockets only: */ - /** Path for an AF_UNIX address */ - char unix_addr[FLEXIBLE_ARRAY_MEMBER]; -} port_cfg_t; - +typedef struct port_cfg_t port_cfg_t; typedef struct routerset_t routerset_t; /** A magic value for the (Socks|OR|...)Port options below, telling Tor @@ -4796,54 +2837,6 @@ typedef struct { #define SOCKS_COMMAND_IS_RESOLVE(c) ((c)==SOCKS_COMMAND_RESOLVE || \ (c)==SOCKS_COMMAND_RESOLVE_PTR) -/** State of a SOCKS request from a user to an OP. Also used to encode other - * information for non-socks user request (such as those on TransPort and - * DNSPort) */ -struct socks_request_t { - /** Which version of SOCKS did the client use? One of "0, 4, 5" -- where - * 0 means that no socks handshake ever took place, and this is just a - * stub connection (e.g. see connection_ap_make_link()). */ - uint8_t socks_version; - /** If using socks5 authentication, which authentication type did we - * negotiate? currently we support 0 (no authentication) and 2 - * (username/password). */ - uint8_t auth_type; - /** What is this stream's goal? One of the SOCKS_COMMAND_* values */ - uint8_t command; - /** Which kind of listener created this stream? */ - uint8_t listener_type; - size_t replylen; /**< Length of reply. */ - uint8_t reply[MAX_SOCKS_REPLY_LEN]; /**< Write an entry into this string if - * we want to specify our own socks reply, - * rather than using the default socks4 or - * socks5 socks reply. We use this for the - * two-stage socks5 handshake. - */ - char address[MAX_SOCKS_ADDR_LEN]; /**< What address did the client ask to - connect to/resolve? */ - uint16_t port; /**< What port did the client ask to connect to? */ - unsigned int has_finished : 1; /**< Has the SOCKS handshake finished? Used to - * make sure we send back a socks reply for - * every connection. */ - unsigned int got_auth : 1; /**< Have we received any authentication data? */ - /** If this is set, we will choose "no authentication" instead of - * "username/password" authentication if both are offered. Used as input to - * parse_socks. */ - unsigned int socks_prefer_no_auth : 1; - - /** Number of bytes in username; 0 if username is NULL */ - size_t usernamelen; - /** Number of bytes in password; 0 if password is NULL */ - uint8_t passwordlen; - /** The negotiated username value if any (for socks5), or the entire - * authentication string (for socks4). This value is NOT nul-terminated; - * see usernamelen for its length. */ - char *username; - /** The negotiated password value if any (for socks5). This value is NOT - * nul-terminated; see passwordlen for its length. */ - char *password; -}; - /********************************* circuitbuild.c **********************/ /** How many hops does a general-purpose circuit have by default? */ @@ -4942,21 +2935,6 @@ int32_t circuit_build_times_initial_timeout(void); #error "RECENT_CIRCUITS is set too low." #endif -/** Information about the state of our local network connection */ -typedef struct { - /** The timestamp we last completed a TLS handshake or received a cell */ - time_t network_last_live; - /** If the network is not live, how many timeouts has this caused? */ - int nonlive_timeouts; - /** Circular array of circuits that have made it to the first hop. Slot is - * 1 if circuit timed out, 0 if circuit succeeded */ - int8_t *timeouts_after_firsthop; - /** Number of elements allocated for the above array */ - int num_recent_circs; - /** Index into circular array. */ - int after_firsthop_idx; -} network_liveness_t; - typedef struct circuit_build_times_s circuit_build_times_t; /********************************* config.c ***************************/ @@ -5086,14 +3064,6 @@ typedef enum { BOOTSTRAP_STATUS_DONE=100 } bootstrap_status_t; -/********************************* directory.c ***************************/ - -/** A pair of digests created by dir_split_resource_info_fingerprint_pairs() */ -typedef struct { - char first[DIGEST_LEN]; - char second[DIGEST_LEN]; -} fp_pair_t; - /********************************* dirserv.c ***************************/ /** An enum to describe what format we're generating a routerstatus line in. @@ -5111,29 +3081,9 @@ typedef enum { NS_V3_CONSENSUS_MICRODESC } routerstatus_format_type_t; -#ifdef DIRSERV_PRIVATE -typedef struct measured_bw_line_t { - char node_id[DIGEST_LEN]; - char node_hex[MAX_HEX_NICKNAME_LEN+1]; - long int bw_kb; -} measured_bw_line_t; - -#endif /* defined(DIRSERV_PRIVATE) */ - /********************************* dirvote.c ************************/ -/** Describes the schedule by which votes should be generated. */ -typedef struct vote_timing_t { - /** Length in seconds between one consensus becoming valid and the next - * becoming valid. */ - int vote_interval; - /** For how many intervals is a consensus valid? */ - int n_intervals_valid; - /** Time in seconds allowed to propagate votes */ - int vote_delay; - /** Time in seconds allowed to propagate signatures */ - int dist_delay; -} vote_timing_t; +typedef struct vote_timing_t vote_timing_t; /********************************* geoip.c **************************/ @@ -5247,18 +3197,9 @@ typedef enum { /********************************* rendcommon.c ***************************/ -/** Hidden-service side configuration of client authorization. */ -typedef struct rend_authorized_client_t { - char *client_name; - uint8_t descriptor_cookie[REND_DESC_COOKIE_LEN]; - crypto_pk_t *client_key; -} rend_authorized_client_t; - -/** ASCII-encoded v2 hidden service descriptor. */ -typedef struct rend_encoded_v2_service_descriptor_t { - char desc_id[DIGEST_LEN]; /**< Descriptor ID. */ - char *desc_str; /**< Descriptor string. */ -} rend_encoded_v2_service_descriptor_t; +typedef struct rend_authorized_client_t rend_authorized_client_t; +typedef struct rend_encoded_v2_service_descriptor_t + rend_encoded_v2_service_descriptor_t; /** The maximum number of non-circuit-build-timeout failures a hidden * service client will tolerate while trying to build a circuit to an @@ -5291,133 +3232,12 @@ typedef struct rend_encoded_v2_service_descriptor_t { * lifetime so this is a hard limit on the amount of time we do that. */ #define MAX_INTRO_POINT_CIRCUIT_RETRIES 3 -/** Introduction point information. Used both in rend_service_t (on - * the service side) and in rend_service_descriptor_t (on both the - * client and service side). */ -typedef struct rend_intro_point_t { - extend_info_t *extend_info; /**< Extend info for connecting to this - * introduction point via a multi-hop path. */ - crypto_pk_t *intro_key; /**< Introduction key that replaces the service - * key, if this descriptor is V2. */ - - /** (Client side only) Flag indicating that a timeout has occurred - * after sending an INTRODUCE cell to this intro point. After a - * timeout, an intro point should not be tried again during the same - * hidden service connection attempt, but it may be tried again - * during a future connection attempt. */ - unsigned int timed_out : 1; - - /** (Client side only) The number of times we have failed to build a - * circuit to this intro point for some reason other than our - * circuit-build timeout. See also MAX_INTRO_POINT_REACHABILITY_FAILURES. */ - unsigned int unreachable_count : 3; - - /** (Service side only) Flag indicating that this intro point was - * included in the last HS descriptor we generated. */ - unsigned int listed_in_last_desc : 1; - - /** (Service side only) A replay cache recording the RSA-encrypted parts - * of INTRODUCE2 cells this intro point's circuit has received. This is - * used to prevent replay attacks. */ - replaycache_t *accepted_intro_rsa_parts; - - /** (Service side only) Count of INTRODUCE2 cells accepted from this - * intro point. - */ - int accepted_introduce2_count; - - /** (Service side only) Maximum number of INTRODUCE2 cells that this IP - * will accept. This is a random value between - * INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS and - * INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS. */ - int max_introductions; - - /** (Service side only) The time at which this intro point was first - * published, or -1 if this intro point has not yet been - * published. */ - time_t time_published; - - /** (Service side only) The time at which this intro point should - * (start to) expire, or -1 if we haven't decided when this intro - * point should expire. */ - time_t time_to_expire; - - /** (Service side only) The amount of circuit creation we've made to this - * intro point. This is incremented every time we do a circuit relaunch on - * this object which is triggered when the circuit dies but the node is - * still in the consensus. After MAX_INTRO_POINT_CIRCUIT_RETRIES, we give - * up on it. */ - unsigned int circuit_retries; - - /** (Service side only) Set if this intro point has an established circuit - * and unset if it doesn't. */ - unsigned int circuit_established:1; -} rend_intro_point_t; - -#define REND_PROTOCOL_VERSION_BITMASK_WIDTH 16 - -/** Information used to connect to a hidden service. Used on both the - * service side and the client side. */ -typedef struct rend_service_descriptor_t { - crypto_pk_t *pk; /**< This service's public key. */ - int version; /**< Version of the descriptor format: 0 or 2. */ - time_t timestamp; /**< Time when the descriptor was generated. */ - /** Bitmask: which introduce/rendezvous protocols are supported? - * (We allow bits '0', '1', '2' and '3' to be set.) */ - unsigned protocols : REND_PROTOCOL_VERSION_BITMASK_WIDTH; - /** List of the service's introduction points. Elements are removed if - * introduction attempts fail. */ - smartlist_t *intro_nodes; - /** Has descriptor been uploaded to all hidden service directories? */ - int all_uploads_performed; - /** List of hidden service directories to which an upload request for - * this descriptor could be sent. Smartlist exists only when at least one - * of the previous upload requests failed (otherwise it's not important - * to know which uploads succeeded and which not). */ - smartlist_t *successful_uploads; -} rend_service_descriptor_t; +typedef struct rend_intro_point_t rend_intro_point_t; +typedef struct rend_service_descriptor_t rend_service_descriptor_t; /********************************* routerlist.c ***************************/ -/** Represents information about a single trusted or fallback directory - * server. */ -typedef struct dir_server_t { - char *description; - char *nickname; - char *address; /**< Hostname. */ - /* XX/teor - why do we duplicate the address and port fields here and in - * fake_status? Surely we could just use fake_status (#17867). */ - tor_addr_t ipv6_addr; /**< IPv6 address if present; AF_UNSPEC if not */ - uint32_t addr; /**< IPv4 address. */ - uint16_t dir_port; /**< Directory port. */ - uint16_t or_port; /**< OR port: Used for tunneling connections. */ - uint16_t ipv6_orport; /**< OR port corresponding to ipv6_addr. */ - double weight; /** Weight used when selecting this node at random */ - char digest[DIGEST_LEN]; /**< Digest of identity key. */ - char v3_identity_digest[DIGEST_LEN]; /**< Digest of v3 (authority only, - * high-security) identity key. */ - - unsigned int is_running:1; /**< True iff we think this server is running. */ - unsigned int is_authority:1; /**< True iff this is a directory authority - * of some kind. */ - - /** True iff this server has accepted the most recent server descriptor - * we tried to upload to it. */ - unsigned int has_accepted_serverdesc:1; - - /** What kind of authority is this? (Bitfield.) */ - dirinfo_type_t type; - - time_t addr_current_at; /**< When was the document that we derived the - * address information from published? */ - - routerstatus_t fake_status; /**< Used when we need to pass this trusted - * dir_server_t to - * directory_request_set_routerstatus. - * as a routerstatus_t. Not updated by the - * router-status management code! - **/ -} dir_server_t; +typedef struct dir_server_t dir_server_t; #define RELAY_REQUIRED_MIN_BANDWIDTH (75*1024) #define BRIDGE_REQUIRED_MIN_BANDWIDTH (50*1024) @@ -5508,28 +3328,7 @@ typedef enum was_router_added_t { ROUTER_CERTS_EXPIRED = -8 } was_router_added_t; -/********************************* routerparse.c ************************/ - -#define MAX_STATUS_TAG_LEN 32 -/** Structure to hold parsed Tor versions. This is a little messier - * than we would like it to be, because we changed version schemes with 0.1.0. - * - * See version-spec.txt for the whole business. - */ -typedef struct tor_version_t { - int major; - int minor; - int micro; - /** Release status. For version in the post-0.1 format, this is always - * VER_RELEASE. */ - enum { VER_PRE=0, VER_RC=1, VER_RELEASE=2, } status; - int patchlevel; - char status_tag[MAX_STATUS_TAG_LEN]; - int svn_revision; - - int git_tag_len; - char git_tag[DIGEST_LEN]; -} tor_version_t; +typedef struct tor_version_t tor_version_t; #endif /* !defined(TOR_OR_H) */ diff --git a/src/or/or_circuit_st.h b/src/or/or_circuit_st.h new file mode 100644 index 0000000000..07022272a7 --- /dev/null +++ b/src/or/or_circuit_st.h @@ -0,0 +1,80 @@ +/* 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 OR_CIRCUIT_ST_H +#define OR_CIRCUIT_ST_H + +#include "or.h" + +#include "circuit_st.h" +#include "crypt_path_st.h" + +struct onion_queue_t; + +/** An or_circuit_t holds information needed to implement a circuit at an + * OR. */ +struct or_circuit_t { + circuit_t base_; + + /** Pointer to an entry on the onion queue, if this circuit is waiting for a + * chance to give an onionskin to a cpuworker. Used only in onion.c */ + struct onion_queue_t *onionqueue_entry; + /** Pointer to a workqueue entry, if this circuit has given an onionskin to + * a cpuworker and is waiting for a response. Used to decide whether it is + * safe to free a circuit or if it is still in use by a cpuworker. */ + struct workqueue_entry_s *workqueue_entry; + + /** The circuit_id used in the previous (backward) hop of this circuit. */ + circid_t p_circ_id; + /** Queue of cells waiting to be transmitted on p_conn. */ + cell_queue_t p_chan_cells; + /** The channel that is previous in this circuit. */ + channel_t *p_chan; + /** + * Circuit mux associated with p_chan to which this circuit is attached; + * NULL if we have no p_chan. + */ + circuitmux_t *p_mux; + /** Linked list of Exit streams associated with this circuit. */ + edge_connection_t *n_streams; + /** Linked list of Exit streams associated with this circuit that are + * still being resolved. */ + edge_connection_t *resolving_streams; + + /** Cryptographic state used for encrypting and authenticating relay + * cells to and from this hop. */ + relay_crypto_t crypto; + + /** Points to spliced circuit if purpose is REND_ESTABLISHED, and circuit + * is not marked for close. */ + struct or_circuit_t *rend_splice; + + /** Stores KH for the handshake. */ + char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */ + + /** How many more relay_early cells can we send on this circuit, according + * to the specification? */ + unsigned int remaining_relay_early_cells : 4; + + /* We have already received an INTRODUCE1 cell on this circuit. */ + unsigned int already_received_introduce1 : 1; + + /** If set, this circuit carries HS traffic. Consider it in any HS + * statistics. */ + unsigned int circuit_carries_hs_traffic_stats : 1; + + /** Number of cells that were removed from circuit queue; reset every + * time when writing buffer stats to disk. */ + uint32_t processed_cells; + + /** Total time in milliseconds that cells spent in both app-ward and + * exit-ward queues of this circuit; reset every time when writing + * buffer stats to disk. */ + uint64_t total_cell_waiting_time; +}; + +#endif + diff --git a/src/or/or_connection_st.h b/src/or/or_connection_st.h new file mode 100644 index 0000000000..dd775bc8a3 --- /dev/null +++ b/src/or/or_connection_st.h @@ -0,0 +1,90 @@ +/* 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 OR_CONNECTION_ST_H +#define OR_CONNECTION_ST_H + +#include "connection_st.h" + +/** Subtype of connection_t for an "OR connection" -- that is, one that speaks + * cells over TLS. */ +struct or_connection_t { + connection_t base_; + + /** Hash of the public RSA key for the other side's identity key, or zeroes + * if the other side hasn't shown us a valid identity key. */ + char identity_digest[DIGEST_LEN]; + + /** Extended ORPort connection identifier. */ + char *ext_or_conn_id; + /** This is the ClientHash value we expect to receive from the + * client during the Extended ORPort authentication protocol. We + * compute it upon receiving the ClientNoce from the client, and we + * compare it with the acual ClientHash value sent by the + * client. */ + char *ext_or_auth_correct_client_hash; + /** String carrying the name of the pluggable transport + * (e.g. "obfs2") that is obfuscating this connection. If no + * pluggable transports are used, it's NULL. */ + char *ext_or_transport; + + char *nickname; /**< Nickname of OR on other side (if any). */ + + tor_tls_t *tls; /**< TLS connection state. */ + int tls_error; /**< Last tor_tls error code. */ + /** When we last used this conn for any client traffic. If not + * recent, we can rate limit it further. */ + + /* Channel using this connection */ + channel_tls_t *chan; + + tor_addr_t real_addr; /**< The actual address that this connection came from + * or went to. The addr field is prone to + * getting overridden by the address from the router + * descriptor matching identity_digest. */ + + /** Should this connection be used for extending circuits to the server + * matching the identity_digest field? Set to true if we're pretty + * sure we aren't getting MITMed, either because we're connected to an + * address listed in a server descriptor, or because an authenticated + * NETINFO cell listed the address we're connected to as recognized. */ + unsigned int is_canonical:1; + + /** True iff this is an outgoing connection. */ + unsigned int is_outgoing:1; + unsigned int proxy_type:2; /**< One of PROXY_NONE...PROXY_SOCKS5 */ + unsigned int wide_circ_ids:1; + /** True iff this connection has had its bootstrap failure logged with + * control_event_bootstrap_problem. */ + unsigned int have_noted_bootstrap_problem:1; + /** True iff this is a client connection and its address has been put in the + * geoip cache and handled by the DoS mitigation subsystem. We use this to + * insure we have a coherent count of concurrent connection. */ + unsigned int tracked_for_dos_mitigation : 1; + + uint16_t link_proto; /**< What protocol version are we using? 0 for + * "none negotiated yet." */ + uint16_t idle_timeout; /**< How long can this connection sit with no + * circuits on it before we close it? Based on + * IDLE_CIRCUIT_TIMEOUT_{NON,}CANONICAL and + * on is_canonical, randomized. */ + or_handshake_state_t *handshake_state; /**< If we are setting this connection + * up, state information to do so. */ + + time_t timestamp_lastempty; /**< When was the outbuf last completely empty?*/ + + token_bucket_rw_t bucket; /**< Used for rate limiting when the connection is + * in state CONN_OPEN. */ + + /* + * Count the number of bytes flushed out on this orconn, and the number of + * bytes TLS actually sent - used for overhead estimation for scheduling. + */ + uint64_t bytes_xmitted, bytes_xmitted_by_tls; +}; + +#endif + diff --git a/src/or/or_handshake_certs_st.h b/src/or/or_handshake_certs_st.h new file mode 100644 index 0000000000..515866af75 --- /dev/null +++ b/src/or/or_handshake_certs_st.h @@ -0,0 +1,39 @@ +/* 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 OR_HANDSHAKE_CERTS_ST +#define OR_HANDSHAKE_CERTS_ST + +/** Structure to hold all the certificates we've received on an OR connection + */ +struct or_handshake_certs_t { + /** True iff we originated this connection. */ + int started_here; + /** The cert for the 'auth' RSA key that's supposed to sign the AUTHENTICATE + * cell. Signed with the RSA identity key. */ + tor_x509_cert_t *auth_cert; + /** The cert for the 'link' RSA key that was used to negotiate the TLS + * connection. Signed with the RSA identity key. */ + tor_x509_cert_t *link_cert; + /** A self-signed identity certificate: the RSA identity key signed + * with itself. */ + tor_x509_cert_t *id_cert; + /** The Ed25519 signing key, signed with the Ed25519 identity key. */ + struct tor_cert_st *ed_id_sign; + /** A digest of the X509 link certificate for the TLS connection, signed + * with the Ed25519 siging key. */ + struct tor_cert_st *ed_sign_link; + /** The Ed25519 authentication key (that's supposed to sign an AUTHENTICATE + * cell) , signed with the Ed25519 siging key. */ + struct tor_cert_st *ed_sign_auth; + /** The Ed25519 identity key, crosssigned with the RSA identity key. */ + uint8_t *ed_rsa_crosscert; + /** The length of ed_rsa_crosscert in bytes */ + size_t ed_rsa_crosscert_len; +}; + +#endif + diff --git a/src/or/or_handshake_state_st.h b/src/or/or_handshake_state_st.h new file mode 100644 index 0000000000..d0e3adaefa --- /dev/null +++ b/src/or/or_handshake_state_st.h @@ -0,0 +1,78 @@ +/* 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 OR_HANDSHAKE_STATE_ST +#define OR_HANDSHAKE_STATE_ST + +/** Stores flags and information related to the portion of a v2/v3 Tor OR + * connection handshake that happens after the TLS handshake is finished. + */ +struct or_handshake_state_t { + /** When was the VERSIONS cell sent on this connection? Used to get + * an estimate of the skew in the returning NETINFO reply. */ + time_t sent_versions_at; + /** True iff we originated this connection */ + unsigned int started_here : 1; + /** True iff we have received and processed a VERSIONS cell. */ + unsigned int received_versions : 1; + /** True iff we have received and processed an AUTH_CHALLENGE cell */ + unsigned int received_auth_challenge : 1; + /** True iff we have received and processed a CERTS cell. */ + unsigned int received_certs_cell : 1; + /** True iff we have received and processed an AUTHENTICATE cell */ + unsigned int received_authenticate : 1; + + /* True iff we've received valid authentication to some identity. */ + unsigned int authenticated : 1; + unsigned int authenticated_rsa : 1; + unsigned int authenticated_ed25519 : 1; + + /* True iff we have sent a netinfo cell */ + unsigned int sent_netinfo : 1; + + /** The signing->ed25519 link certificate corresponding to the x509 + * certificate we used on the TLS connection (if this is a server-side + * connection). We make a copy of this here to prevent a race condition + * caused by TLS context rotation. */ + struct tor_cert_st *own_link_cert; + + /** True iff we should feed outgoing cells into digest_sent and + * digest_received respectively. + * + * From the server's side of the v3 handshake, we want to capture everything + * from the VERSIONS cell through and including the AUTH_CHALLENGE cell. + * From the client's, we want to capture everything from the VERSIONS cell + * through but *not* including the AUTHENTICATE cell. + * + * @{ */ + unsigned int digest_sent_data : 1; + unsigned int digest_received_data : 1; + /**@}*/ + + /** Identity RSA digest that we have received and authenticated for our peer + * on this connection. */ + uint8_t authenticated_rsa_peer_id[DIGEST_LEN]; + /** Identity Ed25519 public key that we have received and authenticated for + * our peer on this connection. */ + ed25519_public_key_t authenticated_ed25519_peer_id; + + /** Digests of the cells that we have sent or received as part of a V3 + * handshake. Used for making and checking AUTHENTICATE cells. + * + * @{ + */ + crypto_digest_t *digest_sent; + crypto_digest_t *digest_received; + /** @} */ + + /** Certificates that a connection initiator sent us in a CERTS cell; we're + * holding on to them until we get an AUTHENTICATE cell. + */ + or_handshake_certs_t *certs; +}; + +#endif + diff --git a/src/or/origin_circuit_st.h b/src/or/origin_circuit_st.h new file mode 100644 index 0000000000..1ea9926db2 --- /dev/null +++ b/src/or/origin_circuit_st.h @@ -0,0 +1,235 @@ +/* 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 ORIGIN_CIRCUIT_ST_H +#define ORIGIN_CIRCUIT_ST_H + +#include "or.h" + +#include "circuit_st.h" + +struct onion_queue_t; + +/** An origin_circuit_t holds data necessary to build and use a circuit. + */ +struct origin_circuit_t { + circuit_t base_; + + /** Linked list of AP streams (or EXIT streams if hidden service) + * associated with this circuit. */ + edge_connection_t *p_streams; + + /** Bytes read on this circuit since last call to + * control_event_circ_bandwidth_used(). Only used if we're configured + * to emit CIRC_BW events. */ + uint32_t n_read_circ_bw; + + /** Bytes written to on this circuit since last call to + * control_event_circ_bandwidth_used(). Only used if we're configured + * to emit CIRC_BW events. */ + uint32_t n_written_circ_bw; + + /** Total known-valid relay cell bytes since last call to + * control_event_circ_bandwidth_used(). Only used if we're configured + * to emit CIRC_BW events. */ + uint32_t n_delivered_read_circ_bw; + + /** Total written relay cell bytes since last call to + * control_event_circ_bandwidth_used(). Only used if we're configured + * to emit CIRC_BW events. */ + uint32_t n_delivered_written_circ_bw; + + /** Total overhead data in all known-valid relay data cells since last + * call to control_event_circ_bandwidth_used(). Only used if we're + * configured to emit CIRC_BW events. */ + uint32_t n_overhead_read_circ_bw; + + /** Total written overhead data in all relay data cells since last call to + * control_event_circ_bandwidth_used(). Only used if we're configured + * to emit CIRC_BW events. */ + uint32_t n_overhead_written_circ_bw; + + /** Build state for this circuit. It includes the intended path + * length, the chosen exit router, rendezvous information, etc. + */ + cpath_build_state_t *build_state; + /** The doubly-linked list of crypt_path_t entries, one per hop, + * for this circuit. This includes ciphers for each hop, + * integrity-checking digests for each hop, and package/delivery + * windows for each hop. + */ + crypt_path_t *cpath; + + /** Holds all rendezvous data on either client or service side. */ + rend_data_t *rend_data; + + /** Holds hidden service identifier on either client or service side. This + * is for both introduction and rendezvous circuit. */ + struct hs_ident_circuit_t *hs_ident; + + /** Holds the data that the entry guard system uses to track the + * status of the guard this circuit is using, and thereby to determine + * whether this circuit can be used. */ + struct circuit_guard_state_t *guard_state; + + /** Index into global_origin_circuit_list for this circuit. -1 if not + * present. */ + int global_origin_circuit_list_idx; + + /** How many more relay_early cells can we send on this circuit, according + * to the specification? */ + unsigned int remaining_relay_early_cells : 4; + + /** Set if this circuit is insanely old and we already informed the user */ + unsigned int is_ancient : 1; + + /** Set if this circuit has already been opened. Used to detect + * cannibalized circuits. */ + unsigned int has_opened : 1; + + /** + * Path bias state machine. Used to ensure integrity of our + * circuit building and usage accounting. See path_state_t + * for more details. + */ + path_state_bitfield_t path_state : 3; + + /* If this flag is set, we should not consider attaching any more + * connections to this circuit. */ + unsigned int unusable_for_new_conns : 1; + + /** + * Tristate variable to guard against pathbias miscounting + * due to circuit purpose transitions changing the decision + * of pathbias_should_count(). This variable is informational + * only. The current results of pathbias_should_count() are + * the official decision for pathbias accounting. + */ + uint8_t pathbias_shouldcount; +#define PATHBIAS_SHOULDCOUNT_UNDECIDED 0 +#define PATHBIAS_SHOULDCOUNT_IGNORED 1 +#define PATHBIAS_SHOULDCOUNT_COUNTED 2 + + /** For path probing. Store the temporary probe stream ID + * for response comparison */ + streamid_t pathbias_probe_id; + + /** For path probing. Store the temporary probe address nonce + * (in host byte order) for response comparison. */ + uint32_t pathbias_probe_nonce; + + /** Set iff this is a hidden-service circuit which has timed out + * according to our current circuit-build timeout, but which has + * been kept around because it might still succeed in connecting to + * its destination, and which is not a fully-connected rendezvous + * circuit. + * + * (We clear this flag for client-side rendezvous circuits when they + * are 'joined' to the other side's rendezvous circuit, so that + * connection_ap_handshake_attach_circuit can put client streams on + * the circuit. We also clear this flag for service-side rendezvous + * circuits when they are 'joined' to a client's rend circ, but only + * for symmetry with the client case. Client-side introduction + * circuits are closed when we get a joined rend circ, and + * service-side introduction circuits never have this flag set.) */ + unsigned int hs_circ_has_timed_out : 1; + + /** Set iff this circuit has been given a relaxed timeout because + * no circuits have opened. Used to prevent spamming logs. */ + unsigned int relaxed_timeout : 1; + + /** Set iff this is a service-side rendezvous circuit for which a + * new connection attempt has been launched. We consider launching + * a new service-side rend circ to a client when the previous one + * fails; now that we don't necessarily close a service-side rend + * circ when we launch a new one to the same client, this flag keeps + * us from launching two retries for the same failed rend circ. */ + unsigned int hs_service_side_rend_circ_has_been_relaunched : 1; + + /** What commands were sent over this circuit that decremented the + * RELAY_EARLY counter? This is for debugging task 878. */ + uint8_t relay_early_commands[MAX_RELAY_EARLY_CELLS_PER_CIRCUIT]; + + /** How many RELAY_EARLY cells have been sent over this circuit? This is + * for debugging task 878, too. */ + int relay_early_cells_sent; + + /** The next stream_id that will be tried when we're attempting to + * construct a new AP stream originating at this circuit. */ + streamid_t next_stream_id; + + /* The intro key replaces the hidden service's public key if purpose is + * S_ESTABLISH_INTRO or S_INTRO, provided that no unversioned rendezvous + * descriptor is used. */ + crypto_pk_t *intro_key; + + /** Quasi-global identifier for this circuit; used for control.c */ + /* XXXX NM This can get re-used after 2**32 circuits. */ + uint32_t global_identifier; + + /** True if we have associated one stream to this circuit, thereby setting + * the isolation parameters for this circuit. Note that this doesn't + * necessarily mean that we've attached any streams to the circuit: + * we may only have marked up this circuit during the launch process. + */ + unsigned int isolation_values_set : 1; + /** True iff any stream has ever been attached to this circuit. + * + * In a better world we could use timestamp_dirty for this, but + * timestamp_dirty is far too overloaded at the moment. + */ + unsigned int isolation_any_streams_attached : 1; + + /** A bitfield of ISO_* flags for every isolation field such that this + * circuit has had streams with more than one value for that field + * attached to it. */ + uint8_t isolation_flags_mixed; + + /** @name Isolation parameters + * + * If any streams have been associated with this circ (isolation_values_set + * == 1), and all streams associated with the circuit have had the same + * value for some field ((isolation_flags_mixed & ISO_FOO) == 0), then these + * elements hold the value for that field. + * + * Note again that "associated" is not the same as "attached": we + * preliminarily associate streams with a circuit while the circuit is being + * launched, so that we can tell whether we need to launch more circuits. + * + * @{ + */ + uint8_t client_proto_type; + uint8_t client_proto_socksver; + uint16_t dest_port; + tor_addr_t client_addr; + char *dest_address; + int session_group; + unsigned nym_epoch; + size_t socks_username_len; + uint8_t socks_password_len; + /* Note that the next two values are NOT NUL-terminated; see + socks_username_len and socks_password_len for their lengths. */ + char *socks_username; + char *socks_password; + /** Global identifier for the first stream attached here; used by + * ISO_STREAM. */ + uint64_t associated_isolated_stream_global_id; + /**@}*/ + /** A list of addr_policy_t for this circuit in particular. Used by + * adjust_exit_policy_from_exitpolicy_failure. + */ + smartlist_t *prepend_policy; + + /** How long do we wait before closing this circuit if it remains + * completely idle after it was built, in seconds? This value + * is randomized on a per-circuit basis from CircuitsAvailableTimoeut + * to 2*CircuitsAvailableTimoeut. */ + int circuit_idle_timeout; + +}; + +#endif + diff --git a/src/or/policies.c b/src/or/policies.c index 1210ca687d..bc4a9a920c 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -30,6 +30,13 @@ #include "geoip.h" #include "ht.h" +#include "dir_server_st.h" +#include "microdesc_st.h" +#include "node_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + /** Policy that addresses for incoming SOCKS connections must match. */ static smartlist_t *socks_policy = NULL; /** Policy that addresses for incoming directory connections must match. */ diff --git a/src/or/port_cfg_st.h b/src/or/port_cfg_st.h new file mode 100644 index 0000000000..8b6b018c59 --- /dev/null +++ b/src/or/port_cfg_st.h @@ -0,0 +1,35 @@ +/* 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 PORT_CFG_ST_H +#define PORT_CFG_ST_H + +#include "entry_port_cfg_st.h" +#include "server_port_cfg_st.h" + +/** Configuration for a single port that we're listening on. */ +struct port_cfg_t { + tor_addr_t addr; /**< The actual IP to listen on, if !is_unix_addr. */ + int port; /**< The configured port, or CFG_AUTO_PORT to tell Tor to pick its + * own port. */ + uint8_t type; /**< One of CONN_TYPE_*_LISTENER */ + unsigned is_unix_addr : 1; /**< True iff this is an AF_UNIX address. */ + + unsigned is_group_writable : 1; + unsigned is_world_writable : 1; + unsigned relax_dirmode_check : 1; + + entry_port_cfg_t entry_cfg; + + server_port_cfg_t server_cfg; + + /* Unix sockets only: */ + /** Path for an AF_UNIX address */ + char unix_addr[FLEXIBLE_ARRAY_MEMBER]; +}; + +#endif + diff --git a/src/or/proto_cell.c b/src/or/proto_cell.c index 75eb2a7e7f..84620ce37d 100644 --- a/src/or/proto_cell.c +++ b/src/or/proto_cell.c @@ -10,6 +10,8 @@ #include "connection_or.h" +#include "var_cell_st.h" + /** True iff the cell command command is one that implies a * variable-length cell in Tor link protocol linkproto. */ static inline int diff --git a/src/or/proto_socks.c b/src/or/proto_socks.c index 57a7d1cd64..1b67c6c28b 100644 --- a/src/or/proto_socks.c +++ b/src/or/proto_socks.c @@ -14,6 +14,8 @@ #include "proto_socks.h" #include "reasons.h" +#include "socks_request_st.h" + static void socks_request_set_socks5_error(socks_request_t *req, socks5_reply_status_t reason); diff --git a/src/or/relay.c b/src/or/relay.c index 50f59d6b99..6af7c8d1d6 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -63,6 +63,7 @@ #include "control.h" #include "crypto_rand.h" #include "crypto_util.h" +#include "directory.h" #include "geoip.h" #include "hs_cache.h" #include "main.h" @@ -81,6 +82,18 @@ #include "scheduler.h" #include "rephist.h" +#include "cell_st.h" +#include "cell_queue_st.h" +#include "cpath_build_state_st.h" +#include "dir_connection_st.h" +#include "destroy_cell_queue_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" +#include "routerinfo_st.h" +#include "socks_request_st.h" + static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t *layer_hint); diff --git a/src/or/relay_crypto.c b/src/or/relay_crypto.c index 530c8e5828..82ff9aca88 100644 --- a/src/or/relay_crypto.c +++ b/src/or/relay_crypto.c @@ -5,12 +5,17 @@ /* See LICENSE for licensing information */ #include "or.h" +#include "circuitlist.h" #include "config.h" #include "crypto_util.h" #include "hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN #include "relay.h" #include "relay_crypto.h" +#include "cell_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + /** Update digest from the payload of cell. Assign integrity part to * cell. */ diff --git a/src/or/relay_crypto_st.h b/src/or/relay_crypto_st.h new file mode 100644 index 0000000000..4e23f4e404 --- /dev/null +++ b/src/or/relay_crypto_st.h @@ -0,0 +1,27 @@ +/* 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 */ + +#ifndef RELAY_CRYPTO_ST_H +#define RELAY_CRYPTO_ST_H + +struct relay_crypto_t { + /* crypto environments */ + /** Encryption key and counter for cells heading towards the OR at this + * step. */ + crypto_cipher_t *f_crypto; + /** Encryption key and counter for cells heading back from the OR at this + * step. */ + crypto_cipher_t *b_crypto; + + /** Digest state for cells heading towards the OR at this step. */ + crypto_digest_t *f_digest; /* for integrity checking */ + /** Digest state for cells heading away from the OR at this step. */ + crypto_digest_t *b_digest; + +}; + +#endif + diff --git a/src/or/rend_authorized_client_st.h b/src/or/rend_authorized_client_st.h new file mode 100644 index 0000000000..e06620fb86 --- /dev/null +++ b/src/or/rend_authorized_client_st.h @@ -0,0 +1,18 @@ +/* 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 REND_AUTHORIZED_CLIENT_ST_H +#define REND_AUTHORIZED_CLIENT_ST_H + +/** Hidden-service side configuration of client authorization. */ +struct rend_authorized_client_t { + char *client_name; + uint8_t descriptor_cookie[REND_DESC_COOKIE_LEN]; + crypto_pk_t *client_key; +}; + +#endif + diff --git a/src/or/rend_encoded_v2_service_descriptor_st.h b/src/or/rend_encoded_v2_service_descriptor_st.h new file mode 100644 index 0000000000..05176eb012 --- /dev/null +++ b/src/or/rend_encoded_v2_service_descriptor_st.h @@ -0,0 +1,17 @@ +/* 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 REND_ENCODED_V2_SERVICE_DESCRIPTOR_ST_H +#define REND_ENCODED_V2_SERVICE_DESCRIPTOR_ST_H + +/** ASCII-encoded v2 hidden service descriptor. */ +struct rend_encoded_v2_service_descriptor_t { + char desc_id[DIGEST_LEN]; /**< Descriptor ID. */ + char *desc_str; /**< Descriptor string. */ +}; + +#endif + diff --git a/src/or/rend_intro_point_st.h b/src/or/rend_intro_point_st.h new file mode 100644 index 0000000000..934b6ea820 --- /dev/null +++ b/src/or/rend_intro_point_st.h @@ -0,0 +1,74 @@ +/* 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 REND_INTRO_POINT_ST_H +#define REND_INTRO_POINT_ST_H + +/** Introduction point information. Used both in rend_service_t (on + * the service side) and in rend_service_descriptor_t (on both the + * client and service side). */ +struct rend_intro_point_t { + extend_info_t *extend_info; /**< Extend info for connecting to this + * introduction point via a multi-hop path. */ + crypto_pk_t *intro_key; /**< Introduction key that replaces the service + * key, if this descriptor is V2. */ + + /** (Client side only) Flag indicating that a timeout has occurred + * after sending an INTRODUCE cell to this intro point. After a + * timeout, an intro point should not be tried again during the same + * hidden service connection attempt, but it may be tried again + * during a future connection attempt. */ + unsigned int timed_out : 1; + + /** (Client side only) The number of times we have failed to build a + * circuit to this intro point for some reason other than our + * circuit-build timeout. See also MAX_INTRO_POINT_REACHABILITY_FAILURES. */ + unsigned int unreachable_count : 3; + + /** (Service side only) Flag indicating that this intro point was + * included in the last HS descriptor we generated. */ + unsigned int listed_in_last_desc : 1; + + /** (Service side only) A replay cache recording the RSA-encrypted parts + * of INTRODUCE2 cells this intro point's circuit has received. This is + * used to prevent replay attacks. */ + replaycache_t *accepted_intro_rsa_parts; + + /** (Service side only) Count of INTRODUCE2 cells accepted from this + * intro point. + */ + int accepted_introduce2_count; + + /** (Service side only) Maximum number of INTRODUCE2 cells that this IP + * will accept. This is a random value between + * INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS and + * INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS. */ + int max_introductions; + + /** (Service side only) The time at which this intro point was first + * published, or -1 if this intro point has not yet been + * published. */ + time_t time_published; + + /** (Service side only) The time at which this intro point should + * (start to) expire, or -1 if we haven't decided when this intro + * point should expire. */ + time_t time_to_expire; + + /** (Service side only) The amount of circuit creation we've made to this + * intro point. This is incremented every time we do a circuit relaunch on + * this object which is triggered when the circuit dies but the node is + * still in the consensus. After MAX_INTRO_POINT_CIRCUIT_RETRIES, we give + * up on it. */ + unsigned int circuit_retries; + + /** (Service side only) Set if this intro point has an established circuit + * and unset if it doesn't. */ + unsigned int circuit_established:1; +}; + +#endif + diff --git a/src/or/rend_service_descriptor_st.h b/src/or/rend_service_descriptor_st.h new file mode 100644 index 0000000000..bd6d55b6ad --- /dev/null +++ b/src/or/rend_service_descriptor_st.h @@ -0,0 +1,34 @@ +/* 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 REND_SERVICE_DESCRIPTOR_ST_H +#define REND_SERVICE_DESCRIPTOR_ST_H + +#define REND_PROTOCOL_VERSION_BITMASK_WIDTH 16 + +/** Information used to connect to a hidden service. Used on both the + * service side and the client side. */ +struct rend_service_descriptor_t { + crypto_pk_t *pk; /**< This service's public key. */ + int version; /**< Version of the descriptor format: 0 or 2. */ + time_t timestamp; /**< Time when the descriptor was generated. */ + /** Bitmask: which introduce/rendezvous protocols are supported? + * (We allow bits '0', '1', '2' and '3' to be set.) */ + unsigned protocols : REND_PROTOCOL_VERSION_BITMASK_WIDTH; + /** List of the service's introduction points. Elements are removed if + * introduction attempts fail. */ + smartlist_t *intro_nodes; + /** Has descriptor been uploaded to all hidden service directories? */ + int all_uploads_performed; + /** List of hidden service directories to which an upload request for + * this descriptor could be sent. Smartlist exists only when at least one + * of the previous upload requests failed (otherwise it's not important + * to know which uploads succeeded and which not). */ + smartlist_t *successful_uploads; +}; + +#endif + diff --git a/src/or/rendcache.c b/src/or/rendcache.c index 854142c26f..8ce0185592 100644 --- a/src/or/rendcache.c +++ b/src/or/rendcache.c @@ -15,6 +15,10 @@ #include "routerparse.h" #include "rendcommon.h" +#include "extend_info_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" + /** Map from service id (as generated by rend_get_service_id) to * rend_cache_entry_t. */ STATIC strmap_t *rend_cache = NULL; diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 7ef12a4faf..4154030b8f 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -33,6 +33,16 @@ #include "routerlist.h" #include "routerset.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "dir_connection_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "origin_circuit_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" +#include "routerstatus_st.h" + static extend_info_t *rend_client_get_random_intro_impl( const rend_cache_entry_t *rend_query, const int strict, const int warnings); diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index f3fa2f64d1..80cb798466 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -12,6 +12,7 @@ #include "or.h" #include "circuitbuild.h" +#include "circuitlist.h" #include "circuituse.h" #include "config.h" #include "control.h" @@ -30,6 +31,16 @@ #include "routerlist.h" #include "routerparse.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "extend_info_st.h" +#include "networkstatus_st.h" +#include "origin_circuit_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" +#include "routerstatus_st.h" + /** Return 0 if one and two are the same service ids, else -1 or 1 */ int rend_cmp_service_ids(const char *one, const char *two) diff --git a/src/or/rendmid.c b/src/or/rendmid.c index c4a34ca62c..8afc730675 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -20,6 +20,8 @@ #include "hs_circuitmap.h" #include "hs_intropoint.h" +#include "or_circuit_st.h" + /** Respond to an ESTABLISH_INTRO cell by checking the signed data and * setting the circuit's purpose and service pk digest. */ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 92c323b10d..e207707e93 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -36,6 +36,19 @@ #include "routerparse.h" #include "routerset.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "crypt_path_reference_st.h" +#include "edge_connection_st.h" +#include "extend_info_st.h" +#include "networkstatus_st.h" +#include "origin_circuit_st.h" +#include "rend_authorized_client_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" +#include "routerstatus_st.h" + struct rend_service_t; static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest); diff --git a/src/or/rephist.c b/src/or/rephist.c index c7117bad63..efc338c5e0 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -89,6 +89,9 @@ #include "connection_or.h" #include "statefile.h" +#include "networkstatus_st.h" +#include "or_circuit_st.h" + static void bw_arrays_init(void); static void predicted_ports_alloc(void); diff --git a/src/or/router.c b/src/or/router.c index 3879863e82..614860f611 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -39,6 +39,17 @@ #include "dirauth/mode.h" +#include "authority_cert_st.h" +#include "crypt_path_st.h" +#include "dir_connection_st.h" +#include "dir_server_st.h" +#include "extend_info_st.h" +#include "extrainfo_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" + /** * \file router.c * \brief Miscellaneous relay functionality, including RSA key maintenance, diff --git a/src/or/routerinfo_st.h b/src/or/routerinfo_st.h new file mode 100644 index 0000000000..11ee3e3509 --- /dev/null +++ b/src/or/routerinfo_st.h @@ -0,0 +1,107 @@ +/* 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 ROUTERINFO_ST_H +#define ROUTERINFO_ST_H + +#include "signed_descriptor_st.h" + +/** Information about another onion router in the network. */ +struct routerinfo_t { + signed_descriptor_t cache_info; + char *nickname; /**< Human-readable OR name. */ + + uint32_t addr; /**< IPv4 address of OR, in host order. */ + uint16_t or_port; /**< Port for TLS connections. */ + uint16_t dir_port; /**< Port for HTTP directory connections. */ + + /** A router's IPv6 address, if it has one. */ + /* XXXXX187 Actually these should probably be part of a list of addresses, + * not just a special case. Use abstractions to access these; don't do it + * directly. */ + tor_addr_t ipv6_addr; + uint16_t ipv6_orport; + + crypto_pk_t *onion_pkey; /**< Public RSA key for onions. */ + crypto_pk_t *identity_pkey; /**< Public RSA key for signing. */ + /** Public curve25519 key for onions */ + curve25519_public_key_t *onion_curve25519_pkey; + /** What's the earliest expiration time on all the certs in this + * routerinfo? */ + time_t cert_expiration_time; + + char *platform; /**< What software/operating system is this OR using? */ + + char *protocol_list; /**< Encoded list of subprotocol versions supported + * by this OR */ + + /* link info */ + uint32_t bandwidthrate; /**< How many bytes does this OR add to its token + * bucket per second? */ + uint32_t bandwidthburst; /**< How large is this OR's token bucket? */ + /** How many bytes/s is this router known to handle? */ + uint32_t bandwidthcapacity; + smartlist_t *exit_policy; /**< What streams will this OR permit + * to exit on IPv4? NULL for 'reject *:*'. */ + /** What streams will this OR permit to exit on IPv6? + * NULL for 'reject *:*' */ + struct short_policy_t *ipv6_exit_policy; + long uptime; /**< How many seconds the router claims to have been up */ + smartlist_t *declared_family; /**< Nicknames of router which this router + * claims are its family. */ + char *contact_info; /**< Declared contact info for this router. */ + unsigned int is_hibernating:1; /**< Whether the router claims to be + * hibernating */ + unsigned int caches_extra_info:1; /**< Whether the router says it caches and + * serves extrainfo documents. */ + unsigned int allow_single_hop_exits:1; /**< Whether the router says + * it allows single hop exits. */ + + unsigned int wants_to_be_hs_dir:1; /**< True iff this router claims to be + * a hidden service directory. */ + unsigned int policy_is_reject_star:1; /**< True iff the exit policy for this + * router rejects everything. */ + /** True if, after we have added this router, we should re-launch + * tests for it. */ + unsigned int needs_retest_if_added:1; + + /** True iff this router included "tunnelled-dir-server" in its descriptor, + * implying it accepts tunnelled directory requests, or it advertised + * dir_port > 0. */ + unsigned int supports_tunnelled_dir_requests:1; + + /** Used during voting to indicate that we should not include an entry for + * this routerinfo. Used only during voting. */ + unsigned int omit_from_vote:1; + + /** Flags to summarize the protocol versions for this routerinfo_t. */ + protover_summary_flags_t pv; + +/** Tor can use this router for general positions in circuits; we got it + * from a directory server as usual, or we're an authority and a server + * uploaded it. */ +#define ROUTER_PURPOSE_GENERAL 0 +/** Tor should avoid using this router for circuit-building: we got it + * from a controller. If the controller wants to use it, it'll have to + * ask for it by identity. */ +#define ROUTER_PURPOSE_CONTROLLER 1 +/** Tor should use this router only for bridge positions in circuits: we got + * it via a directory request from the bridge itself, or a bridge + * authority. */ +#define ROUTER_PURPOSE_BRIDGE 2 +/** Tor should not use this router; it was marked in cached-descriptors with + * a purpose we didn't recognize. */ +#define ROUTER_PURPOSE_UNKNOWN 255 + + /** In what way did we find out about this router? One of ROUTER_PURPOSE_*. + * Routers of different purposes are kept segregated and used for different + * things; see notes on ROUTER_PURPOSE_* macros above. + */ + uint8_t purpose; +}; + +#endif + diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 8788dc0190..ad7e4102c2 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -125,6 +125,18 @@ #include "dirauth/dirvote.h" #include "dirauth/mode.h" +#include "authority_cert_st.h" +#include "dir_connection_st.h" +#include "dir_server_st.h" +#include "document_signature_st.h" +#include "extrainfo_st.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "vote_routerstatus_st.h" + // #define DEBUG_ROUTERLIST /****************************************************************************/ diff --git a/src/or/routerlist_st.h b/src/or/routerlist_st.h new file mode 100644 index 0000000000..6dfecf4d8a --- /dev/null +++ b/src/or/routerlist_st.h @@ -0,0 +1,40 @@ +/* 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 ROUTERLIST_ST_H +#define ROUTERLIST_ST_H + +#include "desc_store_st.h" + +/** Contents of a directory of onion routers. */ +struct routerlist_t { + /** Map from server identity digest to a member of routers. */ + struct digest_ri_map_t *identity_map; + /** Map from server descriptor digest to a signed_descriptor_t from + * routers or old_routers. */ + struct digest_sd_map_t *desc_digest_map; + /** Map from extra-info digest to an extrainfo_t. Only exists for + * routers in routers or old_routers. */ + struct digest_ei_map_t *extra_info_map; + /** Map from extra-info digests to a signed_descriptor_t for a router + * descriptor having that extra-info digest. Only exists for + * routers in routers or old_routers. */ + struct digest_sd_map_t *desc_by_eid_map; + /** List of routerinfo_t for all currently live routers we know. */ + smartlist_t *routers; + /** List of signed_descriptor_t for older router descriptors we're + * caching. */ + smartlist_t *old_routers; + /** Store holding server descriptors. If present, any router whose + * cache_info.saved_location == SAVED_IN_CACHE is stored in this file + * starting at cache_info.saved_offset */ + desc_store_t desc_store; + /** Store holding extra-info documents. */ + desc_store_t extrainfo_store; +}; + +#endif + diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 7af41c3baf..31c545edf4 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -79,11 +79,28 @@ #include "torcert.h" #include "voting_schedule.h" +#include "dirauth/dirvote.h" + +#include "authority_cert_st.h" +#include "document_signature_st.h" +#include "extend_info_st.h" +#include "extrainfo_st.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" +#include "ns_detached_signatures_st.h" +#include "rend_authorized_client_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "tor_version_st.h" +#include "vote_microdesc_hash_st.h" +#include "vote_routerstatus_st.h" + #undef log #include -#include "dirauth/dirvote.h" - /****************************************************************************/ /** List of tokens recognized in router descriptors */ diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 418fd3acdb..663c80fb81 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -43,6 +43,7 @@ routerinfo_t *router_parse_entry_from_string(const char *s, const char *end, int allow_annotations, const char *prepend_annotations, int *can_dl_again_out); +struct digest_ri_map_t; extrainfo_t *extrainfo_parse_entry_from_string(const char *s, const char *end, int cache_copy, struct digest_ri_map_t *routermap, int *can_dl_again_out); diff --git a/src/or/routerset.c b/src/or/routerset.c index a2599b316c..6da1c201b7 100644 --- a/src/or/routerset.c +++ b/src/or/routerset.c @@ -36,6 +36,11 @@ #include "routerparse.h" #include "routerset.h" +#include "extend_info_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + /** Return a new empty routerset. */ routerset_t * routerset_new(void) diff --git a/src/or/routerstatus_st.h b/src/or/routerstatus_st.h new file mode 100644 index 0000000000..f8a27ccac2 --- /dev/null +++ b/src/or/routerstatus_st.h @@ -0,0 +1,80 @@ +/* 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 ROUTERSTATUS_ST_H +#define ROUTERSTATUS_ST_H + +#include "download_status_st.h" + +/** Contents of a single router entry in a network status object. + */ +struct routerstatus_t { + time_t published_on; /**< When was this router published? */ + char nickname[MAX_NICKNAME_LEN+1]; /**< The nickname this router says it + * has. */ + char identity_digest[DIGEST_LEN]; /**< Digest of the router's identity + * key. */ + /** Digest of the router's most recent descriptor or microdescriptor. + * If it's a descriptor, we only use the first DIGEST_LEN bytes. */ + char descriptor_digest[DIGEST256_LEN]; + uint32_t addr; /**< IPv4 address for this router, in host order. */ + uint16_t or_port; /**< IPv4 OR port for this router. */ + uint16_t dir_port; /**< Directory port for this router. */ + tor_addr_t ipv6_addr; /**< IPv6 address for this router. */ + uint16_t ipv6_orport; /**< IPv6 OR port for this router. */ + unsigned int is_authority:1; /**< True iff this router is an authority. */ + unsigned int is_exit:1; /**< True iff this router is a good exit. */ + unsigned int is_stable:1; /**< True iff this router stays up a long time. */ + unsigned int is_fast:1; /**< True iff this router has good bandwidth. */ + /** True iff this router is called 'running' in the consensus. We give it + * this funny name so that we don't accidentally use this bit as a view of + * whether we think the router is *currently* running. If that's what you + * want to know, look at is_running in node_t. */ + unsigned int is_flagged_running:1; + unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */ + unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another + * router. */ + unsigned int is_valid:1; /**< True iff this router isn't invalid. */ + unsigned int is_possible_guard:1; /**< True iff this router would be a good + * choice as an entry guard. */ + unsigned int is_bad_exit:1; /**< True iff this node is a bad choice for + * an exit node. */ + unsigned int is_hs_dir:1; /**< True iff this router is a v2-or-later hidden + * service directory. */ + unsigned int is_v2_dir:1; /** True iff this router publishes an open DirPort + * or it claims to accept tunnelled dir requests. + */ + + unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */ + unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */ + unsigned int bw_is_unmeasured:1; /**< This is a consensus entry, with + * the Unmeasured flag set. */ + + /** Flags to summarize the protocol versions for this routerstatus_t. */ + protover_summary_flags_t pv; + + uint32_t bandwidth_kb; /**< Bandwidth (capacity) of the router as reported in + * the vote/consensus, in kilobytes/sec. */ + + /** The consensus has guardfraction information for this router. */ + unsigned int has_guardfraction:1; + /** The guardfraction value of this router. */ + uint32_t guardfraction_percentage; + + char *exitsummary; /**< exit policy summary - + * XXX weasel: this probably should not stay a string. */ + + /* ---- The fields below aren't derived from the networkstatus; they + * hold local information only. */ + + time_t last_dir_503_at; /**< When did this router last tell us that it + * was too busy to serve directory info? */ + download_status_t dl_status; + +}; + +#endif + diff --git a/src/or/scheduler.c b/src/or/scheduler.c index da894294bf..d12b8555d3 100644 --- a/src/or/scheduler.c +++ b/src/or/scheduler.c @@ -13,6 +13,8 @@ #define TOR_CHANNEL_INTERNAL_ #include "channeltls.h" +#include "or_connection_st.h" + /** * \file scheduler.c * \brief Channel scheduling system: decides which channels should send and diff --git a/src/or/scheduler_kist.c b/src/or/scheduler_kist.c index c6e9b72c48..fc91306412 100644 --- a/src/or/scheduler_kist.c +++ b/src/or/scheduler_kist.c @@ -14,6 +14,8 @@ #define SCHEDULER_PRIVATE_ #include "scheduler.h" +#include "or_connection_st.h" + #define TLS_PER_CELL_OVERHEAD 29 #ifdef HAVE_KIST_SUPPORT diff --git a/src/or/server_port_cfg_st.h b/src/or/server_port_cfg_st.h new file mode 100644 index 0000000000..7a6a0a53fe --- /dev/null +++ b/src/or/server_port_cfg_st.h @@ -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 SERVER_PORT_CFG_ST_H +#define SERVER_PORT_CFG_ST_H + +struct server_port_cfg_t { + /* Server port types (or, dir) only: */ + unsigned int no_advertise : 1; + unsigned int no_listen : 1; + unsigned int all_addrs : 1; + unsigned int bind_ipv4_only : 1; + unsigned int bind_ipv6_only : 1; +}; + +#endif + diff --git a/src/or/shared_random_client.c b/src/or/shared_random_client.c index 3aef83cef4..14997b21ba 100644 --- a/src/or/shared_random_client.c +++ b/src/or/shared_random_client.c @@ -17,6 +17,8 @@ #include "util.h" #include "util_format.h" +#include "networkstatus_st.h" + /* Convert a given srv object to a string for the control port. This doesn't * fail and the srv object MUST be valid. */ static char * diff --git a/src/or/signed_descriptor_st.h b/src/or/signed_descriptor_st.h new file mode 100644 index 0000000000..c057c5ddce --- /dev/null +++ b/src/or/signed_descriptor_st.h @@ -0,0 +1,61 @@ +/* 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 SIGNED_DESCRIPTOR_ST_H +#define SIGNED_DESCRIPTOR_ST_H + +#include "download_status_st.h" + +/** Information need to cache an onion router's descriptor. */ +struct signed_descriptor_t { + /** Pointer to the raw server descriptor, preceded by annotations. Not + * necessarily NUL-terminated. If saved_location is SAVED_IN_CACHE, this + * pointer is null. */ + char *signed_descriptor_body; + /** Length of the annotations preceding the server descriptor. */ + size_t annotations_len; + /** Length of the server descriptor. */ + size_t signed_descriptor_len; + /** Digest of the server descriptor, computed as specified in + * dir-spec.txt. */ + char signed_descriptor_digest[DIGEST_LEN]; + /** Identity digest of the router. */ + char identity_digest[DIGEST_LEN]; + /** Declared publication time of the descriptor. */ + time_t published_on; + /** For routerdescs only: digest of the corresponding extrainfo. */ + char extra_info_digest[DIGEST_LEN]; + /** For routerdescs only: A SHA256-digest of the extrainfo (if any) */ + char extra_info_digest256[DIGEST256_LEN]; + /** Certificate for ed25519 signing key. */ + struct tor_cert_st *signing_key_cert; + /** For routerdescs only: Status of downloading the corresponding + * extrainfo. */ + download_status_t ei_dl_status; + /** Where is the descriptor saved? */ + saved_location_t saved_location; + /** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of + * this descriptor in the corresponding file. */ + off_t saved_offset; + /** What position is this descriptor within routerlist->routers or + * routerlist->old_routers? -1 for none. */ + int routerlist_index; + /** The valid-until time of the most recent consensus that listed this + * descriptor. 0 for "never listed in a consensus, so far as we know." */ + time_t last_listed_as_valid_until; + /* If true, we do not ever try to save this object in the cache. */ + unsigned int do_not_cache : 1; + /* If true, this item is meant to represent an extrainfo. */ + unsigned int is_extrainfo : 1; + /* If true, we got an extrainfo for this item, and the digest was right, + * but it was incompatible. */ + unsigned int extrainfo_is_bogus : 1; + /* If true, we are willing to transmit this item unencrypted. */ + unsigned int send_unencrypted : 1; +}; + +#endif + diff --git a/src/or/socks_request_st.h b/src/or/socks_request_st.h new file mode 100644 index 0000000000..debf87bf08 --- /dev/null +++ b/src/or/socks_request_st.h @@ -0,0 +1,59 @@ +/* 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 SOCKS_REQUEST_ST_H +#define SOCKS_REQUEST_ST_H + +/** State of a SOCKS request from a user to an OP. Also used to encode other + * information for non-socks user request (such as those on TransPort and + * DNSPort) */ +struct socks_request_t { + /** Which version of SOCKS did the client use? One of "0, 4, 5" -- where + * 0 means that no socks handshake ever took place, and this is just a + * stub connection (e.g. see connection_ap_make_link()). */ + uint8_t socks_version; + /** If using socks5 authentication, which authentication type did we + * negotiate? currently we support 0 (no authentication) and 2 + * (username/password). */ + uint8_t auth_type; + /** What is this stream's goal? One of the SOCKS_COMMAND_* values */ + uint8_t command; + /** Which kind of listener created this stream? */ + uint8_t listener_type; + size_t replylen; /**< Length of reply. */ + uint8_t reply[MAX_SOCKS_REPLY_LEN]; /**< Write an entry into this string if + * we want to specify our own socks reply, + * rather than using the default socks4 or + * socks5 socks reply. We use this for the + * two-stage socks5 handshake. + */ + char address[MAX_SOCKS_ADDR_LEN]; /**< What address did the client ask to + connect to/resolve? */ + uint16_t port; /**< What port did the client ask to connect to? */ + unsigned int has_finished : 1; /**< Has the SOCKS handshake finished? Used to + * make sure we send back a socks reply for + * every connection. */ + unsigned int got_auth : 1; /**< Have we received any authentication data? */ + /** If this is set, we will choose "no authentication" instead of + * "username/password" authentication if both are offered. Used as input to + * parse_socks. */ + unsigned int socks_prefer_no_auth : 1; + + /** Number of bytes in username; 0 if username is NULL */ + size_t usernamelen; + /** Number of bytes in password; 0 if password is NULL */ + uint8_t passwordlen; + /** The negotiated username value if any (for socks5), or the entire + * authentication string (for socks4). This value is NOT nul-terminated; + * see usernamelen for its length. */ + char *username; + /** The negotiated password value if any (for socks5). This value is NOT + * nul-terminated; see passwordlen for its length. */ + char *password; +}; + +#endif + diff --git a/src/or/status.c b/src/or/status.c index 4b8033d114..2cfc436794 100644 --- a/src/or/status.c +++ b/src/or/status.c @@ -30,6 +30,8 @@ #include "hs_service.h" #include "dos.h" +#include "routerinfo_st.h" + static void log_accounting(const time_t now, const or_options_t *options); #include "geoip.h" diff --git a/src/or/tor_version_st.h b/src/or/tor_version_st.h new file mode 100644 index 0000000000..8c33602ef5 --- /dev/null +++ b/src/or/tor_version_st.h @@ -0,0 +1,32 @@ +/* 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_VERSION_ST_H +#define TOR_VERSION_ST_H + +#define MAX_STATUS_TAG_LEN 32 +/** Structure to hold parsed Tor versions. This is a little messier + * than we would like it to be, because we changed version schemes with 0.1.0. + * + * See version-spec.txt for the whole business. + */ +struct tor_version_t { + int major; + int minor; + int micro; + /** Release status. For version in the post-0.1 format, this is always + * VER_RELEASE. */ + enum { VER_PRE=0, VER_RC=1, VER_RELEASE=2, } status; + int patchlevel; + char status_tag[MAX_STATUS_TAG_LEN]; + int svn_revision; + + int git_tag_len; + char git_tag[DIGEST_LEN]; +}; + +#endif + diff --git a/src/or/torcert.c b/src/or/torcert.c index 1c5afd965a..5a156f18d4 100644 --- a/src/or/torcert.c +++ b/src/or/torcert.c @@ -35,6 +35,8 @@ #include "compat.h" #include "link_handshake.h" +#include "or_handshake_certs_st.h" + /** Helper for tor_cert_create(): signs any 32 bytes, not just an ed25519 * key. */ diff --git a/src/or/var_cell_st.h b/src/or/var_cell_st.h new file mode 100644 index 0000000000..1a9ea07590 --- /dev/null +++ b/src/or/var_cell_st.h @@ -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-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef VAR_CELL_ST_H +#define VAR_CELL_ST_H + +/** Parsed variable-length onion routing cell. */ +struct var_cell_t { + /** Type of the cell: CELL_VERSIONS, etc. */ + uint8_t command; + /** Circuit thich received the cell */ + circid_t circ_id; + /** Number of bytes actually stored in payload */ + uint16_t payload_len; + /** Payload of this cell */ + uint8_t payload[FLEXIBLE_ARRAY_MEMBER]; +}; + +#endif + diff --git a/src/or/vote_microdesc_hash_st.h b/src/or/vote_microdesc_hash_st.h new file mode 100644 index 0000000000..a7cbf5acdc --- /dev/null +++ b/src/or/vote_microdesc_hash_st.h @@ -0,0 +1,22 @@ +/* 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 VOTE_MICRODESC_HASH_ST_H +#define VOTE_MICRODESC_HASH_ST_H + +/** Linked list of microdesc hash lines for a single router in a directory + * vote. + */ +struct vote_microdesc_hash_t { + /** Next element in the list, or NULL. */ + struct vote_microdesc_hash_t *next; + /** The raw contents of the microdesc hash line, from the "m" through the + * newline. */ + char *microdesc_hash_line; +}; + +#endif + diff --git a/src/or/vote_routerstatus_st.h b/src/or/vote_routerstatus_st.h new file mode 100644 index 0000000000..7ac9a60034 --- /dev/null +++ b/src/or/vote_routerstatus_st.h @@ -0,0 +1,41 @@ +/* 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 VOTE_ROUTERSTATUS_ST_H +#define VOTE_ROUTERSTATUS_ST_H + +#include "routerstatus_st.h" + +/** The claim about a single router, made in a vote. */ +struct vote_routerstatus_t { + routerstatus_t status; /**< Underlying 'status' object for this router. + * Flags are redundant. */ + /** How many known-flags are allowed in a vote? This is the width of + * the flags field of vote_routerstatus_t */ +#define MAX_KNOWN_FLAGS_IN_VOTE 64 + uint64_t flags; /**< Bit-field for all recognized flags; index into + * networkstatus_t.known_flags. */ + char *version; /**< The version that the authority says this router is + * running. */ + char *protocols; /**< The protocols that this authority says this router + * provides. */ + unsigned int has_measured_bw:1; /**< The vote had a measured bw */ + /** True iff the vote included an entry for ed25519 ID, or included + * "id ed25519 none" to indicate that there was no ed25519 ID. */ + unsigned int has_ed25519_listing:1; + /** True if the Ed25519 listing here is the consensus-opinion for the + * Ed25519 listing; false if there was no consensus on Ed25519 key status, + * or if this VRS doesn't reflect it. */ + unsigned int ed25519_reflects_consensus:1; + uint32_t measured_bw_kb; /**< Measured bandwidth (capacity) of the router */ + /** The hash or hashes that the authority claims this microdesc has. */ + vote_microdesc_hash_t *microdesc; + /** Ed25519 identity for this router, or zero if it has none. */ + uint8_t ed25519_id[ED25519_PUBKEY_LEN]; +}; + +#endif + diff --git a/src/or/vote_timing_st.h b/src/or/vote_timing_st.h new file mode 100644 index 0000000000..3bf3619071 --- /dev/null +++ b/src/or/vote_timing_st.h @@ -0,0 +1,24 @@ +/* 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 VOTE_TIMING_ST_H +#define VOTE_TIMING_ST_H + +/** Describes the schedule by which votes should be generated. */ +struct vote_timing_t { + /** Length in seconds between one consensus becoming valid and the next + * becoming valid. */ + int vote_interval; + /** For how many intervals is a consensus valid? */ + int n_intervals_valid; + /** Time in seconds allowed to propagate votes */ + int vote_delay; + /** Time in seconds allowed to propagate signatures */ + int dist_delay; +}; + +#endif + diff --git a/src/or/voting_schedule.c b/src/or/voting_schedule.c index 1d66b5e225..983cabbbf3 100644 --- a/src/or/voting_schedule.c +++ b/src/or/voting_schedule.c @@ -15,6 +15,8 @@ #include "config.h" #include "networkstatus.h" +#include "networkstatus_st.h" + /* ===== * Vote scheduling * ===== */ diff --git a/src/test/bench.c b/src/test/bench.c index 9ab23c9921..cce94a1ce0 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -26,6 +26,9 @@ #include "crypto_rand.h" #include "consdiff.h" +#include "cell_st.h" +#include "or_circuit_st.h" + #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) static uint64_t nanostart; static inline uint64_t diff --git a/src/test/fuzz/fuzz_http.c b/src/test/fuzz/fuzz_http.c index 2ffeb60244..e93204ea3e 100644 --- a/src/test/fuzz/fuzz_http.c +++ b/src/test/fuzz/fuzz_http.c @@ -14,6 +14,8 @@ #include "directory.h" #include "torlog.h" +#include "dir_connection_st.h" + #include "fuzzing.h" static void diff --git a/src/test/fuzz/fuzz_http_connect.c b/src/test/fuzz/fuzz_http_connect.c index dc674070b2..255a34169c 100644 --- a/src/test/fuzz/fuzz_http_connect.c +++ b/src/test/fuzz/fuzz_http_connect.c @@ -15,6 +15,9 @@ #include "proto_socks.h" #include "torlog.h" +#include "entry_connection_st.h" +#include "socks_request_st.h" + #include "fuzzing.h" static void diff --git a/src/test/fuzz/fuzz_iptsv2.c b/src/test/fuzz/fuzz_iptsv2.c index 4abde0c16d..db99f62dc9 100644 --- a/src/test/fuzz/fuzz_iptsv2.c +++ b/src/test/fuzz/fuzz_iptsv2.c @@ -4,6 +4,9 @@ #include "or.h" #include "routerparse.h" #include "rendcommon.h" + +#include "rend_service_descriptor_st.h" + #include "fuzzing.h" static void diff --git a/src/test/fuzz/fuzz_vrs.c b/src/test/fuzz/fuzz_vrs.c index baf0610a0b..a597674940 100644 --- a/src/test/fuzz/fuzz_vrs.c +++ b/src/test/fuzz/fuzz_vrs.c @@ -7,6 +7,10 @@ #include "memarea.h" #include "microdesc.h" #include "networkstatus.h" + +#include "networkstatus_st.h" +#include "vote_routerstatus_st.h" + #include "fuzzing.h" static void diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c index 9ac3894b0b..ec252c39b3 100644 --- a/src/test/rend_test_helpers.c +++ b/src/test/rend_test_helpers.c @@ -7,6 +7,10 @@ #include "rendcommon.h" #include "rend_test_helpers.h" +#include "extend_info_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" + void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points) diff --git a/src/test/test.c b/src/test/test.c index f0e8b9b728..14456d8666 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -62,6 +62,12 @@ double fabs(double x); #include "statefile.h" #include "crypto_curve25519.h" +#include "extend_info_st.h" +#include "or_circuit_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" + /** Run unit tests for the onion handshake code. */ static void test_onion_handshake(void *arg) diff --git a/src/test/test_address_set.c b/src/test/test_address_set.c index f7441a6491..93469573ff 100644 --- a/src/test/test_address_set.c +++ b/src/test/test_address_set.c @@ -10,6 +10,11 @@ #include "routerlist.h" #include "torcert.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + #include "test.h" static networkstatus_t *dummy_ns = NULL; diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c index 54d9716780..fe9cfaf4af 100644 --- a/src/test/test_cell_formats.c +++ b/src/test/test_cell_formats.c @@ -18,6 +18,11 @@ #include "onion_fast.h" #include "onion_ntor.h" #include "relay.h" + +#include "cell_st.h" +#include "cell_queue_st.h" +#include "var_cell_st.h" + #include "test.h" #include diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c index df987f82ce..a333fc55e8 100644 --- a/src/test/test_cell_queue.c +++ b/src/test/test_cell_queue.c @@ -8,6 +8,11 @@ #include "relay.h" #include "test.h" +#include "cell_st.h" +#include "cell_queue_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + static void test_cq_manip(void *arg) { diff --git a/src/test/test_channel.c b/src/test/test_channel.c index 76124a6e75..ba9d8bfb29 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -20,6 +20,12 @@ #include "scheduler.h" #include "networkstatus.h" +#include "cell_st.h" +#include "networkstatus_st.h" +#include "origin_circuit_st.h" +#include "routerstatus_st.h" +#include "var_cell_st.h" + /* Test suite stuff */ #include "log_test_helpers.h" #include "test.h" diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c index 2c803c3443..b2b9dc8d32 100644 --- a/src/test/test_channelpadding.c +++ b/src/test/test_channelpadding.c @@ -20,6 +20,11 @@ #include "networkstatus.h" #include "log_test_helpers.h" +#include "cell_st.h" +#include "networkstatus_st.h" +#include "or_connection_st.h" +#include "routerstatus_st.h" + int channelpadding_get_netflow_inactive_timeout_ms(channel_t *chan); int64_t channelpadding_compute_time_until_pad_for_netflow(channel_t *chan); int channelpadding_send_disable_command(channel_t*); diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index 94f1893cae..0f134f1e70 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -17,6 +17,8 @@ #include "scheduler.h" #include "tortls.h" +#include "or_connection_st.h" + /* Test suite stuff */ #include "test.h" #include "fakechans.h" diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c index a5282df69d..b09f7bf553 100644 --- a/src/test/test_circuitbuild.c +++ b/src/test/test_circuitbuild.c @@ -12,6 +12,8 @@ #include "config.h" #include "circuitbuild.h" +#include "extend_info_st.h" + /* Dummy nodes smartlist for testing */ static smartlist_t dummy_nodes; /* Dummy exit extend_info for testing */ diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c index 3794ffc2c6..86e78c331e 100644 --- a/src/test/test_circuitlist.c +++ b/src/test/test_circuitlist.c @@ -14,6 +14,9 @@ #include "test.h" #include "log_test_helpers.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + static channel_t * new_fake_channel(void) { diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c index 14c7598703..85d91ab8b2 100644 --- a/src/test/test_circuitmux.c +++ b/src/test/test_circuitmux.c @@ -13,6 +13,8 @@ #include "scheduler.h" #include "test.h" +#include "destroy_cell_queue_st.h" + /* XXXX duplicated function from test_circuitlist.c */ static channel_t * new_fake_channel(void) diff --git a/src/test/test_circuitstats.c b/src/test/test_circuitstats.c index 8ebef659ca..b8056e0d1d 100644 --- a/src/test/test_circuitstats.c +++ b/src/test/test_circuitstats.c @@ -17,6 +17,11 @@ #include "circuituse.h" #include "channel.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "extend_info_st.h" +#include "origin_circuit_st.h" + void test_circuitstats_timeout(void *arg); void test_circuitstats_hoplen(void *arg); origin_circuit_t *subtest_fourhop_circuit(struct timeval, int); diff --git a/src/test/test_circuituse.c b/src/test/test_circuituse.c index df1b43807f..16ae84380a 100644 --- a/src/test/test_circuituse.c +++ b/src/test/test_circuituse.c @@ -14,6 +14,9 @@ #include "circuitbuild.h" #include "nodelist.h" +#include "cpath_build_state_st.h" +#include "origin_circuit_st.h" + static void test_circuit_is_available_for_use_ret_false_when_marked_for_close(void *arg) { diff --git a/src/test/test_config.c b/src/test/test_config.c index 461aa646d6..ea0f45f22e 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -44,6 +44,10 @@ #include "test_helpers.h" +#include "dir_server_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" + static void test_config_addressmap(void *arg) { diff --git a/src/test/test_connection.c b/src/test/test_connection.c index dc0f6860d9..5d2aa65c80 100644 --- a/src/test/test_connection.c +++ b/src/test/test_connection.c @@ -11,6 +11,7 @@ #include "test.h" #include "connection.h" +#include "connection_edge.h" #include "hs_common.h" #include "main.h" #include "microdesc.h" @@ -23,6 +24,13 @@ #include "test_connection.h" #include "test_helpers.h" +#include "dir_connection_st.h" +#include "entry_connection_st.h" +#include "node_st.h" +#include "or_connection_st.h" +#include "routerinfo_st.h" +#include "socks_request_st.h" + static void * test_conn_get_basic_setup(const struct testcase_t *tc); static int test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg); diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c index 3b91baca39..dc223274b9 100644 --- a/src/test/test_consdiffmgr.c +++ b/src/test/test_consdiffmgr.c @@ -14,6 +14,8 @@ #include "routerparse.h" #include "workqueue.h" +#include "networkstatus_st.h" + #include "test.h" #include "log_test_helpers.h" diff --git a/src/test/test_controller.c b/src/test/test_controller.c index c9517583c2..e91aa2e726 100644 --- a/src/test/test_controller.c +++ b/src/test/test_controller.c @@ -14,6 +14,9 @@ #include "test.h" #include "test_helpers.h" +#include "control_connection_st.h" +#include "download_status_st.h" + static void test_add_onion_helper_keyarg_v3(void *arg) { diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c index e81aea8d66..70ce1a6960 100644 --- a/src/test/test_controller_events.c +++ b/src/test/test_controller_events.c @@ -11,6 +11,9 @@ #include "control.h" #include "test.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + static void add_testing_cell_stats_entry(circuit_t *circ, uint8_t command, unsigned int waiting_time, diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 0106e40d97..ac5b3bd7c2 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -28,6 +28,7 @@ #include "dirserv.h" #include "dirauth/dirvote.h" #include "entrynodes.h" +#include "fp_pair.h" #include "hibernate.h" #include "memarea.h" #include "networkstatus.h" @@ -44,6 +45,19 @@ #include "log_test_helpers.h" #include "voting_schedule.h" +#include "authority_cert_st.h" +#include "document_signature_st.h" +#include "extrainfo_st.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" +#include "ns_detached_signatures_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" +#include "tor_version_st.h" +#include "vote_microdesc_hash_st.h" +#include "vote_routerstatus_st.h" + #define NS_MODULE dir static void diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c index 230410f7fa..3ec9fd6910 100644 --- a/src/test/test_dir_common.c +++ b/src/test/test_dir_common.c @@ -14,6 +14,13 @@ #include "test_dir_common.h" #include "voting_schedule.h" +#include "authority_cert_st.h" +#include "networkstatus_st.h" +#include "networkstatus_voter_info_st.h" +#include "routerinfo_st.h" +#include "vote_microdesc_hash_st.h" +#include "vote_routerstatus_st.h" + void dir_common_setup_vote(networkstatus_t **vote, time_t now); networkstatus_t * dir_common_add_rs_and_parse(networkstatus_t *vote, networkstatus_t **vote_out, diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index 688d26bdc1..3babffb9ee 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -34,6 +34,13 @@ #include "log_test_helpers.h" #include "voting_schedule.h" +#include "dir_connection_st.h" +#include "dir_server_st.h" +#include "networkstatus_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "routerinfo_st.h" +#include "routerlist_st.h" + #ifdef _WIN32 /* For mkdir() */ #include diff --git a/src/test/test_dns.c b/src/test/test_dns.c index 1fee01d2c0..ffc6fb4514 100644 --- a/src/test/test_dns.c +++ b/src/test/test_dns.c @@ -10,6 +10,9 @@ #include "connection.h" #include "router.h" +#include "edge_connection_st.h" +#include "or_circuit_st.h" + #define NS_MODULE dns #define NS_SUBMODULE clip_ttl diff --git a/src/test/test_dos.c b/src/test/test_dos.c index 8ae967f3ae..bc77bd8cd6 100644 --- a/src/test/test_dos.c +++ b/src/test/test_dos.c @@ -15,6 +15,11 @@ #include "networkstatus.h" #include "nodelist.h" #include "routerlist.h" + +#include "networkstatus_st.h" +#include "or_connection_st.h" +#include "routerstatus_st.h" + #include "test.h" #include "log_test_helpers.h" diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c index 9d8a072c77..1c1eda02f1 100644 --- a/src/test/test_entryconn.c +++ b/src/test/test_entryconn.c @@ -19,6 +19,9 @@ #include "hs_cache.h" #include "rendcache.h" +#include "entry_connection_st.h" +#include "socks_request_st.h" + static void * entryconn_rewrite_setup(const struct testcase_t *tc) { diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c index cfcb88a66e..bc075e91ab 100644 --- a/src/test/test_entrynodes.c +++ b/src/test/test_entrynodes.c @@ -30,6 +30,16 @@ #include "statefile.h" #include "util.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "dir_connection_st.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + #include "test_helpers.h" #include "log_test_helpers.h" diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c index e05342cb8a..77874a74e2 100644 --- a/src/test/test_extorport.c +++ b/src/test/test_extorport.c @@ -13,6 +13,9 @@ #include "crypto_rand.h" #include "ext_orport.h" #include "main.h" + +#include "or_connection_st.h" + #include "test.h" /* Test connection_or_remove_from_ext_or_id_map and diff --git a/src/test/test_guardfraction.c b/src/test/test_guardfraction.c index 51ca8f08ec..38f237c5dd 100644 --- a/src/test/test_guardfraction.c +++ b/src/test/test_guardfraction.c @@ -15,6 +15,10 @@ #include "routerparse.h" #include "networkstatus.h" +#include "networkstatus_st.h" +#include "vote_microdesc_hash_st.h" +#include "vote_routerstatus_st.h" + #include "test.h" #include "test_helpers.h" #include "log_test_helpers.h" diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index 1db5e9064f..7b6aa25e60 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -24,6 +24,12 @@ #include "relay.h" #include "routerlist.h" +#include "cell_st.h" +#include "connection_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" +#include "routerlist_st.h" + #include "test.h" #include "test_helpers.h" #include "test_connection.h" diff --git a/src/test/test_hs.c b/src/test/test_hs.c index 64448de510..f2c520aeec 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -21,6 +21,12 @@ #include "rendservice.h" #include "routerset.h" #include "circuitbuild.h" + +#include "node_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "rend_intro_point_st.h" +#include "routerinfo_st.h" + #include "test_helpers.h" /* mock ID digest and longname for node that's in nodelist */ diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c index 458ce1a92e..415f6f30ee 100644 --- a/src/test/test_hs_cache.c +++ b/src/test/test_hs_cache.c @@ -18,6 +18,9 @@ #include "connection.h" #include "proto_http.h" +#include "dir_connection_st.h" +#include "networkstatus_st.h" + #include "hs_test_helpers.h" #include "test_helpers.h" #include "test.h" diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index 50dca588ed..64c098dbb1 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -37,6 +37,15 @@ #include "connection_edge.h" #include "networkstatus.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "dir_connection_st.h" +#include "entry_connection_st.h" +#include "extend_info_st.h" +#include "networkstatus_st.h" +#include "origin_circuit_st.h" +#include "socks_request_st.h" + static int mock_connection_ap_handshake_send_begin(entry_connection_t *ap_conn) { diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index 8bcb2c7e46..b4969fa7b0 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -33,6 +33,12 @@ #include "util.h" #include "voting_schedule.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + /** Test the validation of HS v3 addresses */ static void test_validate_address(void *arg) diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c index 308843e9b8..f720373375 100644 --- a/src/test/test_hs_control.c +++ b/src/test/test_hs_control.c @@ -7,10 +7,6 @@ **/ #define CONTROL_PRIVATE -#define CIRCUITBUILD_PRIVATE -#define RENDCOMMON_PRIVATE -#define RENDSERVICE_PRIVATE -#define HS_SERVICE_PRIVATE #include "or.h" #include "test.h" @@ -19,10 +15,10 @@ #include "hs_common.h" #include "hs_control.h" #include "nodelist.h" -//#include "rendcommon.h" -//#include "rendservice.h" -//#include "routerset.h" -//#include "circuitbuild.h" + +#include "node_st.h" +#include "routerstatus_st.h" + #include "test_helpers.h" /* mock ID digest and longname for node that's in nodelist */ diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index 4253c9a388..b8462d294e 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -28,6 +28,8 @@ #include "hs_intropoint.h" #include "hs_service.h" +#include "or_circuit_st.h" + /* Trunnel. */ #include "hs/cell_establish_intro.h" #include "hs/cell_introduce1.h" diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index 33b5e96070..a4a1449b4d 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -53,6 +53,13 @@ #include "dirauth/shared_random_state.h" #include "voting_schedule.h" +#include "cpath_build_state_st.h" +#include "crypt_path_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "origin_circuit_st.h" +#include "routerinfo_st.h" + /* Trunnel */ #include "hs/cell_establish_intro.h" diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c index 6840072d76..1447d0435a 100644 --- a/src/test/test_link_handshake.c +++ b/src/test/test_link_handshake.c @@ -21,6 +21,11 @@ #include "scheduler.h" #include "torcert.h" +#include "or_connection_st.h" +#include "or_handshake_certs_st.h" +#include "or_handshake_state_st.h" +#include "var_cell_st.h" + #include "test.h" #include "log_test_helpers.h" diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index 4b168f49ed..28d3494663 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -13,6 +13,11 @@ #include "routerparse.h" #include "torcert.h" +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + #include "test.h" #ifdef _WIN32 diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c index 9499fd0380..df69466fbb 100644 --- a/src/test/test_nodelist.c +++ b/src/test/test_nodelist.c @@ -11,6 +11,13 @@ #include "networkstatus.h" #include "nodelist.h" #include "torcert.h" + +#include "microdesc_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + #include "test.h" /** Test the case when node_get_by_id() returns NULL, diff --git a/src/test/test_oom.c b/src/test/test_oom.c index abf8896452..8d506271af 100644 --- a/src/test/test_oom.c +++ b/src/test/test_oom.c @@ -18,6 +18,11 @@ #include "test.h" #include "test_helpers.h" +#include "cell_st.h" +#include "entry_connection_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + /* small replacement mock for circuit_mark_for_close_ to avoid doing all * the other bookkeeping that comes with marking circuits. */ static void diff --git a/src/test/test_oos.c b/src/test/test_oos.c index e72fcf5de9..b341918030 100644 --- a/src/test/test_oos.c +++ b/src/test/test_oos.c @@ -12,6 +12,9 @@ #include "main.h" #include "test.h" +#include "dir_connection_st.h" +#include "or_connection_st.h" + static or_options_t mock_options; static void diff --git a/src/test/test_policy.c b/src/test/test_policy.c index e89d49aaf5..61ebd27dc9 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -10,6 +10,11 @@ #include "policies.h" #include "test.h" +#include "node_st.h" +#include "port_cfg_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + /* Helper: assert that short_policy parses and writes back out as itself, or as expected if that's provided. */ static void diff --git a/src/test/test_proto_misc.c b/src/test/test_proto_misc.c index 263ca47447..e2d063a772 100644 --- a/src/test/test_proto_misc.c +++ b/src/test/test_proto_misc.c @@ -15,6 +15,8 @@ #include "proto_control0.h" #include "proto_ext_or.h" +#include "var_cell_st.h" + static void test_proto_var_cell(void *arg) { diff --git a/src/test/test_relay.c b/src/test/test_relay.c index 73c0ed5586..df1cfd79af 100644 --- a/src/test/test_relay.c +++ b/src/test/test_relay.c @@ -9,6 +9,9 @@ /* For init/free stuff */ #include "scheduler.h" +#include "cell_st.h" +#include "or_circuit_st.h" + /* Test suite stuff */ #include "test.h" #include "fakechans.h" diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c index 841174982c..dc42709e03 100644 --- a/src/test/test_relaycell.c +++ b/src/test/test_relaycell.c @@ -16,6 +16,12 @@ #include "relay.h" #include "test.h" +#include "cell_st.h" +#include "crypt_path_st.h" +#include "entry_connection_st.h" +#include "origin_circuit_st.h" +#include "socks_request_st.h" + static int srm_ncalls; static entry_connection_t *srm_conn; static int srm_atype; diff --git a/src/test/test_relaycrypt.c b/src/test/test_relaycrypt.c index 60bd479719..9f6b5bbe66 100644 --- a/src/test/test_relaycrypt.c +++ b/src/test/test_relaycrypt.c @@ -10,6 +10,11 @@ #include "crypto_rand.h" #include "relay.h" #include "relay_crypto.h" + +#include "cell_st.h" +#include "or_circuit_st.h" +#include "origin_circuit_st.h" + #include "test.h" static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = { diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c index 9f6cfc4a22..6bc8038281 100644 --- a/src/test/test_rendcache.c +++ b/src/test/test_rendcache.c @@ -11,6 +11,13 @@ #include "routerlist.h" #include "config.h" #include "hs_common.h" + +#include "extend_info_st.h" +#include "rend_encoded_v2_service_descriptor_st.h" +#include "rend_intro_point_st.h" +#include "rend_service_descriptor_st.h" +#include "routerinfo_st.h" + #include "rend_test_helpers.h" #include "log_test_helpers.h" diff --git a/src/test/test_router.c b/src/test/test_router.c index 4e96e24534..d560a1aecf 100644 --- a/src/test/test_router.c +++ b/src/test/test_router.c @@ -14,6 +14,8 @@ #include "router.h" #include "routerlist.h" +#include "routerinfo_st.h" + /* Test suite stuff */ #include "test.h" diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c index 701227c1c7..41f7c09bde 100644 --- a/src/test/test_routerlist.c +++ b/src/test/test_routerlist.c @@ -33,6 +33,13 @@ #include "routerparse.h" #include "dirauth/shared_random.h" #include "statefile.h" + +#include "authority_cert_st.h" +#include "dir_connection_st.h" +#include "networkstatus_st.h" +#include "node_st.h" +#include "routerstatus_st.h" + #include "test.h" #include "test_dir_common.h" #include "log_test_helpers.h" diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c index c541324674..11a1ff2aff 100644 --- a/src/test/test_routerset.c +++ b/src/test/test_routerset.c @@ -9,6 +9,12 @@ #include "routerparse.h" #include "policies.h" #include "nodelist.h" + +#include "extend_info_st.h" +#include "node_st.h" +#include "routerinfo_st.h" +#include "routerstatus_st.h" + #include "test.h" #define NS_MODULE routerset diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c index f6ab0dfabd..a1b4d60a2c 100644 --- a/src/test/test_shared_random.c +++ b/src/test/test_shared_random.c @@ -22,6 +22,9 @@ #include "shared_random_client.h" #include "voting_schedule.h" +#include "dir_server_st.h" +#include "networkstatus_st.h" + static authority_cert_t *mock_cert; static authority_cert_t * diff --git a/src/test/test_socks.c b/src/test/test_socks.c index 8da7191e82..6c266438e8 100644 --- a/src/test/test_socks.c +++ b/src/test/test_socks.c @@ -9,6 +9,7 @@ #include "proto_socks.h" #include "test.h" #include "log_test_helpers.h" +#include "socks_request_st.h" typedef struct socks_test_data_t { socks_request_t *req; diff --git a/src/test/test_status.c b/src/test/test_status.c index b4ca17891b..cedce16765 100644 --- a/src/test/test_status.c +++ b/src/test/test_status.c @@ -24,6 +24,10 @@ #include "main.h" #include "nodelist.h" #include "statefile.h" + +#include "origin_circuit_st.h" +#include "routerinfo_st.h" + #include "test.h" #define NS_MODULE status