diff options
Diffstat (limited to 'src/or')
250 files changed, 8759 insertions, 7319 deletions
diff --git a/src/or/addr_policy_st.h b/src/or/addr_policy_st.h new file mode 100644 index 0000000000..be3e9d8f01 --- /dev/null +++ b/src/or/addr_policy_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef TOR_ADDR_POLICY_ST_H +#define TOR_ADDR_POLICY_ST_H + +#include "lib/cc/torint.h" +#include "lib/net/address.h" + +/** What action type does an address policy indicate: accept or reject? */ +typedef enum { + ADDR_POLICY_ACCEPT=1, + ADDR_POLICY_REJECT=2, +} addr_policy_action_t; +#define addr_policy_action_bitfield_t ENUM_BF(addr_policy_action_t) + +/** A reference-counted address policy rule. */ +typedef struct addr_policy_t { + int refcnt; /**< Reference count */ + /** What to do when the policy matches.*/ + addr_policy_action_bitfield_t policy_type:2; + unsigned int is_private:1; /**< True iff this is the pseudo-address, + * "private". */ + unsigned int is_canonical:1; /**< True iff this policy is the canonical + * copy (stored in a hash table to avoid + * duplication of common policies) */ + maskbits_t maskbits; /**< Accept/reject all addresses <b>a</b> such that the + * first <b>maskbits</b> bits of <b>a</b> match + * <b>addr</b>. */ + /** Base address to accept or reject. + * + * Note that wildcards are treated + * differntly depending on address family. An AF_UNSPEC address means + * "All addresses, IPv4 or IPv6." An AF_INET address with maskbits==0 means + * "All IPv4 addresses" and an AF_INET6 address with maskbits == 0 means + * "All IPv6 addresses". + **/ + tor_addr_t addr; + uint16_t prt_min; /**< Lowest port number to accept/reject. */ + uint16_t prt_max; /**< Highest port number to accept/reject. */ +} addr_policy_t; + +#endif diff --git a/src/or/addressmap.c b/src/or/addressmap.c index 7f861e4d24..ba78a5f908 100644 --- a/src/or/addressmap.c +++ b/src/or/addressmap.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -15,16 +15,19 @@ #define ADDRESSMAP_PRIVATE -#include "or.h" -#include "addressmap.h" -#include "circuituse.h" -#include "config.h" -#include "connection_edge.h" -#include "control.h" -#include "crypto_rand.h" -#include "dns.h" -#include "nodelist.h" -#include "routerset.h" +#include "lib/crypt_ops/crypto_rand.h" + +#include "or/or.h" +#include "or/addressmap.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection_edge.h" +#include "or/control.h" +#include "or/dns.h" +#include "or/nodelist.h" +#include "or/routerset.h" + +#include "or/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 @@ -640,7 +643,7 @@ client_dns_incr_failures(const char *address) ent->expires = time(NULL) + MAX_DNS_ENTRY_AGE; strmap_set(addressmap,address,ent); } - if (ent->num_resolve_failures < SHORT_MAX) + if (ent->num_resolve_failures < SHRT_MAX) ++ent->num_resolve_failures; /* don't overflow */ log_info(LD_APP, "Address %s now has %d resolve failures.", safe_str_client(address), @@ -1151,4 +1154,3 @@ addressmap_get_mappings(smartlist_t *sl, time_t min_expires, iter = strmap_iter_next(addressmap,iter); } } - diff --git a/src/or/addressmap.h b/src/or/addressmap.h index 1544b76e10..b0db5c8b4e 100644 --- a/src/or/addressmap.h +++ b/src/or/addressmap.h @@ -1,13 +1,13 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_ADDRESSMAP_H #define TOR_ADDRESSMAP_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" void addressmap_init(void); void addressmap_clear_excluded_trackexithosts(const or_options_t *options); diff --git a/src/or/authority_cert_st.h b/src/or/authority_cert_st.h new file mode 100644 index 0000000000..19c3fda2de --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef AUTHORITY_CERT_ST_H +#define AUTHORITY_CERT_ST_H + +#include "or/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 <b>signing_key</b> */ + 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..ca0a13f2a0 100644 --- a/src/or/bridges.c +++ b/src/or/bridges.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,19 +13,24 @@ #define TOR_BRIDGES_PRIVATE -#include "or.h" -#include "bridges.h" -#include "circuitbuild.h" -#include "config.h" -#include "connection.h" -#include "directory.h" -#include "entrynodes.h" -#include "nodelist.h" -#include "policies.h" -#include "router.h" -#include "routerlist.h" -#include "routerset.h" -#include "transports.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/circuitbuild.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/directory.h" +#include "or/entrynodes.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerset.h" +#include "or/transports.h" + +#include "or/extend_info_st.h" +#include "or/node_st.h" +#include "or/routerinfo_st.h" +#include "or/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 diff --git a/src/or/bridges.h b/src/or/bridges.h index 3108eb555d..70588c1b91 100644 --- a/src/or/bridges.h +++ b/src/or/bridges.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,6 +13,7 @@ #define TOR_BRIDGES_H struct bridge_line_t; +struct ed25519_public_key_t; /* Opaque handle to a configured bridge */ typedef struct bridge_info_t bridge_info_t; @@ -38,7 +39,7 @@ int routerinfo_is_a_configured_bridge(const routerinfo_t *ri); int node_is_a_configured_bridge(const node_t *node); void learned_router_identity(const tor_addr_t *addr, uint16_t port, const char *digest, - const ed25519_public_key_t *ed_id); + const struct ed25519_public_key_t *ed_id); void bridge_add_from_config(struct bridge_line_t *bridge_line); void retry_bridge_descriptor_fetch_directly(const char *digest); @@ -77,4 +78,3 @@ STATIC void bridge_resolve_conflicts(const tor_addr_t *addr, #endif /* defined(TOR_BRIDGES_PRIVATE) */ #endif /* !defined(TOR_BRIDGES_H) */ - diff --git a/src/or/cached_dir_st.h b/src/or/cached_dir_st.h new file mode 100644 index 0000000000..38ae86d975 --- /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-2018, 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 <b>dir</b> (not counting its NUL). */ + size_t dir_compressed_len; /**< Length of <b>dir_compressed</b>. */ + 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..40110019bc --- /dev/null +++ b/src/or/cell_queue_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef PACKED_CELL_ST_H +#define PACKED_CELL_ST_H + +#include "tor_queue.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..6728e783b9 --- /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-2018, 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..2dbacbde98 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -1,5 +1,5 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -57,28 +57,31 @@ /* This one's for stuff only channel.c and the test suite should see */ #define CHANNEL_PRIVATE_ -#include "or.h" -#include "channel.h" -#include "channeltls.h" -#include "channelpadding.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuitstats.h" -#include "config.h" -#include "connection_or.h" /* For var_cell_free() */ -#include "circuitmux.h" -#include "entrynodes.h" -#include "geoip.h" -#include "main.h" -#include "nodelist.h" -#include "relay.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "scheduler.h" -#include "compat_time.h" -#include "networkstatus.h" -#include "rendservice.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/channelpadding.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "or/connection_or.h" /* For var_cell_free() */ +#include "or/circuitmux.h" +#include "or/entrynodes.h" +#include "or/geoip.h" +#include "or/main.h" +#include "or/nodelist.h" +#include "or/relay.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/scheduler.h" +#include "lib/time/compat_time.h" +#include "or/networkstatus.h" +#include "or/rendservice.h" +#include "common/timers.h" + +#include "or/cell_queue_st.h" /* Global lists of channels */ @@ -388,9 +391,9 @@ channel_register(channel_t *chan) if (chan->registered) return; log_debug(LD_CHANNEL, - "Registering channel %p (ID " U64_FORMAT ") " + "Registering channel %p (ID %"PRIu64 ") " "in state %s (%d) with digest %s", - chan, U64_PRINTF_ARG(chan->global_identifier), + chan, (chan->global_identifier), channel_state_to_string(chan->state), chan->state, hex_str(chan->identity_digest, DIGEST_LEN)); @@ -418,9 +421,9 @@ channel_register(channel_t *chan) channel_add_to_digest_map(chan); } else { log_info(LD_CHANNEL, - "Channel %p (global ID " U64_FORMAT ") " + "Channel %p (global ID %"PRIu64 ") " "in state %s (%d) registered with no identity digest", - chan, U64_PRINTF_ARG(chan->global_identifier), + chan, (chan->global_identifier), channel_state_to_string(chan->state), chan->state); } } @@ -484,9 +487,9 @@ channel_listener_register(channel_listener_t *chan_l) if (chan_l->registered) return; log_debug(LD_CHANNEL, - "Registering channel listener %p (ID " U64_FORMAT ") " + "Registering channel listener %p (ID %"PRIu64 ") " "in state %s (%d)", - chan_l, U64_PRINTF_ARG(chan_l->global_identifier), + chan_l, (chan_l->global_identifier), channel_listener_state_to_string(chan_l->state), chan_l->state); @@ -576,9 +579,9 @@ channel_add_to_digest_map(channel_t *chan) TOR_LIST_INSERT_HEAD(&ent->channel_list, chan, next_with_same_id); log_debug(LD_CHANNEL, - "Added channel %p (global ID " U64_FORMAT ") " + "Added channel %p (global ID %"PRIu64 ") " "to identity map in state %s (%d) with digest %s", - chan, U64_PRINTF_ARG(chan->global_identifier), + chan, (chan->global_identifier), channel_state_to_string(chan->state), chan->state, hex_str(chan->identity_digest, DIGEST_LEN)); } @@ -615,18 +618,18 @@ channel_remove_from_digest_map(channel_t *chan) } log_debug(LD_CHANNEL, - "Removed channel %p (global ID " U64_FORMAT ") from " + "Removed channel %p (global ID %"PRIu64 ") from " "identity map in state %s (%d) with digest %s", - chan, U64_PRINTF_ARG(chan->global_identifier), + chan, (chan->global_identifier), channel_state_to_string(chan->state), chan->state, hex_str(chan->identity_digest, DIGEST_LEN)); } else { /* Shouldn't happen */ log_warn(LD_BUG, - "Trying to remove channel %p (global ID " U64_FORMAT ") with " + "Trying to remove channel %p (global ID %"PRIu64 ") with " "digest %s from identity map, but couldn't find any with " "that digest", - chan, U64_PRINTF_ARG(chan->global_identifier), + chan, (chan->global_identifier), hex_str(chan->identity_digest, DIGEST_LEN)); } } @@ -880,8 +883,8 @@ channel_free_(channel_t *chan) tor_assert(!(chan->registered)); log_debug(LD_CHANNEL, - "Freeing channel " U64_FORMAT " at %p", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Freeing channel %"PRIu64 " at %p", + (chan->global_identifier), chan); /* Get this one out of the scheduler */ scheduler_release_channel(chan); @@ -926,8 +929,8 @@ channel_listener_free_(channel_listener_t *chan_l) if (!chan_l) return; log_debug(LD_CHANNEL, - "Freeing channel_listener_t " U64_FORMAT " at %p", - U64_PRINTF_ARG(chan_l->global_identifier), + "Freeing channel_listener_t %"PRIu64 " at %p", + (chan_l->global_identifier), chan_l); /* It must be closed or errored */ @@ -953,8 +956,8 @@ channel_force_xfree(channel_t *chan) tor_assert(chan); log_debug(LD_CHANNEL, - "Force-freeing channel " U64_FORMAT " at %p", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Force-freeing channel %"PRIu64 " at %p", + (chan->global_identifier), chan); /* Get this one out of the scheduler */ scheduler_release_channel(chan); @@ -997,8 +1000,8 @@ channel_listener_force_xfree(channel_listener_t *chan_l) tor_assert(chan_l); log_debug(LD_CHANNEL, - "Force-freeing channel_listener_t " U64_FORMAT " at %p", - U64_PRINTF_ARG(chan_l->global_identifier), + "Force-freeing channel_listener_t %"PRIu64 " at %p", + (chan_l->global_identifier), chan_l); /* Call a free method if there is one */ @@ -1037,8 +1040,8 @@ channel_listener_set_listener_fn(channel_listener_t *chan_l, log_debug(LD_CHANNEL, "Setting listener callback for channel listener %p " - "(global ID " U64_FORMAT ") to %p", - chan_l, U64_PRINTF_ARG(chan_l->global_identifier), + "(global ID %"PRIu64 ") to %p", + chan_l, (chan_l->global_identifier), listener); chan_l->listener = listener; @@ -1137,9 +1140,9 @@ channel_mark_for_close(channel_t *chan) return; log_debug(LD_CHANNEL, - "Closing channel %p (global ID " U64_FORMAT ") " + "Closing channel %p (global ID %"PRIu64 ") " "by request", - chan, U64_PRINTF_ARG(chan->global_identifier)); + chan, (chan->global_identifier)); /* Note closing by request from above */ chan->reason_for_closing = CHANNEL_CLOSE_REQUESTED; @@ -1177,9 +1180,9 @@ channel_listener_mark_for_close(channel_listener_t *chan_l) chan_l->state == CHANNEL_LISTENER_STATE_ERROR) return; log_debug(LD_CHANNEL, - "Closing channel listener %p (global ID " U64_FORMAT ") " + "Closing channel listener %p (global ID %"PRIu64 ") " "by request", - chan_l, U64_PRINTF_ARG(chan_l->global_identifier)); + chan_l, (chan_l->global_identifier)); /* Note closing by request from above */ chan_l->reason_for_closing = CHANNEL_LISTENER_CLOSE_REQUESTED; @@ -1215,9 +1218,9 @@ channel_close_from_lower_layer(channel_t *chan) return; log_debug(LD_CHANNEL, - "Closing channel %p (global ID " U64_FORMAT ") " + "Closing channel %p (global ID %"PRIu64 ") " "due to lower-layer event", - chan, U64_PRINTF_ARG(chan->global_identifier)); + chan, (chan->global_identifier)); /* Note closing by event from below */ chan->reason_for_closing = CHANNEL_CLOSE_FROM_BELOW; @@ -1300,8 +1303,8 @@ channel_clear_identity_digest(channel_t *chan) log_debug(LD_CHANNEL, "Clearing remote endpoint digest on channel %p with " - "global ID " U64_FORMAT, - chan, U64_PRINTF_ARG(chan->global_identifier)); + "global ID %"PRIu64, + chan, (chan->global_identifier)); state_not_in_map = CHANNEL_CONDEMNED(chan); @@ -1331,8 +1334,8 @@ channel_set_identity_digest(channel_t *chan, log_debug(LD_CHANNEL, "Setting remote endpoint digest on channel %p with " - "global ID " U64_FORMAT " to digest %s", - chan, U64_PRINTF_ARG(chan->global_identifier), + "global ID %"PRIu64 " to digest %s", + chan, (chan->global_identifier), identity_digest ? hex_str(identity_digest, DIGEST_LEN) : "(null)"); @@ -1388,8 +1391,8 @@ channel_clear_remote_end(channel_t *chan) log_debug(LD_CHANNEL, "Clearing remote endpoint identity on channel %p with " - "global ID " U64_FORMAT, - chan, U64_PRINTF_ARG(chan->global_identifier)); + "global ID %"PRIu64, + chan, (chan->global_identifier)); state_not_in_map = CHANNEL_CONDEMNED(chan); @@ -1472,13 +1475,13 @@ channel_write_packed_cell(channel_t *chan, packed_cell_t *cell) if (CHANNEL_IS_CLOSING(chan)) { log_debug(LD_CHANNEL, "Discarding %p on closing channel %p with " - "global ID "U64_FORMAT, cell, chan, - U64_PRINTF_ARG(chan->global_identifier)); + "global ID %"PRIu64, cell, chan, + (chan->global_identifier)); goto end; } log_debug(LD_CHANNEL, "Writing %p to channel %p with global ID " - U64_FORMAT, cell, chan, U64_PRINTF_ARG(chan->global_identifier)); + "%"PRIu64, cell, chan, (chan->global_identifier)); ret = write_packed_cell(chan, cell); @@ -1515,9 +1518,9 @@ channel_change_state_(channel_t *chan, channel_state_t to_state) if (from_state == to_state) { log_debug(LD_CHANNEL, "Got no-op transition from \"%s\" to itself on channel %p" - "(global ID " U64_FORMAT ")", + "(global ID %"PRIu64 ")", channel_state_to_string(to_state), - chan, U64_PRINTF_ARG(chan->global_identifier)); + chan, (chan->global_identifier)); return; } @@ -1529,10 +1532,10 @@ channel_change_state_(channel_t *chan, channel_state_t to_state) } log_debug(LD_CHANNEL, - "Changing state of channel %p (global ID " U64_FORMAT + "Changing state of channel %p (global ID %"PRIu64 ") from \"%s\" to \"%s\"", chan, - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), channel_state_to_string(chan->state), channel_state_to_string(to_state)); @@ -1635,9 +1638,9 @@ channel_listener_change_state(channel_listener_t *chan_l, if (from_state == to_state) { log_debug(LD_CHANNEL, "Got no-op transition from \"%s\" to itself on channel " - "listener %p (global ID " U64_FORMAT ")", + "listener %p (global ID %"PRIu64 ")", channel_listener_state_to_string(to_state), - chan_l, U64_PRINTF_ARG(chan_l->global_identifier)); + chan_l, (chan_l->global_identifier)); return; } @@ -1649,9 +1652,9 @@ channel_listener_change_state(channel_listener_t *chan_l, } log_debug(LD_CHANNEL, - "Changing state of channel listener %p (global ID " U64_FORMAT + "Changing state of channel listener %p (global ID %"PRIu64 "from \"%s\" to \"%s\"", - chan_l, U64_PRINTF_ARG(chan_l->global_identifier), + chan_l, (chan_l->global_identifier), channel_listener_state_to_string(chan_l->state), channel_listener_state_to_string(to_state)); @@ -1800,8 +1803,8 @@ channel_listener_process_incoming(channel_listener_t *listener) log_debug(LD_CHANNEL, "Processing queue of incoming connections for channel " - "listener %p (global ID " U64_FORMAT ")", - listener, U64_PRINTF_ARG(listener->global_identifier)); + "listener %p (global ID %"PRIu64 ")", + listener, (listener->global_identifier)); if (!(listener->incoming_list)) return; @@ -1810,12 +1813,12 @@ channel_listener_process_incoming(channel_listener_t *listener) tor_assert(chan); log_debug(LD_CHANNEL, - "Handling incoming channel %p (" U64_FORMAT ") " - "for listener %p (" U64_FORMAT ")", + "Handling incoming channel %p (%"PRIu64 ") " + "for listener %p (%"PRIu64 ")", chan, - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), listener, - U64_PRINTF_ARG(listener->global_identifier)); + (listener->global_identifier)); /* Make sure this is set correctly */ channel_mark_incoming(chan); listener->listener(listener, chan); @@ -1921,10 +1924,10 @@ channel_listener_queue_incoming(channel_listener_t *listener, tor_assert(incoming); log_debug(LD_CHANNEL, - "Queueing incoming channel %p (global ID " U64_FORMAT ") on " - "channel listener %p (global ID " U64_FORMAT ")", - incoming, U64_PRINTF_ARG(incoming->global_identifier), - listener, U64_PRINTF_ARG(listener->global_identifier)); + "Queueing incoming channel %p (global ID %"PRIu64 ") on " + "channel listener %p (global ID %"PRIu64 ")", + incoming, (incoming->global_identifier), + listener, (listener->global_identifier)); /* Do we need to queue it, or can we just call the listener right away? */ if (!(listener->listener)) need_to_queue = 1; @@ -1981,8 +1984,8 @@ channel_process_cell(channel_t *chan, cell_t *cell) log_debug(LD_CHANNEL, "Processing incoming cell_t %p for channel %p (global ID " - U64_FORMAT ")", cell, chan, - U64_PRINTF_ARG(chan->global_identifier)); + "%"PRIu64 ")", cell, chan, + (chan->global_identifier)); chan->cell_handler(chan, cell); } @@ -2022,8 +2025,8 @@ channel_send_destroy(circid_t circ_id, channel_t *chan, int reason) tor_assert(chan); if (circ_id == 0) { log_warn(LD_BUG, "Attempted to send a destroy cell for circID 0 " - "on a channel " U64_FORMAT " at %p in state %s (%d)", - U64_PRINTF_ARG(chan->global_identifier), + "on a channel %"PRIu64 " at %p in state %s (%d)", + (chan->global_identifier), chan, channel_state_to_string(chan->state), chan->state); return 0; @@ -2035,14 +2038,14 @@ channel_send_destroy(circid_t circ_id, channel_t *chan, int reason) circuitmux_append_destroy_cell(chan, chan->cmux, circ_id, reason); log_debug(LD_OR, "Sending destroy (circID %u) on channel %p " - "(global ID " U64_FORMAT ")", + "(global ID %"PRIu64 ")", (unsigned)circ_id, chan, - U64_PRINTF_ARG(chan->global_identifier)); + (chan->global_identifier)); } else { log_warn(LD_BUG, "Someone called channel_send_destroy() for circID %u " - "on a channel " U64_FORMAT " at %p in state %s (%d)", - (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier), + "on a channel %"PRIu64 " at %p in state %s (%d)", + (unsigned)circ_id, (chan->global_identifier), chan, channel_state_to_string(chan->state), chan->state); } @@ -2176,9 +2179,9 @@ channel_free_list(smartlist_t *channels, int mark_for_close) /* Deregister and free it */ tor_assert(curr); log_debug(LD_CHANNEL, - "Cleaning up channel %p (global ID " U64_FORMAT ") " + "Cleaning up channel %p (global ID %"PRIu64 ") " "in state %s (%d)", - curr, U64_PRINTF_ARG(curr->global_identifier), + curr, (curr->global_identifier), channel_state_to_string(curr->state), curr->state); /* Detach circuits early so they can find the channel */ if (curr->cmux) { @@ -2207,9 +2210,9 @@ channel_listener_free_list(smartlist_t *listeners, int mark_for_close) /* Deregister and free it */ tor_assert(curr); log_debug(LD_CHANNEL, - "Cleaning up channel listener %p (global ID " U64_FORMAT ") " + "Cleaning up channel listener %p (global ID %"PRIu64 ") " "in state %s (%d)", - curr, U64_PRINTF_ARG(curr->global_identifier), + curr, (curr->global_identifier), channel_listener_state_to_string(curr->state), curr->state); channel_listener_unregister(curr); if (mark_for_close) { @@ -2532,33 +2535,33 @@ channel_dump_statistics, (channel_t *chan, int severity)) age = (double)(now - chan->timestamp_created); tor_log(severity, LD_GENERAL, - "Channel " U64_FORMAT " (at %p) with transport %s is in state " + "Channel %"PRIu64 " (at %p) with transport %s is in state " "%s (%d)", - U64_PRINTF_ARG(chan->global_identifier), chan, + (chan->global_identifier), chan, channel_describe_transport(chan), channel_state_to_string(chan->state), chan->state); tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " was created at " U64_FORMAT - " (" U64_FORMAT " seconds ago) " - "and last active at " U64_FORMAT " (" U64_FORMAT " seconds ago)", - U64_PRINTF_ARG(chan->global_identifier), - U64_PRINTF_ARG(chan->timestamp_created), - U64_PRINTF_ARG(now - chan->timestamp_created), - U64_PRINTF_ARG(chan->timestamp_active), - U64_PRINTF_ARG(now - chan->timestamp_active)); + " * Channel %"PRIu64 " was created at %"PRIu64 + " (%"PRIu64 " seconds ago) " + "and last active at %"PRIu64 " (%"PRIu64 " seconds ago)", + (chan->global_identifier), + (uint64_t)(chan->timestamp_created), + (uint64_t)(now - chan->timestamp_created), + (uint64_t)(chan->timestamp_active), + (uint64_t)(now - chan->timestamp_active)); /* Handle digest. */ if (!tor_digest_is_zero(chan->identity_digest)) { tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " says it is connected " + " * Channel %"PRIu64 " says it is connected " "to an OR with digest %s", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), hex_str(chan->identity_digest, DIGEST_LEN)); } else { tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " does not know the digest" + " * Channel %"PRIu64 " does not know the digest" " of the OR it is connected to", - U64_PRINTF_ARG(chan->global_identifier)); + (chan->global_identifier)); } /* Handle remote address and descriptions */ @@ -2567,10 +2570,10 @@ channel_dump_statistics, (channel_t *chan, int severity)) char *actual = tor_strdup(channel_get_actual_remote_descr(chan)); remote_addr_str = tor_addr_to_str_dup(&remote_addr); tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " says its remote address" + " * Channel %"PRIu64 " says its remote address" " is %s, and gives a canonical description of \"%s\" and an " "actual description of \"%s\"", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), safe_str(remote_addr_str), safe_str(channel_get_canonical_remote_descr(chan)), safe_str(actual)); @@ -2579,10 +2582,10 @@ channel_dump_statistics, (channel_t *chan, int severity)) } else { char *actual = tor_strdup(channel_get_actual_remote_descr(chan)); tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " does not know its remote " + " * Channel %"PRIu64 " does not know its remote " "address, but gives a canonical description of \"%s\" and an " "actual description of \"%s\"", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), channel_get_canonical_remote_descr(chan), actual); tor_free(actual); @@ -2590,9 +2593,9 @@ channel_dump_statistics, (channel_t *chan, int severity)) /* Handle marks */ tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has these marks: %s %s %s " + " * Channel %"PRIu64 " has these marks: %s %s %s " "%s %s %s", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), channel_is_bad_for_new_circs(chan) ? "bad_for_new_circs" : "!bad_for_new_circs", channel_is_canonical(chan) ? @@ -2609,9 +2612,9 @@ channel_dump_statistics, (channel_t *chan, int severity)) /* Describe circuits */ tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has %d active circuits out of" + " * Channel %"PRIu64 " has %d active circuits out of" " %d in total", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), (chan->cmux != NULL) ? circuitmux_num_active_circuits(chan->cmux) : 0, (chan->cmux != NULL) ? @@ -2619,78 +2622,78 @@ channel_dump_statistics, (channel_t *chan, int severity)) /* Describe timestamps */ tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " was last used by a " - "client at " U64_FORMAT " (" U64_FORMAT " seconds ago)", - U64_PRINTF_ARG(chan->global_identifier), - U64_PRINTF_ARG(chan->timestamp_client), - U64_PRINTF_ARG(now - chan->timestamp_client)); + " * Channel %"PRIu64 " was last used by a " + "client at %"PRIu64 " (%"PRIu64 " seconds ago)", + (chan->global_identifier), + (uint64_t)(chan->timestamp_client), + (uint64_t)(now - chan->timestamp_client)); tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " last received a cell " - "at " U64_FORMAT " (" U64_FORMAT " seconds ago)", - U64_PRINTF_ARG(chan->global_identifier), - U64_PRINTF_ARG(chan->timestamp_recv), - U64_PRINTF_ARG(now - chan->timestamp_recv)); + " * Channel %"PRIu64 " last received a cell " + "at %"PRIu64 " (%"PRIu64 " seconds ago)", + (chan->global_identifier), + (uint64_t)(chan->timestamp_recv), + (uint64_t)(now - chan->timestamp_recv)); tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " last transmitted a cell " - "at " U64_FORMAT " (" U64_FORMAT " seconds ago)", - U64_PRINTF_ARG(chan->global_identifier), - U64_PRINTF_ARG(chan->timestamp_xmit), - U64_PRINTF_ARG(now - chan->timestamp_xmit)); + " * Channel %"PRIu64 " last transmitted a cell " + "at %"PRIu64 " (%"PRIu64 " seconds ago)", + (chan->global_identifier), + (uint64_t)(chan->timestamp_xmit), + (uint64_t)(now - chan->timestamp_xmit)); /* Describe counters and rates */ tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has received " - U64_FORMAT " bytes in " U64_FORMAT " cells and transmitted " - U64_FORMAT " bytes in " U64_FORMAT " cells", - U64_PRINTF_ARG(chan->global_identifier), - U64_PRINTF_ARG(chan->n_bytes_recved), - U64_PRINTF_ARG(chan->n_cells_recved), - U64_PRINTF_ARG(chan->n_bytes_xmitted), - U64_PRINTF_ARG(chan->n_cells_xmitted)); + " * Channel %"PRIu64 " has received " + "%"PRIu64 " bytes in %"PRIu64 " cells and transmitted " + "%"PRIu64 " bytes in %"PRIu64 " cells", + (chan->global_identifier), + (chan->n_bytes_recved), + (chan->n_cells_recved), + (chan->n_bytes_xmitted), + (chan->n_cells_xmitted)); if (now > chan->timestamp_created && chan->timestamp_created > 0) { if (chan->n_bytes_recved > 0) { avg = (double)(chan->n_bytes_recved) / age; tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has averaged %f " + " * Channel %"PRIu64 " has averaged %f " "bytes received per second", - U64_PRINTF_ARG(chan->global_identifier), avg); + (chan->global_identifier), avg); } if (chan->n_cells_recved > 0) { avg = (double)(chan->n_cells_recved) / age; if (avg >= 1.0) { tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has averaged %f " + " * Channel %"PRIu64 " has averaged %f " "cells received per second", - U64_PRINTF_ARG(chan->global_identifier), avg); + (chan->global_identifier), avg); } else if (avg >= 0.0) { interval = 1.0 / avg; tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has averaged %f " + " * Channel %"PRIu64 " has averaged %f " "seconds between received cells", - U64_PRINTF_ARG(chan->global_identifier), interval); + (chan->global_identifier), interval); } } if (chan->n_bytes_xmitted > 0) { avg = (double)(chan->n_bytes_xmitted) / age; tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has averaged %f " + " * Channel %"PRIu64 " has averaged %f " "bytes transmitted per second", - U64_PRINTF_ARG(chan->global_identifier), avg); + (chan->global_identifier), avg); } if (chan->n_cells_xmitted > 0) { avg = (double)(chan->n_cells_xmitted) / age; if (avg >= 1.0) { tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has averaged %f " + " * Channel %"PRIu64 " has averaged %f " "cells transmitted per second", - U64_PRINTF_ARG(chan->global_identifier), avg); + (chan->global_identifier), avg); } else if (avg >= 0.0) { interval = 1.0 / avg; tor_log(severity, LD_GENERAL, - " * Channel " U64_FORMAT " has averaged %f " + " * Channel %"PRIu64 " has averaged %f " "seconds between transmitted cells", - U64_PRINTF_ARG(chan->global_identifier), interval); + (chan->global_identifier), interval); } } } @@ -2715,29 +2718,29 @@ channel_listener_dump_statistics(channel_listener_t *chan_l, int severity) age = (double)(now - chan_l->timestamp_created); tor_log(severity, LD_GENERAL, - "Channel listener " U64_FORMAT " (at %p) with transport %s is in " + "Channel listener %"PRIu64 " (at %p) with transport %s is in " "state %s (%d)", - U64_PRINTF_ARG(chan_l->global_identifier), chan_l, + (chan_l->global_identifier), chan_l, channel_listener_describe_transport(chan_l), channel_listener_state_to_string(chan_l->state), chan_l->state); tor_log(severity, LD_GENERAL, - " * Channel listener " U64_FORMAT " was created at " U64_FORMAT - " (" U64_FORMAT " seconds ago) " - "and last active at " U64_FORMAT " (" U64_FORMAT " seconds ago)", - U64_PRINTF_ARG(chan_l->global_identifier), - U64_PRINTF_ARG(chan_l->timestamp_created), - U64_PRINTF_ARG(now - chan_l->timestamp_created), - U64_PRINTF_ARG(chan_l->timestamp_active), - U64_PRINTF_ARG(now - chan_l->timestamp_active)); + " * Channel listener %"PRIu64 " was created at %"PRIu64 + " (%"PRIu64 " seconds ago) " + "and last active at %"PRIu64 " (%"PRIu64 " seconds ago)", + (chan_l->global_identifier), + (uint64_t)(chan_l->timestamp_created), + (uint64_t)(now - chan_l->timestamp_created), + (uint64_t)(chan_l->timestamp_active), + (uint64_t)(now - chan_l->timestamp_active)); tor_log(severity, LD_GENERAL, - " * Channel listener " U64_FORMAT " last accepted an incoming " - "channel at " U64_FORMAT " (" U64_FORMAT " seconds ago) " - "and has accepted " U64_FORMAT " channels in total", - U64_PRINTF_ARG(chan_l->global_identifier), - U64_PRINTF_ARG(chan_l->timestamp_accepted), - U64_PRINTF_ARG(now - chan_l->timestamp_accepted), - U64_PRINTF_ARG(chan_l->n_accepted)); + " * Channel listener %"PRIu64 " last accepted an incoming " + "channel at %"PRIu64 " (%"PRIu64 " seconds ago) " + "and has accepted %"PRIu64 " channels in total", + (chan_l->global_identifier), + (uint64_t)(chan_l->timestamp_accepted), + (uint64_t)(now - chan_l->timestamp_accepted), + (uint64_t)(chan_l->n_accepted)); /* * If it's sensible to do so, get the rate of incoming channels on this @@ -2749,15 +2752,15 @@ channel_listener_dump_statistics(channel_listener_t *chan_l, int severity) avg = (double)(chan_l->n_accepted) / age; if (avg >= 1.0) { tor_log(severity, LD_GENERAL, - " * Channel listener " U64_FORMAT " has averaged %f incoming " + " * Channel listener %"PRIu64 " has averaged %f incoming " "channels per second", - U64_PRINTF_ARG(chan_l->global_identifier), avg); + (chan_l->global_identifier), avg); } else if (avg >= 0.0) { interval = 1.0 / avg; tor_log(severity, LD_GENERAL, - " * Channel listener " U64_FORMAT " has averaged %f seconds " + " * Channel listener %"PRIu64 " has averaged %f seconds " "between incoming channels", - U64_PRINTF_ARG(chan_l->global_identifier), interval); + (chan_l->global_identifier), interval); } } @@ -3475,4 +3478,3 @@ channel_update_bad_for_new_circs(const char *digest, int force) channel_rsa_id_group_set_badness(&(*iter)->channel_list, force); } } - diff --git a/src/or/channel.h b/src/or/channel.h index 6cf8cd7f72..010a8aa5bc 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,10 +9,15 @@ #ifndef TOR_CHANNEL_H #define TOR_CHANNEL_H -#include "or.h" -#include "circuitmux.h" -#include "timers.h" -#include "handles.h" +#include "or/or.h" +#include "or/circuitmux.h" +#include "common/handles.h" +#include "lib/crypt_ops/crypto_ed25519.h" + +#include "tor_queue.h" + +#define tor_timer_t timeout +struct tor_timer_t; /* Channel handler function pointer typedefs */ typedef void (*channel_listener_fn_ptr)(channel_listener_t *, channel_t *); @@ -30,6 +35,141 @@ typedef enum { CHANNEL_USED_FOR_USER_TRAFFIC, } channel_usage_info_t; +/** Possible rules for generating circuit IDs on an OR connection. */ +typedef enum { + CIRC_ID_TYPE_LOWER=0, /**< Pick from 0..1<<15-1. */ + CIRC_ID_TYPE_HIGHER=1, /**< Pick from 1<<15..1<<16-1. */ + /** The other side of a connection is an OP: never create circuits to it, + * and let it use any circuit ID it wants. */ + CIRC_ID_TYPE_NEITHER=2 +} circ_id_type_t; +#define circ_id_type_bitfield_t ENUM_BF(circ_id_type_t) + +/* channel states for channel_t */ + +typedef enum { + /* + * Closed state - channel is inactive + * + * Permitted transitions from: + * - CHANNEL_STATE_CLOSING + * Permitted transitions to: + * - CHANNEL_STATE_OPENING + */ + CHANNEL_STATE_CLOSED = 0, + /* + * Opening state - channel is trying to connect + * + * Permitted transitions from: + * - CHANNEL_STATE_CLOSED + * Permitted transitions to: + * - CHANNEL_STATE_CLOSING + * - CHANNEL_STATE_ERROR + * - CHANNEL_STATE_OPEN + */ + CHANNEL_STATE_OPENING, + /* + * Open state - channel is active and ready for use + * + * Permitted transitions from: + * - CHANNEL_STATE_MAINT + * - CHANNEL_STATE_OPENING + * Permitted transitions to: + * - CHANNEL_STATE_CLOSING + * - CHANNEL_STATE_ERROR + * - CHANNEL_STATE_MAINT + */ + CHANNEL_STATE_OPEN, + /* + * Maintenance state - channel is temporarily offline for subclass specific + * maintenance activities such as TLS renegotiation. + * + * Permitted transitions from: + * - CHANNEL_STATE_OPEN + * Permitted transitions to: + * - CHANNEL_STATE_CLOSING + * - CHANNEL_STATE_ERROR + * - CHANNEL_STATE_OPEN + */ + CHANNEL_STATE_MAINT, + /* + * Closing state - channel is shutting down + * + * Permitted transitions from: + * - CHANNEL_STATE_MAINT + * - CHANNEL_STATE_OPEN + * Permitted transitions to: + * - CHANNEL_STATE_CLOSED, + * - CHANNEL_STATE_ERROR + */ + CHANNEL_STATE_CLOSING, + /* + * Error state - channel has experienced a permanent error + * + * Permitted transitions from: + * - CHANNEL_STATE_CLOSING + * - CHANNEL_STATE_MAINT + * - CHANNEL_STATE_OPENING + * - CHANNEL_STATE_OPEN + * Permitted transitions to: + * - None + */ + CHANNEL_STATE_ERROR, + /* + * Placeholder for maximum state value + */ + CHANNEL_STATE_LAST +} channel_state_t; + +/* channel listener states for channel_listener_t */ + +typedef enum { + /* + * Closed state - channel listener is inactive + * + * Permitted transitions from: + * - CHANNEL_LISTENER_STATE_CLOSING + * Permitted transitions to: + * - CHANNEL_LISTENER_STATE_LISTENING + */ + CHANNEL_LISTENER_STATE_CLOSED = 0, + /* + * Listening state - channel listener is listening for incoming + * connections + * + * Permitted transitions from: + * - CHANNEL_LISTENER_STATE_CLOSED + * Permitted transitions to: + * - CHANNEL_LISTENER_STATE_CLOSING + * - CHANNEL_LISTENER_STATE_ERROR + */ + CHANNEL_LISTENER_STATE_LISTENING, + /* + * Closing state - channel listener is shutting down + * + * Permitted transitions from: + * - CHANNEL_LISTENER_STATE_LISTENING + * Permitted transitions to: + * - CHANNEL_LISTENER_STATE_CLOSED, + * - CHANNEL_LISTENER_STATE_ERROR + */ + CHANNEL_LISTENER_STATE_CLOSING, + /* + * Error state - channel listener has experienced a permanent error + * + * Permitted transitions from: + * - CHANNEL_STATE_CLOSING + * - CHANNEL_STATE_LISTENING + * Permitted transitions to: + * - None + */ + CHANNEL_LISTENER_STATE_ERROR, + /* + * Placeholder for maximum state value + */ + CHANNEL_LISTENER_STATE_LAST +} channel_listener_state_t; + /** * Channel struct; see the channel_t typedef in or.h. A channel is an * abstract interface for the OR-to-OR connection, similar to connection_or_t, @@ -92,7 +232,7 @@ struct channel_s { monotime_coarse_t next_padding_time; /** The callback pointer for the padding callbacks */ - tor_timer_t *padding_timer; + struct tor_timer_t *padding_timer; /** The handle to this channel (to free on canceled timers) */ struct channel_handle_t *timer_handle; @@ -251,7 +391,7 @@ struct channel_s { * necessarily its true identity. Don't believe this identity unless * authentication has happened. */ - ed25519_public_key_t ed25519_identity; + struct ed25519_public_key_t ed25519_identity; /** * Linked list of channels with the same RSA identity digest, for use with @@ -470,8 +610,8 @@ void channel_mark_incoming(channel_t *chan); void channel_mark_outgoing(channel_t *chan); void channel_mark_remote(channel_t *chan); void channel_set_identity_digest(channel_t *chan, - const char *identity_digest, - const ed25519_public_key_t *ed_identity); + const char *identity_digest, + const struct ed25519_public_key_t *ed_identity); void channel_listener_change_state(channel_listener_t *chan_l, channel_listener_state_t to_state); @@ -521,10 +661,10 @@ int channel_send_destroy(circid_t circ_id, channel_t *chan, channel_t * channel_connect(const tor_addr_t *addr, uint16_t port, const char *rsa_id_digest, - const ed25519_public_key_t *ed_id); + const struct ed25519_public_key_t *ed_id); channel_t * channel_get_for_extend(const char *rsa_id_digest, - const ed25519_public_key_t *ed_id, + const struct ed25519_public_key_t *ed_id, const tor_addr_t *target_addr, const char **msg_out, int *launch_out); @@ -537,7 +677,7 @@ int channel_is_better(channel_t *a, channel_t *b); channel_t * channel_find_by_global_id(uint64_t global_identifier); channel_t * channel_find_by_remote_identity(const char *rsa_id_digest, - const ed25519_public_key_t *ed_id); + const struct ed25519_public_key_t *ed_id); /** For things returned by channel_find_by_remote_digest(), walk the list. * The RSA key will match for all returned elements; the Ed25519 key might not. @@ -635,6 +775,6 @@ int packed_cell_is_destroy(channel_t *chan, HANDLE_DECL(channel, channel_s,) #define channel_handle_free(h) \ FREE_AND_NULL(channel_handle_t, channel_handle_free_, (h)) +#undef tor_timer_t #endif /* !defined(TOR_CHANNEL_H) */ - diff --git a/src/or/channelpadding.c b/src/or/channelpadding.c index a8b9a2b47b..298fea79a9 100644 --- a/src/or/channelpadding.c +++ b/src/or/channelpadding.c @@ -1,27 +1,31 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2015, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* TOR_CHANNEL_INTERNAL_ define needed for an O(1) implementation of * channelpadding_channel_to_channelinfo() */ #define TOR_CHANNEL_INTERNAL_ -#include "or.h" -#include "channel.h" -#include "channelpadding.h" -#include "channeltls.h" -#include "config.h" -#include "networkstatus.h" -#include "connection.h" -#include "connection_or.h" -#include "crypto_rand.h" -#include "main.h" -#include "rephist.h" -#include "router.h" -#include "compat_time.h" -#include "rendservice.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/channelpadding.h" +#include "or/channeltls.h" +#include "or/config.h" +#include "or/networkstatus.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/main.h" +#include "or/rephist.h" +#include "or/router.h" +#include "lib/time/compat_time.h" +#include "or/rendservice.h" +#include "common/timers.h" + +#include "or/cell_st.h" +#include "or/or_connection_st.h" STATIC int32_t channelpadding_get_netflow_inactive_timeout_ms( const channel_t *); @@ -279,10 +283,10 @@ channelpadding_update_padding_for_channel(channel_t *chan, pad_vars->ito_high_ms); log_fn(LOG_INFO,LD_OR, - "Negotiated padding=%d, lo=%d, hi=%d on "U64_FORMAT, + "Negotiated padding=%d, lo=%d, hi=%d on %"PRIu64, chan->padding_enabled, chan->padding_timeout_low_ms, chan->padding_timeout_high_ms, - U64_PRINTF_ARG(chan->global_identifier)); + (chan->global_identifier)); return 1; } @@ -390,13 +394,13 @@ channelpadding_send_padding_cell_for_callback(channel_t *chan) monotime_coarse_get(&now); log_fn(LOG_INFO,LD_OR, - "Sending netflow keepalive on "U64_FORMAT" to %s (%s) after " - I64_FORMAT" ms. Delta "I64_FORMAT"ms", - U64_PRINTF_ARG(chan->global_identifier), + "Sending netflow keepalive on %"PRIu64" to %s (%s) after " + "%"PRId64" ms. Delta %"PRId64"ms", + (chan->global_identifier), safe_str_client(chan->get_remote_descr(chan, 0)), safe_str_client(hex_str(chan->identity_digest, DIGEST_LEN)), - I64_PRINTF_ARG(monotime_coarse_diff_msec(&chan->timestamp_xfer,&now)), - I64_PRINTF_ARG( + (monotime_coarse_diff_msec(&chan->timestamp_xfer,&now)), + ( monotime_coarse_diff_msec(&chan->next_padding_time,&now))); } @@ -536,9 +540,9 @@ channelpadding_compute_time_until_pad_for_netflow(channel_t *chan) if (ms_till_pad > DFLT_NETFLOW_INACTIVE_KEEPALIVE_MAX) { tor_fragile_assert(); log_warn(LD_BUG, - "Channel padding timeout scheduled "I64_FORMAT"ms in the future. " + "Channel padding timeout scheduled %"PRId64"ms in the future. " "Did the monotonic clock just jump?", - I64_PRINTF_ARG(ms_till_pad)); + (ms_till_pad)); return 0; /* Clock jumped: Send padding now */ } @@ -562,8 +566,8 @@ channelpadding_compute_time_until_pad_for_netflow(channel_t *chan) int severity = (ms_till_pad < -NETFLOW_MISSED_WINDOW) ? LOG_NOTICE : LOG_INFO; log_fn(severity, LD_OR, - "Channel padding timeout scheduled "I64_FORMAT"ms in the past. ", - I64_PRINTF_ARG(-ms_till_pad)); + "Channel padding timeout scheduled %"PRId64"ms in the past. ", + (-ms_till_pad)); return 0; /* Clock jumped: Send padding now */ } @@ -694,8 +698,8 @@ channelpadding_reduce_padding_on_channel(channel_t *chan) chan->padding_timeout_high_ms = consensus_nf_ito_high_reduced; log_fn(LOG_INFO,LD_OR, - "Reduced padding on channel "U64_FORMAT": lo=%d, hi=%d", - U64_PRINTF_ARG(chan->global_identifier), + "Reduced padding on channel %"PRIu64": lo=%d, hi=%d", + (chan->global_identifier), chan->padding_timeout_low_ms, chan->padding_timeout_high_ms); } @@ -794,4 +798,3 @@ channelpadding_decide_to_pad_channel(channel_t *chan) return CHANNELPADDING_PADLATER; } } - diff --git a/src/or/channelpadding.h b/src/or/channelpadding.h index 58bf741d5c..7eddbdbe2d 100644 --- a/src/or/channelpadding.h +++ b/src/or/channelpadding.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2015, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,7 +11,7 @@ #ifndef TOR_CHANNELPADDING_H #define TOR_CHANNELPADDING_H -#include "channelpadding_negotiation.h" +#include "trunnel/channelpadding_negotiation.h" #define CHANNELPADDING_TOR2WEB_PARAM "nf_pad_tor2web" #define CHANNELPADDING_TOR2WEB_DEFAULT 1 diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 54d94f6109..85dfe0c0f1 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -38,27 +38,38 @@ #define CHANNELTLS_PRIVATE -#include "or.h" -#include "channel.h" -#include "channeltls.h" -#include "circuitmux.h" -#include "circuitmux_ewma.h" -#include "command.h" -#include "config.h" -#include "connection.h" -#include "connection_or.h" -#include "control.h" -#include "entrynodes.h" -#include "link_handshake.h" -#include "relay.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "scheduler.h" -#include "torcert.h" -#include "networkstatus.h" -#include "channelpadding_negotiation.h" -#include "channelpadding.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/circuitmux.h" +#include "or/circuitmux_ewma.h" +#include "or/command.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "or/entrynodes.h" +#include "trunnel/link_handshake.h" +#include "or/relay.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/scheduler.h" +#include "or/torcert.h" +#include "or/networkstatus.h" +#include "trunnel/channelpadding_negotiation.h" +#include "or/channelpadding.h" + +#include "or/cell_st.h" +#include "or/cell_queue_st.h" +#include "or/extend_info_st.h" +#include "or/or_connection_st.h" +#include "or/or_handshake_certs_st.h" +#include "or/or_handshake_state_st.h" +#include "or/routerinfo_st.h" +#include "or/var_cell_st.h" + +#include "lib/tls/tortls.h" /** How many CELL_PADDING cells have we received, ever? */ uint64_t stats_n_padding_cells_processed = 0; @@ -183,19 +194,19 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port, log_debug(LD_CHANNEL, "In channel_tls_connect() for channel %p " - "(global id " U64_FORMAT ")", + "(global id %"PRIu64 ")", tlschan, - U64_PRINTF_ARG(chan->global_identifier)); + (chan->global_identifier)); if (is_local_addr(addr)) { log_debug(LD_CHANNEL, - "Marking new outgoing channel " U64_FORMAT " at %p as local", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Marking new outgoing channel %"PRIu64 " at %p as local", + (chan->global_identifier), chan); channel_mark_local(chan); } else { log_debug(LD_CHANNEL, - "Marking new outgoing channel " U64_FORMAT " at %p as remote", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Marking new outgoing channel %"PRIu64 " at %p as remote", + (chan->global_identifier), chan); channel_mark_remote(chan); } @@ -211,8 +222,8 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port, } log_debug(LD_CHANNEL, - "Got orconn %p for channel with global id " U64_FORMAT, - tlschan->conn, U64_PRINTF_ARG(chan->global_identifier)); + "Got orconn %p for channel with global id %"PRIu64, + tlschan->conn, (chan->global_identifier)); goto done; @@ -262,8 +273,8 @@ channel_tls_start_listener(void) channel_tls_listener = listener; log_debug(LD_CHANNEL, - "Starting TLS channel listener %p with global id " U64_FORMAT, - listener, U64_PRINTF_ARG(listener->global_identifier)); + "Starting TLS channel listener %p with global id %"PRIu64, + listener, (listener->global_identifier)); channel_listener_register(listener); } else listener = channel_tls_listener; @@ -292,9 +303,9 @@ channel_tls_free_all(void) */ old_listener = channel_tls_listener; log_debug(LD_CHANNEL, - "Closing channel_tls_listener with ID " U64_FORMAT + "Closing channel_tls_listener with ID %"PRIu64 " at %p.", - U64_PRINTF_ARG(old_listener->global_identifier), + (old_listener->global_identifier), old_listener); channel_listener_unregister(old_listener); channel_listener_mark_for_close(old_listener); @@ -326,13 +337,13 @@ channel_tls_handle_incoming(or_connection_t *orconn) if (is_local_addr(&(TO_CONN(orconn)->addr))) { log_debug(LD_CHANNEL, - "Marking new incoming channel " U64_FORMAT " at %p as local", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Marking new incoming channel %"PRIu64 " at %p as local", + (chan->global_identifier), chan); channel_mark_local(chan); } else { log_debug(LD_CHANNEL, - "Marking new incoming channel " U64_FORMAT " at %p as remote", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Marking new incoming channel %"PRIu64 " at %p as remote", + (chan->global_identifier), chan); channel_mark_remote(chan); } @@ -422,8 +433,8 @@ channel_tls_describe_transport_method(channel_t *chan) if (buf) tor_free(buf); tor_asprintf(&buf, - "TLS channel (connection " U64_FORMAT ")", - U64_PRINTF_ARG(id)); + "TLS channel (connection %"PRIu64 ")", + (id)); rv = buf; } else { @@ -484,8 +495,8 @@ channel_tls_get_overhead_estimate_method(channel_t *chan) } log_debug(LD_CHANNEL, - "Estimated overhead ratio for TLS chan " U64_FORMAT " is %f", - U64_PRINTF_ARG(chan->global_identifier), overhead); + "Estimated overhead ratio for TLS chan %"PRIu64 " is %f", + (chan->global_identifier), overhead); return overhead; } @@ -616,8 +627,8 @@ channel_tls_has_queued_writes_method(channel_t *chan) if (!(tlschan->conn)) { log_info(LD_CHANNEL, "something called has_queued_writes on a tlschan " - "(%p with ID " U64_FORMAT " but no conn", - chan, U64_PRINTF_ARG(chan->global_identifier)); + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); } outbuf_len = (tlschan->conn != NULL) ? @@ -684,8 +695,8 @@ channel_tls_matches_extend_info_method(channel_t *chan, if (!(tlschan->conn)) { log_info(LD_CHANNEL, "something called matches_extend_info on a tlschan " - "(%p with ID " U64_FORMAT " but no conn", - chan, U64_PRINTF_ARG(chan->global_identifier)); + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); return 0; } @@ -714,8 +725,8 @@ channel_tls_matches_target_method(channel_t *chan, if (!(tlschan->conn)) { log_info(LD_CHANNEL, "something called matches_target on a tlschan " - "(%p with ID " U64_FORMAT " but no conn", - chan, U64_PRINTF_ARG(chan->global_identifier)); + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); return 0; } @@ -797,8 +808,8 @@ channel_tls_write_cell_method(channel_t *chan, cell_t *cell) } else { log_info(LD_CHANNEL, "something called write_cell on a tlschan " - "(%p with ID " U64_FORMAT " but no conn", - chan, U64_PRINTF_ARG(chan->global_identifier)); + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); } return written; @@ -830,8 +841,8 @@ channel_tls_write_packed_cell_method(channel_t *chan, } else { log_info(LD_CHANNEL, "something called write_packed_cell on a tlschan " - "(%p with ID " U64_FORMAT " but no conn", - chan, U64_PRINTF_ARG(chan->global_identifier)); + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); return -1; } @@ -859,8 +870,8 @@ channel_tls_write_var_cell_method(channel_t *chan, var_cell_t *var_cell) } else { log_info(LD_CHANNEL, "something called write_var_cell on a tlschan " - "(%p with ID " U64_FORMAT " but no conn", - chan, U64_PRINTF_ARG(chan->global_identifier)); + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); } return written; @@ -1332,15 +1343,15 @@ channel_tls_update_marks(or_connection_t *conn) if (is_local_addr(&(TO_CONN(conn)->addr))) { if (!channel_is_local(chan)) { log_debug(LD_CHANNEL, - "Marking channel " U64_FORMAT " at %p as local", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Marking channel %"PRIu64 " at %p as local", + (chan->global_identifier), chan); channel_mark_local(chan); } } else { if (channel_is_local(chan)) { log_debug(LD_CHANNEL, - "Marking channel " U64_FORMAT " at %p as remote", - U64_PRINTF_ARG(chan->global_identifier), chan); + "Marking channel %"PRIu64 " at %p as remote", + (chan->global_identifier), chan); channel_mark_remote(chan); } } @@ -2445,4 +2456,3 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan) #undef ERR } - diff --git a/src/or/channeltls.h b/src/or/channeltls.h index d9c4239c3a..1ab899af96 100644 --- a/src/or/channeltls.h +++ b/src/or/channeltls.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,8 +9,11 @@ #ifndef TOR_CHANNELTLS_H #define TOR_CHANNELTLS_H -#include "or.h" -#include "channel.h" +#include "or/or.h" +#include "or/channel.h" + +struct ed25519_public_key_t; +struct curve25519_public_key_t; #define BASE_CHAN_TO_TLS(c) (channel_tls_from_base((c))) #define TLS_CHAN_TO_BASE(c) (channel_tls_to_base((c))) @@ -30,7 +33,7 @@ struct channel_tls_s { channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port, const char *id_digest, - const ed25519_public_key_t *ed_id); + const struct ed25519_public_key_t *ed_id); channel_listener_t * channel_tls_get_listener(void); channel_listener_t * channel_tls_start_listener(void); channel_t * channel_tls_handle_incoming(or_connection_t *orconn); @@ -72,4 +75,3 @@ STATIC void channel_tls_process_authenticate_cell(var_cell_t *cell, #endif /* defined(CHANNELTLS_PRIVATE) */ #endif /* !defined(TOR_CHANNELTLS_H) */ - diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c index ff42bf91e4..32b3212d3f 100644 --- a/src/or/circpathbias.c +++ b/src/or/circpathbias.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,19 +21,27 @@ * each guard, and stored persistently in the state file. */ -#include "or.h" -#include "channel.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "circuitstats.h" -#include "connection_edge.h" -#include "config.h" -#include "crypto_rand.h" -#include "entrynodes.h" -#include "networkstatus.h" -#include "relay.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/circuitstats.h" +#include "or/connection_edge.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/entrynodes.h" +#include "or/networkstatus.h" +#include "or/relay.h" +#include "lib/math/fp.h" +#include "lib/math/laplace.h" + +#include "or/cell_st.h" +#include "or/cpath_build_state_st.h" +#include "or/crypt_path_st.h" +#include "or/extend_info_st.h" +#include "or/origin_circuit_st.h" static void pathbias_count_successful_close(origin_circuit_t *circ); static void pathbias_count_collapse(origin_circuit_t *circ); @@ -1568,4 +1576,3 @@ pathbias_scale_use_rates(entry_guard_t *guard) entry_guards_changed(); } } - diff --git a/src/or/circpathbias.h b/src/or/circpathbias.h index c9e572d2ae..c99d1277bb 100644 --- a/src/or/circpathbias.h +++ b/src/or/circpathbias.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -23,7 +23,6 @@ int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell); void pathbias_count_use_attempt(origin_circuit_t *circ); void pathbias_mark_use_success(origin_circuit_t *circ); void pathbias_mark_use_rollback(origin_circuit_t *circ); -const char *pathbias_state_to_string(path_state_t state); +const char *pathbias_state_to_string(enum path_state_t state); #endif /* !defined(TOR_CIRCPATHBIAS_H) */ - diff --git a/src/or/circuit_st.h b/src/or/circuit_st.h new file mode 100644 index 0000000000..8453efa633 --- /dev/null +++ b/src/or/circuit_st.h @@ -0,0 +1,182 @@ +/* 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 CIRCUIT_ST_H +#define CIRCUIT_ST_H + +#include "or/or.h" + +#include "or/cell_queue_st.h" + +struct hs_token_t; + +/** "magic" value for an origin_circuit_t */ +#define ORIGIN_CIRCUIT_MAGIC 0x35315243u +/** "magic" value for an or_circuit_t */ +#define OR_CIRCUIT_MAGIC 0x98ABC04Fu +/** "magic" value for a circuit that would have been freed by circuit_free, + * but which we're keeping around until a cpuworker reply arrives. See + * circuit_free() for more documentation. */ +#define DEAD_CIRCUIT_MAGIC 0xdeadc14c + +/** + * 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. */ + struct 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..39ae7ebf48 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,43 +27,54 @@ #define CIRCUITBUILD_PRIVATE -#include "or.h" -#include "bridges.h" -#include "channel.h" -#include "circpathbias.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/channel.h" +#include "or/circpathbias.h" #define CIRCUITBUILD_PRIVATE -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuitstats.h" -#include "circuituse.h" -#include "command.h" -#include "config.h" -#include "confparse.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_rand.h" -#include "directory.h" -#include "entrynodes.h" -#include "hs_ntor.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "onion.h" -#include "onion_tap.h" -#include "onion_fast.h" -#include "policies.h" -#include "relay.h" -#include "relay_crypto.h" -#include "rendcommon.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" -#include "transports.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuitstats.h" +#include "or/circuituse.h" +#include "or/command.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/directory.h" +#include "or/entrynodes.h" +#include "or/hs_ntor.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/onion.h" +#include "or/onion_tap.h" +#include "or/onion_fast.h" +#include "or/policies.h" +#include "or/relay.h" +#include "or/relay_crypto.h" +#include "or/rendcommon.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "or/transports.h" + +#include "or/cell_st.h" +#include "or/cpath_build_state_st.h" +#include "or/entry_connection_st.h" +#include "or/extend_info_st.h" +#include "or/node_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" +#include "or/microdesc_st.h" +#include "or/routerinfo_st.h" +#include "or/routerstatus_st.h" static channel_t * channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port, @@ -191,11 +202,11 @@ get_unique_circ_id_by_chan(channel_t *chan) chan->cmux); log_warn(LD_CIRC, " Circuitmux on this channel has %u circuits, " - "of which %u are active. It says it has "I64_FORMAT + "of which %u are active. It says it has %"PRId64 " destroy cells queued.", circuitmux_num_circuits(chan->cmux), circuitmux_num_active_circuits(chan->cmux), - I64_PRINTF_ARG(queued_destroys)); + (queued_destroys)); /* Change this into "if (1)" in order to get more information about * possible failure modes here. You'll need to know how to use gdb with @@ -1139,20 +1150,20 @@ circuit_note_clock_jumped(int64_t seconds_elapsed, bool was_idle) { int severity = server_mode(get_options()) ? LOG_WARN : LOG_NOTICE; if (was_idle) { - tor_log(severity, LD_GENERAL, "Tor has been idle for "I64_FORMAT + tor_log(severity, LD_GENERAL, "Tor has been idle for %"PRId64 " seconds; assuming established circuits no longer work.", - I64_PRINTF_ARG(seconds_elapsed)); + (seconds_elapsed)); } else { tor_log(severity, LD_GENERAL, - "Your system clock just jumped "I64_FORMAT" seconds %s; " + "Your system clock just jumped %"PRId64" seconds %s; " "assuming established circuits no longer work.", - I64_PRINTF_ARG( + ( seconds_elapsed >=0 ? seconds_elapsed : -seconds_elapsed), seconds_elapsed >=0 ? "forward" : "backward"); } - control_event_general_status(LOG_WARN, "CLOCK_JUMPED TIME="I64_FORMAT + control_event_general_status(LOG_WARN, "CLOCK_JUMPED TIME=%"PRId64 " IDLE=%d", - I64_PRINTF_ARG(seconds_elapsed), was_idle?1:0); + (seconds_elapsed), was_idle?1:0); /* so we log when it works again */ note_that_we_maybe_cant_complete_circuits(); control_event_client_status(severity, "CIRCUIT_NOT_ESTABLISHED REASON=%s", diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 0184898e29..9f5d99c2a5 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,6 +12,9 @@ #ifndef TOR_CIRCUITBUILD_H #define TOR_CIRCUITBUILD_H +struct ed25519_public_key_t; +struct curve25519_public_key_t; + int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei); char *circuit_list_path(origin_circuit_t *circ, int verbose); char *circuit_list_path_for_controller(origin_circuit_t *circ); @@ -52,9 +55,9 @@ int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info); void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop); extend_info_t *extend_info_new(const char *nickname, const char *rsa_id_digest, - const ed25519_public_key_t *ed_id, + const struct ed25519_public_key_t *ed_id, crypto_pk_t *onion_key, - const curve25519_public_key_t *ntor_key, + const struct curve25519_public_key_t *ntor_key, const tor_addr_t *addr, uint16_t port); extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect); extend_info_t *extend_info_dup(extend_info_t *info); @@ -91,8 +94,10 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei, int is_hs_v3_rp_circuit); #if defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS) -STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags, - const or_options_t *options); +enum router_crn_flags_t; +STATIC const node_t *pick_tor2web_rendezvous_node( + enum router_crn_flags_t flags, + const or_options_t *options); unsigned int cpath_get_n_hops(crypt_path_t **head_ptr); #endif /* defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS) */ @@ -100,4 +105,3 @@ unsigned int cpath_get_n_hops(crypt_path_t **head_ptr); #endif /* defined(CIRCUITBUILD_PRIVATE) */ #endif /* !defined(TOR_CIRCUITBUILD_H) */ - diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 45fff7cc17..d9d12db9b4 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -1,7 +1,7 @@ /* Copyright 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -51,46 +51,58 @@ * logic, which was originally circuit-focused. **/ #define CIRCUITLIST_PRIVATE -#include "torint.h" /* TOR_PRIuSZ */ - -#include "or.h" -#include "channel.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "circuitstats.h" -#include "connection.h" -#include "config.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "entrynodes.h" -#include "main.h" -#include "hs_circuit.h" -#include "hs_circuitmap.h" -#include "hs_ident.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "onion.h" -#include "onion_fast.h" -#include "policies.h" -#include "relay.h" -#include "relay_crypto.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rephist.h" -#include "routerlist.h" -#include "routerset.h" -#include "channelpadding.h" -#include "compress_lzma.h" -#include "compress_zlib.h" -#include "compress_zstd.h" +#include "lib/cc/torint.h" /* TOR_PRIuSZ */ + +#include "or/or.h" +#include "or/channel.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/circuitstats.h" +#include "or/connection.h" +#include "or/config.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "or/directory.h" +#include "or/entrynodes.h" +#include "or/main.h" +#include "or/hs_circuit.h" +#include "or/hs_circuitmap.h" +#include "or/hs_ident.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/onion.h" +#include "or/onion_fast.h" +#include "or/policies.h" +#include "or/relay.h" +#include "or/relay_crypto.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rephist.h" +#include "or/routerlist.h" +#include "or/routerset.h" +#include "or/channelpadding.h" +#include "lib/compress/compress.h" +#include "lib/compress/compress_lzma.h" +#include "lib/compress/compress_zlib.h" +#include "lib/compress/compress_zstd.h" +#include "lib/container/buffers.h" #include "ht.h" +#include "or/cpath_build_state_st.h" +#include "or/crypt_path_reference_st.h" +#include "or/dir_connection_st.h" +#include "or/edge_connection_st.h" +#include "or/extend_info_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" + /********* START VARIABLES **********/ /** A global list of all circuits at this hop. */ @@ -126,6 +138,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 { @@ -966,9 +1003,9 @@ origin_circuit_new(void) } log_info(LD_CIRC, - "Circuit " U64_FORMAT " chose an idle timeout of %d based on " + "Circuit %"PRIu32" chose an idle timeout of %d based on " "%d seconds of predictive building remaining.", - U64_PRINTF_ARG(circ->global_identifier), + (circ->global_identifier), circ->circuit_idle_timeout, prediction_time_remaining); } @@ -1355,9 +1392,9 @@ circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan, if (found && found->circuit) { log_debug(LD_CIRC, "circuit_get_by_circid_channel_impl() returning circuit %p for" - " circ_id %u, channel ID " U64_FORMAT " (%p)", + " circ_id %u, channel ID %"PRIu64 " (%p)", found->circuit, (unsigned)circ_id, - U64_PRINTF_ARG(chan->global_identifier), chan); + (chan->global_identifier), chan); if (found_entry_out) *found_entry_out = 1; return found->circuit; @@ -1365,10 +1402,10 @@ circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan, log_debug(LD_CIRC, "circuit_get_by_circid_channel_impl() found %s for" - " circ_id %u, channel ID " U64_FORMAT " (%p)", + " circ_id %u, channel ID %"PRIu64 " (%p)", found ? "placeholder" : "nothing", (unsigned)circ_id, - U64_PRINTF_ARG(chan->global_identifier), chan); + (chan->global_identifier), chan); if (found_entry_out) *found_entry_out = found ? 1 : 0; @@ -2567,10 +2604,10 @@ circuits_handle_oom(size_t current_allocation) done_recovering_mem: - log_notice(LD_GENERAL, "Removed "U64_FORMAT" bytes by killing %d circuits; " + log_notice(LD_GENERAL, "Removed %"TOR_PRIuSZ" bytes by killing %d circuits; " "%d circuits remain alive. Also killed %d non-linked directory " "connections.", - U64_PRINTF_ARG(mem_recovered), + mem_recovered, n_circuits_killed, smartlist_len(circlist) - n_circuits_killed, n_dirconns_killed); @@ -2703,4 +2740,3 @@ assert_circuit_ok,(const circuit_t *c)) tor_assert(!or_circ || !or_circ->rend_splice); } } - diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index 246f0c8815..7c9bc0199a 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,8 +12,158 @@ #ifndef TOR_CIRCUITLIST_H #define TOR_CIRCUITLIST_H -#include "testsupport.h" -#include "hs_ident.h" +#include "lib/testsupport/testsupport.h" +#include "or/hs_ident.h" + +/** Circuit state: I'm the origin, still haven't done all my handshakes. */ +#define CIRCUIT_STATE_BUILDING 0 +/** Circuit state: Waiting to process the onionskin. */ +#define CIRCUIT_STATE_ONIONSKIN_PENDING 1 +/** Circuit state: I'd like to deliver a create, but my n_chan is still + * connecting. */ +#define CIRCUIT_STATE_CHAN_WAIT 2 +/** Circuit state: the circuit is open but we don't want to actually use it + * until we find out if a better guard will be available. + */ +#define CIRCUIT_STATE_GUARD_WAIT 3 +/** Circuit state: onionskin(s) processed, ready to send/receive cells. */ +#define CIRCUIT_STATE_OPEN 4 + +#define CIRCUIT_PURPOSE_MIN_ 1 + +/* these circuits were initiated elsewhere */ +#define CIRCUIT_PURPOSE_OR_MIN_ 1 +/** OR-side circuit purpose: normal circuit, at OR. */ +#define CIRCUIT_PURPOSE_OR 1 +/** OR-side circuit purpose: At OR, from the service, waiting for intro from + * clients. */ +#define CIRCUIT_PURPOSE_INTRO_POINT 2 +/** OR-side circuit purpose: At OR, from the client, waiting for the service. + */ +#define CIRCUIT_PURPOSE_REND_POINT_WAITING 3 +/** OR-side circuit purpose: At OR, both circuits have this purpose. */ +#define CIRCUIT_PURPOSE_REND_ESTABLISHED 4 +#define CIRCUIT_PURPOSE_OR_MAX_ 4 + +/* these circuits originate at this node */ + +/* here's how circ client-side purposes work: + * normal circuits are C_GENERAL. + * circuits that are c_introducing are either on their way to + * becoming open, or they are open and waiting for a + * suitable rendcirc before they send the intro. + * circuits that are c_introduce_ack_wait have sent the intro, + * but haven't gotten a response yet. + * circuits that are c_establish_rend are either on their way + * to becoming open, or they are open and have sent the + * establish_rendezvous cell but haven't received an ack. + * circuits that are c_rend_ready are open and have received a + * rend ack, but haven't heard from the service yet. if they have a + * buildstate->pending_final_cpath then they're expecting a + * cell from the service, else they're not. + * circuits that are c_rend_ready_intro_acked are open, and + * some intro circ has sent its intro and received an ack. + * circuits that are c_rend_joined are open, have heard from + * the service, and are talking to it. + */ +/** Client-side circuit purpose: Normal circuit, with cpath. */ +#define CIRCUIT_PURPOSE_C_GENERAL 5 +#define CIRCUIT_PURPOSE_C_HS_MIN_ 6 +/** Client-side circuit purpose: at the client, connecting to intro point. */ +#define CIRCUIT_PURPOSE_C_INTRODUCING 6 +/** Client-side circuit purpose: at the client, sent INTRODUCE1 to intro point, + * waiting for ACK/NAK. */ +#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7 +/** Client-side circuit purpose: at the client, introduced and acked, closing. + */ +#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED 8 +/** Client-side circuit purpose: at the client, waiting for ack. */ +#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 9 +/** Client-side circuit purpose: at the client, waiting for the service. */ +#define CIRCUIT_PURPOSE_C_REND_READY 10 +/** Client-side circuit purpose: at the client, waiting for the service, + * INTRODUCE has been acknowledged. */ +#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED 11 +/** Client-side circuit purpose: at the client, rendezvous established. */ +#define CIRCUIT_PURPOSE_C_REND_JOINED 12 +/** This circuit is used for getting hsdirs */ +#define CIRCUIT_PURPOSE_C_HSDIR_GET 13 +#define CIRCUIT_PURPOSE_C_HS_MAX_ 13 +/** This circuit is used for build time measurement only */ +#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT 14 +#define CIRCUIT_PURPOSE_C_MAX_ 14 + +#define CIRCUIT_PURPOSE_S_HS_MIN_ 15 +/** Hidden-service-side circuit purpose: at the service, waiting for + * introductions. */ +#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 15 +/** Hidden-service-side circuit purpose: at the service, successfully + * established intro. */ +#define CIRCUIT_PURPOSE_S_INTRO 16 +/** Hidden-service-side circuit purpose: at the service, connecting to rend + * point. */ +#define CIRCUIT_PURPOSE_S_CONNECT_REND 17 +/** Hidden-service-side circuit purpose: at the service, rendezvous + * established. */ +#define CIRCUIT_PURPOSE_S_REND_JOINED 18 +/** This circuit is used for uploading hsdirs */ +#define CIRCUIT_PURPOSE_S_HSDIR_POST 19 +#define CIRCUIT_PURPOSE_S_HS_MAX_ 19 + +/** A testing circuit; not meant to be used for actual traffic. */ +#define CIRCUIT_PURPOSE_TESTING 20 +/** A controller made this circuit and Tor should not use it. */ +#define CIRCUIT_PURPOSE_CONTROLLER 21 +/** This circuit is used for path bias probing only */ +#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING 22 + +/** This circuit is used for vanguards/restricted paths. + * + * This type of circuit is *only* created preemptively and never + * on-demand. When an HS operation needs to take place (e.g. connect to an + * intro point), these circuits are then cannibalized and repurposed to the + * actual needed HS purpose. */ +#define CIRCUIT_PURPOSE_HS_VANGUARDS 23 + +#define CIRCUIT_PURPOSE_MAX_ 23 +/** A catch-all for unrecognized purposes. Currently we don't expect + * to make or see any circuits with this purpose. */ +#define CIRCUIT_PURPOSE_UNKNOWN 255 + +/** True iff the circuit purpose <b>p</b> is for a circuit that + * originated at this node. */ +#define CIRCUIT_PURPOSE_IS_ORIGIN(p) ((p)>CIRCUIT_PURPOSE_OR_MAX_) +/** True iff the circuit purpose <b>p</b> is for a circuit that originated + * here to serve as a client. (Hidden services don't count here.) */ +#define CIRCUIT_PURPOSE_IS_CLIENT(p) \ + ((p)> CIRCUIT_PURPOSE_OR_MAX_ && \ + (p)<=CIRCUIT_PURPOSE_C_MAX_) +/** True iff the circuit_t <b>c</b> is actually an origin_circuit_t. */ +#define CIRCUIT_IS_ORIGIN(c) (CIRCUIT_PURPOSE_IS_ORIGIN((c)->purpose)) +/** True iff the circuit purpose <b>p</b> is for an established rendezvous + * circuit. */ +#define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \ + ((p) == CIRCUIT_PURPOSE_C_REND_JOINED || \ + (p) == CIRCUIT_PURPOSE_S_REND_JOINED) +/** True iff the circuit_t c is actually an or_circuit_t */ +#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC) + +/** True iff this circuit purpose should count towards the global + * pending rate limit (set by MaxClientCircuitsPending). We count all + * general purpose circuits, as well as the first step of client onion + * service connections (HSDir gets). */ +#define CIRCUIT_PURPOSE_COUNTS_TOWARDS_MAXPENDING(p) \ + ((p) == CIRCUIT_PURPOSE_C_GENERAL || \ + (p) == CIRCUIT_PURPOSE_C_HSDIR_GET) + +/** 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); @@ -95,4 +245,3 @@ STATIC uint32_t circuit_max_queued_item_age(const circuit_t *c, uint32_t now); #endif /* defined(CIRCUITLIST_PRIVATE) */ #endif /* !defined(TOR_CIRCUITLIST_H) */ - diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c index f9f5faa057..9e0126b8f1 100644 --- a/src/or/circuitmux.c +++ b/src/or/circuitmux.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -69,11 +69,15 @@ * made to attach all existing circuits to the new policy. **/ -#include "or.h" -#include "channel.h" -#include "circuitlist.h" -#include "circuitmux.h" -#include "relay.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/circuitlist.h" +#include "or/circuitmux.h" +#include "or/relay.h" + +#include "or/cell_queue_st.h" +#include "or/destroy_cell_queue_st.h" +#include "or/or_circuit_st.h" /* * Private typedefs for circuitmux.c @@ -316,10 +320,10 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out) } else { /* Complain and move on */ log_warn(LD_CIRC, - "Circuit %u/channel " U64_FORMAT " had direction == " + "Circuit %u/channel %"PRIu64 " had direction == " "CELL_DIRECTION_IN, but isn't an or_circuit_t", (unsigned)to_remove->circ_id, - U64_PRINTF_ARG(to_remove->chan_id)); + (to_remove->chan_id)); } /* Free policy-specific data if we have it */ @@ -340,15 +344,15 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out) } else { /* Complain and move on */ log_warn(LD_CIRC, - "Couldn't find circuit %u (for channel " U64_FORMAT ")", + "Couldn't find circuit %u (for channel %"PRIu64 ")", (unsigned)to_remove->circ_id, - U64_PRINTF_ARG(to_remove->chan_id)); + (to_remove->chan_id)); } } else { /* Complain and move on */ log_warn(LD_CIRC, - "Couldn't find channel " U64_FORMAT " (for circuit id %u)", - U64_PRINTF_ARG(to_remove->chan_id), + "Couldn't find channel %"PRIu64 " (for circuit id %u)", + (to_remove->chan_id), (unsigned)to_remove->circ_id); } @@ -424,17 +428,17 @@ circuitmux_free_(circuitmux_t *cmux) global_destroy_ctr -= cmux->destroy_cell_queue.n; log_debug(LD_CIRC, "Freeing cmux at %p with %u queued destroys; the last cmux " - "destroy balance was "I64_FORMAT", global is "I64_FORMAT, + "destroy balance was %"PRId64", global is %"PRId64, cmux, cmux->destroy_cell_queue.n, - I64_PRINTF_ARG(cmux->destroy_ctr), - I64_PRINTF_ARG(global_destroy_ctr)); + (cmux->destroy_ctr), + (global_destroy_ctr)); } else { log_debug(LD_CIRC, "Freeing cmux at %p with no queued destroys, the cmux destroy " - "balance was "I64_FORMAT", global is "I64_FORMAT, + "balance was %"PRId64", global is %"PRId64, cmux, - I64_PRINTF_ARG(cmux->destroy_ctr), - I64_PRINTF_ARG(global_destroy_ctr)); + (cmux->destroy_ctr), + (global_destroy_ctr)); } destroy_cell_queue_clear(&cmux->destroy_cell_queue); @@ -831,9 +835,9 @@ circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ, * directions match and update the cell count and active circuit count. */ log_info(LD_CIRC, - "Circuit %u on channel " U64_FORMAT " was already attached to " + "Circuit %u on channel %"PRIu64 " was already attached to " "cmux %p (trying to attach to %p)", - (unsigned)circ_id, U64_PRINTF_ARG(channel_id), + (unsigned)circ_id, (channel_id), ((direction == CELL_DIRECTION_OUT) ? circ->n_mux : TO_OR_CIRCUIT(circ)->p_mux), cmux); @@ -865,8 +869,8 @@ circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ, * counts. */ log_debug(LD_CIRC, - "Attaching circuit %u on channel " U64_FORMAT " to cmux %p", - (unsigned)circ_id, U64_PRINTF_ARG(channel_id), cmux); + "Attaching circuit %u on channel %"PRIu64 " to cmux %p", + (unsigned)circ_id, (channel_id), cmux); /* * Assert that the circuit doesn't already have a mux for this @@ -1237,11 +1241,11 @@ circuitmux_notify_xmit_destroy(circuitmux_t *cmux) --(cmux->destroy_ctr); --(global_destroy_ctr); log_debug(LD_CIRC, - "Cmux at %p sent a destroy, cmux counter is now "I64_FORMAT", " - "global counter is now "I64_FORMAT, + "Cmux at %p sent a destroy, cmux counter is now %"PRId64", " + "global counter is now %"PRId64, cmux, - I64_PRINTF_ARG(cmux->destroy_ctr), - I64_PRINTF_ARG(global_destroy_ctr)); + (cmux->destroy_ctr), + (global_destroy_ctr)); } /*DOCDOC */ @@ -1258,10 +1262,10 @@ circuitmux_append_destroy_cell(channel_t *chan, ++global_destroy_ctr; log_debug(LD_CIRC, "Cmux at %p queued a destroy for circ %u, cmux counter is now " - I64_FORMAT", global counter is now "I64_FORMAT, + "%"PRId64", global counter is now %"PRId64, cmux, circ_id, - I64_PRINTF_ARG(cmux->destroy_ctr), - I64_PRINTF_ARG(global_destroy_ctr)); + (cmux->destroy_ctr), + (global_destroy_ctr)); /* XXXX Duplicate code from append_cell_to_circuit_queue */ if (!channel_has_queued_writes(chan)) { @@ -1299,12 +1303,12 @@ circuitmux_count_queued_destroy_cells(const channel_t *chan, n_destroy_cells != manual_total || n_destroy_cells != manual_total_in_map) { log_warn(LD_BUG, " Discrepancy in counts for queued destroy cells on " - "circuitmux. n="I64_FORMAT". queue_size="I64_FORMAT". " - "manual_total="I64_FORMAT". manual_total_in_map="I64_FORMAT".", - I64_PRINTF_ARG(n_destroy_cells), - I64_PRINTF_ARG(destroy_queue_size), - I64_PRINTF_ARG(manual_total), - I64_PRINTF_ARG(manual_total_in_map)); + "circuitmux. n=%"PRId64". queue_size=%"PRId64". " + "manual_total=%"PRId64". manual_total_in_map=%"PRId64".", + (n_destroy_cells), + (destroy_queue_size), + (manual_total), + (manual_total_in_map)); } return n_destroy_cells; diff --git a/src/or/circuitmux.h b/src/or/circuitmux.h index 336e128c76..e94cc354c7 100644 --- a/src/or/circuitmux.h +++ b/src/or/circuitmux.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,8 +9,8 @@ #ifndef TOR_CIRCUITMUX_H #define TOR_CIRCUITMUX_H -#include "or.h" -#include "testsupport.h" +#include "or/or.h" +#include "lib/testsupport/testsupport.h" typedef struct circuitmux_policy_s circuitmux_policy_t; typedef struct circuitmux_policy_data_s circuitmux_policy_data_t; diff --git a/src/or/circuitmux_ewma.c b/src/or/circuitmux_ewma.c index e5d5a14581..d600602a7e 100644 --- a/src/or/circuitmux_ewma.c +++ b/src/or/circuitmux_ewma.c @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -34,11 +34,12 @@ #include <math.h> -#include "or.h" -#include "circuitmux.h" -#include "circuitmux_ewma.h" -#include "crypto_rand.h" -#include "networkstatus.h" +#include "or/or.h" +#include "or/circuitmux.h" +#include "or/circuitmux_ewma.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/networkstatus.h" +#include "or/or_options_st.h" /*** EWMA parameter #defines ***/ @@ -826,4 +827,3 @@ circuitmux_ewma_free_all(void) { ewma_ticks_initialized = 0; } - diff --git a/src/or/circuitmux_ewma.h b/src/or/circuitmux_ewma.h index f0c4c36095..1214b0264b 100644 --- a/src/or/circuitmux_ewma.h +++ b/src/or/circuitmux_ewma.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,8 +9,8 @@ #ifndef TOR_CIRCUITMUX_EWMA_H #define TOR_CIRCUITMUX_EWMA_H -#include "or.h" -#include "circuitmux.h" +#include "or/or.h" +#include "or/circuitmux.h" /* The public EWMA policy callbacks object. */ extern circuitmux_policy_t ewma_policy; diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c index 94f75c590f..d275399e97 100644 --- a/src/or/circuitstats.c +++ b/src/or/circuitstats.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,21 +25,28 @@ #define CIRCUITSTATS_PRIVATE -#include "or.h" -#include "circuitbuild.h" -#include "circuitstats.h" -#include "config.h" -#include "confparse.h" -#include "control.h" -#include "crypto_rand.h" -#include "main.h" -#include "networkstatus.h" -#include "rendclient.h" -#include "rendservice.h" -#include "router.h" -#include "statefile.h" -#include "circuitlist.h" -#include "circuituse.h" +#include "or/or.h" +#include "or/circuitbuild.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/rendclient.h" +#include "or/rendservice.h" +#include "or/router.h" +#include "or/statefile.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "lib/math/fp.h" +#include "lib/time/tvdiff.h" +#include "lib/encoding/confline.h" + +#include "or/crypt_path_st.h" +#include "or/origin_circuit_st.h" +#include "or/or_state_st.h" #undef log #include <math.h> @@ -706,8 +713,8 @@ circuit_build_times_handle_completed_hop(origin_circuit_t *circ) * Switch their purpose and wait. */ if (circ->base_.purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) { log_info(LD_CIRC, - "Deciding to timeout circuit "U64_FORMAT"\n", - U64_PRINTF_ARG(circ->global_identifier)); + "Deciding to timeout circuit %"PRIu32"\n", + (circ->global_identifier)); circuit_build_times_mark_circ_as_measurement_only(circ); } } @@ -1943,4 +1950,3 @@ cbt_control_event_buildtimeout_set(const circuit_build_times_t *cbt, tor_free(args); } - diff --git a/src/or/circuitstats.h b/src/or/circuitstats.h index 86116cb7f8..174730d035 100644 --- a/src/or/circuitstats.h +++ b/src/or/circuitstats.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,6 +21,9 @@ int circuit_build_times_disabled(const or_options_t *options); int circuit_build_times_disabled_(const or_options_t *options, int ignore_consensus); +/** A build_time_t is milliseconds */ +typedef uint32_t build_time_t; + int circuit_build_times_enough_to_compute(const circuit_build_times_t *cbt); void circuit_build_times_update_state(const circuit_build_times_t *cbt, or_state_t *state); @@ -47,6 +50,89 @@ double circuit_build_times_close_rate(const circuit_build_times_t *cbt); void circuit_build_times_update_last_circ(circuit_build_times_t *cbt); void circuit_build_times_mark_circ_as_measurement_only(origin_circuit_t *circ); +/** Total size of the circuit timeout history to accumulate. + * 1000 is approx 2.5 days worth of continual-use circuits. */ +#define CBT_NCIRCUITS_TO_OBSERVE 1000 + +/** Width of the histogram bins in milliseconds */ +#define CBT_BIN_WIDTH ((build_time_t)50) + +/** Number of modes to use in the weighted-avg computation of Xm */ +#define CBT_DEFAULT_NUM_XM_MODES 3 +#define CBT_MIN_NUM_XM_MODES 1 +#define CBT_MAX_NUM_XM_MODES 20 + +/** + * CBT_BUILD_ABANDONED is our flag value to represent a force-closed + * circuit (Aka a 'right-censored' pareto value). + */ +#define CBT_BUILD_ABANDONED ((build_time_t)(INT32_MAX-1)) +#define CBT_BUILD_TIME_MAX ((build_time_t)(INT32_MAX)) + +/** Save state every 10 circuits */ +#define CBT_SAVE_STATE_EVERY 10 + +/* Circuit build times consensus parameters */ + +/** + * How long to wait before actually closing circuits that take too long to + * build in terms of CDF quantile. + */ +#define CBT_DEFAULT_CLOSE_QUANTILE 95 +#define CBT_MIN_CLOSE_QUANTILE CBT_MIN_QUANTILE_CUTOFF +#define CBT_MAX_CLOSE_QUANTILE CBT_MAX_QUANTILE_CUTOFF + +/** + * How many circuits count as recent when considering if the + * connection has gone gimpy or changed. + */ +#define CBT_DEFAULT_RECENT_CIRCUITS 20 +#define CBT_MIN_RECENT_CIRCUITS 3 +#define CBT_MAX_RECENT_CIRCUITS 1000 + +/** + * Maximum count of timeouts that finish the first hop in the past + * RECENT_CIRCUITS before calculating a new timeout. + * + * This tells us whether to abandon timeout history and set + * the timeout back to whatever circuit_build_times_get_initial_timeout() + * gives us. + */ +#define CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT (CBT_DEFAULT_RECENT_CIRCUITS*9/10) +#define CBT_MIN_MAX_RECENT_TIMEOUT_COUNT 3 +#define CBT_MAX_MAX_RECENT_TIMEOUT_COUNT 10000 + +/** Minimum circuits before estimating a timeout */ +#define CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE 100 +#define CBT_MIN_MIN_CIRCUITS_TO_OBSERVE 1 +#define CBT_MAX_MIN_CIRCUITS_TO_OBSERVE 10000 + +/** Cutoff percentile on the CDF for our timeout estimation. */ +#define CBT_DEFAULT_QUANTILE_CUTOFF 80 +#define CBT_MIN_QUANTILE_CUTOFF 10 +#define CBT_MAX_QUANTILE_CUTOFF 99 +double circuit_build_times_quantile_cutoff(void); + +/** How often in seconds should we build a test circuit */ +#define CBT_DEFAULT_TEST_FREQUENCY 10 +#define CBT_MIN_TEST_FREQUENCY 1 +#define CBT_MAX_TEST_FREQUENCY INT32_MAX + +/** Lowest allowable value for CircuitBuildTimeout in milliseconds */ +#define CBT_DEFAULT_TIMEOUT_MIN_VALUE (1500) +#define CBT_MIN_TIMEOUT_MIN_VALUE 500 +#define CBT_MAX_TIMEOUT_MIN_VALUE INT32_MAX + +/** Initial circuit build timeout in milliseconds */ +#define CBT_DEFAULT_TIMEOUT_INITIAL_VALUE (60*1000) +#define CBT_MIN_TIMEOUT_INITIAL_VALUE CBT_MIN_TIMEOUT_MIN_VALUE +#define CBT_MAX_TIMEOUT_INITIAL_VALUE INT32_MAX +int32_t circuit_build_times_initial_timeout(void); + +#if CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT < CBT_MIN_MAX_RECENT_TIMEOUT_COUNT +#error "RECENT_CIRCUITS is set too low." +#endif + #ifdef CIRCUITSTATS_PRIVATE STATIC double circuit_build_times_calculate_timeout(circuit_build_times_t *cbt, double quantile); @@ -73,6 +159,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 */ @@ -110,4 +211,3 @@ struct circuit_build_times_s { #endif /* defined(CIRCUITSTATS_PRIVATE) */ #endif /* !defined(TOR_CIRCUITSTATS_H) */ - diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 8e007ce920..a3a69dc354 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,34 +27,45 @@ * logic in circuitstats.c. **/ -#include "or.h" -#include "addressmap.h" -#include "bridges.h" -#include "channel.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuitstats.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "control.h" -#include "entrynodes.h" -#include "hs_common.h" -#include "hs_client.h" -#include "hs_circuit.h" -#include "hs_ident.h" -#include "hs_stats.h" -#include "nodelist.h" -#include "networkstatus.h" -#include "policies.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" +#include "or/or.h" +#include "or/addressmap.h" +#include "or/bridges.h" +#include "or/channel.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuitstats.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/control.h" +#include "or/directory.h" +#include "or/entrynodes.h" +#include "or/hs_common.h" +#include "or/hs_client.h" +#include "or/hs_circuit.h" +#include "or/hs_ident.h" +#include "or/hs_stats.h" +#include "or/nodelist.h" +#include "or/networkstatus.h" +#include "or/policies.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "lib/math/fp.h" +#include "lib/time/tvdiff.h" + +#include "or/cpath_build_state_st.h" +#include "or/dir_connection_st.h" +#include "or/entry_connection_st.h" +#include "or/extend_info_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" +#include "or/socks_request_st.h" static void circuit_expire_old_circuits_clientside(void); static void circuit_increment_failure_count(void); @@ -708,9 +719,8 @@ circuit_expire_building(void) circuit_build_times_enough_to_compute(get_circuit_build_times())) { log_info(LD_CIRC, - "Deciding to count the timeout for circuit "U64_FORMAT"\n", - U64_PRINTF_ARG( - TO_ORIGIN_CIRCUIT(victim)->global_identifier)); + "Deciding to count the timeout for circuit %"PRIu32"\n", + TO_ORIGIN_CIRCUIT(victim)->global_identifier); /* Circuits are allowed to last longer for measurement. * Switch their purpose and wait. */ @@ -1499,10 +1509,10 @@ circuit_expire_old_circuits_clientside(void) circ->purpose <= CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) || circ->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) { log_info(LD_CIRC, - "Closing circuit "U64_FORMAT + "Closing circuit %"PRIu32 " that has been unused for %ld msec.", - U64_PRINTF_ARG(TO_ORIGIN_CIRCUIT(circ)->global_identifier), - tv_mdiff(&circ->timestamp_began, &now)); + TO_ORIGIN_CIRCUIT(circ)->global_identifier, + tv_mdiff(&circ->timestamp_began, &now)); circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED); } else if (!TO_ORIGIN_CIRCUIT(circ)->is_ancient) { /* Server-side rend joined circuits can end up really old, because @@ -3143,4 +3153,3 @@ circuit_read_valid_data(origin_circuit_t *circ, uint16_t relay_body_len) tor_add_u32_nowrap(circ->n_overhead_read_circ_bw, RELAY_PAYLOAD_SIZE-relay_body_len); } - diff --git a/src/or/circuituse.h b/src/or/circuituse.h index 6458bd6908..b65e85d170 100644 --- a/src/or/circuituse.h +++ b/src/or/circuituse.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/command.c b/src/or/command.c index 39950f41bf..c2d6e2bb26 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -36,25 +36,30 @@ * callbacks registered in command_setup_channel(), * called when channels are created in circuitbuild.c */ -#include "or.h" -#include "channel.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "command.h" -#include "connection.h" -#include "connection_or.h" -#include "config.h" -#include "control.h" -#include "cpuworker.h" -#include "crypto_util.h" -#include "dos.h" -#include "hibernate.h" -#include "nodelist.h" -#include "onion.h" -#include "rephist.h" -#include "relay.h" -#include "router.h" -#include "routerlist.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/command.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "or/config.h" +#include "or/control.h" +#include "or/cpuworker.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/dos.h" +#include "or/hibernate.h" +#include "or/nodelist.h" +#include "or/onion.h" +#include "or/rephist.h" +#include "or/relay.h" +#include "or/router.h" +#include "or/routerlist.h" + +#include "or/cell_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" +#include "or/var_cell_st.h" /** How many CELL_CREATE cells have we received, ever? */ uint64_t stats_n_create_cells_processed = 0; @@ -244,10 +249,10 @@ command_process_create_cell(cell_t *cell, channel_t *chan) tor_assert(chan); log_debug(LD_OR, - "Got a CREATE cell for circ_id %u on channel " U64_FORMAT + "Got a CREATE cell for circ_id %u on channel %"PRIu64 " (%p)", (unsigned)cell->circ_id, - U64_PRINTF_ARG(chan->global_identifier), chan); + (chan->global_identifier), chan); /* First thing we do, even though the cell might be invalid, is inform the * DoS mitigation subsystem layer of this event. Validation is done by this diff --git a/src/or/command.h b/src/or/command.h index c0d1996cbb..864a5b2fd0 100644 --- a/src/or/command.h +++ b/src/or/command.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,7 @@ #ifndef TOR_COMMAND_H #define TOR_COMMAND_H -#include "channel.h" +#include "or/channel.h" void command_process_cell(channel_t *chan, cell_t *cell); void command_process_var_cell(channel_t *chan, var_cell_t *cell); diff --git a/src/or/config.c b/src/or/config.c index 94a58f3488..13002dd963 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -2,7 +2,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -60,61 +60,85 @@ **/ #define CONFIG_PRIVATE -#include "or.h" -#include "bridges.h" -#include "compat.h" -#include "addressmap.h" -#include "channel.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuitmux.h" -#include "circuitmux_ewma.h" -#include "circuitstats.h" -#include "compress.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "consdiffmgr.h" -#include "control.h" -#include "confparse.h" -#include "cpuworker.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "dirserv.h" -#include "dns.h" -#include "dos.h" -#include "entrynodes.h" -#include "git_revision.h" -#include "geoip.h" -#include "hibernate.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "relay.h" -#include "rendclient.h" -#include "rendservice.h" -#include "hs_config.h" -#include "rephist.h" -#include "router.h" -#include "sandbox.h" -#include "util.h" -#include "routerlist.h" -#include "routerset.h" -#include "scheduler.h" -#include "statefile.h" -#include "transports.h" -#include "ext_orport.h" -#include "voting_schedule.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/addressmap.h" +#include "or/channel.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuitmux.h" +#include "or/circuitmux_ewma.h" +#include "or/circuitstats.h" +#include "lib/compress/compress.h" +#include "or/config.h" +#include "lib/encoding/confline.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/consdiffmgr.h" +#include "or/control.h" +#include "or/confparse.h" +#include "or/cpuworker.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/dirserv.h" +#include "or/dns.h" +#include "or/dos.h" +#include "or/entrynodes.h" +#include "or/git_revision.h" +#include "or/geoip.h" +#include "or/hibernate.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/relay.h" +#include "or/rendclient.h" +#include "or/rendservice.h" +#include "or/hs_config.h" +#include "or/rephist.h" +#include "or/router.h" +#include "lib/sandbox/sandbox.h" +#include "common/util.h" +#include "or/routerlist.h" +#include "or/routerset.h" +#include "or/scheduler.h" +#include "or/statefile.h" +#include "or/transports.h" +#include "or/ext_orport.h" +#include "or/voting_schedule.h" #ifdef _WIN32 #include <shlobj.h> #endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "lib/meminfo/meminfo.h" +#include "lib/osinfo/uname.h" +#include "lib/process/daemon.h" +#include "lib/process/pidfile.h" +#include "lib/process/restrict.h" +#include "lib/process/setuid.h" +#include "lib/process/subprocess.h" +#include "lib/net/gethostname.h" +#include "lib/thread/numcpus.h" -#include "procmon.h" +#include "lib/encoding/keyval.h" +#include "lib/fs/conffile.h" +#include "common/procmon.h" -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" + +#include "or/connection_st.h" +#include "or/port_cfg_st.h" #ifdef HAVE_SYSTEMD # if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) @@ -132,6 +156,10 @@ static const char unix_socket_prefix[] = "unix:"; * configuration. */ static const char unix_q_socket_prefix[] = "unix:\""; +/* 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 */ + /** macro to help with the bulk rename of *DownloadSchedule to * *DowloadInitialDelay . */ #define DOWNLOAD_SCHEDULE(name) \ @@ -2626,7 +2654,7 @@ print_usage(void) printf( "Copyright (c) 2001-2004, Roger Dingledine\n" "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n" -"Copyright (c) 2007-2017, The Tor Project, Inc.\n\n" +"Copyright (c) 2007-2018, The Tor Project, Inc.\n\n" "tor -f <torrc> [args]\n" "See man page for options, or https://www.torproject.org/ for " "documentation.\n"); @@ -3033,8 +3061,8 @@ ensure_bandwidth_cap(uint64_t *value, const char *desc, char **msg) --*value; } if (*value > ROUTER_MAX_DECLARED_BANDWIDTH) { - tor_asprintf(msg, "%s ("U64_FORMAT") must be at most %d", - desc, U64_PRINTF_ARG(*value), + tor_asprintf(msg, "%s (%"PRIu64") must be at most %d", + desc, (*value), ROUTER_MAX_DECLARED_BANDWIDTH); return -1; } @@ -4567,8 +4595,8 @@ compute_real_max_mem_in_queues(const uint64_t val, int log_guess) uint64_t result; if (val == 0) { -#define ONE_GIGABYTE (U64_LITERAL(1) << 30) -#define ONE_MEGABYTE (U64_LITERAL(1) << 20) +#define ONE_GIGABYTE (UINT64_C(1) << 30) +#define ONE_MEGABYTE (UINT64_C(1) << 20) /* The user didn't pick a memory limit. Choose a very large one * that is still smaller than the system memory */ static int notice_sent = 0; @@ -4622,10 +4650,10 @@ compute_real_max_mem_in_queues(const uint64_t val, int log_guess) } } if (log_guess && ! notice_sent) { - log_notice(LD_CONFIG, "%sMaxMemInQueues is set to "U64_FORMAT" MB. " + log_notice(LD_CONFIG, "%sMaxMemInQueues is set to %"PRIu64" MB. " "You can override this by setting MaxMemInQueues by hand.", ram ? "Based on detected system memory, " : "", - U64_PRINTF_ARG(result / ONE_MEGABYTE)); + (result / ONE_MEGABYTE)); notice_sent = 1; } return result; @@ -5635,6 +5663,23 @@ addressmap_register_auto(const char *from, const char *to, } /** + * As add_file_log, but open the file as appropriate. + */ +STATIC int +open_and_add_file_log(const log_severity_list_t *severity, + const char *filename, int truncate_log) +{ + int open_flags = O_WRONLY|O_CREAT; + open_flags |= truncate_log ? O_TRUNC : O_APPEND; + + int fd = tor_open_cloexec(filename, open_flags, 0640); + if (fd < 0) + return -1; + + return add_file_log(severity, filename, fd); +} + +/** * Initialize the logs based on the configuration file. */ static int @@ -5759,7 +5804,7 @@ options_init_logs(const or_options_t *old_options, or_options_t *options, } } } - if (add_file_log(severity, fname, truncate_log) < 0) { + if (open_and_add_file_log(severity, fname, truncate_log) < 0) { log_warn(LD_CONFIG, "Couldn't open file for 'Log %s': %s", opt->value, strerror(errno)); ok = 0; @@ -8449,4 +8494,3 @@ options_any_client_port_set(const or_options_t *options) options->DNSPort_set || options->HTTPTunnelPort_set); } - diff --git a/src/or/config.h b/src/or/config.h index 4b41274434..6d2feb5f43 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,8 @@ #ifndef TOR_CONFIG_H #define TOR_CONFIG_H -#include "testsupport.h" +#include "or/or_options_st.h" +#include "lib/testsupport/testsupport.h" #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(DARWIN) #define KERNEL_MAY_SUPPORT_IPFW @@ -24,9 +25,9 @@ /** Maximum default value for MaxMemInQueues, in bytes. */ #if SIZEOF_VOID_P >= 8 -#define MAX_DEFAULT_MEMORY_QUEUE_SIZE (U64_LITERAL(8) << 30) +#define MAX_DEFAULT_MEMORY_QUEUE_SIZE (UINT64_C(8) << 30) #else -#define MAX_DEFAULT_MEMORY_QUEUE_SIZE (U64_LITERAL(2) << 30) +#define MAX_DEFAULT_MEMORY_QUEUE_SIZE (UINT64_C(2) << 30) #endif MOCK_DECL(const char*, get_dirportfrontpage, (void)); @@ -42,7 +43,16 @@ void init_protocol_warning_severity_level(void); int get_protocol_warning_severity_level(void); const char *get_version(void); const char *get_short_version(void); -setopt_err_t options_trial_assign(config_line_t *list, unsigned flags, + +/** An error from options_trial_assign() or options_init_from_string(). */ +typedef enum setopt_err_t { + SETOPT_OK = 0, + SETOPT_ERR_MISC = -1, + SETOPT_ERR_PARSE = -2, + SETOPT_ERR_TRANSITION = -3, + SETOPT_ERR_SETTING = -4, +} setopt_err_t; +setopt_err_t options_trial_assign(struct config_line_t *list, unsigned flags, char **msg); uint32_t get_last_resolved_addr(void); @@ -62,7 +72,7 @@ setopt_err_t options_init_from_string(const char *cf_defaults, const char *cf, int command, const char *command_arg, char **msg); int option_is_recognized(const char *key); const char *option_get_canonical_name(const char *key); -config_line_t *option_get_assignment(const or_options_t *options, +struct config_line_t *option_get_assignment(const or_options_t *options, const char *key); int options_save_current(void); const char *get_torrc_fname(int defaults_fname); @@ -180,8 +190,8 @@ int init_cookie_authentication(const char *fname, const char *header, or_options_t *options_new(void); int config_parse_commandline(int argc, char **argv, int ignore_errors, - config_line_t **result, - config_line_t **cmdline_result); + struct config_line_t **result, + struct config_line_t **cmdline_result); void config_register_addressmaps(const or_options_t *options); /* XXXX move to connection_edge.h */ @@ -260,7 +270,7 @@ STATIC int parse_dir_fallback_line(const char *line, int validate_only); STATIC int have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem, char **msg); STATIC int parse_port_config(smartlist_t *out, - const config_line_t *ports, + const struct config_line_t *ports, const char *portname, int listener_type, const char *defaultaddr, @@ -271,8 +281,10 @@ STATIC int check_bridge_distribution_setting(const char *bd); STATIC uint64_t compute_real_max_mem_in_queues(const uint64_t val, int log_guess); +STATIC int open_and_add_file_log(const log_severity_list_t *severity, + const char *fname, + int truncate_log); #endif /* defined(CONFIG_PRIVATE) */ #endif /* !defined(TOR_CONFIG_H) */ - diff --git a/src/or/confparse.c b/src/or/confparse.c index 6bab790945..87405c6e7d 100644 --- a/src/or/confparse.c +++ b/src/or/confparse.c @@ -1,8 +1,7 @@ - /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -22,9 +21,12 @@ * specified, and a linked list of key-value pairs. */ -#include "or.h" -#include "confparse.h" -#include "routerset.h" +#include "or/or.h" +#include "or/confparse.h" +#include "or/routerset.h" + +#include "lib/container/bitarray.h" +#include "lib/encoding/confline.h" static uint64_t config_parse_memunit(const char *s, int *ok); static int config_parse_msec_interval(const char *s, int *ok); @@ -573,8 +575,8 @@ config_get_assigned_option(const config_format_t *fmt, const void *options, escape_val = 0; /* Can't need escape. */ break; case CONFIG_TYPE_MEMUNIT: - tor_asprintf(&result->value, U64_FORMAT, - U64_PRINTF_ARG(*(uint64_t*)value)); + tor_asprintf(&result->value, "%"PRIu64, + (*(uint64_t*)value)); escape_val = 0; /* Can't need escape. */ break; case CONFIG_TYPE_DOUBLE: @@ -1039,15 +1041,15 @@ static struct unit_table_t memory_units[] = { { "gigabit", 1<<27 }, { "gbits", 1<<27 }, { "gbit", 1<<27 }, - { "tb", U64_LITERAL(1)<<40 }, - { "tbyte", U64_LITERAL(1)<<40 }, - { "tbytes", U64_LITERAL(1)<<40 }, - { "terabyte", U64_LITERAL(1)<<40 }, - { "terabytes", U64_LITERAL(1)<<40 }, - { "terabits", U64_LITERAL(1)<<37 }, - { "terabit", U64_LITERAL(1)<<37 }, - { "tbits", U64_LITERAL(1)<<37 }, - { "tbit", U64_LITERAL(1)<<37 }, + { "tb", UINT64_C(1)<<40 }, + { "tbyte", UINT64_C(1)<<40 }, + { "tbytes", UINT64_C(1)<<40 }, + { "terabyte", UINT64_C(1)<<40 }, + { "terabytes", UINT64_C(1)<<40 }, + { "terabits", UINT64_C(1)<<37 }, + { "terabit", UINT64_C(1)<<37 }, + { "tbits", UINT64_C(1)<<37 }, + { "tbit", UINT64_C(1)<<37 }, { NULL, 0 }, }; @@ -1116,7 +1118,7 @@ config_parse_units(const char *val, struct unit_table_t *u, int *ok) if (!cp) { *ok = 1; - v = use_float ? DBL_TO_U64(d) : v; + v = use_float ? ((uint64_t)d) : v; goto done; } @@ -1186,4 +1188,3 @@ config_parse_interval(const char *s, int *ok) } return (int)r; } - diff --git a/src/or/confparse.h b/src/or/confparse.h index 4b4bf0adb4..cbd2ea88e2 100644 --- a/src/or/confparse.h +++ b/src/or/confparse.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONFPARSE_H @@ -65,9 +65,9 @@ typedef union { time_t *ISOTIME; smartlist_t **CSV; int *CSV_INTERVAL; - config_line_t **LINELIST; - config_line_t **LINELIST_S; - config_line_t **LINELIST_V; + struct config_line_t **LINELIST; + struct config_line_t **LINELIST_S; + struct config_line_t **LINELIST_V; routerset_t **ROUTERSET; } confparse_dummy_values_t; #endif /* defined(TOR_UNIT_TESTS) */ @@ -185,7 +185,7 @@ void config_free_(const config_format_t *fmt, void *options); (options) = NULL; \ } while (0) -config_line_t *config_get_assigned_option(const config_format_t *fmt, +struct config_line_t *config_get_assigned_option(const config_format_t *fmt, const void *options, const char *key, int escape_val); int config_is_same(const config_format_t *fmt, @@ -197,7 +197,7 @@ char *config_dump(const config_format_t *fmt, const void *default_options, const void *options, int minimal, int comment_defaults); int config_assign(const config_format_t *fmt, void *options, - config_line_t *list, + struct config_line_t *list, unsigned flags, char **msg); config_var_t *config_find_option_mutable(config_format_t *fmt, const char *key); @@ -219,4 +219,3 @@ void warn_deprecated_option(const char *what, const char *why); #define CFG_EQ_ROUTERSET(a,b,opt) routerset_equal((a)->opt, (b)->opt) #endif /* !defined(TOR_CONFPARSE_H) */ - diff --git a/src/or/connection.c b/src/or/connection.c index 7283a81043..9680b08b56 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -55,64 +55,84 @@ **/ #define CONNECTION_PRIVATE -#include "or.h" -#include "bridges.h" -#include "buffers.h" -#include "buffers_tls.h" +#include "or/or.h" +#include "or/bridges.h" +#include "lib/container/buffers.h" +#include "lib/tls/buffers_tls.h" /* * Define this so we get channel internal functions, since we're implementing * part of a subclass (channel_tls_t). */ #define TOR_CHANNEL_INTERNAL_ #define CONNECTION_PRIVATE -#include "backtrace.h" -#include "channel.h" -#include "channeltls.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_util.h" -#include "directory.h" -#include "dirserv.h" -#include "dns.h" -#include "dnsserv.h" -#include "dos.h" -#include "entrynodes.h" -#include "ext_orport.h" -#include "geoip.h" -#include "main.h" -#include "hibernate.h" -#include "hs_common.h" -#include "hs_ident.h" -#include "nodelist.h" -#include "proto_http.h" -#include "proto_socks.h" -#include "policies.h" -#include "reasons.h" -#include "relay.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "transports.h" -#include "routerparse.h" -#include "sandbox.h" +#include "lib/err/backtrace.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/dns.h" +#include "or/dnsserv.h" +#include "or/dos.h" +#include "or/entrynodes.h" +#include "or/ext_orport.h" +#include "or/geoip.h" +#include "or/main.h" +#include "or/hibernate.h" +#include "or/hs_common.h" +#include "or/hs_ident.h" +#include "or/nodelist.h" +#include "or/proto_http.h" +#include "or/proto_socks.h" +#include "or/policies.h" +#include "or/reasons.h" +#include "or/relay.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/transports.h" +#include "or/routerparse.h" +#include "lib/sandbox/sandbox.h" +#include "lib/net/buffers_net.h" +#include "lib/tls/tortls.h" +#include "common/compat_libevent.h" +#include "lib/compress/compress.h" #ifdef HAVE_PWD_H #include <pwd.h> #endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + #ifdef HAVE_SYS_UN_H #include <sys/socket.h> #include <sys/un.h> #endif +#include "or/dir_connection_st.h" +#include "or/control_connection_st.h" +#include "or/entry_connection_st.h" +#include "or/listener_connection_st.h" +#include "or/or_connection_st.h" +#include "or/port_cfg_st.h" +#include "or/routerinfo_st.h" +#include "or/socks_request_st.h" + static connection_t *connection_listener_new( const struct sockaddr *listensockaddr, socklen_t listensocklen, int type, @@ -167,6 +187,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 <b>type</b> */ @@ -583,9 +624,9 @@ connection_free_minimal(connection_t *conn) /* Owww, this shouldn't happen, but... */ log_info(LD_CHANNEL, "Freeing orconn at %p, saw channel %p with ID " - U64_FORMAT " left un-NULLed", + "%"PRIu64 " left un-NULLed", or_conn, TLS_CHAN_TO_BASE(or_conn->chan), - U64_PRINTF_ARG( + ( TLS_CHAN_TO_BASE(or_conn->chan)->global_identifier)); if (!CHANNEL_FINISHED(TLS_CHAN_TO_BASE(or_conn->chan))) { channel_close_for_error(TLS_CHAN_TO_BASE(or_conn->chan)); @@ -4111,6 +4152,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 <b>buf</b> to <b>conn</b>'s outbuf, draining them * from <b>buf</b>. (If the connection is marked and will soon be closed, @@ -4815,6 +4863,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 @@ -4937,16 +4999,16 @@ connection_dump_buffer_mem_stats(int severity) } tor_log(severity, LD_GENERAL, - "In buffers for %d connections: "U64_FORMAT" used/"U64_FORMAT" allocated", + "In buffers for %d connections: %"PRIu64" used/%"PRIu64" allocated", smartlist_len(conns), - U64_PRINTF_ARG(total_used), U64_PRINTF_ARG(total_alloc)); + (total_used), (total_alloc)); for (i=CONN_TYPE_MIN_; i <= CONN_TYPE_MAX_; ++i) { if (!n_conns_by_type[i]) continue; tor_log(severity, LD_GENERAL, - " For %d %s connections: "U64_FORMAT" used/"U64_FORMAT" allocated", + " For %d %s connections: %"PRIu64" used/%"PRIu64" allocated", n_conns_by_type[i], conn_type_to_string(i), - U64_PRINTF_ARG(used_by_type[i]), U64_PRINTF_ARG(alloc_by_type[i])); + (used_by_type[i]), (alloc_by_type[i])); } } @@ -5267,4 +5329,3 @@ clock_skew_warning, (const connection_t *conn, long apparent_skew, int trusted, tor_free(warn); tor_free(ext_source); } - diff --git a/src/or/connection.h b/src/or/connection.h index ad3129c9d8..3419ee65e8 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,8 +12,74 @@ #ifndef TOR_CONNECTION_H #define TOR_CONNECTION_H -/* XXXX For buf_datalen in inline function */ -#include "buffers.h" +listener_connection_t *TO_LISTENER_CONN(connection_t *); + +struct buf_t; + +#define CONN_TYPE_MIN_ 3 +/** Type for sockets listening for OR connections. */ +#define CONN_TYPE_OR_LISTENER 3 +/** A bidirectional TLS connection transmitting a sequence of cells. + * May be from an OR to an OR, or from an OP to an OR. */ +#define CONN_TYPE_OR 4 +/** A TCP connection from an onion router to a stream's destination. */ +#define CONN_TYPE_EXIT 5 +/** Type for sockets listening for SOCKS connections. */ +#define CONN_TYPE_AP_LISTENER 6 +/** A SOCKS proxy connection from the user application to the onion + * proxy. */ +#define CONN_TYPE_AP 7 +/** Type for sockets listening for HTTP connections to the directory server. */ +#define CONN_TYPE_DIR_LISTENER 8 +/** Type for HTTP connections to the directory server. */ +#define CONN_TYPE_DIR 9 +/* Type 10 is unused. */ +/** Type for listening for connections from user interface process. */ +#define CONN_TYPE_CONTROL_LISTENER 11 +/** Type for connections from user interface process. */ +#define CONN_TYPE_CONTROL 12 +/** Type for sockets listening for transparent connections redirected by pf or + * netfilter. */ +#define CONN_TYPE_AP_TRANS_LISTENER 13 +/** Type for sockets listening for transparent connections redirected by + * natd. */ +#define CONN_TYPE_AP_NATD_LISTENER 14 +/** Type for sockets listening for DNS requests. */ +#define CONN_TYPE_AP_DNS_LISTENER 15 + +/** Type for connections from the Extended ORPort. */ +#define CONN_TYPE_EXT_OR 16 +/** Type for sockets listening for Extended ORPort connections. */ +#define CONN_TYPE_EXT_OR_LISTENER 17 +/** Type for sockets listening for HTTP CONNECT tunnel connections. */ +#define CONN_TYPE_AP_HTTP_CONNECT_LISTENER 18 + +#define CONN_TYPE_MAX_ 19 +/* !!!! If _CONN_TYPE_MAX is ever over 31, we must grow the type field in + * connection_t. */ + +/* Proxy client handshake states */ +/* We use a proxy but we haven't even connected to it yet. */ +#define PROXY_INFANT 1 +/* We use an HTTP proxy and we've sent the CONNECT command. */ +#define PROXY_HTTPS_WANT_CONNECT_OK 2 +/* We use a SOCKS4 proxy and we've sent the CONNECT command. */ +#define PROXY_SOCKS4_WANT_CONNECT_OK 3 +/* We use a SOCKS5 proxy and we try to negotiate without + any authentication . */ +#define PROXY_SOCKS5_WANT_AUTH_METHOD_NONE 4 +/* We use a SOCKS5 proxy and we try to negotiate with + Username/Password authentication . */ +#define PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929 5 +/* We use a SOCKS5 proxy and we just sent our credentials. */ +#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 6 +/* We use a SOCKS5 proxy and we just sent our CONNECT command. */ +#define PROXY_SOCKS5_WANT_CONNECT_OK 7 +/* We use a proxy and we CONNECTed successfully!. */ +#define PROXY_CONNECTED 8 + +/** State for any listener connection. */ +#define LISTENER_STATE_READY 0 const char *conn_type_to_string(int type); const char *conn_state_to_string(int type, int state); @@ -150,39 +216,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_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; -} +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, struct buf_t *buf); +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,22 +303,27 @@ 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); +/** Execute the statement <b>stmt</b>, which may log events concerning the + * connection <b>conn</b>. To prevent infinite loops, disable log messages + * being sent to controllers if <b>conn</b> is a control connection. + * + * Stmt must not contain any return or goto statements. + */ +#define CONN_LOG_PROTECT(conn, stmt) \ + STMT_BEGIN \ + int _log_conn_is_control; \ + tor_assert(conn); \ + _log_conn_is_control = (conn->type == CONN_TYPE_CONTROL); \ + if (_log_conn_is_control) \ + disable_control_logging(); \ + STMT_BEGIN stmt; STMT_END; \ + if (_log_conn_is_control) \ + enable_control_logging(); \ + STMT_END + #ifdef CONNECTION_PRIVATE STATIC void connection_free_minimal(connection_t *conn); @@ -292,4 +341,3 @@ MOCK_DECL(STATIC smartlist_t *, pick_oos_victims, (int n)); #endif /* defined(CONNECTION_PRIVATE) */ #endif /* !defined(TOR_CONNECTION_H) */ - diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 046369af60..f3f77dbc91 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -55,47 +55,58 @@ **/ #define CONNECTION_EDGE_PRIVATE -#include "or.h" - -#include "backtrace.h" - -#include "addressmap.h" -#include "buffers.h" -#include "channel.h" -#include "circpathbias.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_util.h" -#include "dns.h" -#include "dnsserv.h" -#include "directory.h" -#include "dirserv.h" -#include "hibernate.h" -#include "hs_common.h" -#include "hs_cache.h" -#include "hs_client.h" -#include "hs_circuit.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "proto_http.h" -#include "proto_socks.h" -#include "reasons.h" -#include "relay.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerset.h" -#include "circuitbuild.h" +#include "or/or.h" + +#include "lib/err/backtrace.h" + +#include "or/addressmap.h" +#include "lib/container/buffers.h" +#include "or/channel.h" +#include "or/circpathbias.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/dns.h" +#include "or/dnsserv.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/hibernate.h" +#include "or/hs_common.h" +#include "or/hs_cache.h" +#include "or/hs_client.h" +#include "or/hs_circuit.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/proto_http.h" +#include "or/proto_socks.h" +#include "or/reasons.h" +#include "or/relay.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerset.h" +#include "or/circuitbuild.h" + +#include "or/cell_st.h" +#include "or/cpath_build_state_st.h" +#include "or/dir_connection_st.h" +#include "or/entry_connection_st.h" +#include "or/extend_info_st.h" +#include "or/node_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" +#include "or/socks_request_st.h" +#include "common/compat_libevent.h" #ifdef HAVE_LINUX_TYPES_H #include <linux/types.h> @@ -137,6 +148,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. @@ -3165,9 +3200,9 @@ connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply, !CIRCUIT_IS_ORIGIN(conn->edge_.on_circuit)) { if (endreason != END_STREAM_REASON_RESOLVEFAILED) { log_info(LD_BUG, - "No origin circuit for successful SOCKS stream "U64_FORMAT + "No origin circuit for successful SOCKS stream %"PRIu64 ". Reason: %d", - U64_PRINTF_ARG(ENTRY_TO_CONN(conn)->global_identifier), + (ENTRY_TO_CONN(conn)->global_identifier), endreason); } /* @@ -4187,4 +4222,3 @@ connection_edge_free_all(void) pending_entry_connections = NULL; mainloop_event_free(attach_pending_entry_connections_ev); } - diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index c6583d3845..24968b2778 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,9 +12,61 @@ #ifndef TOR_CONNECTION_EDGE_H #define TOR_CONNECTION_EDGE_H -#include "testsupport.h" - -#define connection_mark_unattached_ap(conn, endreason) \ +#include "lib/testsupport/testsupport.h" + +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 EXIT_CONN_STATE_MIN_ 1 +/** State for an exit connection: waiting for response from DNS farm. */ +#define EXIT_CONN_STATE_RESOLVING 1 +/** State for an exit connection: waiting for connect() to finish. */ +#define EXIT_CONN_STATE_CONNECTING 2 +/** State for an exit connection: open and ready to transmit data. */ +#define EXIT_CONN_STATE_OPEN 3 +/** State for an exit connection: waiting to be removed. */ +#define EXIT_CONN_STATE_RESOLVEFAILED 4 +#define EXIT_CONN_STATE_MAX_ 4 + +/* The AP state values must be disjoint from the EXIT state values. */ +#define AP_CONN_STATE_MIN_ 5 +/** State for a SOCKS connection: waiting for SOCKS request. */ +#define AP_CONN_STATE_SOCKS_WAIT 5 +/** State for a SOCKS connection: got a y.onion URL; waiting to receive + * rendezvous descriptor. */ +#define AP_CONN_STATE_RENDDESC_WAIT 6 +/** The controller will attach this connection to a circuit; it isn't our + * job to do so. */ +#define AP_CONN_STATE_CONTROLLER_WAIT 7 +/** State for a SOCKS connection: waiting for a completed circuit. */ +#define AP_CONN_STATE_CIRCUIT_WAIT 8 +/** State for a SOCKS connection: sent BEGIN, waiting for CONNECTED. */ +#define AP_CONN_STATE_CONNECT_WAIT 9 +/** State for a SOCKS connection: sent RESOLVE, waiting for RESOLVED. */ +#define AP_CONN_STATE_RESOLVE_WAIT 10 +/** State for a SOCKS connection: ready to send and receive. */ +#define AP_CONN_STATE_OPEN 11 +/** State for a transparent natd connection: waiting for original + * destination. */ +#define AP_CONN_STATE_NATD_WAIT 12 +/** State for an HTTP tunnel: waiting for an HTTP CONNECT command. */ +#define AP_CONN_STATE_HTTP_CONNECT_WAIT 13 +#define AP_CONN_STATE_MAX_ 13 + +#define EXIT_PURPOSE_MIN_ 1 +/** This exit stream wants to do an ordinary connect. */ +#define EXIT_PURPOSE_CONNECT 1 +/** This exit stream wants to do a resolve (either normal or reverse). */ +#define EXIT_PURPOSE_RESOLVE 2 +#define EXIT_PURPOSE_MAX_ 2 + +/** True iff the AP_CONN_STATE_* value <b>s</b> means that the corresponding + * edge connection is not attached to any circuit. */ +#define AP_CONN_STATE_IS_UNATTACHED(s) \ + ((s) <= AP_CONN_STATE_CIRCUIT_WAIT || (s) == AP_CONN_STATE_NATD_WAIT) + +#define connection_mark_unattached_ap(conn, endreason) \ connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__) MOCK_DECL(void,connection_mark_unattached_ap_, @@ -194,4 +246,3 @@ STATIC int connection_ap_process_http_connect(entry_connection_t *conn); #endif /* defined(CONNECTION_EDGE_PRIVATE) */ #endif /* !defined(TOR_CONNECTION_EDGE_H) */ - diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 7898fbd42e..71ab905942 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -20,46 +20,58 @@ * * This module also implements the client side of the v3 Tor link handshake, **/ -#include "or.h" -#include "bridges.h" -#include "buffers.h" +#include "or/or.h" +#include "or/bridges.h" +#include "lib/container/buffers.h" /* * Define this so we get channel internal functions, since we're implementing * part of a subclass (channel_tls_t). */ #define TOR_CHANNEL_INTERNAL_ #define CONNECTION_OR_PRIVATE -#include "channel.h" -#include "channeltls.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuitstats.h" -#include "command.h" -#include "config.h" -#include "connection.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "dirserv.h" -#include "entrynodes.h" -#include "geoip.h" -#include "main.h" -#include "link_handshake.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "proto_cell.h" -#include "reasons.h" -#include "relay.h" -#include "rephist.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "ext_orport.h" -#include "scheduler.h" -#include "torcert.h" -#include "channelpadding.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuitstats.h" +#include "or/command.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/dirserv.h" +#include "or/entrynodes.h" +#include "or/geoip.h" +#include "or/main.h" +#include "trunnel/link_handshake.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/proto_cell.h" +#include "or/reasons.h" +#include "or/relay.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/ext_orport.h" +#include "or/scheduler.h" +#include "or/torcert.h" +#include "or/channelpadding.h" + +#include "or/cell_st.h" +#include "or/cell_queue_st.h" +#include "or/or_connection_st.h" +#include "or/or_handshake_certs_st.h" +#include "or/or_handshake_state_st.h" +#include "or/or_state_st.h" +#include "or/routerinfo_st.h" +#include "or/var_cell_st.h" +#include "lib/crypt_ops/crypto_format.h" + +#include "lib/tls/tortls.h" static int connection_tls_finish_handshake(or_connection_t *conn); static int connection_or_launch_v3_or_handshake(or_connection_t *conn); @@ -86,6 +98,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; @@ -834,9 +855,9 @@ connection_or_set_canonical(or_connection_t *or_conn, TLS_CHAN_TO_BASE(or_conn->chan), is_canonical); log_info(LD_CIRC, - "Channel " U64_FORMAT " chose an idle timeout of %d.", + "Channel %"PRIu64 " chose an idle timeout of %d.", or_conn->chan ? - U64_PRINTF_ARG(TLS_CHAN_TO_BASE(or_conn->chan)->global_identifier):0, + (TLS_CHAN_TO_BASE(or_conn->chan)->global_identifier):0, or_conn->idle_timeout); } @@ -2973,4 +2994,3 @@ connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype)) return 0; } - diff --git a/src/or/connection_or.h b/src/or/connection_or.h index 158eb1fdad..2d95fdea18 100644 --- a/src/or/connection_or.h +++ b/src/or/connection_or.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,6 +12,38 @@ #ifndef TOR_CONNECTION_OR_H #define TOR_CONNECTION_OR_H +struct ed25519_public_key_t; +struct ed25519_keypair_t; + +or_connection_t *TO_OR_CONN(connection_t *); + +#define OR_CONN_STATE_MIN_ 1 +/** State for a connection to an OR: waiting for connect() to finish. */ +#define OR_CONN_STATE_CONNECTING 1 +/** State for a connection to an OR: waiting for proxy handshake to complete */ +#define OR_CONN_STATE_PROXY_HANDSHAKING 2 +/** State for an OR connection client: SSL is handshaking, not done + * yet. */ +#define OR_CONN_STATE_TLS_HANDSHAKING 3 +/** State for a connection to an OR: We're doing a second SSL handshake for + * renegotiation purposes. (V2 handshake only.) */ +#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 4 +/** State for a connection at an OR: We're waiting for the client to + * renegotiate (to indicate a v2 handshake) or send a versions cell (to + * indicate a v3 handshake) */ +#define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 5 +/** State for an OR connection: We're done with our SSL handshake, we've done + * renegotiation, but we haven't yet negotiated link protocol versions and + * sent a netinfo cell. */ +#define OR_CONN_STATE_OR_HANDSHAKING_V2 6 +/** State for an OR connection: We're done with our SSL handshake, but we + * haven't yet negotiated link protocol versions, done a V3 handshake, and + * sent a netinfo cell. */ +#define OR_CONN_STATE_OR_HANDSHAKING_V3 7 +/** State for an OR connection: Ready to send/receive cells. */ +#define OR_CONN_STATE_OPEN 8 +#define OR_CONN_STATE_MAX_ 8 + void connection_or_clear_identity(or_connection_t *conn); void connection_or_clear_identity_map(void); void clear_broken_connection_map(int disable); @@ -40,7 +72,7 @@ MOCK_DECL(or_connection_t *, connection_or_connect, (const tor_addr_t *addr, uint16_t port, const char *id_digest, - const ed25519_public_key_t *ed_id, + const struct ed25519_public_key_t *ed_id, channel_tls_t *chan)); void connection_or_close_normally(or_connection_t *orconn, int flush); @@ -58,14 +90,14 @@ void connection_or_set_canonical(or_connection_t *or_conn, int connection_init_or_handshake_state(or_connection_t *conn, int started_here); void connection_or_init_conn_from_address(or_connection_t *conn, - const tor_addr_t *addr, - uint16_t port, - const char *rsa_id_digest, - const ed25519_public_key_t *ed_id, - int started_here); + const tor_addr_t *addr, + uint16_t port, + const char *rsa_id_digest, + const struct ed25519_public_key_t *ed_id, + int started_here); int connection_or_client_learned_peer_id(or_connection_t *conn, const uint8_t *rsa_peer_id, - const ed25519_public_key_t *ed_peer_id); + const struct ed25519_public_key_t *ed_peer_id); time_t connection_or_client_used(or_connection_t *conn); MOCK_DECL(int, connection_or_get_num_circuits, (or_connection_t *conn)); void or_handshake_state_free_(or_handshake_state_t *state); @@ -92,11 +124,12 @@ int connection_or_send_auth_challenge_cell(or_connection_t *conn); int authchallenge_type_is_supported(uint16_t challenge_type); int authchallenge_type_is_better(uint16_t challenge_type_a, uint16_t challenge_type_b); -var_cell_t *connection_or_compute_authenticate_cell_body(or_connection_t *conn, - const int authtype, - crypto_pk_t *signing_key, - const ed25519_keypair_t *ed_signing_key, - int server); +var_cell_t *connection_or_compute_authenticate_cell_body( + or_connection_t *conn, + const int authtype, + crypto_pk_t *signing_key, + const struct ed25519_keypair_t *ed_signing_key, + int server); MOCK_DECL(int,connection_or_send_authenticate_cell, (or_connection_t *conn, int type)); @@ -130,4 +163,3 @@ extern int certs_cell_ed25519_disabled_for_testing; #endif #endif /* !defined(TOR_CONNECTION_OR_H) */ - diff --git a/src/or/connection_st.h b/src/or/connection_st.h new file mode 100644 index 0000000000..6c22478689 --- /dev/null +++ b/src/or/connection_st.h @@ -0,0 +1,149 @@ +/* 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 CONNECTION_ST_H +#define CONNECTION_ST_H + +struct buf_t; + +/* Values for connection_t.magic: used to make sure that downcasts (casts from +* connection_t to foo_connection_t) are safe. */ +#define BASE_CONNECTION_MAGIC 0x7C3C304Eu +#define OR_CONNECTION_MAGIC 0x7D31FF03u +#define EDGE_CONNECTION_MAGIC 0xF0374013u +#define ENTRY_CONNECTION_MAGIC 0xbb4a5703 +#define DIR_CONNECTION_MAGIC 0x9988ffeeu +#define CONTROL_CONNECTION_MAGIC 0x8abc765du +#define LISTENER_CONNECTION_MAGIC 0x1a1ac741u + +/** 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. + */ +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; +}; + +/** True iff <b>x</b> is an edge connection. */ +#define CONN_IS_EDGE(x) \ + ((x)->type == CONN_TYPE_EXIT || (x)->type == CONN_TYPE_AP) + +/** True iff the purpose of <b>conn</b> means that it's a server-side + * directory connection. */ +#define DIR_CONN_IS_SERVER(conn) ((conn)->purpose == DIR_PURPOSE_SERVER) + +#endif diff --git a/src/or/conscache.c b/src/or/conscache.c index 51dc9d621f..bc5928ff23 100644 --- a/src/or/conscache.c +++ b/src/or/conscache.c @@ -1,12 +1,13 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" +#include "or/or.h" -#include "config.h" -#include "conscache.h" -#include "crypto_util.h" -#include "storagedir.h" +#include "or/config.h" +#include "or/conscache.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/fs/storagedir.h" +#include "lib/encoding/confline.h" #define CCE_MAGIC 0x17162253 @@ -624,4 +625,3 @@ consensus_cache_entry_is_mapped(consensus_cache_entry_t *ent) } } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/conscache.h b/src/or/conscache.h index 08a5c5a37b..c46b824235 100644 --- a/src/or/conscache.h +++ b/src/or/conscache.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONSCACHE_H #define TOR_CONSCACHE_H -#include "handles.h" +#include "common/handles.h" typedef struct consensus_cache_entry_t consensus_cache_entry_t; typedef struct consensus_cache_t consensus_cache_t; @@ -27,9 +27,9 @@ void consensus_cache_delete_pending(consensus_cache_t *cache, int force); int consensus_cache_get_n_filenames_available(consensus_cache_t *cache); consensus_cache_entry_t *consensus_cache_add(consensus_cache_t *cache, - const config_line_t *labels, - const uint8_t *data, - size_t datalen); + const struct config_line_t *labels, + const uint8_t *data, + size_t datalen); consensus_cache_entry_t *consensus_cache_find_first( consensus_cache_t *cache, @@ -46,7 +46,7 @@ void consensus_cache_filter_list(smartlist_t *lst, const char *consensus_cache_entry_get_value(const consensus_cache_entry_t *ent, const char *key); -const config_line_t *consensus_cache_entry_get_labels( +const struct config_line_t *consensus_cache_entry_get_labels( const consensus_cache_entry_t *ent); void consensus_cache_entry_incref(consensus_cache_entry_t *ent); @@ -64,4 +64,3 @@ int consensus_cache_entry_is_mapped(consensus_cache_entry_t *ent); #endif #endif /* !defined(TOR_CONSCACHE_H) */ - diff --git a/src/or/consdiff.c b/src/or/consdiff.c index deaf465fe7..88edda716e 100644 --- a/src/or/consdiff.c +++ b/src/or/consdiff.c @@ -1,5 +1,5 @@ /* Copyright (c) 2014, Daniel Martà - * Copyright (c) 2014, The Tor Project, Inc. */ + * Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -38,10 +38,10 @@ #define CONSDIFF_PRIVATE -#include "or.h" -#include "consdiff.h" -#include "memarea.h" -#include "routerparse.h" +#include "or/or.h" +#include "or/consdiff.h" +#include "lib/memarea/memarea.h" +#include "or/routerparse.h" static const char* ns_diff_version = "network-status-diff-version 1"; static const char* hash_token = "hash"; @@ -1412,4 +1412,3 @@ looks_like_a_consensus_diff(const char *document, size_t len) return (len >= strlen(ns_diff_version) && fast_memeq(document, ns_diff_version, strlen(ns_diff_version))); } - diff --git a/src/or/consdiff.h b/src/or/consdiff.h index eb772c0b2b..1cae59a1a5 100644 --- a/src/or/consdiff.h +++ b/src/or/consdiff.h @@ -1,11 +1,11 @@ /* Copyright (c) 2014, Daniel Martà - * Copyright (c) 2014, The Tor Project, Inc. */ + * Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONSDIFF_H #define TOR_CONSDIFF_H -#include "or.h" +#include "or/or.h" char *consensus_diff_generate(const char *cons1, const char *cons2); @@ -15,6 +15,8 @@ char *consensus_diff_apply(const char *consensus, int looks_like_a_consensus_diff(const char *document, size_t len); #ifdef CONSDIFF_PRIVATE +#include "lib/container/bitarray.h" + struct memarea_t; /** Line type used for constructing consensus diffs. Each of these lines @@ -95,4 +97,3 @@ MOCK_DECL(STATIC int, #endif /* defined(CONSDIFF_PRIVATE) */ #endif /* !defined(TOR_CONSDIFF_H) */ - diff --git a/src/or/consdiffmgr.c b/src/or/consdiffmgr.c index 323f4f9ca0..c75b59c1f5 100644 --- a/src/or/consdiffmgr.c +++ b/src/or/consdiffmgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,15 +13,21 @@ #define CONSDIFFMGR_PRIVATE -#include "or.h" -#include "config.h" -#include "conscache.h" -#include "consdiff.h" -#include "consdiffmgr.h" -#include "cpuworker.h" -#include "networkstatus.h" -#include "routerparse.h" -#include "workqueue.h" +#include "or/or.h" +#include "or/config.h" +#include "or/conscache.h" +#include "or/consdiff.h" +#include "or/consdiffmgr.h" +#include "or/cpuworker.h" +#include "or/networkstatus.h" +#include "or/routerparse.h" +#include "common/compat_libevent.h" +#include "common/workqueue.h" +#include "lib/compress/compress.h" +#include "lib/encoding/confline.h" + +#include "or/networkstatus_st.h" +#include "or/networkstatus_voter_info_st.h" /** * Labels to apply to items in the conscache object. @@ -1937,4 +1943,3 @@ consensus_cache_entry_get_valid_after(const consensus_cache_entry_t *ent, else return 0; } - diff --git a/src/or/consdiffmgr.h b/src/or/consdiffmgr.h index df569c8e23..66c3d65002 100644 --- a/src/or/consdiffmgr.h +++ b/src/or/consdiffmgr.h @@ -1,9 +1,11 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONSDIFFMGR_H #define TOR_CONSDIFFMGR_H +enum compress_method_t; + /** * Possible outcomes from trying to look up a given consensus diff. */ @@ -25,7 +27,7 @@ int consdiffmgr_add_consensus(const char *consensus, consdiff_status_t consdiffmgr_find_consensus( struct consensus_cache_entry_t **entry_out, consensus_flavor_t flavor, - compress_method_t method); + enum compress_method_t method); consdiff_status_t consdiffmgr_find_diff_from( struct consensus_cache_entry_t **entry_out, @@ -33,7 +35,7 @@ consdiff_status_t consdiffmgr_find_diff_from( int digest_type, const uint8_t *digest, size_t digestlen, - compress_method_t method); + enum compress_method_t method); int consensus_cache_entry_get_voter_id_digests( const struct consensus_cache_entry_t *ent, @@ -71,4 +73,3 @@ STATIC int uncompress_or_copy(char **out, size_t *outlen, #endif /* defined(CONSDIFFMGR_PRIVATE) */ #endif /* !defined(TOR_CONSDIFFMGR_H) */ - diff --git a/src/or/control.c b/src/or/control.c index 09cf833e37..ea12448126 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -35,59 +35,86 @@ #define CONTROL_PRIVATE -#include "or.h" -#include "addressmap.h" -#include "bridges.h" -#include "buffers.h" -#include "channel.h" -#include "channeltls.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuitstats.h" -#include "circuituse.h" -#include "command.h" -#include "compat_libevent.h" -#include "config.h" -#include "confparse.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "dirserv.h" -#include "dnsserv.h" -#include "entrynodes.h" -#include "geoip.h" -#include "hibernate.h" -#include "hs_cache.h" -#include "hs_common.h" -#include "hs_control.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "proto_control0.h" -#include "proto_http.h" -#include "reasons.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "shared_random_client.h" +#include "or/or.h" +#include "or/addressmap.h" +#include "or/bridges.h" +#include "lib/container/buffers.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuitstats.h" +#include "or/circuituse.h" +#include "or/command.h" +#include "common/compat_libevent.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/dnsserv.h" +#include "or/entrynodes.h" +#include "or/geoip.h" +#include "or/hibernate.h" +#include "or/hs_cache.h" +#include "or/hs_common.h" +#include "or/hs_control.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/proto_control0.h" +#include "or/proto_http.h" +#include "or/reasons.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/shared_random_client.h" +#include "lib/encoding/confline.h" + +#include "or/cached_dir_st.h" +#include "or/control_connection_st.h" +#include "or/cpath_build_state_st.h" +#include "or/entry_connection_st.h" +#include "or/extrainfo_st.h" +#include "or/networkstatus_st.h" +#include "or/node_st.h" +#include "or/or_connection_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" +#include "or/microdesc_st.h" +#include "or/rend_authorized_client_st.h" +#include "or/rend_encoded_v2_service_descriptor_st.h" +#include "or/rend_service_descriptor_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/socks_request_st.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif #ifndef _WIN32 #include <pwd.h> #include <sys/resource.h> #endif -#include "crypto_s2k.h" -#include "procmon.h" +#include "lib/crypt_ops/crypto_s2k.h" +#include "common/procmon.h" +#include "common/compat_libevent.h" /** Yield true iff <b>s</b> is the state of a control_connection_t that has * finished authentication and is accepting commands. */ @@ -226,6 +253,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 @@ -1857,9 +1893,9 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, } *answer = tor_dup_ip(addr); } else if (!strcmp(question, "traffic/read")) { - tor_asprintf(answer, U64_FORMAT, U64_PRINTF_ARG(get_bytes_read())); + tor_asprintf(answer, "%"PRIu64, (get_bytes_read())); } else if (!strcmp(question, "traffic/written")) { - tor_asprintf(answer, U64_FORMAT, U64_PRINTF_ARG(get_bytes_written())); + tor_asprintf(answer, "%"PRIu64, (get_bytes_written())); } else if (!strcmp(question, "process/pid")) { int myPid = -1; @@ -1894,8 +1930,8 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, int max_fds = get_max_sockets(); tor_asprintf(answer, "%d", max_fds); } else if (!strcmp(question, "limits/max-mem-in-queues")) { - tor_asprintf(answer, U64_FORMAT, - U64_PRINTF_ARG(get_options()->MaxMemInQueues)); + tor_asprintf(answer, "%"PRIu64, + (get_options()->MaxMemInQueues)); } else if (!strcmp(question, "fingerprint")) { crypto_pk_t *server_key; if (!server_mode(get_options())) { @@ -2207,6 +2243,27 @@ getinfo_helper_dir(control_connection_t *control_conn, return -1; } } + } else if (!strcmp(question, "md/all")) { + const smartlist_t *nodes = nodelist_get_list(); + tor_assert(nodes); + + if (smartlist_len(nodes) == 0) { + *answer = tor_strdup(""); + return 0; + } + + smartlist_t *microdescs = smartlist_new(); + + SMARTLIST_FOREACH_BEGIN(nodes, node_t *, n) { + if (n->md && n->md->body) { + char *copy = tor_strndup(n->md->body, n->md->bodylen); + smartlist_add(microdescs, copy); + } + } SMARTLIST_FOREACH_END(n); + + *answer = smartlist_join_strings(microdescs, "", 0, NULL); + SMARTLIST_FOREACH(microdescs, char *, md, tor_free(md)); + smartlist_free(microdescs); } else if (!strcmpstart(question, "md/id/")) { const node_t *node = node_get_by_hex_id(question+strlen("md/id/"), 0); const microdesc_t *md = NULL; @@ -3241,6 +3298,7 @@ static const getinfo_item_t getinfo_items[] = { ITEM("desc/download-enabled", dir, "Do we try to download router descriptors?"), ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */ + ITEM("md/all", dir, "All known microdescriptors."), PREFIX("md/id/", dir, "Microdescriptors by ID"), PREFIX("md/name/", dir, "Microdescriptors by name"), ITEM("md/download-enabled", dir, @@ -3400,6 +3458,7 @@ handle_control_getinfo(control_connection_t *conn, uint32_t len, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); SMARTLIST_FOREACH_BEGIN(questions, const char *, q) { const char *errmsg = NULL; + if (handle_getinfo_helper(conn, q, &ans, &errmsg) < 0) { if (!errmsg) errmsg = "Internal error"; @@ -4629,7 +4688,7 @@ handle_control_add_onion(control_connection_t *conn, static const char *max_s_prefix = "MaxStreams="; static const char *auth_prefix = "ClientAuth="; - const char *arg = smartlist_get(args, i); + const char *arg = smartlist_get(args, (int)i); if (!strcasecmpstart(arg, port_prefix)) { /* "Port=VIRTPORT[,TARGET]". */ const char *port_str = arg + strlen(port_prefix); @@ -5832,8 +5891,8 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp, if (circ && CIRCUIT_IS_ORIGIN(circ)) origin_circ = TO_ORIGIN_CIRCUIT(circ); send_control_event(EVENT_STREAM_STATUS, - "650 STREAM "U64_FORMAT" %s %lu %s%s%s%s\r\n", - U64_PRINTF_ARG(ENTRY_TO_CONN(conn)->global_identifier), + "650 STREAM %"PRIu64" %s %lu %s%s%s%s\r\n", + (ENTRY_TO_CONN(conn)->global_identifier), status, origin_circ? (unsigned long)origin_circ->global_identifier : 0ul, @@ -5904,12 +5963,12 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp, orconn_target_get_name(name, sizeof(name), conn); send_control_event(EVENT_OR_CONN_STATUS, - "650 ORCONN %s %s%s%s%s ID="U64_FORMAT"\r\n", + "650 ORCONN %s %s%s%s%s ID=%"PRIu64"\r\n", name, status, reason ? " REASON=" : "", orconn_end_reason_to_control_string(reason), ncircs_buf, - U64_PRINTF_ARG(conn->base_.global_identifier)); + (conn->base_.global_identifier)); return 0; } @@ -5929,8 +5988,8 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn) tor_gettimeofday(&now); format_iso_time_nospace_usec(tbuf, &now); send_control_event(EVENT_STREAM_BANDWIDTH_USED, - "650 STREAM_BW "U64_FORMAT" %lu %lu %s\r\n", - U64_PRINTF_ARG(edge_conn->base_.global_identifier), + "650 STREAM_BW %"PRIu64" %lu %lu %s\r\n", + (edge_conn->base_.global_identifier), (unsigned long)edge_conn->n_read, (unsigned long)edge_conn->n_written, tbuf); @@ -5963,8 +6022,8 @@ control_event_stream_bandwidth_used(void) tor_gettimeofday(&now); format_iso_time_nospace_usec(tbuf, &now); send_control_event(EVENT_STREAM_BANDWIDTH_USED, - "650 STREAM_BW "U64_FORMAT" %lu %lu %s\r\n", - U64_PRINTF_ARG(edge_conn->base_.global_identifier), + "650 STREAM_BW %"PRIu64" %lu %lu %s\r\n", + (edge_conn->base_.global_identifier), (unsigned long)edge_conn->n_read, (unsigned long)edge_conn->n_written, tbuf); @@ -6042,9 +6101,9 @@ control_event_conn_bandwidth(connection_t *conn) return 0; } send_control_event(EVENT_CONN_BW, - "650 CONN_BW ID="U64_FORMAT" TYPE=%s " + "650 CONN_BW ID=%"PRIu64" TYPE=%s " "READ=%lu WRITTEN=%lu\r\n", - U64_PRINTF_ARG(conn->global_identifier), + (conn->global_identifier), conn_type_str, (unsigned long)conn->n_read_conn_bw, (unsigned long)conn->n_written_conn_bw); @@ -6109,9 +6168,9 @@ append_cell_stats_by_command(smartlist_t *event_parts, const char *key, int i; for (i = 0; i <= CELL_COMMAND_MAX_; i++) { if (include_if_non_zero[i] > 0) { - smartlist_add_asprintf(key_value_strings, "%s:"U64_FORMAT, + smartlist_add_asprintf(key_value_strings, "%s:%"PRIu64, cell_command_to_string(i), - U64_PRINTF_ARG(number_to_include[i])); + (number_to_include[i])); } } if (smartlist_len(key_value_strings) > 0) { @@ -6138,8 +6197,8 @@ format_cell_stats(char **event_string, circuit_t *circ, or_circuit_t *or_circ = TO_OR_CIRCUIT(circ); smartlist_add_asprintf(event_parts, "InboundQueue=%lu", (unsigned long)or_circ->p_circ_id); - smartlist_add_asprintf(event_parts, "InboundConn="U64_FORMAT, - U64_PRINTF_ARG(or_circ->p_chan->global_identifier)); + smartlist_add_asprintf(event_parts, "InboundConn=%"PRIu64, + (or_circ->p_chan->global_identifier)); append_cell_stats_by_command(event_parts, "InboundAdded", cell_stats->added_cells_appward, cell_stats->added_cells_appward); @@ -6153,8 +6212,8 @@ format_cell_stats(char **event_string, circuit_t *circ, if (circ->n_chan) { smartlist_add_asprintf(event_parts, "OutboundQueue=%lu", (unsigned long)circ->n_circ_id); - smartlist_add_asprintf(event_parts, "OutboundConn="U64_FORMAT, - U64_PRINTF_ARG(circ->n_chan->global_identifier)); + smartlist_add_asprintf(event_parts, "OutboundConn=%"PRIu64, + (circ->n_chan->global_identifier)); append_cell_stats_by_command(event_parts, "OutboundAdded", cell_stats->added_cells_exitward, cell_stats->added_cells_exitward); @@ -7741,4 +7800,3 @@ control_testing_set_global_event_mask(uint64_t mask) global_event_mask = mask; } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/control.h b/src/or/control.h index 92cbf866dd..5c5fe8a917 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,6 +12,93 @@ #ifndef TOR_CONTROL_H #define TOR_CONTROL_H +/** Used to indicate the type of a circuit event passed to the controller. + * The various types are defined in control-spec.txt */ +typedef enum circuit_status_event_t { + CIRC_EVENT_LAUNCHED = 0, + CIRC_EVENT_BUILT = 1, + CIRC_EVENT_EXTENDED = 2, + CIRC_EVENT_FAILED = 3, + CIRC_EVENT_CLOSED = 4, +} circuit_status_event_t; + +/** Used to indicate the type of a CIRC_MINOR event passed to the controller. + * The various types are defined in control-spec.txt . */ +typedef enum circuit_status_minor_event_t { + CIRC_MINOR_EVENT_PURPOSE_CHANGED, + CIRC_MINOR_EVENT_CANNIBALIZED, +} circuit_status_minor_event_t; + +/** Used to indicate the type of a stream event passed to the controller. + * The various types are defined in control-spec.txt */ +typedef enum stream_status_event_t { + STREAM_EVENT_SENT_CONNECT = 0, + STREAM_EVENT_SENT_RESOLVE = 1, + STREAM_EVENT_SUCCEEDED = 2, + STREAM_EVENT_FAILED = 3, + STREAM_EVENT_CLOSED = 4, + STREAM_EVENT_NEW = 5, + STREAM_EVENT_NEW_RESOLVE = 6, + STREAM_EVENT_FAILED_RETRIABLE = 7, + STREAM_EVENT_REMAP = 8 +} stream_status_event_t; + +/** Used to indicate the type of an OR connection event passed to the + * controller. The various types are defined in control-spec.txt */ +typedef enum or_conn_status_event_t { + OR_CONN_EVENT_LAUNCHED = 0, + OR_CONN_EVENT_CONNECTED = 1, + OR_CONN_EVENT_FAILED = 2, + OR_CONN_EVENT_CLOSED = 3, + OR_CONN_EVENT_NEW = 4, +} or_conn_status_event_t; + +/** Used to indicate the type of a buildtime event */ +typedef enum buildtimeout_set_event_t { + BUILDTIMEOUT_SET_EVENT_COMPUTED = 0, + BUILDTIMEOUT_SET_EVENT_RESET = 1, + BUILDTIMEOUT_SET_EVENT_SUSPENDED = 2, + BUILDTIMEOUT_SET_EVENT_DISCARD = 3, + BUILDTIMEOUT_SET_EVENT_RESUME = 4 +} buildtimeout_set_event_t; + +/** Enum describing various stages of bootstrapping, for use with controller + * bootstrap status events. The values range from 0 to 100. */ +typedef enum { + BOOTSTRAP_STATUS_UNDEF=-1, + BOOTSTRAP_STATUS_STARTING=0, + BOOTSTRAP_STATUS_CONN_DIR=5, + BOOTSTRAP_STATUS_HANDSHAKE=-2, + BOOTSTRAP_STATUS_HANDSHAKE_DIR=10, + BOOTSTRAP_STATUS_ONEHOP_CREATE=15, + BOOTSTRAP_STATUS_REQUESTING_STATUS=20, + BOOTSTRAP_STATUS_LOADING_STATUS=25, + BOOTSTRAP_STATUS_LOADING_KEYS=40, + BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS=45, + BOOTSTRAP_STATUS_LOADING_DESCRIPTORS=50, + BOOTSTRAP_STATUS_CONN_OR=80, + BOOTSTRAP_STATUS_HANDSHAKE_OR=85, + BOOTSTRAP_STATUS_CIRCUIT_CREATE=90, + BOOTSTRAP_STATUS_DONE=100 +} bootstrap_status_t; + +control_connection_t *TO_CONTROL_CONN(connection_t *); + +#define CONTROL_CONN_STATE_MIN_ 1 +/** State for a control connection: Authenticated and accepting v1 commands. */ +#define CONTROL_CONN_STATE_OPEN 1 +/** State for a control connection: Waiting for authentication; speaking + * protocol v1. */ +#define CONTROL_CONN_STATE_NEEDAUTH 2 +#define CONTROL_CONN_STATE_MAX_ 2 + +/** Reason for remapping an AP connection's address: we have a cached + * answer. */ +#define REMAP_STREAM_SOURCE_CACHE 1 +/** Reason for remapping an AP connection's address: the exit node told us an + * answer. */ +#define REMAP_STREAM_SOURCE_EXIT 2 + void control_initialize_event_queue(void); void control_update_global_event_mask(void); @@ -97,7 +184,8 @@ int control_event_signal(uintptr_t signal); int init_control_cookie_authentication(int enabled); char *get_controller_cookie_file_name(void); -smartlist_t *decode_hashed_passwords(config_line_t *passwords); +struct config_line_t; +smartlist_t *decode_hashed_passwords(struct config_line_t *passwords); void disable_control_logging(void); void enable_control_logging(void); @@ -160,6 +248,8 @@ void control_event_hs_descriptor_content(const char *onion_address, void control_free_all(void); #ifdef CONTROL_PRIVATE +#include "lib/crypt_ops/crypto_ed25519.h" + /* Recognized asynchronous event types. It's okay to expand this list * because it is used both as a list of v0 event types, and as indices * into the bitfield to determine which controllers want which events. @@ -323,4 +413,3 @@ STATIC int getinfo_helper_current_time( #endif /* defined(CONTROL_PRIVATE) */ #endif /* !defined(TOR_CONTROL_H) */ - diff --git a/src/or/control_connection_st.h b/src/or/control_connection_st.h new file mode 100644 index 0000000000..4f8ab25d99 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef CONTROL_CONNECTION_ST_H +#define CONTROL_CONNECTION_ST_H + +#include "or/or.h" +#include "or/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..1db7251132 --- /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-2018, 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..b37dfd1684 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,20 +17,23 @@ * <li>and for calculating diffs and compressing them in consdiffmgr.c. * </ul> **/ -#include "or.h" -#include "channel.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "connection_or.h" -#include "config.h" -#include "cpuworker.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "main.h" -#include "onion.h" -#include "rephist.h" -#include "router.h" -#include "workqueue.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/connection_or.h" +#include "or/config.h" +#include "or/cpuworker.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/main.h" +#include "or/onion.h" +#include "or/rephist.h" +#include "or/router.h" +#include "common/workqueue.h" + +#include "or/or_circuit_st.h" +#include "lib/intmath/weakrng.h" static void queue_pending_tasks(void); @@ -280,7 +283,7 @@ get_overhead_for_onionskins(uint32_t *usec_out, double *frac_out, onionskins_usec_internal[onionskin_type]; *usec_out = (uint32_t)(overhead / onionskins_n_processed[onionskin_type]); - *frac_out = U64_TO_DBL(overhead) / onionskins_usec_internal[onionskin_type]; + *frac_out = ((double)overhead) / onionskins_usec_internal[onionskin_type]; return 0; } @@ -594,4 +597,3 @@ cpuworker_cancel_circ_handshake(or_circuit_t *circ) circ->workqueue_entry = NULL; } } - diff --git a/src/or/cpuworker.h b/src/or/cpuworker.h index d39851325f..50812b2dab 100644 --- a/src/or/cpuworker.h +++ b/src/or/cpuworker.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/crypt_path_reference_st.h b/src/or/crypt_path_reference_st.h new file mode 100644 index 0000000000..bb0e519233 --- /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-2018, 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..0fde1fab0e --- /dev/null +++ b/src/or/crypt_path_st.h @@ -0,0 +1,70 @@ +/* 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 "or/relay_crypto_st.h" +struct crypto_dh_t; + +#define CRYPT_PATH_MAGIC 0x70127012u + +struct fast_handshake_state_t; +struct ntor_handshake_state_t; +struct crypto_dh_t; +struct onion_handshake_state_t { + uint16_t tag; + union { + struct fast_handshake_state_t *fast; + struct crypto_dh_t *tap; + struct ntor_handshake_state_t *ntor; + } u; +}; + +/** 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 */ + struct 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..168a83b230 --- /dev/null +++ b/src/or/desc_store_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef DESC_STORE_ST_H +#define DESC_STORE_ST_H + +/** Allowable types of desc_store_t. */ +typedef enum store_type_t { + ROUTER_STORE = 0, + 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. */ +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..2839b0bd11 --- /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-2018, 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..1282f82d64 --- /dev/null +++ b/src/or/dir_connection_st.h @@ -0,0 +1,67 @@ +/* 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 DIR_CONNECTION_ST_H +#define DIR_CONNECTION_ST_H + +#include "or/connection_st.h" + +struct tor_compress_state_t; + +/** 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. */ + struct 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..fe1f5c3d5f --- /dev/null +++ b/src/or/dir_server_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef DIR_SERVER_ST_H +#define DIR_SERVER_ST_H + +#include "lib/cc/torint.h" +#include "or/or.h" +#include "or/routerstatus_st.h" + +/** Represents information about a single trusted or fallback directory + * server. */ +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! + **/ +}; + +#endif diff --git a/src/or/dirauth/dircollate.c b/src/or/dirauth/dircollate.c index dec6f75154..246977dcc8 100644 --- a/src/or/dirauth/dircollate.c +++ b/src/or/dirauth/dircollate.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -22,8 +22,11 @@ */ #define DIRCOLLATE_PRIVATE -#include "dircollate.h" -#include "dirvote.h" +#include "or/dirauth/dircollate.h" +#include "or/dirauth/dirvote.h" + +#include "or/networkstatus_st.h" +#include "or/vote_routerstatus_st.h" static void dircollator_collate_by_ed25519(dircollator_t *dc); diff --git a/src/or/dirauth/dircollate.h b/src/or/dirauth/dircollate.h index 0584b2fe06..aae7829786 100644 --- a/src/or/dirauth/dircollate.h +++ b/src/or/dirauth/dircollate.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,8 +12,8 @@ #ifndef TOR_DIRCOLLATE_H #define TOR_DIRCOLLATE_H -#include "testsupport.h" -#include "or.h" +#include "lib/testsupport/testsupport.h" +#include "or/or.h" typedef struct dircollator_s dircollator_t; diff --git a/src/or/dirauth/dirvote.c b/src/or/dirauth/dirvote.c index b097b10cf9..15f8378744 100644 --- a/src/or/dirauth/dirvote.c +++ b/src/or/dirauth/dirvote.c @@ -1,32 +1,51 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DIRVOTE_PRIVATE -#include "or.h" -#include "config.h" -#include "dircollate.h" -#include "directory.h" -#include "dirserv.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "parsecommon.h" -#include "policies.h" -#include "protover.h" -#include "rephist.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "routerparse.h" -#include "entrynodes.h" /* needed for guardfraction methods */ -#include "torcert.h" -#include "voting_schedule.h" - -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" -#include "dirauth/shared_random_state.h" +#include "or/or.h" +#include "or/config.h" +#include "or/dirauth/dircollate.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/parsecommon.h" +#include "or/policies.h" +#include "or/protover.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/entrynodes.h" /* needed for guardfraction methods */ +#include "or/torcert.h" +#include "or/voting_schedule.h" + +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" +#include "or/dirauth/shared_random_state.h" + +#include "or/authority_cert_st.h" +#include "or/cached_dir_st.h" +#include "or/dir_server_st.h" +#include "or/document_signature_st.h" +#include "or/microdesc_st.h" +#include "or/networkstatus_st.h" +#include "or/networkstatus_voter_info_st.h" +#include "or/node_st.h" +#include "or/ns_detached_signatures_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/vote_microdesc_hash_st.h" +#include "or/vote_routerstatus_st.h" +#include "or/vote_timing_st.h" + +#include "lib/container/order.h" +#include "lib/encoding/confline.h" +#include "lib/crypt_ops/crypto_format.h" /** * \file dirvote.c @@ -982,13 +1001,13 @@ networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg, out: if (berr) { log_info(LD_DIR, - "Bw weight mismatch %d. G="I64_FORMAT" M="I64_FORMAT - " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT + "Bw weight mismatch %d. G=%"PRId64" M=%"PRId64 + " E=%"PRId64" D=%"PRId64" T=%"PRId64 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d" " Wgd=%d Wgg=%d Wme=%d Wmg=%d", berr, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee, (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg); } @@ -1014,10 +1033,10 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, if (G <= 0 || M <= 0 || E <= 0 || D <= 0) { log_warn(LD_DIR, "Consensus with empty bandwidth: " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT - " D="I64_FORMAT" T="I64_FORMAT, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T)); + "G=%"PRId64" M=%"PRId64" E=%"PRId64 + " D=%"PRId64" T=%"PRId64, + (G), (M), (E), + (D), (T)); return 0; } @@ -1048,13 +1067,13 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, if (berr) { log_warn(LD_DIR, - "Bw Weights error %d for %s v10. G="I64_FORMAT" M="I64_FORMAT - " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT + "Bw Weights error %d for %s v10. G=%"PRId64" M=%"PRId64 + " E=%"PRId64" D=%"PRId64" T=%"PRId64 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d" " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d", berr, casename, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee, (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale); return 0; @@ -1119,13 +1138,13 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, if (berr != BW_WEIGHTS_NO_ERROR && berr != BW_WEIGHTS_BALANCE_MID_ERROR) { log_warn(LD_DIR, - "Bw Weights error %d for %s v10. G="I64_FORMAT" M="I64_FORMAT - " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT + "Bw Weights error %d for %s v10. G=%"PRId64" M=%"PRId64 + " E=%"PRId64" D=%"PRId64" T=%"PRId64 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d" " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d", berr, casename, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee, (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale); return 0; @@ -1136,10 +1155,10 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, // Case 3: Exactly one of Guard or Exit is scarce if (!(3*E < T || 3*G < T) || !(3*G >= T || 3*E >= T)) { log_warn(LD_BUG, - "Bw-Weights Case 3 v10 but with G="I64_FORMAT" M=" - I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T)); + "Bw-Weights Case 3 v10 but with G=%"PRId64" M=" + "%"PRId64" E=%"PRId64" D=%"PRId64" T=%"PRId64, + (G), (M), (E), + (D), (T)); } if (3*(S+D) < T) { // Subcase a: S+D < T/3 @@ -1191,13 +1210,13 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, } if (berr) { log_warn(LD_DIR, - "Bw Weights error %d for %s v10. G="I64_FORMAT" M="I64_FORMAT - " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT + "Bw Weights error %d for %s v10. G=%"PRId64" M=%"PRId64 + " E=%"PRId64" D=%"PRId64" T=%"PRId64 " Wmd=%d Wme=%d Wmg=%d Wed=%d Wee=%d" " Wgd=%d Wgg=%d Wme=%d Wmg=%d weight_scale=%d", berr, casename, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), (int)Wmd, (int)Wme, (int)Wmg, (int)Wed, (int)Wee, (int)Wgd, (int)Wgg, (int)Wme, (int)Wmg, (int)weight_scale); return 0; @@ -1231,11 +1250,11 @@ networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, (int)weight_scale, (int)Wmd, (int)Wme, (int)Wmg, (int)weight_scale); log_notice(LD_CIRC, "Computed bandwidth weights for %s with v10: " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT, + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64, casename, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T)); + (G), (M), (E), + (D), (T)); return 1; } @@ -1739,9 +1758,9 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Build the flag indexes. Note that no vote can have more than 64 members * for known_flags, so no value will be greater than 63, so it's safe to - * do U64_LITERAL(1) << index on these values. But note also that + * do UINT64_C(1) << index on these values. But note also that * named_flag and unnamed_flag are initialized to -1, so we need to check - * that they're actually set before doing U64_LITERAL(1) << index with + * that they're actually set before doing UINT64_C(1) << index with * them.*/ SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) { flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags), @@ -1770,7 +1789,7 @@ networkstatus_compute_consensus(smartlist_t *votes, uint64_t nf; if (named_flag[v_sl_idx]<0) continue; - nf = U64_LITERAL(1) << named_flag[v_sl_idx]; + nf = UINT64_C(1) << named_flag[v_sl_idx]; SMARTLIST_FOREACH_BEGIN(v->routerstatus_list, vote_routerstatus_t *, rs) { @@ -1795,7 +1814,7 @@ networkstatus_compute_consensus(smartlist_t *votes, uint64_t uf; if (unnamed_flag[v_sl_idx]<0) continue; - uf = U64_LITERAL(1) << unnamed_flag[v_sl_idx]; + uf = UINT64_C(1) << unnamed_flag[v_sl_idx]; SMARTLIST_FOREACH_BEGIN(v->routerstatus_list, vote_routerstatus_t *, rs) { if ((rs->flags & uf) != 0) { @@ -1885,11 +1904,11 @@ networkstatus_compute_consensus(smartlist_t *votes, /* Tally up all the flags. */ for (int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) { - if (rs->flags & (U64_LITERAL(1) << flag)) + if (rs->flags & (UINT64_C(1) << flag)) ++flag_counts[flag_map[voter_idx][flag]]; } if (named_flag[voter_idx] >= 0 && - (rs->flags & (U64_LITERAL(1) << named_flag[voter_idx]))) { + (rs->flags & (UINT64_C(1) << named_flag[voter_idx]))) { if (chosen_name && strcmp(chosen_name, rs->status.nickname)) { log_notice(LD_DIR, "Conflict on naming for router: %s vs %s", chosen_name, rs->status.nickname); @@ -4220,7 +4239,7 @@ routers_make_ed_keys_unique(smartlist_t *routers) if (ri2_pub < ri_pub || (ri2_pub == ri_pub && fast_memcmp(ri->cache_info.signed_descriptor_digest, - ri2->cache_info.signed_descriptor_digest,DIGEST_LEN)<0)) { + ri2->cache_info.signed_descriptor_digest,DIGEST_LEN)<0)) { digest256map_set(by_ed_key, pk, ri); ri2->omit_from_vote = 1; } else { @@ -4393,10 +4412,10 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, vrs->protocols = tor_strdup(ri->protocol_list); } else { vrs->protocols = tor_strdup( - protover_compute_for_old_tor(vrs->version)); + protover_compute_for_old_tor(vrs->version)); } vrs->microdesc = dirvote_format_all_microdesc_vote_lines(ri, now, - microdescriptors); + microdescriptors); smartlist_add(routerstatuses, vrs); } @@ -4489,9 +4508,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, /* We should not recommend anything we don't have. */ tor_assert_nonfatal(protover_all_supported( - v3_out->recommended_relay_protocols, NULL)); + v3_out->recommended_relay_protocols, NULL)); tor_assert_nonfatal(protover_all_supported( - v3_out->recommended_client_protocols, NULL)); + v3_out->recommended_client_protocols, NULL)); v3_out->package_lines = smartlist_new(); { @@ -4547,4 +4566,3 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, return v3_out; } - diff --git a/src/or/dirauth/dirvote.h b/src/or/dirauth/dirvote.h index b69bbbf5d9..7ce8e4a699 100644 --- a/src/or/dirauth/dirvote.h +++ b/src/or/dirauth/dirvote.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -164,7 +164,8 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) } static inline int -dirvote_add_signatures(const char *detached_signatures_body, const char *source, +dirvote_add_signatures(const char *detached_signatures_body, + const char *source, const char **msg_out) { (void) detached_signatures_body; @@ -244,4 +245,3 @@ STATIC microdesc_t *dirvote_create_microdescriptor(const routerinfo_t *ri, #endif /* defined(DIRVOTE_PRIVATE) */ #endif /* !defined(TOR_DIRVOTE_H) */ - diff --git a/src/or/dirauth/mode.h b/src/or/dirauth/mode.h index 8a0d3142f1..17c35aff64 100644 --- a/src/or/dirauth/mode.h +++ b/src/or/dirauth/mode.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,7 +11,7 @@ #ifdef HAVE_MODULE_DIRAUTH -#include "router.h" +#include "or/router.h" /* Return true iff we believe ourselves to be a v3 authoritative directory * server. */ diff --git a/src/or/dirauth/shared_random.c b/src/or/dirauth/shared_random.c index 6dd1f330e0..8b53c1e743 100644 --- a/src/or/dirauth/shared_random.c +++ b/src/or/dirauth/shared_random.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -87,23 +87,26 @@ #define SHARED_RANDOM_PRIVATE -#include "or.h" -#include "shared_random.h" -#include "config.h" -#include "confparse.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "networkstatus.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "shared_random_client.h" -#include "shared_random_state.h" -#include "util.h" -#include "voting_schedule.h" - -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" +#include "or/or.h" +#include "or/dirauth/shared_random.h" +#include "or/config.h" +#include "or/confparse.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/networkstatus.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/shared_random_client.h" +#include "or/dirauth/shared_random_state.h" +#include "common/util.h" +#include "or/voting_schedule.h" + +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" + +#include "or/authority_cert_st.h" +#include "or/networkstatus_st.h" /* String prefix of shared random values in votes/consensuses. */ static const char previous_srv_str[] = "shared-rand-previous-value"; diff --git a/src/or/dirauth/shared_random.h b/src/or/dirauth/shared_random.h index 1778ce8f09..93bab99f71 100644 --- a/src/or/dirauth/shared_random.h +++ b/src/or/dirauth/shared_random.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_SHARED_RANDOM_H @@ -10,7 +10,7 @@ * with "sr_" which stands for shared random. */ -#include "or.h" +#include "or/or.h" /* Protocol version */ #define SR_PROTO_VERSION 1 diff --git a/src/or/dirauth/shared_random_state.c b/src/or/dirauth/shared_random_state.c index fc0e4e5630..87ddcc0736 100644 --- a/src/or/dirauth/shared_random_state.c +++ b/src/or/dirauth/shared_random_state.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -10,17 +10,20 @@ #define SHARED_RANDOM_STATE_PRIVATE -#include "or.h" -#include "config.h" -#include "confparse.h" -#include "crypto_util.h" -#include "dirauth/dirvote.h" -#include "networkstatus.h" -#include "router.h" -#include "shared_random.h" -#include "shared_random_client.h" -#include "shared_random_state.h" -#include "voting_schedule.h" +#include "or/or.h" +#include "or/config.h" +#include "or/confparse.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/dirauth/dirvote.h" +#include "or/networkstatus.h" +#include "or/router.h" +#include "or/dirauth/shared_random.h" +#include "or/shared_random_client.h" +#include "or/dirauth/shared_random_state.h" +#include "or/voting_schedule.h" +#include "lib/encoding/confline.h" + +#include "or/or_state_st.h" /* Default filename of the shared random state on disk. */ static const char default_fname[] = "sr-state"; @@ -1321,4 +1324,3 @@ get_sr_state(void) } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/dirauth/shared_random_state.h b/src/or/dirauth/shared_random_state.h index 60a326f86c..f99874872b 100644 --- a/src/or/dirauth/shared_random_state.h +++ b/src/or/dirauth/shared_random_state.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_SHARED_RANDOM_STATE_H #define TOR_SHARED_RANDOM_STATE_H -#include "shared_random.h" +#include "or/dirauth/shared_random.h" /* Action that can be performed on the state for any objects. */ typedef enum { @@ -85,11 +85,11 @@ typedef struct sr_disk_state_t { /* State valid until? */ time_t ValidUntil; /* All commits seen that are valid. */ - config_line_t *Commit; + struct config_line_t *Commit; /* Previous and current shared random value. */ - config_line_t *SharedRandValues; + struct config_line_t *SharedRandValues; /* Extra Lines for configuration we might not know. */ - config_line_t *ExtraLines; + struct config_line_t *ExtraLines; } sr_disk_state_t; /* API */ @@ -144,4 +144,3 @@ STATIC sr_state_t *get_sr_state(void); #endif /* defined(TOR_UNIT_TESTS) */ #endif /* !defined(TOR_SHARED_RANDOM_STATE_H) */ - diff --git a/src/or/directory.c b/src/or/directory.c index e763de268f..8f2bd8d3a7 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1,47 +1,50 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DIRECTORY_PRIVATE -#include "or.h" -#include "backtrace.h" -#include "bridges.h" -#include "buffers.h" -#include "circuitbuild.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "conscache.h" -#include "consdiff.h" -#include "consdiffmgr.h" -#include "control.h" -#include "compat.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "dirserv.h" -#include "entrynodes.h" -#include "geoip.h" -#include "hs_cache.h" -#include "hs_common.h" -#include "hs_control.h" -#include "hs_client.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "relay.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" +#include "or/or.h" +#include "lib/err/backtrace.h" +#include "or/bridges.h" +#include "lib/container/buffers.h" +#include "or/circuitbuild.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/conscache.h" +#include "or/consdiff.h" +#include "or/consdiffmgr.h" +#include "or/control.h" +#include "lib/compress/compress.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/entrynodes.h" +#include "or/fp_pair.h" +#include "or/geoip.h" +#include "or/hs_cache.h" +#include "or/hs_common.h" +#include "or/hs_control.h" +#include "or/hs_client.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/relay.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "lib/encoding/confline.h" +#include "lib/crypt_ops/crypto_format.h" #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) #if !defined(OpenBSD) @@ -49,9 +52,19 @@ #endif #endif -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" -#include "dirauth/shared_random.h" +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" +#include "or/dirauth/shared_random.h" + +#include "or/authority_cert_st.h" +#include "or/cached_dir_st.h" +#include "or/dir_connection_st.h" +#include "or/dir_server_st.h" +#include "or/entry_connection_st.h" +#include "or/networkstatus_st.h" +#include "or/node_st.h" +#include "or/rend_service_descriptor_st.h" +#include "or/routerinfo_st.h" /** * \file directory.c @@ -131,6 +144,15 @@ static void connection_dir_close_consensus_fetches( /********* START VARIABLES **********/ +/** Maximum size, in bytes, for resized buffers. */ +#define MAX_BUF_SIZE ((1<<24)-1) /* 16MB-1 */ +/** Maximum size, in bytes, for any directory object that we've downloaded. */ +#define MAX_DIR_DL_SIZE MAX_BUF_SIZE + +/** Maximum size, in bytes, for any directory object that we're accepting + * as an upload. */ +#define MAX_DIR_UL_SIZE MAX_BUF_SIZE + /** How far in the future do we allow a directory server to tell us it is * before deciding that one of us has the wrong time? */ #define ALLOW_DIRECTORY_TIME_SKEW (30*60) @@ -151,6 +173,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 <b>dir_purpose</b> * does not require an anonymous (three-hop) connection. * @@ -1910,12 +1941,12 @@ directory_send_command(dir_connection_t *conn, log_debug(LD_DIR, "Sent request to directory server '%s:%d': " - "(purpose: %d, request size: " U64_FORMAT ", " - "payload size: " U64_FORMAT ")", + "(purpose: %d, request size: %"TOR_PRIuSZ", " + "payload size: %"TOR_PRIuSZ")", conn->base_.address, conn->base_.port, conn->base_.purpose, - U64_PRINTF_ARG(total_request_len), - U64_PRINTF_ARG(payload ? payload_len : 0)); + (total_request_len), + (payload ? payload_len : 0)); } /** Parse an HTTP request string <b>headers</b> of the form @@ -2401,14 +2432,14 @@ connection_dir_client_reached_eof(dir_connection_t *conn) tor_log(LOG_DEBUG, LD_DIR, "Received response from directory server '%s:%d': %d %s " - "(purpose: %d, response size: " U64_FORMAT + "(purpose: %d, response size: %"TOR_PRIuSZ #ifdef MEASUREMENTS_21206 ", data cells received: %d, data cells sent: %d" #endif ", compression: %d)", conn->base_.address, conn->base_.port, status_code, escaped(reason), conn->base_.purpose, - U64_PRINTF_ARG(received_bytes), + (received_bytes), #ifdef MEASUREMENTS_21206 conn->data_cells_received, conn->data_cells_sent, #endif @@ -5614,6 +5645,27 @@ download_status_reset(download_status_t *dls) /* Don't reset dls->want_authority or dls->increment_on */ } +/** Return true iff, as of <b>now</b>, the resource tracked by <b>dls</b> 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 <b>dl</b> 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 <b>dls</b> since the last success (if * any). */ int @@ -5912,4 +5964,3 @@ dir_split_resource_into_spoolable(const char *resource, smartlist_free(fingerprints); return r; } - diff --git a/src/or/directory.h b/src/or/directory.h index 5f5ff7eca6..992ff618fb 100644 --- a/src/or/directory.h +++ b/src/or/directory.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,82 @@ #ifndef TOR_DIRECTORY_H #define TOR_DIRECTORY_H -#include "hs_ident.h" +#include "or/hs_ident.h" +enum compress_method_t; + +dir_connection_t *TO_DIR_CONN(connection_t *c); + +#define DIR_CONN_STATE_MIN_ 1 +/** State for connection to directory server: waiting for connect(). */ +#define DIR_CONN_STATE_CONNECTING 1 +/** State for connection to directory server: sending HTTP request. */ +#define DIR_CONN_STATE_CLIENT_SENDING 2 +/** State for connection to directory server: reading HTTP response. */ +#define DIR_CONN_STATE_CLIENT_READING 3 +/** State for connection to directory server: happy and finished. */ +#define DIR_CONN_STATE_CLIENT_FINISHED 4 +/** State for connection at directory server: waiting for HTTP request. */ +#define DIR_CONN_STATE_SERVER_COMMAND_WAIT 5 +/** State for connection at directory server: sending HTTP response. */ +#define DIR_CONN_STATE_SERVER_WRITING 6 +#define DIR_CONN_STATE_MAX_ 6 + +#define DIR_PURPOSE_MIN_ 4 +/** A connection to a directory server: set after a v2 rendezvous + * descriptor is downloaded. */ +#define DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 4 +/** A connection to a directory server: download one or more server + * descriptors. */ +#define DIR_PURPOSE_FETCH_SERVERDESC 6 +/** A connection to a directory server: download one or more extra-info + * documents. */ +#define DIR_PURPOSE_FETCH_EXTRAINFO 7 +/** A connection to a directory server: upload a server descriptor. */ +#define DIR_PURPOSE_UPLOAD_DIR 8 +/** A connection to a directory server: upload a v3 networkstatus vote. */ +#define DIR_PURPOSE_UPLOAD_VOTE 10 +/** A connection to a directory server: upload a v3 consensus signature */ +#define DIR_PURPOSE_UPLOAD_SIGNATURES 11 +/** A connection to a directory server: download one or more v3 networkstatus + * votes. */ +#define DIR_PURPOSE_FETCH_STATUS_VOTE 12 +/** A connection to a directory server: download a v3 detached signatures + * object for a consensus. */ +#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES 13 +/** A connection to a directory server: download a v3 networkstatus + * consensus. */ +#define DIR_PURPOSE_FETCH_CONSENSUS 14 +/** A connection to a directory server: download one or more directory + * authority certificates. */ +#define DIR_PURPOSE_FETCH_CERTIFICATE 15 + +/** Purpose for connection at a directory server. */ +#define DIR_PURPOSE_SERVER 16 +/** A connection to a hidden service directory server: upload a v2 rendezvous + * descriptor. */ +#define DIR_PURPOSE_UPLOAD_RENDDESC_V2 17 +/** A connection to a hidden service directory server: download a v2 rendezvous + * descriptor. */ +#define DIR_PURPOSE_FETCH_RENDDESC_V2 18 +/** A connection to a directory server: download a microdescriptor. */ +#define DIR_PURPOSE_FETCH_MICRODESC 19 +/** A connection to a hidden service directory: upload a v3 descriptor. */ +#define DIR_PURPOSE_UPLOAD_HSDESC 20 +/** A connection to a hidden service directory: fetch a v3 descriptor. */ +#define DIR_PURPOSE_FETCH_HSDESC 21 +/** A connection to a directory server: set after a hidden service descriptor + * is downloaded. */ +#define DIR_PURPOSE_HAS_FETCHED_HSDESC 22 +#define DIR_PURPOSE_MAX_ 22 + +/** True iff <b>p</b> is a purpose corresponding to uploading + * data to a directory server. */ +#define DIR_PURPOSE_IS_UPLOAD(p) \ + ((p)==DIR_PURPOSE_UPLOAD_DIR || \ + (p)==DIR_PURPOSE_UPLOAD_VOTE || \ + (p)==DIR_PURPOSE_UPLOAD_SIGNATURES || \ + (p)==DIR_PURPOSE_UPLOAD_RENDDESC_V2 || \ + (p)==DIR_PURPOSE_UPLOAD_HSDESC) int directories_have_accepted_server_descriptor(void); void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, @@ -60,6 +135,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, @@ -88,7 +164,7 @@ void directory_request_add_header(directory_request_t *req, MOCK_DECL(void, directory_initiate_request, (directory_request_t *request)); int parse_http_response(const char *headers, int *code, time_t *date, - compress_method_t *compression, char **response); + enum compress_method_t *compression, char **response); int parse_http_command(const char *headers, char **command_out, char **url_out); char *http_get_header(const char *headers, const char *which); @@ -132,30 +208,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 <b>now</b>, the resource tracked by <b>dls</b> 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 <b>dl</b> 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); @@ -208,7 +263,7 @@ struct directory_request_t { /** Hidden-service-specific information v2. */ const rend_data_t *rend_query; /** Extra headers to append to the request */ - config_line_t *additional_headers; + struct config_line_t *additional_headers; /** Hidden-service-specific information for v3+. */ const hs_ident_dir_conn_t *hs_ident; /** Used internally to directory.c: gets informed when the attempt to @@ -222,8 +277,10 @@ STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn, const struct get_handler_args_t *args); STATIC int directory_handle_command(dir_connection_t *conn); STATIC char *accept_encoding_header(void); -STATIC int allowed_anonymous_connection_compression_method(compress_method_t); -STATIC void warn_disallowed_anonymous_compression_method(compress_method_t); +STATIC int allowed_anonymous_connection_compression_method( + enum compress_method_t); +STATIC void warn_disallowed_anonymous_compression_method( + enum compress_method_t); STATIC int handle_response_fetch_hsdesc_v3(dir_connection_t *conn, const response_handler_args_t *args); @@ -258,7 +315,8 @@ STATIC int handle_post_hs_descriptor(const char *url, const char *body); STATIC char* authdir_type_to_string(dirinfo_type_t auth); STATIC const char * dir_conn_purpose_to_string(int purpose); STATIC int should_use_directory_guards(const or_options_t *options); -STATIC compression_level_t choose_compression_level(ssize_t n_bytes); +enum compression_level_t; +STATIC enum compression_level_t choose_compression_level(ssize_t n_bytes); STATIC int find_dl_min_delay(const download_status_t *dls, const or_options_t *options); @@ -287,4 +345,3 @@ STATIC unsigned parse_accept_encoding_header(const char *h); #endif /* defined(TOR_UNIT_TESTS) || defined(DIRECTORY_PRIVATE) */ #endif /* !defined(TOR_DIRECTORY_H) */ - diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 2362089d32..2980d63f0a 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1,45 +1,60 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DIRSERV_PRIVATE -#include "or.h" -#include "buffers.h" -#include "config.h" -#include "confparse.h" -#include "channel.h" -#include "channeltls.h" -#include "command.h" -#include "connection.h" -#include "connection_or.h" -#include "conscache.h" -#include "consdiffmgr.h" -#include "control.h" -#include "directory.h" -#include "dirserv.h" -#include "hibernate.h" -#include "keypin.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "protover.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" -#include "torcert.h" -#include "voting_schedule.h" - -#include "dirauth/dirvote.h" +#include "or/or.h" +#include "lib/container/buffers.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/command.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "or/conscache.h" +#include "or/consdiffmgr.h" +#include "or/control.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/hibernate.h" +#include "or/keypin.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/protover.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "or/torcert.h" +#include "or/voting_schedule.h" + +#include "or/dirauth/dirvote.h" + +#include "or/cached_dir_st.h" +#include "or/dir_connection_st.h" +#include "or/extrainfo_st.h" +#include "or/microdesc_st.h" +#include "or/node_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/tor_version_st.h" +#include "or/vote_routerstatus_st.h" + +#include "lib/compress/compress.h" +#include "lib/container/order.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/encoding/confline.h" /** * \file dirserv.c * \brief Directory server core implementation. Manages directory - * contents and generates directories. + * contents and generates directory documents. * * This module implements most of directory cache functionality, and some of * the directory authority functionality. The directory.c module delegates @@ -3581,4 +3596,3 @@ dirserv_free_all(void) dirserv_clear_measured_bw_cache(); } - diff --git a/src/or/dirserv.h b/src/or/dirserv.h index 9026f332bc..3b4a646094 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,24 @@ #ifndef TOR_DIRSERV_H #define TOR_DIRSERV_H -#include "testsupport.h" +struct ed25519_public_key_t; + +#include "lib/testsupport/testsupport.h" + +/** An enum to describe what format we're generating a routerstatus line in. + */ +typedef enum { + /** For use in a v2 opinion */ + NS_V2, + /** For use in a consensus networkstatus document (ns flavor) */ + NS_V3_CONSENSUS, + /** For use in a vote networkstatus document */ + NS_V3_VOTE, + /** For passing to the controlport in response to a GETINFO request */ + NS_CONTROL_PORT, + /** For use in a consensus networkstatus document (microdesc flavor) */ + NS_V3_CONSENSUS_MICRODESC +} routerstatus_format_type_t; /** What fraction (1 over this number) of the relay ID space do we * (as a directory authority) launch connections to at each reachability @@ -87,6 +104,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); @@ -130,7 +155,7 @@ int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key, void dirserv_orconn_tls_done(const tor_addr_t *addr, uint16_t or_port, const char *digest_rcvd, - const ed25519_public_key_t *ed_id_rcvd); + const struct ed25519_public_key_t *ed_id_rcvd); int dirserv_should_launch_reachability_test(const routerinfo_t *ri, const routerinfo_t *ri_old); void dirserv_single_reachability_test(time_t now, routerinfo_t *router); @@ -212,4 +237,3 @@ void dirserv_spool_sort(dir_connection_t *conn); void dir_conn_clear_spool(dir_connection_t *conn); #endif /* !defined(TOR_DIRSERV_H) */ - diff --git a/src/or/dns.c b/src/or/dns.c index ba734ed900..45c4384eb1 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -49,21 +49,30 @@ #define DNS_PRIVATE -#include "or.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "control.h" -#include "crypto_rand.h" -#include "dns.h" -#include "main.h" -#include "policies.h" -#include "relay.h" -#include "router.h" +#include "or/or.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/dns.h" +#include "or/main.h" +#include "or/policies.h" +#include "or/relay.h" +#include "or/router.h" #include "ht.h" -#include "sandbox.h" +#include "lib/sandbox/sandbox.h" +#include "common/compat_libevent.h" + +#include "or/edge_connection_st.h" +#include "or/or_circuit_st.h" + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + #include <event2/event.h> #include <event2/dns.h> @@ -2132,4 +2141,3 @@ dns_insert_cache_entry(cached_resolve_t *new_entry) { HT_INSERT(cache_map, &cache_root, new_entry); } - diff --git a/src/or/dns.h b/src/or/dns.h index 28d9f947b4..12853205ff 100644 --- a/src/or/dns.h +++ b/src/or/dns.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -41,7 +41,7 @@ void dns_reset_correctness_checks(void); void dump_dns_mem_usage(int severity); #ifdef DNS_PRIVATE -#include "dns_structs.h" +#include "or/dns_structs.h" MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve,or_circuit_t *oncirc, char **hostname_out, diff --git a/src/or/dns_structs.h b/src/or/dns_structs.h index e22f23ac15..28c48ca0bc 100644 --- a/src/or/dns_structs.h +++ b/src/or/dns_structs.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 7e344deeab..d2ef4a496e 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2017, The Tor Project, Inc. */ +/* Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,14 +21,21 @@ * DNS client. **/ -#include "or.h" -#include "dnsserv.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "control.h" -#include "main.h" -#include "policies.h" +#include "or/or.h" +#include "or/dnsserv.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/control.h" +#include "or/main.h" +#include "or/policies.h" + +#include "or/control_connection_st.h" +#include "or/entry_connection_st.h" +#include "or/listener_connection_st.h" +#include "or/socks_request_st.h" +#include "common/compat_libevent.h" + #include <event2/dns.h> #include <event2/dns_compat.h> /* XXXX this implies we want an improved evdns */ @@ -406,4 +413,3 @@ dnsserv_close_listener(connection_t *conn) listener_conn->dns_server_port = NULL; } } - diff --git a/src/or/dnsserv.h b/src/or/dnsserv.h index 2af366eee5..afdde3a342 100644 --- a/src/or/dnsserv.h +++ b/src/or/dnsserv.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/document_signature_st.h b/src/or/document_signature_st.h new file mode 100644 index 0000000000..0291e099bf --- /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-2018, 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 <b>signature</b> */ + 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..d86ede02cb 100644 --- a/src/or/dos.c +++ b/src/or/dos.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* @@ -8,18 +8,22 @@ #define DOS_PRIVATE -#include "or.h" -#include "channel.h" -#include "config.h" -#include "crypto_rand.h" -#include "geoip.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "relay.h" -#include "router.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/geoip.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/relay.h" +#include "or/router.h" -#include "dos.h" +#include "or/dos.h" + +#include "or/or_connection_st.h" /* * Circuit creation denial of service mitigation. @@ -795,4 +799,3 @@ dos_init(void) /* To initialize, we only need to get the parameters. */ set_dos_parameters(NULL); } - diff --git a/src/or/dos.h b/src/or/dos.h index 5d35a2b12e..760ef11057 100644 --- a/src/or/dos.h +++ b/src/or/dos.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* diff --git a/src/or/download_status_st.h b/src/or/download_status_st.h new file mode 100644 index 0000000000..3f18f754a1 --- /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-2018, 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 + * <b>schedule</b>, which can be different depending on whether the object is + * being downloaded from an authority or a mirror (<b>want_authority</b>). + * <b>next_attempt_at</b> contains the next time we will attempt to download + * the object. + * For schedules that <b>increment_on</b> failure, <b>n_download_failures</b> + * 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, <b>n_download_failures</b> is incremented, + * the new delay value is looked up from the schedule, and + * <b>next_attempt_at</b> 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 <b>increment_on</b> attempt, <b>n_download_attempts</b> + * is used to determine the position in the schedule. Every time a + * connection attempt is made, <b>n_download_attempts</b> is incremented, + * the new delay value is looked up from the schedule, and + * <b>next_attempt_at</b> 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..d58e1c2b8c --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef EDGE_CONNECTION_ST_H +#define EDGE_CONNECTION_ST_H + +#include "or/or.h" + +#include "or/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..2f9676088c --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef ENTRY_CONNECTION_ST_H +#define ENTRY_CONNECTION_ST_H + +#include "or/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..9b07ccb067 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef ENTRY_PORT_CFG_ST_H +#define ENTRY_PORT_CFG_ST_H + +#include "lib/cc/torint.h" +#include "or/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..ba9c30f8b3 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -112,32 +112,40 @@ #define ENTRYNODES_PRIVATE -#include "or.h" -#include "channel.h" -#include "bridges.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "circuitstats.h" -#include "config.h" -#include "confparse.h" -#include "connection.h" -#include "control.h" -#include "crypto_rand.h" -#include "directory.h" -#include "entrynodes.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" -#include "transports.h" -#include "statefile.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/bridges.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/connection.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/directory.h" +#include "or/entrynodes.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "or/transports.h" +#include "or/statefile.h" +#include "lib/math/fp.h" +#include "lib/encoding/confline.h" + +#include "or/node_st.h" +#include "or/origin_circuit_st.h" +#include "or/or_state_st.h" + +#include "lib/crypt_ops/digestset.h" /** A list of existing guard selection contexts. */ static smartlist_t *guard_contexts = NULL; @@ -1060,7 +1068,7 @@ get_eligible_guards(const or_options_t *options, continue; } ++n_guards; - if (digestset_contains(sampled_guard_ids, node->identity)) + if (digestset_probably_contains(sampled_guard_ids, node->identity)) continue; smartlist_add(eligible_guards, (node_t*)node); } SMARTLIST_FOREACH_END(node); @@ -3684,4 +3692,3 @@ entry_guards_free_all(void) } circuit_build_times_free_timeouts(get_circuit_build_times_mutable()); } - diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index e8c91da41b..56b961e9a0 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,7 @@ #ifndef TOR_ENTRYNODES_H #define TOR_ENTRYNODES_H -#include "handles.h" +#include "common/handles.h" /* Forward declare for guard_selection_t; entrynodes.c has the real struct */ typedef struct guard_selection_s guard_selection_t; @@ -64,6 +64,8 @@ typedef struct guard_pathbias_t { } guard_pathbias_t; #if defined(ENTRYNODES_PRIVATE) +#include "lib/crypt_ops/crypto_ed25519.h" + /** * @name values for entry_guard_t.is_reachable. * @@ -635,4 +637,3 @@ guard_get_guardfraction_bandwidth(guardfraction_bandwidth_t *guardfraction_bw, uint32_t guardfraction_percentage); #endif /* !defined(TOR_ENTRYNODES_H) */ - diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c index b842442caf..701dc45288 100644 --- a/src/or/ext_orport.c +++ b/src/or/ext_orport.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,17 +17,19 @@ */ #define EXT_ORPORT_PRIVATE -#include "or.h" -#include "connection.h" -#include "connection_or.h" -#include "control.h" -#include "config.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "ext_orport.h" -#include "main.h" -#include "proto_ext_or.h" -#include "util.h" +#include "or/or.h" +#include "or/connection.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/ext_orport.h" +#include "or/main.h" +#include "or/proto_ext_or.h" +#include "common/util.h" + +#include "or/or_connection_st.h" /** Allocate and return a structure capable of holding an Extended * ORPort message of body length <b>len</b>. */ diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h index 09acbc407e..7eebfdb25b 100644 --- a/src/or/ext_orport.h +++ b/src/or/ext_orport.h @@ -1,12 +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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef EXT_ORPORT_H #define EXT_ORPORT_H +/** States of the Extended ORPort protocol. Be careful before changing + * the numbers: they matter. */ +#define EXT_OR_CONN_STATE_MIN_ 1 +/** Extended ORPort authentication is waiting for the authentication + * type selected by the client. */ +#define EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE 1 +/** Extended ORPort authentication is waiting for the client nonce. */ +#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE 2 +/** Extended ORPort authentication is waiting for the client hash. */ +#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH 3 +#define EXT_OR_CONN_STATE_AUTH_MAX 3 +/** Authentication finished and the Extended ORPort is now accepting + * traffic. */ +#define EXT_OR_CONN_STATE_OPEN 4 +/** Extended ORPort is flushing its last messages and preparing to + * start accepting OR connections. */ +#define EXT_OR_CONN_STATE_FLUSHING 5 +#define EXT_OR_CONN_STATE_MAX_ 5 + int connection_ext_or_start_auth(or_connection_t *or_conn); ext_or_cmd_t *ext_or_cmd_new(uint16_t len); @@ -43,4 +62,3 @@ extern int ext_or_auth_cookie_is_set; #endif /* defined(EXT_ORPORT_PRIVATE) */ #endif /* !defined(EXT_ORPORT_H) */ - diff --git a/src/or/extend_info_st.h b/src/or/extend_info_st.h new file mode 100644 index 0000000000..277766c4d6 --- /dev/null +++ b/src/or/extend_info_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef EXTEND_INFO_ST_H +#define EXTEND_INFO_ST_H + +#include "lib/crypt_ops/crypto_curve25519.h" +#include "lib/crypt_ops/crypto_ed25519.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..f91bba7b68 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef EXTRAINFO_ST_H +#define EXTRAINFO_ST_H + +#include "or/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.c b/src/or/fp_pair.c index c938e76678..1d7b751c23 100644 --- a/src/or/fp_pair.c +++ b/src/or/fp_pair.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Tor Project, Inc. */ +/* Copyright (c) 2013-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,8 +17,8 @@ * certificate for any (ID key, signing key) pair. **/ -#include "or.h" -#include "fp_pair.h" +#include "or/or.h" +#include "or/fp_pair.h" /* Define fp_pair_map_t structures */ diff --git a/src/or/fp_pair.h b/src/or/fp_pair.h index 4498a16101..500c7c9928 100644 --- a/src/or/fp_pair.h +++ b/src/or/fp_pair.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Tor Project, Inc. */ +/* Copyright (c) 2013-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -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/geoip.c b/src/or/geoip.c index d59043a7f6..3e6f20ea3f 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2017, The Tor Project, Inc. */ +/* Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -28,15 +28,18 @@ */ #define GEOIP_PRIVATE -#include "or.h" +#include "or/or.h" #include "ht.h" -#include "buffers.h" -#include "config.h" -#include "control.h" -#include "dnsserv.h" -#include "dos.h" -#include "geoip.h" -#include "routerlist.h" +#include "lib/container/buffers.h" +#include "or/config.h" +#include "or/control.h" +#include "or/dnsserv.h" +#include "or/dos.h" +#include "or/geoip.h" +#include "or/routerlist.h" + +#include "lib/container/order.h" +#include "lib/time/tvdiff.h" static void init_geoip_countries(void); @@ -1037,12 +1040,12 @@ geoip_get_transport_history(void) void *transport_count_ptr = strmap_get(transport_counts, transport_name); uintptr_t transport_count = (uintptr_t) transport_count_ptr; - log_debug(LD_GENERAL, "We got "U64_FORMAT" clients with transport '%s'.", - U64_PRINTF_ARG((uint64_t)transport_count), transport_name); + log_debug(LD_GENERAL, "We got %"PRIu64" clients with transport '%s'.", + ((uint64_t)transport_count), transport_name); - smartlist_add_asprintf(string_chunks, "%s="U64_FORMAT, + smartlist_add_asprintf(string_chunks, "%s=%"PRIu64, transport_name, - U64_PRINTF_ARG(round_uint64_to_next_multiple_of( + (round_uint64_to_next_multiple_of( (uint64_t)transport_count, granularity))); } SMARTLIST_FOREACH_END(transport_name); @@ -1884,4 +1887,3 @@ geoip_free_all(void) memset(geoip_digest, 0, sizeof(geoip_digest)); memset(geoip6_digest, 0, sizeof(geoip6_digest)); } - diff --git a/src/or/geoip.h b/src/or/geoip.h index 753bdbf82a..fd19b7560a 100644 --- a/src/or/geoip.h +++ b/src/or/geoip.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,8 +12,66 @@ #ifndef TOR_GEOIP_H #define TOR_GEOIP_H -#include "testsupport.h" -#include "dos.h" +#include "lib/testsupport/testsupport.h" +#include "or/dos.h" + +/** Indicates an action that we might be noting geoip statistics on. + * Note that if we're noticing CONNECT, we're a bridge, and if we're noticing + * the others, we're not. + */ +typedef enum { + /** We've noticed a connection as a bridge relay or entry guard. */ + GEOIP_CLIENT_CONNECT = 0, + /** We've served a networkstatus consensus as a directory server. */ + GEOIP_CLIENT_NETWORKSTATUS = 1, +} geoip_client_action_t; +/** Indicates either a positive reply or a reason for rejectng a network + * status request that will be included in geoip statistics. */ +typedef enum { + /** Request is answered successfully. */ + GEOIP_SUCCESS = 0, + /** V3 network status is not signed by a sufficient number of requested + * authorities. */ + GEOIP_REJECT_NOT_ENOUGH_SIGS = 1, + /** Requested network status object is unavailable. */ + GEOIP_REJECT_UNAVAILABLE = 2, + /** Requested network status not found. */ + GEOIP_REJECT_NOT_FOUND = 3, + /** Network status has not been modified since If-Modified-Since time. */ + GEOIP_REJECT_NOT_MODIFIED = 4, + /** Directory is busy. */ + GEOIP_REJECT_BUSY = 5, +} geoip_ns_response_t; +#define GEOIP_NS_RESPONSE_NUM 6 + +/** Directory requests that we are measuring can be either direct or + * tunneled. */ +typedef enum { + DIRREQ_DIRECT = 0, + DIRREQ_TUNNELED = 1, +} dirreq_type_t; + +/** Possible states for either direct or tunneled directory requests that + * are relevant for determining network status download times. */ +typedef enum { + /** Found that the client requests a network status; applies to both + * direct and tunneled requests; initial state of a request that we are + * measuring. */ + DIRREQ_IS_FOR_NETWORK_STATUS = 0, + /** Finished writing a network status to the directory connection; + * applies to both direct and tunneled requests; completes a direct + * request. */ + DIRREQ_FLUSHING_DIR_CONN_FINISHED = 1, + /** END cell sent to circuit that initiated a tunneled request. */ + DIRREQ_END_CELL_SENT = 2, + /** Flushed last cell from queue of the circuit that initiated a + * tunneled request to the outbuf of the OR connection. */ + DIRREQ_CIRC_QUEUE_FLUSHED = 3, + /** Flushed last byte from buffer of the channel belonging to the + * circuit that initiated a tunneled request; completes a tunneled + * request. */ + DIRREQ_CHANNEL_BUFFER_FLUSHED = 4 +} dirreq_state_t; #ifdef GEOIP_PRIVATE STATIC int geoip_parse_entry(const char *line, sa_family_t family); @@ -97,4 +155,3 @@ char *geoip_get_bridge_stats_controller(time_t); char *format_client_stats_heartbeat(time_t now); #endif /* !defined(TOR_GEOIP_H) */ - diff --git a/src/or/git_revision.c b/src/or/git_revision.c index 8f326b8751..be6f67423c 100644 --- a/src/or/git_revision.c +++ b/src/or/git_revision.c @@ -1,9 +1,9 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "git_revision.h" +#include "or/git_revision.h" /** String describing which Tor Git repository version the source was * built from. This string is generated by a bit of shell kludging in diff --git a/src/or/git_revision.h b/src/or/git_revision.h index 5613cb4335..02070cfd5e 100644 --- a/src/or/git_revision.h +++ b/src/or/git_revision.h @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_GIT_REVISION_H diff --git a/src/or/hibernate.c b/src/or/hibernate.c index d7d259470f..1024c03546 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -28,19 +28,27 @@ hibernating, phase 2: */ #define HIBERNATE_PRIVATE -#include "or.h" -#include "channel.h" -#include "channeltls.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_rand.h" -#include "hibernate.h" -#include "main.h" -#include "router.h" -#include "statefile.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/hibernate.h" +#include "or/main.h" +#include "or/router.h" +#include "or/statefile.h" +#include "common/compat_libevent.h" + +#include "or/or_connection_st.h" +#include "or/or_state_st.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /** Are we currently awake, asleep, running out of bandwidth, or shutting * down? */ @@ -759,13 +767,13 @@ read_bandwidth_usage(void) "Successfully read bandwidth accounting info from state written at %s " "for interval starting at %s. We have been active for %lu seconds in " "this interval. At the start of the interval, we expected to use " - "about %lu KB per second. ("U64_FORMAT" bytes read so far, " - U64_FORMAT" bytes written so far)", + "about %lu KB per second. (%"PRIu64" bytes read so far, " + "%"PRIu64" bytes written so far)", tbuf1, tbuf2, (unsigned long)n_seconds_active_in_interval, (unsigned long)(expected_bandwidth_usage*1024/60), - U64_PRINTF_ARG(n_bytes_read_in_interval), - U64_PRINTF_ARG(n_bytes_written_in_interval)); + (n_bytes_read_in_interval), + (n_bytes_written_in_interval)); } return 0; @@ -797,7 +805,7 @@ hibernate_soft_limit_reached(void) * - We have used up 95% of our bytes. * - We have less than 500MB of bytes left. */ - uint64_t soft_limit = DBL_TO_U64(U64_TO_DBL(acct_max) * SOFT_LIM_PCT); + uint64_t soft_limit = (uint64_t) (acct_max * SOFT_LIM_PCT); if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) { soft_limit = acct_max - SOFT_LIM_BYTES; } @@ -1132,9 +1140,9 @@ getinfo_helper_accounting(control_connection_t *conn, *answer = tor_strdup(hibernate_state_to_string(hibernate_state)); tor_strlower(*answer); } else if (!strcmp(question, "accounting/bytes")) { - tor_asprintf(answer, U64_FORMAT" "U64_FORMAT, - U64_PRINTF_ARG(n_bytes_read_in_interval), - U64_PRINTF_ARG(n_bytes_written_in_interval)); + tor_asprintf(answer, "%"PRIu64" %"PRIu64, + (n_bytes_read_in_interval), + (n_bytes_written_in_interval)); } else if (!strcmp(question, "accounting/bytes-left")) { uint64_t limit = get_options()->AccountingMax; if (get_options()->AccountingRule == ACCT_SUM) { @@ -1142,28 +1150,28 @@ getinfo_helper_accounting(control_connection_t *conn, uint64_t total_bytes = get_accounting_bytes(); if (total_bytes < limit) total_left = limit - total_bytes; - tor_asprintf(answer, U64_FORMAT" "U64_FORMAT, - U64_PRINTF_ARG(total_left), U64_PRINTF_ARG(total_left)); + tor_asprintf(answer, "%"PRIu64" %"PRIu64, + (total_left), (total_left)); } else if (get_options()->AccountingRule == ACCT_IN) { uint64_t read_left = 0; if (n_bytes_read_in_interval < limit) read_left = limit - n_bytes_read_in_interval; - tor_asprintf(answer, U64_FORMAT" "U64_FORMAT, - U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(limit)); + tor_asprintf(answer, "%"PRIu64" %"PRIu64, + (read_left), (limit)); } else if (get_options()->AccountingRule == ACCT_OUT) { uint64_t write_left = 0; if (n_bytes_written_in_interval < limit) write_left = limit - n_bytes_written_in_interval; - tor_asprintf(answer, U64_FORMAT" "U64_FORMAT, - U64_PRINTF_ARG(limit), U64_PRINTF_ARG(write_left)); + tor_asprintf(answer, "%"PRIu64" %"PRIu64, + (limit), (write_left)); } else { uint64_t read_left = 0, write_left = 0; if (n_bytes_read_in_interval < limit) read_left = limit - n_bytes_read_in_interval; if (n_bytes_written_in_interval < limit) write_left = limit - n_bytes_written_in_interval; - tor_asprintf(answer, U64_FORMAT" "U64_FORMAT, - U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(write_left)); + tor_asprintf(answer, "%"PRIu64" %"PRIu64, + (read_left), (write_left)); } } else if (!strcmp(question, "accounting/interval-start")) { *answer = tor_malloc(ISO_TIME_LEN+1); @@ -1225,4 +1233,3 @@ hibernate_set_state_for_testing_(hibernate_state_t newstate) hibernate_state = newstate; } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/hibernate.h b/src/or/hibernate.h index 453969d052..bfd8571cd6 100644 --- a/src/or/hibernate.h +++ b/src/or/hibernate.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,7 @@ #ifndef TOR_HIBERNATE_H #define TOR_HIBERNATE_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" int accounting_parse_options(const or_options_t *options, int validate_only); MOCK_DECL(int, accounting_is_enabled, (const or_options_t *options)); diff --git a/src/or/hs_cache.c b/src/or/hs_cache.c index ecc845d17f..3772e0c0ed 100644 --- a/src/or/hs_cache.c +++ b/src/or/hs_cache.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,17 +9,20 @@ /* For unit tests.*/ #define HS_CACHE_PRIVATE -#include "or.h" -#include "config.h" -#include "crypto_util.h" -#include "hs_ident.h" -#include "hs_common.h" -#include "hs_client.h" -#include "hs_descriptor.h" -#include "networkstatus.h" -#include "rendcache.h" +#include "or/or.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/hs_ident.h" +#include "or/hs_common.h" +#include "or/hs_client.h" +#include "or/hs_descriptor.h" +#include "or/networkstatus.h" +#include "or/rendcache.h" -#include "hs_cache.h" +#include "or/hs_cache.h" + +#include "or/networkstatus_st.h" static int cached_client_descriptor_has_expired(time_t now, const hs_cache_client_descriptor_t *cached_desc); @@ -974,4 +977,3 @@ hs_cache_free_all(void) cache_client_intro_state_free_void); hs_cache_client_intro_state = NULL; } - diff --git a/src/or/hs_cache.h b/src/or/hs_cache.h index 0d0085ffdc..1e479700fa 100644 --- a/src/or/hs_cache.h +++ b/src/or/hs_cache.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,11 +11,12 @@ #include <stdint.h> -#include "crypto_ed25519.h" -#include "hs_common.h" -#include "hs_descriptor.h" -#include "rendcommon.h" -#include "torcert.h" +#include "or/hs_common.h" +#include "or/hs_descriptor.h" +#include "or/rendcommon.h" +#include "or/torcert.h" + +struct ed25519_public_key_t; /* This is the maximum time an introduction point state object can stay in the * client cache in seconds (2 mins or 120 seconds). */ @@ -79,30 +80,32 @@ int hs_cache_lookup_as_dir(uint32_t version, const char *query, const char **desc_out); const hs_descriptor_t * -hs_cache_lookup_as_client(const ed25519_public_key_t *key); +hs_cache_lookup_as_client(const struct ed25519_public_key_t *key); const char * -hs_cache_lookup_encoded_as_client(const ed25519_public_key_t *key); +hs_cache_lookup_encoded_as_client(const struct ed25519_public_key_t *key); int hs_cache_store_as_client(const char *desc_str, - const ed25519_public_key_t *identity_pk); + const struct ed25519_public_key_t *identity_pk); void hs_cache_clean_as_client(time_t now); void hs_cache_purge_as_client(void); /* Client failure cache. */ -void hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk, - const ed25519_public_key_t *auth_key, - rend_intro_point_failure_t failure); +void hs_cache_client_intro_state_note( + const struct ed25519_public_key_t *service_pk, + const struct ed25519_public_key_t *auth_key, + rend_intro_point_failure_t failure); const hs_cache_intro_state_t *hs_cache_client_intro_state_find( - const ed25519_public_key_t *service_pk, - const ed25519_public_key_t *auth_key); + const struct ed25519_public_key_t *service_pk, + const struct ed25519_public_key_t *auth_key); void hs_cache_client_intro_state_clean(time_t now); void hs_cache_client_intro_state_purge(void); #ifdef HS_CACHE_PRIVATE +#include "lib/crypt_ops/crypto_ed25519.h" /** Represents a locally cached HS descriptor on a hidden service client. */ typedef struct hs_cache_client_descriptor_t { /* This object is indexed using the service identity public key */ - ed25519_public_key_t key; + struct ed25519_public_key_t key; /* When will this entry expire? We expire cached client descriptors in the * start of the next time period, since that's when clients need to start @@ -125,4 +128,3 @@ lookup_v3_desc_as_client(const uint8_t *key); #endif /* defined(HS_CACHE_PRIVATE) */ #endif /* !defined(TOR_HS_CACHE_H) */ - diff --git a/src/or/hs_cell.c b/src/or/hs_cell.c index 03273a44f9..b50c87dfa3 100644 --- a/src/or/hs_cell.c +++ b/src/or/hs_cell.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -6,22 +6,24 @@ * \brief Hidden service API for cell creation and handling. **/ -#include "or.h" -#include "config.h" -#include "crypto_util.h" -#include "rendservice.h" -#include "replaycache.h" -#include "util.h" +#include "or/or.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/rendservice.h" +#include "or/replaycache.h" +#include "common/util.h" -#include "hs_cell.h" -#include "hs_ntor.h" +#include "or/hs_cell.h" +#include "or/hs_ntor.h" + +#include "or/origin_circuit_st.h" /* Trunnel. */ -#include "ed25519_cert.h" -#include "hs/cell_common.h" -#include "hs/cell_establish_intro.h" -#include "hs/cell_introduce1.h" -#include "hs/cell_rendezvous.h" +#include "trunnel/ed25519_cert.h" +#include "trunnel/hs/cell_common.h" +#include "trunnel/hs/cell_establish_intro.h" +#include "trunnel/hs/cell_introduce1.h" +#include "trunnel/hs/cell_rendezvous.h" /* Compute the MAC of an INTRODUCE cell in mac_out. The encoded_cell param is * the cell content up to the ENCRYPTED section of length encoded_cell_len. diff --git a/src/or/hs_cell.h b/src/or/hs_cell.h index 958dde4ffc..4a522810c6 100644 --- a/src/or/hs_cell.h +++ b/src/or/hs_cell.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,8 +9,8 @@ #ifndef TOR_HS_CELL_H #define TOR_HS_CELL_H -#include "or.h" -#include "hs_service.h" +#include "or/or.h" +#include "or/hs_service.h" /* An INTRODUCE1 cell requires at least this amount of bytes (see section * 3.2.2 of the specification). Below this value, the cell must be padded. */ diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c index a35d2af8ba..5a2c7e4e42 100644 --- a/src/or/hs_circuit.c +++ b/src/or/hs_circuit.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -7,31 +7,38 @@ #define HS_CIRCUIT_PRIVATE -#include "or.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "nodelist.h" -#include "policies.h" -#include "relay.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" - -#include "hs_cell.h" -#include "hs_ident.h" -#include "hs_ntor.h" -#include "hs_service.h" -#include "hs_circuit.h" +#include "or/or.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/relay.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" + +#include "or/hs_cell.h" +#include "or/hs_circuitmap.h" +#include "or/hs_ident.h" +#include "or/hs_ntor.h" +#include "or/hs_service.h" +#include "or/hs_circuit.h" /* Trunnel. */ -#include "ed25519_cert.h" -#include "hs/cell_common.h" -#include "hs/cell_establish_intro.h" +#include "trunnel/ed25519_cert.h" +#include "trunnel/hs/cell_common.h" +#include "trunnel/hs/cell_establish_intro.h" + +#include "or/cpath_build_state_st.h" +#include "or/crypt_path_st.h" +#include "or/node_st.h" +#include "or/origin_circuit_st.h" /* A circuit is about to become an e2e rendezvous circuit. Check * <b>circ_purpose</b> and ensure that it's properly set. Return true iff @@ -97,7 +104,8 @@ create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len, /* We are a v2 legacy HS client: Create and return a crypt path for the hidden * service on the other side of the rendezvous circuit <b>circ</b>. Initialize * the crypt path crypto using the body of the RENDEZVOUS1 cell at - * <b>rend_cell_body</b> (which must be at least DH_KEY_LEN+DIGEST_LEN bytes). + * <b>rend_cell_body</b> (which must be at least DH1024_KEY_LEN+DIGEST_LEN + * bytes). */ static crypt_path_t * create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body) @@ -105,7 +113,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body) crypt_path_t *hop = NULL; char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN]; - /* first DH_KEY_LEN bytes are g^y from the service. Finish the dh + /* first DH1024_KEY_LEN bytes are g^y from the service. Finish the dh * handshake...*/ tor_assert(circ->build_state); tor_assert(circ->build_state->pending_final_cpath); @@ -113,7 +121,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body) tor_assert(hop->rend_dh_handshake_state); if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->rend_dh_handshake_state, - (char*)rend_cell_body, DH_KEY_LEN, + (char*)rend_cell_body, DH1024_KEY_LEN, keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) { log_warn(LD_GENERAL, "Couldn't complete DH handshake."); goto err; @@ -125,7 +133,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body) goto err; /* Check whether the digest is right... */ - if (tor_memneq(keys, rend_cell_body+DH_KEY_LEN, DIGEST_LEN)) { + if (tor_memneq(keys, rend_cell_body+DH1024_KEY_LEN, DIGEST_LEN)) { log_warn(LD_PROTOCOL, "Incorrect digest of key material."); goto err; } @@ -1239,4 +1247,3 @@ hs_circ_cleanup(circuit_t *circ) hs_circuitmap_remove_circuit(circ); } } - diff --git a/src/or/hs_circuit.h b/src/or/hs_circuit.h index f69137e1d5..425070f4ca 100644 --- a/src/or/hs_circuit.h +++ b/src/or/hs_circuit.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,10 +9,10 @@ #ifndef TOR_HS_CIRCUIT_H #define TOR_HS_CIRCUIT_H -#include "or.h" -#include "crypto_ed25519.h" +#include "or/or.h" +#include "lib/crypt_ops/crypto_ed25519.h" -#include "hs_service.h" +#include "or/hs_service.h" /* Cleanup function when the circuit is closed or/and freed. */ void hs_circ_cleanup(circuit_t *circ); diff --git a/src/or/hs_circuitmap.c b/src/or/hs_circuitmap.c index 112c8bdced..c4bf9fab43 100644 --- a/src/or/hs_circuitmap.c +++ b/src/or/hs_circuitmap.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,10 +13,13 @@ #define HS_CIRCUITMAP_PRIVATE -#include "or.h" -#include "config.h" -#include "circuitlist.h" -#include "hs_circuitmap.h" +#include "or/or.h" +#include "or/config.h" +#include "or/circuitlist.h" +#include "or/hs_circuitmap.h" + +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" /************************** HS circuitmap code *******************************/ @@ -580,4 +583,3 @@ hs_circuitmap_free_all(void) tor_free(the_hs_circuitmap); } } - diff --git a/src/or/hs_circuitmap.h b/src/or/hs_circuitmap.h index 9e653480b5..c39a37c052 100644 --- a/src/or/hs_circuitmap.h +++ b/src/or/hs_circuitmap.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,7 +11,7 @@ typedef HT_HEAD(hs_circuitmap_ht, circuit_t) hs_circuitmap_ht; -typedef struct hs_token_s hs_token_t; +typedef struct hs_token_t hs_token_t; struct or_circuit_t; struct origin_circuit_t; @@ -90,7 +90,7 @@ typedef enum { /** Represents a token used in the HS protocol. Each such token maps to a * specific introduction or rendezvous circuit. */ -struct hs_token_s { +struct hs_token_t { /* Type of HS token. */ hs_token_type_t type; @@ -110,4 +110,3 @@ hs_circuitmap_ht *get_hs_circuitmap(void); #endif /* TOR_UNIT_TESTS */ #endif /* !defined(TOR_HS_CIRCUITMAP_H) */ - diff --git a/src/or/hs_client.c b/src/or/hs_client.c index b39bb2cad0..cc461e368d 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -8,32 +8,39 @@ #define HS_CLIENT_PRIVATE -#include "or.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "container.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "hs_cache.h" -#include "hs_cell.h" -#include "hs_circuit.h" -#include "hs_client.h" -#include "hs_control.h" -#include "hs_descriptor.h" -#include "hs_ident.h" -#include "hs_ntor.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "reasons.h" -#include "rendclient.h" -#include "router.h" -#include "routerset.h" +#include "or/or.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/hs_cache.h" +#include "or/hs_cell.h" +#include "or/hs_circuit.h" +#include "or/hs_circuitmap.h" +#include "or/hs_client.h" +#include "or/hs_control.h" +#include "or/hs_descriptor.h" +#include "or/hs_ident.h" +#include "or/hs_ntor.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/reasons.h" +#include "or/rendclient.h" +#include "or/router.h" +#include "or/routerset.h" + +#include "or/cpath_build_state_st.h" +#include "or/dir_connection_st.h" +#include "or/entry_connection_st.h" +#include "or/extend_info_st.h" +#include "or/origin_circuit_st.h" /* Return a human-readable string for the client fetch status code. */ static const char * @@ -1614,4 +1621,3 @@ hs_client_dir_info_changed(void) * AP_CONN_STATE_RENDDESC_WAIT state in order to fetch the descriptor. */ retry_all_socks_conn_waiting_for_desc(); } - diff --git a/src/or/hs_client.h b/src/or/hs_client.h index 2523568ad1..8083910747 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,9 +9,9 @@ #ifndef TOR_HS_CLIENT_H #define TOR_HS_CLIENT_H -#include "crypto_ed25519.h" -#include "hs_descriptor.h" -#include "hs_ident.h" +#include "lib/crypt_ops/crypto_ed25519.h" +#include "or/hs_descriptor.h" +#include "or/hs_ident.h" /* Status code of a descriptor fetch request. */ typedef enum { diff --git a/src/or/hs_common.c b/src/or/hs_common.c index 5354055bb0..d91f45a639 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,30 +11,36 @@ #define HS_COMMON_PRIVATE -#include "or.h" - -#include "config.h" -#include "circuitbuild.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "hs_cache.h" -#include "hs_common.h" -#include "hs_client.h" -#include "hs_ident.h" -#include "hs_service.h" -#include "hs_circuitmap.h" -#include "policies.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "routerset.h" -#include "router.h" -#include "shared_random_client.h" -#include "dirauth/shared_random_state.h" +#include "or/or.h" + +#include "or/config.h" +#include "or/circuitbuild.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/hs_cache.h" +#include "or/hs_common.h" +#include "or/hs_client.h" +#include "or/hs_ident.h" +#include "or/hs_service.h" +#include "or/hs_circuitmap.h" +#include "or/policies.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/routerset.h" +#include "or/router.h" +#include "or/shared_random_client.h" +#include "or/dirauth/shared_random_state.h" + +#include "or/edge_connection_st.h" +#include "or/networkstatus_st.h" +#include "or/node_st.h" +#include "or/origin_circuit_st.h" +#include "or/routerstatus_st.h" /* Trunnel */ -#include "ed25519_cert.h" +#include "trunnel/ed25519_cert.h" /* Ed25519 Basepoint value. Taken from section 5 of * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03 */ @@ -1817,4 +1823,3 @@ hs_inc_rdv_stream_counter(origin_circuit_t *circ) tor_assert_nonfatal_unreached(); } } - diff --git a/src/or/hs_common.h b/src/or/hs_common.h index ef7d5dca2b..24f5f3a20f 100644 --- a/src/or/hs_common.h +++ b/src/or/hs_common.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,10 +9,15 @@ #ifndef TOR_HS_COMMON_H #define TOR_HS_COMMON_H -#include "or.h" +#include "or/or.h" +#include "lib/defs/x25519_sizes.h" + +struct curve25519_public_key_t; +struct ed25519_public_key_t; +struct ed25519_keypair_t; /* Trunnel */ -#include "ed25519_cert.h" +#include "trunnel/ed25519_cert.h" /* Protocol version 2. Use this instead of hardcoding "2" in the code base, * this adds a clearer semantic to the value when used. */ @@ -122,7 +127,7 @@ * bigger than the 84 bytes needed for version 3 so we need to pad up to that * length so it is indistinguishable between versions. */ #define HS_LEGACY_RENDEZVOUS_CELL_SIZE \ - (REND_COOKIE_LEN + DH_KEY_LEN + DIGEST_LEN) + (REND_COOKIE_LEN + DH1024_KEY_LEN + DIGEST_LEN) /* Type of authentication key used by an introduction point. */ typedef enum { @@ -167,20 +172,20 @@ int hs_check_service_private_dir(const char *username, const char *path, int hs_get_service_max_rend_failures(void); char *hs_path_from_filename(const char *directory, const char *filename); -void hs_build_address(const ed25519_public_key_t *key, uint8_t version, +void hs_build_address(const struct ed25519_public_key_t *key, uint8_t version, char *addr_out); int hs_address_is_valid(const char *address); -int hs_parse_address(const char *address, ed25519_public_key_t *key_out, +int hs_parse_address(const char *address, struct ed25519_public_key_t *key_out, uint8_t *checksum_out, uint8_t *version_out); -void hs_build_blinded_pubkey(const ed25519_public_key_t *pubkey, +void hs_build_blinded_pubkey(const struct ed25519_public_key_t *pubkey, const uint8_t *secret, size_t secret_len, uint64_t time_period_num, - ed25519_public_key_t *pubkey_out); -void hs_build_blinded_keypair(const ed25519_keypair_t *kp, + struct ed25519_public_key_t *pubkey_out); +void hs_build_blinded_keypair(const struct ed25519_keypair_t *kp, const uint8_t *secret, size_t secret_len, uint64_t time_period_num, - ed25519_keypair_t *kp_out); + struct ed25519_keypair_t *kp_out); int hs_service_requires_uptime_circ(const smartlist_t *ports); void rend_data_free_(rend_data_t *data); @@ -203,8 +208,8 @@ const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data, routerstatus_t *pick_hsdir(const char *desc_id, const char *desc_id_base32); -void hs_get_subcredential(const ed25519_public_key_t *identity_pk, - const ed25519_public_key_t *blinded_pk, +void hs_get_subcredential(const struct ed25519_public_key_t *identity_pk, + const struct ed25519_public_key_t *blinded_pk, uint8_t *subcred_out); uint64_t hs_get_previous_time_period_num(time_t now); @@ -222,18 +227,18 @@ uint8_t *hs_get_current_srv(uint64_t time_period_num, uint8_t *hs_get_previous_srv(uint64_t time_period_num, const networkstatus_t *ns); -void hs_build_hsdir_index(const ed25519_public_key_t *identity_pk, +void hs_build_hsdir_index(const struct ed25519_public_key_t *identity_pk, const uint8_t *srv, uint64_t period_num, uint8_t *hsdir_index_out); void hs_build_hs_index(uint64_t replica, - const ed25519_public_key_t *blinded_pk, + const struct ed25519_public_key_t *blinded_pk, uint64_t period_num, uint8_t *hs_index_out); int32_t hs_get_hsdir_n_replicas(void); int32_t hs_get_hsdir_spread_fetch(void); int32_t hs_get_hsdir_spread_store(void); -void hs_get_responsible_hsdirs(const ed25519_public_key_t *blinded_pk, +void hs_get_responsible_hsdirs(const struct ed25519_public_key_t *blinded_pk, uint64_t time_period_num, int use_second_hsdir_index, int for_fetching, smartlist_t *responsible_dirs); @@ -254,8 +259,8 @@ void hs_inc_rdv_stream_counter(origin_circuit_t *circ); void hs_dec_rdv_stream_counter(origin_circuit_t *circ); extend_info_t *hs_get_extend_info_from_lspecs(const smartlist_t *lspecs, - const curve25519_public_key_t *onion_key, - int direct_conn); + const struct curve25519_public_key_t *onion_key, + int direct_conn); #ifdef HS_COMMON_PRIVATE @@ -281,4 +286,3 @@ STATIC uint8_t *get_second_cached_disaster_srv(void); #endif /* defined(HS_COMMON_PRIVATE) */ #endif /* !defined(TOR_HS_COMMON_H) */ - diff --git a/src/or/hs_config.c b/src/or/hs_config.c index be223503a0..cb55faa9d5 100644 --- a/src/or/hs_config.c +++ b/src/or/hs_config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,10 +25,12 @@ #define HS_CONFIG_PRIVATE -#include "hs_common.h" -#include "hs_config.h" -#include "hs_service.h" -#include "rendservice.h" +#include "or/hs_common.h" +#include "or/hs_config.h" +#include "or/hs_service.h" +#include "or/rendservice.h" +#include "lib/encoding/confline.h" +#include "or/or_options_st.h" /* Using the given list of services, stage them into our global state. Every * service version are handled. This function can remove entries in the given @@ -587,4 +589,3 @@ hs_config_service_all(const or_options_t *options, int validate_only) /* Tor main should call the free all function on error. */ return ret; } - diff --git a/src/or/hs_config.h b/src/or/hs_config.h index 6cd7aed460..461d58d384 100644 --- a/src/or/hs_config.h +++ b/src/or/hs_config.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,7 +9,7 @@ #ifndef TOR_HS_CONFIG_H #define TOR_HS_CONFIG_H -#include "or.h" +#include "or/or.h" /* Max value for HiddenServiceMaxStreams */ #define HS_CONFIG_MAX_STREAMS_PER_RDV_CIRCUIT 65535 diff --git a/src/or/hs_control.c b/src/or/hs_control.c index 6b9b95c6d8..be456e8da4 100644 --- a/src/or/hs_control.c +++ b/src/or/hs_control.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -6,14 +6,18 @@ * \brief Contains control port event related code. **/ -#include "or.h" -#include "control.h" -#include "crypto_util.h" -#include "hs_common.h" -#include "hs_control.h" -#include "hs_descriptor.h" -#include "hs_service.h" -#include "nodelist.h" +#include "or/or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/hs_common.h" +#include "or/hs_control.h" +#include "or/hs_descriptor.h" +#include "or/hs_service.h" +#include "or/nodelist.h" + +#include "or/node_st.h" +#include "or/routerstatus_st.h" /* Send on the control port the "HS_DESC REQUESTED [...]" event. * @@ -255,4 +259,3 @@ hs_control_hspost_command(const char *body, const char *onion_address, smartlist_free(hsdirs); return ret; } - diff --git a/src/or/hs_control.h b/src/or/hs_control.h index 95c46e655e..040ce4a793 100644 --- a/src/or/hs_control.h +++ b/src/or/hs_control.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,7 +9,7 @@ #ifndef TOR_HS_CONTROL_H #define TOR_HS_CONTROL_H -#include "hs_ident.h" +#include "or/hs_ident.h" /* Event "HS_DESC REQUESTED [...]" */ void hs_control_desc_event_requested(const ed25519_public_key_t *onion_pk, diff --git a/src/or/hs_descriptor.c b/src/or/hs_descriptor.c index 7ffa885ca8..5fd8971dc0 100644 --- a/src/or/hs_descriptor.c +++ b/src/or/hs_descriptor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -55,17 +55,21 @@ /* For unit tests.*/ #define HS_DESCRIPTOR_PRIVATE -#include "or.h" -#include "ed25519_cert.h" /* Trunnel interface. */ -#include "hs_descriptor.h" -#include "circuitbuild.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "parsecommon.h" -#include "rendcache.h" -#include "hs_cache.h" -#include "hs_config.h" -#include "torcert.h" /* tor_cert_encode_ed22519() */ +#include "or/or.h" +#include "trunnel/ed25519_cert.h" /* Trunnel interface. */ +#include "or/hs_descriptor.h" +#include "or/circuitbuild.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/parsecommon.h" +#include "or/rendcache.h" +#include "or/hs_cache.h" +#include "or/hs_config.h" +#include "or/torcert.h" /* tor_cert_encode_ed22519() */ +#include "lib/memarea/memarea.h" +#include "lib/crypt_ops/crypto_format.h" + +#include "or/extend_info_st.h" /* Constant string value used for the descriptor format. */ #define str_hs_desc "hs-descriptor" @@ -2605,4 +2609,3 @@ hs_desc_lspec_to_trunnel(const hs_desc_link_specifier_t *spec) return ls; } - diff --git a/src/or/hs_descriptor.h b/src/or/hs_descriptor.h index 8195c6efbc..7a4010cd3b 100644 --- a/src/or/hs_descriptor.h +++ b/src/or/hs_descriptor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,13 +11,9 @@ #include <stdint.h> -#include "or.h" -#include "address.h" -#include "container.h" -#include "crypto.h" -#include "crypto_ed25519.h" -#include "ed25519_cert.h" /* needed for trunnel */ -#include "torcert.h" +#include "or/or.h" +#include "trunnel/ed25519_cert.h" /* needed for trunnel */ +#include "or/torcert.h" /* Trunnel */ struct link_specifier_t; @@ -282,4 +278,3 @@ MOCK_DECL(STATIC size_t, decrypt_desc_layer,(const hs_descriptor_t *desc, #endif /* defined(HS_DESCRIPTOR_PRIVATE) */ #endif /* !defined(TOR_HS_DESCRIPTOR_H) */ - diff --git a/src/or/hs_ident.c b/src/or/hs_ident.c index 3603e329d4..20539ca878 100644 --- a/src/or/hs_ident.c +++ b/src/or/hs_ident.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -7,8 +7,8 @@ * subsytem. **/ -#include "crypto_util.h" -#include "hs_ident.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/hs_ident.h" /* Return a newly allocated circuit identifier. The given public key is copied * identity_pk into the identifier. */ diff --git a/src/or/hs_ident.h b/src/or/hs_ident.h index 8f9da30c35..8c53b9dbeb 100644 --- a/src/or/hs_ident.h +++ b/src/or/hs_ident.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,9 +21,9 @@ #ifndef TOR_HS_IDENT_H #define TOR_HS_IDENT_H -#include "crypto_ed25519.h" +#include "lib/crypt_ops/crypto_ed25519.h" -#include "hs_common.h" +#include "or/hs_common.h" /* Length of the rendezvous cookie that is used to connect circuits at the * rendezvous point. */ diff --git a/src/or/hs_intropoint.c b/src/or/hs_intropoint.c index 3274e8e9c0..2594058679 100644 --- a/src/or/hs_intropoint.c +++ b/src/or/hs_intropoint.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -8,24 +8,27 @@ #define HS_INTROPOINT_PRIVATE -#include "or.h" -#include "config.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "relay.h" -#include "rendmid.h" -#include "rephist.h" +#include "or/or.h" +#include "or/config.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/relay.h" +#include "or/rendmid.h" +#include "or/rephist.h" +#include "lib/crypt_ops/crypto_format.h" /* Trunnel */ -#include "ed25519_cert.h" -#include "hs/cell_common.h" -#include "hs/cell_establish_intro.h" -#include "hs/cell_introduce1.h" +#include "trunnel/ed25519_cert.h" +#include "trunnel/hs/cell_common.h" +#include "trunnel/hs/cell_establish_intro.h" +#include "trunnel/hs/cell_introduce1.h" -#include "hs_circuitmap.h" -#include "hs_descriptor.h" -#include "hs_intropoint.h" -#include "hs_common.h" +#include "or/hs_circuitmap.h" +#include "or/hs_descriptor.h" +#include "or/hs_intropoint.h" +#include "or/hs_common.h" + +#include "or/or_circuit_st.h" /** Extract the authentication key from an ESTABLISH_INTRO or INTRODUCE1 using * the given <b>cell_type</b> from <b>cell</b> and place it in @@ -609,4 +612,3 @@ hs_intropoint_clear(hs_intropoint_t *ip) smartlist_free(ip->link_specifiers); memset(ip, 0, sizeof(hs_intropoint_t)); } - diff --git a/src/or/hs_intropoint.h b/src/or/hs_intropoint.h index 749d1530e1..5f82920991 100644 --- a/src/or/hs_intropoint.h +++ b/src/or/hs_intropoint.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,8 +9,8 @@ #ifndef TOR_HS_INTRO_H #define TOR_HS_INTRO_H -#include "crypto_curve25519.h" -#include "torcert.h" +#include "lib/crypt_ops/crypto_curve25519.h" +#include "or/torcert.h" /* Authentication key type in an ESTABLISH_INTRO cell. */ typedef enum { @@ -55,8 +55,8 @@ void hs_intropoint_clear(hs_intropoint_t *ip); #ifdef HS_INTROPOINT_PRIVATE -#include "hs/cell_establish_intro.h" -#include "hs/cell_introduce1.h" +#include "trunnel/hs/cell_establish_intro.h" +#include "trunnel/hs/cell_introduce1.h" STATIC int verify_establish_intro_cell(const trn_cell_establish_intro_t *out, diff --git a/src/or/hs_ntor.c b/src/or/hs_ntor.c index 809fa83bb8..b5007545db 100644 --- a/src/or/hs_ntor.c +++ b/src/or/hs_ntor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** \file hs_ntor.c @@ -24,9 +24,11 @@ * rendezvous key expansion to setup end-to-end rend circuit keys. */ -#include "or.h" -#include "crypto_util.h" -#include "hs_ntor.h" +#include "or/or.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/crypt_ops/crypto_curve25519.h" +#include "lib/crypt_ops/crypto_ed25519.h" +#include "or/hs_ntor.h" /* String constants used by the ntor HS protocol */ #define PROTOID "tor-hs-ntor-curve25519-sha3-256-1" @@ -616,4 +618,3 @@ hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len, return 0; } - diff --git a/src/or/hs_ntor.h b/src/or/hs_ntor.h index 77e544a130..67a9573436 100644 --- a/src/or/hs_ntor.h +++ b/src/or/hs_ntor.h @@ -1,10 +1,13 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_HS_NTOR_H #define TOR_HS_NTOR_H -#include "or.h" +#include "or/or.h" +struct ed25519_public_key_t; +struct curve25519_public_key_t; +struct curve25519_keypair_t; /* Output length of KDF for key expansion */ #define HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN \ @@ -28,32 +31,32 @@ typedef struct { } hs_ntor_rend_cell_keys_t; int hs_ntor_client_get_introduce1_keys( - const ed25519_public_key_t *intro_auth_pubkey, - const curve25519_public_key_t *intro_enc_pubkey, - const curve25519_keypair_t *client_ephemeral_enc_keypair, - const uint8_t *subcredential, - hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out); + const struct ed25519_public_key_t *intro_auth_pubkey, + const struct curve25519_public_key_t *intro_enc_pubkey, + const struct curve25519_keypair_t *client_ephemeral_enc_keypair, + const uint8_t *subcredential, + hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out); int hs_ntor_client_get_rendezvous1_keys( - const ed25519_public_key_t *intro_auth_pubkey, - const curve25519_keypair_t *client_ephemeral_enc_keypair, - const curve25519_public_key_t *intro_enc_pubkey, - const curve25519_public_key_t *service_ephemeral_rend_pubkey, - hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out); + const struct ed25519_public_key_t *intro_auth_pubkey, + const struct curve25519_keypair_t *client_ephemeral_enc_keypair, + const struct curve25519_public_key_t *intro_enc_pubkey, + const struct curve25519_public_key_t *service_ephemeral_rend_pubkey, + hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out); int hs_ntor_service_get_introduce1_keys( - const ed25519_public_key_t *intro_auth_pubkey, - const curve25519_keypair_t *intro_enc_keypair, - const curve25519_public_key_t *client_ephemeral_enc_pubkey, - const uint8_t *subcredential, - hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out); + const struct ed25519_public_key_t *intro_auth_pubkey, + const struct curve25519_keypair_t *intro_enc_keypair, + const struct curve25519_public_key_t *client_ephemeral_enc_pubkey, + const uint8_t *subcredential, + hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out); int hs_ntor_service_get_rendezvous1_keys( - const ed25519_public_key_t *intro_auth_pubkey, - const curve25519_keypair_t *intro_enc_keypair, - const curve25519_keypair_t *service_ephemeral_rend_keypair, - const curve25519_public_key_t *client_ephemeral_enc_pubkey, - hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out); + const struct ed25519_public_key_t *intro_auth_pubkey, + const struct curve25519_keypair_t *intro_enc_keypair, + const struct curve25519_keypair_t *service_ephemeral_rend_keypair, + const struct curve25519_public_key_t *client_ephemeral_enc_pubkey, + hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out); int hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len, @@ -64,4 +67,3 @@ int hs_ntor_client_rendezvous2_mac_is_good( const uint8_t *rcvd_mac); #endif /* !defined(TOR_HS_NTOR_H) */ - diff --git a/src/or/hs_service.c b/src/or/hs_service.c index f1f26954ae..6cb01b57c9 100644 --- a/src/or/hs_service.c +++ b/src/or/hs_service.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -8,41 +8,60 @@ #define HS_SERVICE_PRIVATE -#include "or.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "relay.h" -#include "rendservice.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "shared_random_client.h" -#include "statefile.h" - -#include "hs_circuit.h" -#include "hs_common.h" -#include "hs_config.h" -#include "hs_control.h" -#include "hs_descriptor.h" -#include "hs_ident.h" -#include "hs_intropoint.h" -#include "hs_service.h" -#include "hs_stats.h" +#include "or/or.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/relay.h" +#include "or/rendservice.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/shared_random_client.h" +#include "or/statefile.h" + +#include "or/hs_circuit.h" +#include "or/hs_common.h" +#include "or/hs_config.h" +#include "or/hs_control.h" +#include "or/hs_descriptor.h" +#include "or/hs_ident.h" +#include "or/hs_intropoint.h" +#include "or/hs_service.h" +#include "or/hs_stats.h" + +#include "or/dir_connection_st.h" +#include "or/edge_connection_st.h" +#include "or/extend_info_st.h" +#include "or/networkstatus_st.h" +#include "or/node_st.h" +#include "or/origin_circuit_st.h" +#include "or/or_state_st.h" +#include "or/routerstatus_st.h" + +#include "lib/encoding/confline.h" +#include "lib/crypt_ops/crypto_format.h" /* Trunnel */ -#include "ed25519_cert.h" -#include "hs/cell_common.h" -#include "hs/cell_establish_intro.h" +#include "trunnel/ed25519_cert.h" +#include "trunnel/hs/cell_common.h" +#include "trunnel/hs/cell_establish_intro.h" + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* Helper macro. Iterate over every service in the global map. The var is the * name of the service pointer. */ @@ -3623,4 +3642,3 @@ get_first_service(void) } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/hs_service.h b/src/or/hs_service.h index 5494b6f5fa..4676042b54 100644 --- a/src/or/hs_service.h +++ b/src/or/hs_service.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,17 +9,17 @@ #ifndef TOR_HS_SERVICE_H #define TOR_HS_SERVICE_H -#include "crypto_curve25519.h" -#include "crypto_ed25519.h" -#include "replaycache.h" +#include "lib/crypt_ops/crypto_curve25519.h" +#include "lib/crypt_ops/crypto_ed25519.h" +#include "or/replaycache.h" -#include "hs_common.h" -#include "hs_descriptor.h" -#include "hs_ident.h" -#include "hs_intropoint.h" +#include "or/hs_common.h" +#include "or/hs_descriptor.h" +#include "or/hs_ident.h" +#include "or/hs_intropoint.h" /* Trunnel */ -#include "hs/cell_establish_intro.h" +#include "trunnel/hs/cell_establish_intro.h" /* When loading and configuring a service, this is the default version it will * be configured for as it is possible that no HiddenServiceVersion is diff --git a/src/or/hs_stats.c b/src/or/hs_stats.c index 1e2a96945b..c8a99b19d4 100644 --- a/src/or/hs_stats.c +++ b/src/or/hs_stats.c @@ -6,9 +6,9 @@ * \brief Keeps stats about the activity of our onion service(s). **/ -#include "or.h" -#include "hs_stats.h" -#include "hs_service.h" +#include "or/or.h" +#include "or/hs_stats.h" +#include "or/hs_service.h" /** Number of v3 INTRODUCE2 cells received */ static uint32_t n_introduce2_v3 = 0; diff --git a/src/or/hsdir_index_st.h b/src/or/hsdir_index_st.h new file mode 100644 index 0000000000..de5cc9bd16 --- /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-2018, 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 59d593a5e9..9b5f7c1f60 100644 --- a/src/or/include.am +++ b/src/or/include.am @@ -1,9 +1,9 @@ bin_PROGRAMS+= src/or/tor noinst_LIBRARIES += \ - src/or/libtor.a + src/or/libtor-app.a if UNITTESTS_ENABLED noinst_LIBRARIES += \ - src/or/libtor-testing.a + src/or/libtor-app-testing.a endif if COVERAGE_ENABLED noinst_PROGRAMS+= src/or/tor-cov @@ -17,7 +17,7 @@ endif EXTRA_DIST+= src/or/ntmain.c src/or/Makefile.nmake -LIBTOR_A_SOURCES = \ +LIBTOR_APP_A_SOURCES = \ src/or/addressmap.c \ src/or/bridges.c \ src/or/channel.c \ @@ -75,7 +75,7 @@ LIBTOR_A_SOURCES = \ src/or/onion_fast.c \ src/or/onion_tap.c \ src/or/transports.c \ - src/or/parsecommon.c \ + src/or/parsecommon.c \ src/or/periodic.c \ src/or/protover.c \ src/or/protover_rust.c \ @@ -118,7 +118,7 @@ LIBTOR_A_SOURCES = \ # source files of every module to libtor-testing.a so we can build the unit # tests for everything. See the UNITTESTS_ENABLED branch below. # -LIBTOR_TESTING_A_SOURCES = $(LIBTOR_A_SOURCES) +LIBTOR_APP_TESTING_A_SOURCES = $(LIBTOR_APP_A_SOURCES) # The Directory Authority module. MODULE_DIRAUTH_SOURCES = \ @@ -127,32 +127,31 @@ MODULE_DIRAUTH_SOURCES = \ src/or/dirauth/shared_random.c \ src/or/dirauth/shared_random_state.c if BUILD_MODULE_DIRAUTH -LIBTOR_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) +LIBTOR_APP_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) endif -src_or_libtor_a_SOURCES = $(LIBTOR_A_SOURCES) +src_or_libtor_app_a_SOURCES = $(LIBTOR_APP_A_SOURCES) if UNITTESTS_ENABLED # Add the sources of the modules that are needed for tests to work here. -LIBTOR_TESTING_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) +LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) -src_or_libtor_testing_a_SOURCES = $(LIBTOR_TESTING_A_SOURCES) +src_or_libtor_app_testing_a_SOURCES = $(LIBTOR_APP_TESTING_A_SOURCES) else -src_or_libtor_testing_a_SOURCES = +src_or_libtor_app_testing_a_SOURCES = endif src_or_tor_SOURCES = src/or/tor_main.c -AM_CPPFLAGS += -I$(srcdir)/src/or -Isrc/or -src/or/tor_main.$(OBJEXT) \ - src/or/src_or_tor_cov-tor_main.$(OBJEXT): micro-revision.i +src/or/git_revision.$(OBJEXT) \ + src/or/src_or_libtor_app_testing_a-git_revision.$(OBJEXT): micro-revision.i AM_CPPFLAGS += -DSHARE_DATADIR="\"$(datadir)\"" \ -DLOCALSTATEDIR="\"$(localstatedir)\"" \ -DBINDIR="\"$(bindir)\"" -src_or_libtor_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS) -src_or_libtor_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) +src_or_libtor_app_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS) +src_or_libtor_app_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) # -L flags need to go in LDFLAGS. -l flags need to go in LDADD. # This seems to matter nowhere but on windows, but I assure you that it @@ -160,13 +159,10 @@ src_or_libtor_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) src_or_tor_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@ -src_or_tor_LDADD = src/or/libtor.a src/common/libor.a src/common/libor-ctime.a \ - src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \ - src/common/libor-event.a src/trunnel/libor-trunnel.a \ - src/trace/libor-trace.a \ +src_or_tor_LDADD = $(TOR_INTERNAL_LIBS) \ $(rust_ldadd) \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \ + @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ \ @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@ @@ -175,19 +171,21 @@ src_or_tor_cov_SOURCES = src/or/tor_main.c src_or_tor_cov_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS) src_or_tor_cov_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) src_or_tor_cov_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@ -src_or_tor_cov_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ - src/common/libor-ctime-testing.a \ - src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \ - src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \ +src_or_tor_cov_LDADD = $(TOR_INTERNAL_TESTING_LIBS) \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ \ + @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ \ + @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ \ @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@ endif ORHEADERS = \ src/or/addressmap.h \ + src/or/addr_policy_st.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 \ @@ -198,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 \ @@ -236,20 +252,36 @@ 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/or_options_st.h \ + src/or/or_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 \ @@ -260,25 +292,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/keypin.c b/src/or/keypin.c index 97e16c1f78..34cf64f5c4 100644 --- a/src/or/keypin.c +++ b/src/or/keypin.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,17 +11,17 @@ #define KEYPIN_PRIVATE #include "orconfig.h" -#include "compat.h" -#include "crypto_digest.h" -#include "crypto_format.h" -#include "di_ops.h" +#include "lib/crypt_ops/crypto_digest.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/ctime/di_ops.h" #include "ht.h" -#include "keypin.h" +#include "or/keypin.h" #include "siphash.h" -#include "torint.h" -#include "torlog.h" -#include "util.h" -#include "util_format.h" +#include "lib/cc/torint.h" +#include "lib/log/torlog.h" +#include "lib/fdio/fdio.h" +#include "common/util.h" +#include "lib/encoding/binascii.h" #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -308,7 +308,7 @@ keypin_open_journal(const char *fname) char tbuf[ISO_TIME_LEN+1]; format_iso_time(tbuf, approx_time()); tor_snprintf(buf, sizeof(buf), "@opened-at %s\n", tbuf); - if (write_all(fd, buf, strlen(buf), 0) < 0) + if (write_all_to_fd(fd, buf, strlen(buf)) < 0) goto err; keypin_journal_fd = fd; @@ -347,7 +347,7 @@ keypin_journal_append_entry(const uint8_t *rsa_id_digest, (const char*)ed25519_id_key); line[BASE64_DIGEST_LEN+1+BASE64_DIGEST256_LEN] = '\n'; - if (write_all(keypin_journal_fd, line, JOURNAL_LINE_LEN, 0)<0) { + if (write_all_to_fd(keypin_journal_fd, line, JOURNAL_LINE_LEN)<0) { log_warn(LD_DIRSERV, "Error while adding a line to the key-pinning " "journal: %s", strerror(errno)); keypin_close_journal(); @@ -498,4 +498,3 @@ keypin_clear(void) bad_entries); } } - diff --git a/src/or/keypin.h b/src/or/keypin.h index fbb77e5c35..73a76be563 100644 --- a/src/or/keypin.h +++ b/src/or/keypin.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_KEYPIN_H #define TOR_KEYPIN_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" int keypin_check_and_add(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key, diff --git a/src/or/listener_connection_st.h b/src/or/listener_connection_st.h new file mode 100644 index 0000000000..7b5aafcb58 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef LISTENER_CONNECTION_ST_H +#define LISTENER_CONNECTION_ST_H + +#include "or/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..408d9cf77c 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -47,80 +47,98 @@ **/ #define MAIN_PRIVATE -#include "or.h" -#include "addressmap.h" -#include "backtrace.h" -#include "bridges.h" -#include "buffers.h" -#include "buffers_tls.h" -#include "channel.h" -#include "channeltls.h" -#include "channelpadding.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "circuitmux_ewma.h" -#include "command.h" -#include "compress.h" -#include "config.h" -#include "confparse.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "consdiffmgr.h" -#include "control.h" -#include "cpuworker.h" -#include "crypto_s2k.h" -#include "crypto_rand.h" -#include "directory.h" -#include "dirserv.h" -#include "dns.h" -#include "dnsserv.h" -#include "dos.h" -#include "entrynodes.h" -#include "geoip.h" -#include "hibernate.h" -#include "hs_cache.h" -#include "hs_circuitmap.h" -#include "hs_client.h" -#include "keypin.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "ntmain.h" -#include "onion.h" -#include "periodic.h" -#include "policies.h" -#include "protover.h" -#include "transports.h" -#include "relay.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "routerparse.h" -#include "scheduler.h" -#include "statefile.h" -#include "status.h" -#include "tor_api.h" -#include "tor_api_internal.h" -#include "util_process.h" -#include "ext_orport.h" -#ifdef USE_DMALLOC -#include <dmalloc.h> -#endif -#include "memarea.h" -#include "sandbox.h" +#include "or/or.h" +#include "or/addressmap.h" +#include "lib/err/backtrace.h" +#include "or/bridges.h" +#include "lib/container/buffers.h" +#include "lib/tls/buffers_tls.h" +#include "or/channel.h" +#include "or/channeltls.h" +#include "or/channelpadding.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/circuitmux_ewma.h" +#include "or/command.h" +#include "lib/compress/compress.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/consdiffmgr.h" +#include "or/control.h" +#include "or/cpuworker.h" +#include "lib/crypt_ops/crypto_s2k.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/dns.h" +#include "or/dnsserv.h" +#include "or/dos.h" +#include "or/entrynodes.h" +#include "or/geoip.h" +#include "or/hibernate.h" +#include "or/hs_cache.h" +#include "or/hs_circuitmap.h" +#include "or/hs_client.h" +#include "or/keypin.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/ntmain.h" +#include "or/onion.h" +#include "or/periodic.h" +#include "or/policies.h" +#include "or/protover.h" +#include "or/transports.h" +#include "or/relay.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/scheduler.h" +#include "or/statefile.h" +#include "or/status.h" +#include "or/tor_api.h" +#include "or/tor_api_internal.h" +#include "lib/process/waitpid.h" +#include "or/ext_orport.h" +#include "lib/memarea/memarea.h" +#include "lib/meminfo/meminfo.h" +#include "lib/osinfo/uname.h" +#include "lib/sandbox/sandbox.h" +#include "lib/fs/lockfile.h" +#include "lib/net/buffers_net.h" +#include "lib/tls/tortls.h" +#include "common/compat_libevent.h" +#include "lib/encoding/confline.h" +#include "common/timers.h" #include <event2/event.h> -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" -#include "dirauth/shared_random.h" +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" +#include "or/dirauth/shared_random.h" + +#include "or/cell_st.h" +#include "or/entry_connection_st.h" +#include "or/networkstatus_st.h" +#include "or/or_connection_st.h" +#include "or/or_state_st.h" +#include "or/port_cfg_st.h" +#include "or/routerinfo_st.h" +#include "or/socks_request_st.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #ifdef HAVE_SYSTEMD # if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) @@ -1262,9 +1280,9 @@ run_connection_housekeeping(int i, time_t now) } else if (!have_any_circuits && now - or_conn->idle_timeout >= chan->timestamp_last_had_circuits) { - log_info(LD_OR,"Expiring non-used OR connection "U64_FORMAT" to fd %d " + log_info(LD_OR,"Expiring non-used OR connection %"PRIu64" to fd %d " "(%s:%d) [no circuits for %d; timeout %d; %scanonical].", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), (int)conn->s, conn->address, conn->port, (int)(now - chan->timestamp_last_had_circuits), or_conn->idle_timeout, @@ -2687,11 +2705,6 @@ do_hup(void) { const or_options_t *options = get_options(); -#ifdef USE_DMALLOC - dmalloc_log_stats(); - dmalloc_log_changed(0, 1, 0, 0); -#endif - log_notice(LD_GENERAL,"Received reload signal (hup). Reloading config and " "resetting internal state."); if (accounting_is_enabled(options)) @@ -3195,8 +3208,8 @@ static void dumpmemusage(int severity) { connection_dump_buffer_mem_stats(severity); - tor_log(severity, LD_GENERAL, "In rephist: "U64_FORMAT" used by %d Tors.", - U64_PRINTF_ARG(rephist_total_alloc), rephist_total_num); + tor_log(severity, LD_GENERAL, "In rephist: %"PRIu64" used by %d Tors.", + (rephist_total_alloc), rephist_total_num); dump_routerlist_mem_usage(severity); dump_cell_pool_usage(severity); dump_dns_mem_usage(severity); @@ -3259,28 +3272,28 @@ dumpstats(int severity) channel_listener_dumpstats(severity); tor_log(severity, LD_NET, - "Cells processed: "U64_FORMAT" padding\n" - " "U64_FORMAT" create\n" - " "U64_FORMAT" created\n" - " "U64_FORMAT" relay\n" - " ("U64_FORMAT" relayed)\n" - " ("U64_FORMAT" delivered)\n" - " "U64_FORMAT" destroy", - U64_PRINTF_ARG(stats_n_padding_cells_processed), - U64_PRINTF_ARG(stats_n_create_cells_processed), - U64_PRINTF_ARG(stats_n_created_cells_processed), - U64_PRINTF_ARG(stats_n_relay_cells_processed), - U64_PRINTF_ARG(stats_n_relay_cells_relayed), - U64_PRINTF_ARG(stats_n_relay_cells_delivered), - U64_PRINTF_ARG(stats_n_destroy_cells_processed)); + "Cells processed: %"PRIu64" padding\n" + " %"PRIu64" create\n" + " %"PRIu64" created\n" + " %"PRIu64" relay\n" + " (%"PRIu64" relayed)\n" + " (%"PRIu64" delivered)\n" + " %"PRIu64" destroy", + (stats_n_padding_cells_processed), + (stats_n_create_cells_processed), + (stats_n_created_cells_processed), + (stats_n_relay_cells_processed), + (stats_n_relay_cells_relayed), + (stats_n_relay_cells_delivered), + (stats_n_destroy_cells_processed)); if (stats_n_data_cells_packaged) tor_log(severity,LD_NET,"Average packaged cell fullness: %2.3f%%", - 100*(U64_TO_DBL(stats_n_data_bytes_packaged) / - U64_TO_DBL(stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)) ); + 100*(((double)stats_n_data_bytes_packaged) / + ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)) ); if (stats_n_data_cells_received) tor_log(severity,LD_NET,"Average delivered cell fullness: %2.3f%%", - 100*(U64_TO_DBL(stats_n_data_bytes_received) / - U64_TO_DBL(stats_n_data_cells_received*RELAY_PAYLOAD_SIZE)) ); + 100*(((double)stats_n_data_bytes_received) / + ((double)stats_n_data_cells_received*RELAY_PAYLOAD_SIZE)) ); cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_TAP, "TAP"); cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_NTOR,"ntor"); @@ -3292,13 +3305,13 @@ dumpstats(int severity) if (elapsed) { tor_log(severity, LD_NET, - "Average bandwidth: "U64_FORMAT"/%d = %d bytes/sec reading", - U64_PRINTF_ARG(stats_n_bytes_read), + "Average bandwidth: %"PRIu64"/%d = %d bytes/sec reading", + (stats_n_bytes_read), (int)elapsed, (int) (stats_n_bytes_read/elapsed)); tor_log(severity, LD_NET, - "Average bandwidth: "U64_FORMAT"/%d = %d bytes/sec writing", - U64_PRINTF_ARG(stats_n_bytes_written), + "Average bandwidth: %"PRIu64"/%d = %d bytes/sec writing", + (stats_n_bytes_written), (int)elapsed, (int) (stats_n_bytes_written/elapsed)); } @@ -3631,7 +3644,7 @@ release_lockfile(void) * only the parts of memory that we won't touch. If !<b>postfork</b>, * Tor is shutting down and we should free everything. * - * Helps us find the real leaks with dmalloc and the like. Also valgrind + * Helps us find the real leaks with sanitizers and the like. Also valgrind * should then report 0 reachable in its leak report (in an ideal world -- * in practice libevent, SSL, libc etc never quite free everything). */ void @@ -3787,18 +3800,11 @@ tor_cleanup(void) timers_shutdown(); -#ifdef USE_DMALLOC - dmalloc_log_stats(); -#endif tor_free_all(0); /* We could move tor_free_all back into the ifdef below later, if it makes shutdown unacceptably slow. But for now, leave it here: it's helped us catch bugs in the past. */ crypto_global_cleanup(); -#ifdef USE_DMALLOC - dmalloc_log_unfreed(); - dmalloc_shutdown(); -#endif } /** Read/create keys as needed, and echo our fingerprint to stdout. */ @@ -4221,7 +4227,13 @@ tor_run_main(const tor_main_configuration_t *tor_cfg) } #endif /* defined(_WIN32) */ - configure_backtrace_handler(get_version()); + { + int bt_err = configure_backtrace_handler(get_version()); + if (bt_err < 0) { + log_warn(LD_BUG, "Unable to install backtrace handler: %s", + strerror(-bt_err)); + } + } init_protocol_warning_severity_level(); update_approx_time(time(NULL)); @@ -4229,14 +4241,6 @@ tor_run_main(const tor_main_configuration_t *tor_cfg) tor_compress_init(); init_logging(0); monotime_init(); -#ifdef USE_DMALLOC - { - /* Instruct OpenSSL to use our internal wrappers for malloc, - realloc and free. */ - int r = crypto_use_tor_alloc_functions(); - tor_assert(r == 0); - } -#endif /* defined(USE_DMALLOC) */ #ifdef NT_SERVICE { int done = 0; @@ -4305,4 +4309,3 @@ tor_run_main(const tor_main_configuration_t *tor_cfg) tor_cleanup(); return result; } - diff --git a/src/or/main.h b/src/or/main.h index 9dbbc6e5ee..90146f4bd4 100644 --- a/src/or/main.h +++ b/src/or/main.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -96,10 +96,12 @@ uint64_t get_main_loop_idle_count(void); void periodic_events_on_new_options(const or_options_t *options); void reschedule_per_second_timer(void); +struct token_bucket_rw_t; + extern time_t time_of_process_start; extern int quiet_level; -extern token_bucket_rw_t global_bucket; -extern token_bucket_rw_t global_relayed_bucket; +extern struct token_bucket_rw_t global_bucket; +extern struct token_bucket_rw_t global_relayed_bucket; #ifdef MAIN_PRIVATE STATIC void init_connection_lists(void); @@ -112,10 +114,9 @@ STATIC int get_my_roles(const or_options_t *options); extern smartlist_t *connection_array; /* We need the periodic_event_item_t definition. */ -#include "periodic.h" +#include "or/periodic.h" extern periodic_event_item_t periodic_events[]; #endif #endif /* defined(MAIN_PRIVATE) */ #endif /* !defined(TOR_MAIN_H) */ - diff --git a/src/or/microdesc.c b/src/or/microdesc.c index b4a934e095..95c5e8b6f7 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2017, The Tor Project, Inc. */ +/* Copyright (c) 2009-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -8,19 +8,34 @@ * less-frequently-changing router information. */ -#include "or.h" -#include "circuitbuild.h" -#include "config.h" -#include "directory.h" -#include "dirserv.h" -#include "entrynodes.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" +#include "or/or.h" + +#include "lib/fdio/fdio.h" + +#include "or/circuitbuild.h" +#include "or/config.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/entrynodes.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" + +#include "or/microdesc_st.h" +#include "or/networkstatus_st.h" +#include "or/node_st.h" +#include "or/routerstatus_st.h" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif /** 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 @@ -189,7 +204,7 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out) char annotation[ISO_TIME_LEN+32]; format_iso_time(buf, md->last_listed); tor_snprintf(annotation, sizeof(annotation), "@last-listed %s\n", buf); - if (write_all(fd, annotation, strlen(annotation), 0) < 0) { + if (write_all_to_fd(fd, annotation, strlen(annotation)) < 0) { log_warn(LD_DIR, "Couldn't write microdescriptor annotation: %s", strerror(errno)); @@ -202,7 +217,7 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out) } md->off = tor_fd_getpos(fd); - written = write_all(fd, md->body, md->bodylen, 0); + written = write_all_to_fd(fd, md->body, md->bodylen); if (written != (ssize_t)md->bodylen) { written = written < 0 ? 0 : written; log_warn(LD_DIR, @@ -706,9 +721,9 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force) off_real = tor_fd_getpos(fd); if (off_real != off) { log_warn(LD_BUG, "Discontinuity in position in microdescriptor cache." - "By my count, I'm at "I64_FORMAT - ", but I should be at "I64_FORMAT, - I64_PRINTF_ARG(off), I64_PRINTF_ARG(off_real)); + "By my count, I'm at %"PRId64 + ", but I should be at %"PRId64, + (off), (off_real)); if (off_real >= 0) off = off_real; } @@ -1042,4 +1057,3 @@ usable_consensus_flavor,(void)) return FLAV_NS; } } - diff --git a/src/or/microdesc.h b/src/or/microdesc.h index 83a90bd8ff..f11b841cf1 100644 --- a/src/or/microdesc.h +++ b/src/or/microdesc.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/microdesc_st.h b/src/or/microdesc_st.h new file mode 100644 index 0000000000..e9dc3e0174 --- /dev/null +++ b/src/or/microdesc_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef MICRODESC_ST_H +#define MICRODESC_ST_H + +struct curve25519_public_key_t; +struct ed25519_public_key_t; +struct 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. */ +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 <b>bodylen</b>. */ + char *body; + /** The length of the microdescriptor in <b>body</b>. */ + 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 */ + struct curve25519_public_key_t *onion_curve25519_pkey; + /** Ed25519 identity key, if included. */ + struct 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 */ + struct short_policy_t *exit_policy; + /** IPv6 exit policy summary */ + struct short_policy_t *ipv6_exit_policy; +}; + +#endif diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 998eaf74e6..f91e46cdd7 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -37,42 +37,60 @@ */ #define NETWORKSTATUS_PRIVATE -#include "or.h" -#include "bridges.h" -#include "channel.h" -#include "circuitmux.h" -#include "circuitmux_ewma.h" -#include "circuitstats.h" -#include "config.h" -#include "connection.h" -#include "connection_or.h" -#include "consdiffmgr.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "dirserv.h" -#include "dos.h" -#include "entrynodes.h" -#include "hibernate.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "protover.h" -#include "relay.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "scheduler.h" -#include "transports.h" -#include "torcert.h" -#include "channelpadding.h" -#include "voting_schedule.h" - -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" -#include "dirauth/shared_random.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/channel.h" +#include "or/circuitmux.h" +#include "or/circuitmux_ewma.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/consdiffmgr.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/dos.h" +#include "or/entrynodes.h" +#include "or/hibernate.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/protover.h" +#include "or/relay.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/scheduler.h" +#include "or/transports.h" +#include "or/torcert.h" +#include "or/channelpadding.h" +#include "or/voting_schedule.h" + +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" +#include "or/dirauth/shared_random.h" + +#include "or/authority_cert_st.h" +#include "or/dir_connection_st.h" +#include "or/dir_server_st.h" +#include "or/document_signature_st.h" +#include "or/networkstatus_st.h" +#include "or/networkstatus_voter_info_st.h" +#include "or/ns_detached_signatures_st.h" +#include "or/node_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/vote_microdesc_hash_st.h" +#include "or/vote_routerstatus_st.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /** Most recently received and validated v3 "ns"-flavored consensus network * status. */ @@ -593,8 +611,11 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus, char *tmp = smartlist_join_strings(list_good, " ", 0, NULL); smartlist_add_asprintf(sl, "A consensus needs %d good signatures from recognized " - "authorities for us to accept it. This one has %d (%s).", - n_required, n_good, tmp); + "authorities for us to accept it. " + "This %s one has %d (%s).", + n_required, + networkstatus_get_flavor_name(consensus->flavor), + n_good, tmp); tor_free(tmp); if (n_no_signature) { tmp = smartlist_join_strings(list_no_signature, " ", 0, NULL); @@ -2703,4 +2724,3 @@ networkstatus_free_all(void) tor_free(waiting->body); } } - diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h index 94f85c3c29..cc6badf0b2 100644 --- a/src/or/networkstatus.h +++ b/src/or/networkstatus.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,7 @@ #ifndef TOR_NETWORKSTATUS_H #define TOR_NETWORKSTATUS_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" void networkstatus_reset_warnings(void); void networkstatus_reset_download_failures(void); diff --git a/src/or/networkstatus_sr_info_st.h b/src/or/networkstatus_sr_info_st.h new file mode 100644 index 0000000000..6c937a75f5 --- /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-2018, 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..4a193ad149 --- /dev/null +++ b/src/or/networkstatus_st.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef NETWORKSTATUS_ST_H +#define NETWORKSTATUS_ST_H + +#include "or/networkstatus_sr_info_st.h" + +/** Enumerates the possible seriousness values of a networkstatus document. */ +typedef enum networkstatus_type_t { + NS_TYPE_VOTE, + NS_TYPE_CONSENSUS, + NS_TYPE_OPINION, +} networkstatus_type_t; + +/** 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..93ff3cd418 --- /dev/null +++ b/src/or/networkstatus_voter_info_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-2018, 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. */ +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; +}; + +#endif diff --git a/src/or/node_st.h b/src/or/node_st.h new file mode 100644 index 0000000000..d56ce27884 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef NODE_ST_H +#define NODE_ST_H + +#include "or/hsdir_index_st.h" +#include "lib/crypt_ops/crypto_ed25519.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 ce1830083f..bc04ab9526 100644 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -40,33 +40,41 @@ #define NODELIST_PRIVATE -#include "or.h" -#include "address.h" -#include "address_set.h" -#include "bridges.h" -#include "config.h" -#include "control.h" -#include "dirserv.h" -#include "entrynodes.h" -#include "geoip.h" -#include "hs_common.h" -#include "hs_client.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "protover.h" -#include "rendservice.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" -#include "torcert.h" +#include "or/or.h" +#include "lib/net/address.h" +#include "common/address_set.h" +#include "or/bridges.h" +#include "or/config.h" +#include "or/control.h" +#include "or/dirserv.h" +#include "or/entrynodes.h" +#include "or/geoip.h" +#include "or/hs_common.h" +#include "or/hs_client.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/protover.h" +#include "or/rendservice.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "or/torcert.h" #include <string.h> -#include "dirauth/mode.h" +#include "or/dirauth/mode.h" + +#include "or/dir_server_st.h" +#include "or/microdesc_st.h" +#include "or/networkstatus_st.h" +#include "or/node_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/routerstatus_st.h" static void nodelist_drop_node(node_t *node, int remove_from_ht); #define node_free(val) \ @@ -643,6 +651,15 @@ nodelist_set_consensus(networkstatus_t *ns) } } +/** Return 1 iff <b>node</b> 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) @@ -2243,9 +2260,14 @@ compute_frac_paths_available(const networkstatus_t *consensus, * browsing (as distinct from hidden service web browsing). */ } - f_guard = frac_nodes_with_descriptors(guards, WEIGHT_FOR_GUARD); - f_mid = frac_nodes_with_descriptors(mid, WEIGHT_FOR_MID); - f_exit = frac_nodes_with_descriptors(exits, WEIGHT_FOR_EXIT); + f_guard = frac_nodes_with_descriptors(guards, WEIGHT_FOR_GUARD, 1); + f_mid = frac_nodes_with_descriptors(mid, WEIGHT_FOR_MID, 0); + f_exit = frac_nodes_with_descriptors(exits, WEIGHT_FOR_EXIT, 0); + + /* If we are using bridges and have at least one bridge with a full + * descriptor, assume f_guard is 1.0. */ + if (options->UseBridges && num_bridges_usable(0) > 0) + f_guard = 1.0; log_debug(LD_NET, "f_guard: %.2f, f_mid: %.2f, f_exit: %.2f", @@ -2299,9 +2321,10 @@ compute_frac_paths_available(const networkstatus_t *consensus, np, nu); - f_myexit= frac_nodes_with_descriptors(myexits,WEIGHT_FOR_EXIT); + f_myexit= frac_nodes_with_descriptors(myexits, WEIGHT_FOR_EXIT, 0); f_myexit_unflagged= - frac_nodes_with_descriptors(myexits_unflagged,WEIGHT_FOR_EXIT); + frac_nodes_with_descriptors(myexits_unflagged, + WEIGHT_FOR_EXIT, 0); log_debug(LD_NET, "f_exit: %.2f, f_myexit: %.2f, f_myexit_unflagged: %.2f", diff --git a/src/or/nodelist.h b/src/or/nodelist.h index dbe9ad18ff..ed3a542971 100644 --- a/src/or/nodelist.h +++ b/src/or/nodelist.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,15 +12,19 @@ #ifndef TOR_NODELIST_H #define TOR_NODELIST_H +struct ed25519_public_key_t; +struct curve25519_public_key_t; + #define node_assert_ok(n) STMT_BEGIN { \ tor_assert((n)->ri || (n)->rs); \ } STMT_END MOCK_DECL(node_t *, node_get_mutable_by_id,(const char *identity_digest)); MOCK_DECL(const node_t *, node_get_by_id, (const char *identity_digest)); -node_t *node_get_mutable_by_ed25519_id(const ed25519_public_key_t *ed_id); +node_t *node_get_mutable_by_ed25519_id( + const struct ed25519_public_key_t *ed_id); MOCK_DECL(const node_t *, node_get_by_ed25519_id, - (const ed25519_public_key_t *ed_id)); + (const struct ed25519_public_key_t *ed_id)); #define NNF_NO_WARN_UNNAMED (1u<<0) @@ -47,6 +51,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); @@ -64,9 +69,9 @@ uint32_t node_get_prim_addr_ipv4h(const node_t *node); void node_get_address_string(const node_t *node, char *cp, size_t len); long node_get_declared_uptime(const node_t *node); const smartlist_t *node_get_declared_family(const node_t *node); -const ed25519_public_key_t *node_get_ed25519_id(const node_t *node); +const struct ed25519_public_key_t *node_get_ed25519_id(const node_t *node); int node_ed25519_id_matches(const node_t *node, - const ed25519_public_key_t *id); + const struct ed25519_public_key_t *id); int node_supports_ed25519_link_authentication(const node_t *node, int compatible_with_us); int node_supports_v3_hsdir(const node_t *node); @@ -88,7 +93,7 @@ void node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out); void node_get_pref_dirport(const node_t *node, tor_addr_port_t *ap_out); void node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out); int node_has_curve25519_onion_key(const node_t *node); -const curve25519_public_key_t *node_get_curve25519_onion_key( +const struct curve25519_public_key_t *node_get_curve25519_onion_key( const node_t *node); MOCK_DECL(smartlist_t *, nodelist_get_list, (void)); @@ -161,4 +166,3 @@ node_set_hsdir_index(node_t *node, const networkstatus_t *ns); MOCK_DECL(int, get_estimated_address_per_node, (void)); #endif /* !defined(TOR_NODELIST_H) */ - diff --git a/src/or/ns_detached_signatures_st.h b/src/or/ns_detached_signatures_st.h new file mode 100644 index 0000000000..26ceec84b9 --- /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-2018, 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/ntmain.c b/src/or/ntmain.c index e9a299807a..99e77a285e 100644 --- a/src/or/ntmain.c +++ b/src/or/ntmain.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,10 +19,13 @@ #ifdef _WIN32 -#include "or.h" -#include "config.h" -#include "main.h" -#include "ntmain.h" +#include "or/or.h" +#include "or/config.h" +#include "or/main.h" +#include "or/ntmain.h" +#include "lib/log/win32err.h" +#include "lib/fs/winlib.h" +#include "common/compat_libevent.h" #include <windows.h> #define GENSRV_SERVICENAME "tor" @@ -778,4 +781,3 @@ nt_service_parse_options(int argc, char **argv, int *should_exit) } #endif /* defined(_WIN32) */ - diff --git a/src/or/ntmain.h b/src/or/ntmain.h index 81b7159855..223d9e318b 100644 --- a/src/or/ntmain.h +++ b/src/or/ntmain.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion.c b/src/or/onion.c index 829be12bae..80d8e1a8b1 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -62,23 +62,28 @@ * onion_fast.c for more information. **/ -#include "or.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "config.h" -#include "cpuworker.h" -#include "crypto_util.h" -#include "networkstatus.h" -#include "onion.h" -#include "onion_fast.h" -#include "onion_ntor.h" -#include "onion_tap.h" -#include "relay.h" -#include "rephist.h" -#include "router.h" +#include "or/or.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/config.h" +#include "or/cpuworker.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "or/networkstatus.h" +#include "or/onion.h" +#include "or/onion_fast.h" +#include "or/onion_ntor.h" +#include "or/onion_tap.h" +#include "or/relay.h" +#include "or/rephist.h" +#include "or/router.h" + +#include "or/cell_st.h" +#include "or/extend_info_st.h" +#include "or/or_circuit_st.h" // trunnel -#include "ed25519_cert.h" +#include "trunnel/ed25519_cert.h" /** Type for a linked list of circuits that are waiting for a free CPU worker * to process a waiting onion handshake. */ @@ -554,7 +559,7 @@ onion_skin_server_handshake(int type, (char*)keys_out, keys_out_len)<0) return -1; r = TAP_ONIONSKIN_REPLY_LEN; - memcpy(rend_nonce_out, reply_out+DH_KEY_LEN, DIGEST_LEN); + memcpy(rend_nonce_out, reply_out+DH1024_KEY_LEN, DIGEST_LEN); break; case ONION_HANDSHAKE_TYPE_FAST: if (onionskin_len != CREATE_FAST_LEN) @@ -631,7 +636,7 @@ onion_skin_client_handshake(int type, msg_out) < 0) return -1; - memcpy(rend_authenticator_out, reply+DH_KEY_LEN, DIGEST_LEN); + memcpy(rend_authenticator_out, reply+DH1024_KEY_LEN, DIGEST_LEN); return 0; case ONION_HANDSHAKE_TYPE_FAST: @@ -1339,4 +1344,3 @@ extended_cell_format(uint8_t *command_out, uint16_t *len_out, return 0; } - diff --git a/src/or/onion.h b/src/or/onion.h index 3b738debeb..ff70f299d5 100644 --- a/src/or/onion.h +++ b/src/or/onion.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,6 +13,10 @@ #define TOR_ONION_H struct create_cell_t; +struct curve25519_keypair_t; +struct curve25519_public_key_t; +#include "lib/crypt_ops/crypto_ed25519.h" + int onion_pending_add(or_circuit_t *circ, struct create_cell_t *onionskin); or_circuit_t *onion_next_task(struct create_cell_t **onionskin_out); int onion_num_pending(uint16_t handshake_type); @@ -23,8 +27,8 @@ typedef struct server_onion_keys_t { uint8_t my_identity[DIGEST_LEN]; crypto_pk_t *onion_key; crypto_pk_t *last_onion_key; - di_digest256_map_t *curve25519_key_map; - curve25519_keypair_t *junk_keypair; + struct di_digest256_map_t *curve25519_key_map; + struct curve25519_keypair_t *junk_keypair; } server_onion_keys_t; #define MAX_ONIONSKIN_CHALLENGE_LEN 255 @@ -88,7 +92,7 @@ typedef struct extend_cell_t { /** Identity fingerprint of the node we're conecting to.*/ uint8_t node_id[DIGEST_LEN]; /** Ed25519 public identity key. Zero if not set. */ - ed25519_public_key_t ed_pubkey; + struct ed25519_public_key_t ed_pubkey; /** The "create cell" embedded in this extend cell. Note that unlike the * create cells we generate ourself, this once can have a handshake type we * don't recognize. */ @@ -122,4 +126,3 @@ int extended_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extended_cell_t *cell_in); #endif /* !defined(TOR_ONION_H) */ - diff --git a/src/or/onion_fast.c b/src/or/onion_fast.c index 9f9b2199d4..6e834ccf95 100644 --- a/src/or/onion_fast.c +++ b/src/or/onion_fast.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,10 +27,11 @@ * many RSA1024 keys. **/ -#include "or.h" -#include "onion_fast.h" -#include "crypto_rand.h" -#include "crypto_util.h" +#include "or/or.h" +#include "or/onion_fast.h" +#include "lib/crypt_ops/crypto_hkdf.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" /** Release all state held in <b>victim</b>. */ void @@ -141,4 +142,3 @@ fast_client_handshake(const fast_handshake_state_t *handshake_state, tor_free(out); return r; } - diff --git a/src/or/onion_fast.h b/src/or/onion_fast.h index c56712e2c2..a7b6ec53f4 100644 --- a/src/or/onion_fast.h +++ b/src/or/onion_fast.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/onion_ntor.c b/src/or/onion_ntor.c index 02d43cb722..34b1112020 100644 --- a/src/or/onion_ntor.c +++ b/src/or/onion_ntor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,12 +21,14 @@ #include "orconfig.h" #define ONION_NTOR_PRIVATE -#include "crypto.h" -#include "crypto_digest.h" -#include "crypto_util.h" -#include "onion_ntor.h" -#include "torlog.h" -#include "util.h" +#include "lib/crypt_ops/crypto.h" +#include "lib/crypt_ops/crypto_hkdf.h" +#include "lib/crypt_ops/crypto_digest.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/onion_ntor.h" +#include "lib/log/torlog.h" +#include "lib/ctime/di_ops.h" +#include "common/util.h" /** Free storage held in an ntor handshake state. */ void @@ -334,4 +336,3 @@ onion_skin_ntor_client_handshake( return bad ? -1 : 0; } - diff --git a/src/or/onion_ntor.h b/src/or/onion_ntor.h index f7c962b7d0..0ba4abe49e 100644 --- a/src/or/onion_ntor.h +++ b/src/or/onion_ntor.h @@ -1,12 +1,14 @@ -/* Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_ONION_NTOR_H #define TOR_ONION_NTOR_H -#include "torint.h" -#include "crypto_curve25519.h" -#include "di_ops.h" +#include "lib/cc/torint.h" + +struct di_digest256_map_t; +struct curve25519_public_key_t; +struct curve25519_keypair_t; /** State to be maintained by a client between sending an ntor onionskin * and receiving a reply. */ @@ -22,17 +24,17 @@ void ntor_handshake_state_free_(ntor_handshake_state_t *state); FREE_AND_NULL(ntor_handshake_state_t, ntor_handshake_state_free_, (state)) int onion_skin_ntor_create(const uint8_t *router_id, - const curve25519_public_key_t *router_key, + const struct curve25519_public_key_t *router_key, ntor_handshake_state_t **handshake_state_out, uint8_t *onion_skin_out); int onion_skin_ntor_server_handshake(const uint8_t *onion_skin, - const di_digest256_map_t *private_keys, - const curve25519_keypair_t *junk_keypair, - const uint8_t *my_node_id, - uint8_t *handshake_reply_out, - uint8_t *key_out, - size_t key_out_len); + const struct di_digest256_map_t *private_keys, + const struct curve25519_keypair_t *junk_keypair, + const uint8_t *my_node_id, + uint8_t *handshake_reply_out, + uint8_t *key_out, + size_t key_out_len); int onion_skin_ntor_client_handshake( const ntor_handshake_state_t *handshake_state, @@ -42,6 +44,7 @@ int onion_skin_ntor_client_handshake( const char **msg_out); #ifdef ONION_NTOR_PRIVATE +#include "lib/crypt_ops/crypto_curve25519.h" /** Storage held by a client while waiting for an ntor reply from a server. */ struct ntor_handshake_state_t { @@ -60,4 +63,3 @@ struct ntor_handshake_state_t { #endif /* defined(ONION_NTOR_PRIVATE) */ #endif /* !defined(TOR_ONION_NTOR_H) */ - diff --git a/src/or/onion_tap.c b/src/or/onion_tap.c index 44737034f4..05bcce2e87 100644 --- a/src/or/onion_tap.c +++ b/src/or/onion_tap.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,12 +27,13 @@ * invoked from onion.c. **/ -#include "or.h" -#include "config.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "onion_tap.h" -#include "rephist.h" +#include "or/or.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/onion_tap.h" +#include "or/rephist.h" /*----------------------------------------------------------------------*/ @@ -53,7 +54,7 @@ onion_skin_TAP_create(crypto_pk_t *dest_router_key, crypto_dh_t **handshake_state_out, char *onion_skin_out) /* TAP_ONIONSKIN_CHALLENGE_LEN bytes */ { - char challenge[DH_KEY_LEN]; + char challenge[DH1024_KEY_LEN]; crypto_dh_t *dh = NULL; int dhbytes, pkbytes; @@ -77,7 +78,7 @@ onion_skin_TAP_create(crypto_pk_t *dest_router_key, /* set meeting point, meeting cookie, etc here. Leave zero for now. */ if (crypto_pk_obsolete_public_hybrid_encrypt(dest_router_key, onion_skin_out, TAP_ONIONSKIN_CHALLENGE_LEN, - challenge, DH_KEY_LEN, + challenge, DH1024_KEY_LEN, PK_PKCS1_OAEP_PADDING, 1)<0) goto err; @@ -136,7 +137,7 @@ onion_skin_TAP_server_handshake( log_info(LD_PROTOCOL, "Couldn't decrypt onionskin: client may be using old onion key"); goto err; - } else if (len != DH_KEY_LEN) { + } else if (len != DH1024_KEY_LEN) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Unexpected onionskin length after decryption: %ld", (long)len); @@ -152,7 +153,7 @@ onion_skin_TAP_server_handshake( goto err; /* LCOV_EXCL_STOP */ } - if (crypto_dh_get_public(dh, handshake_reply_out, DH_KEY_LEN)) { + if (crypto_dh_get_public(dh, handshake_reply_out, DH1024_KEY_LEN)) { /* LCOV_EXCL_START * This can only fail if the length of the key we just allocated is too * big. That should be impossible. */ @@ -164,7 +165,7 @@ onion_skin_TAP_server_handshake( key_material_len = DIGEST_LEN+key_out_len; key_material = tor_malloc(key_material_len); len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, challenge, - DH_KEY_LEN, key_material, + DH1024_KEY_LEN, key_material, key_material_len); if (len < 0) { log_info(LD_GENERAL, "crypto_dh_compute_secret failed."); @@ -172,7 +173,7 @@ onion_skin_TAP_server_handshake( } /* send back H(K|0) as proof that we learned K. */ - memcpy(handshake_reply_out+DH_KEY_LEN, key_material, DIGEST_LEN); + memcpy(handshake_reply_out+DH1024_KEY_LEN, key_material, DIGEST_LEN); /* use the rest of the key material for our shared keys, digests, etc */ memcpy(key_out, key_material+DIGEST_LEN, key_out_len); @@ -212,12 +213,12 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, ssize_t len; char *key_material=NULL; size_t key_material_len; - tor_assert(crypto_dh_get_bytes(handshake_state) == DH_KEY_LEN); + tor_assert(crypto_dh_get_bytes(handshake_state) == DH1024_KEY_LEN); key_material_len = DIGEST_LEN + key_out_len; key_material = tor_malloc(key_material_len); len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state, - handshake_reply, DH_KEY_LEN, key_material, + handshake_reply, DH1024_KEY_LEN, key_material, key_material_len); if (len < 0) { if (msg_out) @@ -225,7 +226,7 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, goto err; } - if (tor_memneq(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) { + if (tor_memneq(key_material, handshake_reply+DH1024_KEY_LEN, DIGEST_LEN)) { /* H(K) does *not* match. Something fishy. */ if (msg_out) *msg_out = "Digest DOES NOT MATCH on onion handshake. Bug or attack."; @@ -243,4 +244,3 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, tor_free(key_material); return -1; } - diff --git a/src/or/onion_tap.h b/src/or/onion_tap.h index 713c1d7391..9a3df684d6 100644 --- a/src/or/onion_tap.h +++ b/src/or/onion_tap.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,25 +14,27 @@ #define TAP_ONIONSKIN_CHALLENGE_LEN (PKCS1_OAEP_PADDING_OVERHEAD+\ CIPHER_KEY_LEN+\ - DH_KEY_LEN) -#define TAP_ONIONSKIN_REPLY_LEN (DH_KEY_LEN+DIGEST_LEN) + DH1024_KEY_LEN) +#define TAP_ONIONSKIN_REPLY_LEN (DH1024_KEY_LEN+DIGEST_LEN) -int onion_skin_TAP_create(crypto_pk_t *router_key, - crypto_dh_t **handshake_state_out, +struct crypto_dh_t; +struct crypto_pk_t; + +int onion_skin_TAP_create(struct crypto_pk_t *router_key, + struct crypto_dh_t **handshake_state_out, char *onion_skin_out); int onion_skin_TAP_server_handshake(const char *onion_skin, - crypto_pk_t *private_key, - crypto_pk_t *prev_private_key, + struct crypto_pk_t *private_key, + struct crypto_pk_t *prev_private_key, char *handshake_reply_out, char *key_out, size_t key_out_len); -int onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, +int onion_skin_TAP_client_handshake(struct crypto_dh_t *handshake_state, const char *handshake_reply, char *key_out, size_t key_out_len, const char **msg_out); #endif /* !defined(TOR_ONION_TAP_H) */ - diff --git a/src/or/or.h b/src/or/or.h index db8f9544fe..b0340ed1a0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,76 +13,32 @@ #define TOR_OR_H #include "orconfig.h" +#include "lib/cc/torint.h" -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif #ifdef HAVE_SIGNAL_H #include <signal.h> #endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> /* FreeBSD needs this to know what version it is */ -#endif -#include "torint.h" -#ifdef HAVE_SYS_FCNTL_H -#include <sys/fcntl.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_ASSERT_H -#include <assert.h> -#endif #ifdef HAVE_TIME_H #include <time.h> #endif -#ifdef _WIN32 -#include <winsock2.h> -#include <io.h> -#include <process.h> -#include <direct.h> -#include <windows.h> -#endif /* defined(_WIN32) */ - -#include "crypto.h" -#include "crypto_format.h" -#include "tortls.h" -#include "torlog.h" -#include "container.h" -#include "compress.h" -#include "address.h" -#include "compat_libevent.h" +#include "common/util.h" + +#include "lib/container/map.h" +#include "lib/container/smartlist.h" +#include "lib/crypt_ops/crypto.h" +#include "lib/defs/dh_sizes.h" +#include "lib/encoding/binascii.h" +#include "lib/net/address.h" + #include "ht.h" -#include "confline.h" -#include "replaycache.h" -#include "crypto_curve25519.h" -#include "crypto_ed25519.h" -#include "tor_queue.h" -#include "token_bucket.h" -#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 "or/entry_port_cfg_st.h" + +struct ed25519_public_key_t; +struct curve25519_public_key_t; /* These signals are defined to help handle_control_signal work. */ @@ -129,17 +85,9 @@ * equal sign or tilde, nickname. */ #define MAX_VERBOSE_NICKNAME_LEN (1+HEX_DIGEST_LEN+1+MAX_NICKNAME_LEN) -/** Maximum size, in bytes, for resized buffers. */ -#define MAX_BUF_SIZE ((1<<24)-1) /* 16MB-1 */ -/** Maximum size, in bytes, for any directory object that we've downloaded. */ -#define MAX_DIR_DL_SIZE MAX_BUF_SIZE - /** For HTTP parsing: Maximum number of bytes we'll accept in the headers * of an HTTP request or response. */ #define MAX_HEADERS_SIZE 50000 -/** Maximum size, in bytes, for any directory object that we're accepting - * as an upload. */ -#define MAX_DIR_UL_SIZE MAX_BUF_SIZE /** Maximum size, in bytes, of a single router descriptor uploaded to us * as a directory authority. Caches and clients fetch whatever descriptors @@ -182,58 +130,6 @@ /** How old do we let a saved descriptor get before force-removing it? */ #define OLD_ROUTER_DESC_MAX_AGE (60*60*24*5) -/** Possible rules for generating circuit IDs on an OR connection. */ -typedef enum { - CIRC_ID_TYPE_LOWER=0, /**< Pick from 0..1<<15-1. */ - CIRC_ID_TYPE_HIGHER=1, /**< Pick from 1<<15..1<<16-1. */ - /** The other side of a connection is an OP: never create circuits to it, - * and let it use any circuit ID it wants. */ - CIRC_ID_TYPE_NEITHER=2 -} circ_id_type_t; -#define circ_id_type_bitfield_t ENUM_BF(circ_id_type_t) - -#define CONN_TYPE_MIN_ 3 -/** Type for sockets listening for OR connections. */ -#define CONN_TYPE_OR_LISTENER 3 -/** A bidirectional TLS connection transmitting a sequence of cells. - * May be from an OR to an OR, or from an OP to an OR. */ -#define CONN_TYPE_OR 4 -/** A TCP connection from an onion router to a stream's destination. */ -#define CONN_TYPE_EXIT 5 -/** Type for sockets listening for SOCKS connections. */ -#define CONN_TYPE_AP_LISTENER 6 -/** A SOCKS proxy connection from the user application to the onion - * proxy. */ -#define CONN_TYPE_AP 7 -/** Type for sockets listening for HTTP connections to the directory server. */ -#define CONN_TYPE_DIR_LISTENER 8 -/** Type for HTTP connections to the directory server. */ -#define CONN_TYPE_DIR 9 -/* Type 10 is unused. */ -/** Type for listening for connections from user interface process. */ -#define CONN_TYPE_CONTROL_LISTENER 11 -/** Type for connections from user interface process. */ -#define CONN_TYPE_CONTROL 12 -/** Type for sockets listening for transparent connections redirected by pf or - * netfilter. */ -#define CONN_TYPE_AP_TRANS_LISTENER 13 -/** Type for sockets listening for transparent connections redirected by - * natd. */ -#define CONN_TYPE_AP_NATD_LISTENER 14 -/** Type for sockets listening for DNS requests. */ -#define CONN_TYPE_AP_DNS_LISTENER 15 - -/** Type for connections from the Extended ORPort. */ -#define CONN_TYPE_EXT_OR 16 -/** Type for sockets listening for Extended ORPort connections. */ -#define CONN_TYPE_EXT_OR_LISTENER 17 -/** Type for sockets listening for HTTP CONNECT tunnel connections. */ -#define CONN_TYPE_AP_HTTP_CONNECT_LISTENER 18 - -#define CONN_TYPE_MAX_ 19 -/* !!!! If _CONN_TYPE_MAX is ever over 31, we must grow the type field in - * connection_t. */ - /* Proxy client types */ #define PROXY_NONE 0 #define PROXY_CONNECT 1 @@ -246,355 +142,6 @@ typedef enum { * instead use the actual underlying proxy type (see above). */ #define PROXY_PLUGGABLE 4 -/* Proxy client handshake states */ -/* We use a proxy but we haven't even connected to it yet. */ -#define PROXY_INFANT 1 -/* We use an HTTP proxy and we've sent the CONNECT command. */ -#define PROXY_HTTPS_WANT_CONNECT_OK 2 -/* We use a SOCKS4 proxy and we've sent the CONNECT command. */ -#define PROXY_SOCKS4_WANT_CONNECT_OK 3 -/* We use a SOCKS5 proxy and we try to negotiate without - any authentication . */ -#define PROXY_SOCKS5_WANT_AUTH_METHOD_NONE 4 -/* We use a SOCKS5 proxy and we try to negotiate with - Username/Password authentication . */ -#define PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929 5 -/* We use a SOCKS5 proxy and we just sent our credentials. */ -#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 6 -/* We use a SOCKS5 proxy and we just sent our CONNECT command. */ -#define PROXY_SOCKS5_WANT_CONNECT_OK 7 -/* We use a proxy and we CONNECTed successfully!. */ -#define PROXY_CONNECTED 8 - -/** True iff <b>x</b> is an edge connection. */ -#define CONN_IS_EDGE(x) \ - ((x)->type == CONN_TYPE_EXIT || (x)->type == CONN_TYPE_AP) - -/** State for any listener connection. */ -#define LISTENER_STATE_READY 0 - -#define OR_CONN_STATE_MIN_ 1 -/** State for a connection to an OR: waiting for connect() to finish. */ -#define OR_CONN_STATE_CONNECTING 1 -/** State for a connection to an OR: waiting for proxy handshake to complete */ -#define OR_CONN_STATE_PROXY_HANDSHAKING 2 -/** State for an OR connection client: SSL is handshaking, not done - * yet. */ -#define OR_CONN_STATE_TLS_HANDSHAKING 3 -/** State for a connection to an OR: We're doing a second SSL handshake for - * renegotiation purposes. (V2 handshake only.) */ -#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 4 -/** State for a connection at an OR: We're waiting for the client to - * renegotiate (to indicate a v2 handshake) or send a versions cell (to - * indicate a v3 handshake) */ -#define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 5 -/** State for an OR connection: We're done with our SSL handshake, we've done - * renegotiation, but we haven't yet negotiated link protocol versions and - * sent a netinfo cell. */ -#define OR_CONN_STATE_OR_HANDSHAKING_V2 6 -/** State for an OR connection: We're done with our SSL handshake, but we - * haven't yet negotiated link protocol versions, done a V3 handshake, and - * sent a netinfo cell. */ -#define OR_CONN_STATE_OR_HANDSHAKING_V3 7 -/** State for an OR connection: Ready to send/receive cells. */ -#define OR_CONN_STATE_OPEN 8 -#define OR_CONN_STATE_MAX_ 8 - -/** States of the Extended ORPort protocol. Be careful before changing - * the numbers: they matter. */ -#define EXT_OR_CONN_STATE_MIN_ 1 -/** Extended ORPort authentication is waiting for the authentication - * type selected by the client. */ -#define EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE 1 -/** Extended ORPort authentication is waiting for the client nonce. */ -#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE 2 -/** Extended ORPort authentication is waiting for the client hash. */ -#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH 3 -#define EXT_OR_CONN_STATE_AUTH_MAX 3 -/** Authentication finished and the Extended ORPort is now accepting - * traffic. */ -#define EXT_OR_CONN_STATE_OPEN 4 -/** Extended ORPort is flushing its last messages and preparing to - * start accepting OR connections. */ -#define EXT_OR_CONN_STATE_FLUSHING 5 -#define EXT_OR_CONN_STATE_MAX_ 5 - -#define EXIT_CONN_STATE_MIN_ 1 -/** State for an exit connection: waiting for response from DNS farm. */ -#define EXIT_CONN_STATE_RESOLVING 1 -/** State for an exit connection: waiting for connect() to finish. */ -#define EXIT_CONN_STATE_CONNECTING 2 -/** State for an exit connection: open and ready to transmit data. */ -#define EXIT_CONN_STATE_OPEN 3 -/** State for an exit connection: waiting to be removed. */ -#define EXIT_CONN_STATE_RESOLVEFAILED 4 -#define EXIT_CONN_STATE_MAX_ 4 - -/* The AP state values must be disjoint from the EXIT state values. */ -#define AP_CONN_STATE_MIN_ 5 -/** State for a SOCKS connection: waiting for SOCKS request. */ -#define AP_CONN_STATE_SOCKS_WAIT 5 -/** State for a SOCKS connection: got a y.onion URL; waiting to receive - * rendezvous descriptor. */ -#define AP_CONN_STATE_RENDDESC_WAIT 6 -/** The controller will attach this connection to a circuit; it isn't our - * job to do so. */ -#define AP_CONN_STATE_CONTROLLER_WAIT 7 -/** State for a SOCKS connection: waiting for a completed circuit. */ -#define AP_CONN_STATE_CIRCUIT_WAIT 8 -/** State for a SOCKS connection: sent BEGIN, waiting for CONNECTED. */ -#define AP_CONN_STATE_CONNECT_WAIT 9 -/** State for a SOCKS connection: sent RESOLVE, waiting for RESOLVED. */ -#define AP_CONN_STATE_RESOLVE_WAIT 10 -/** State for a SOCKS connection: ready to send and receive. */ -#define AP_CONN_STATE_OPEN 11 -/** State for a transparent natd connection: waiting for original - * destination. */ -#define AP_CONN_STATE_NATD_WAIT 12 -/** State for an HTTP tunnel: waiting for an HTTP CONNECT command. */ -#define AP_CONN_STATE_HTTP_CONNECT_WAIT 13 -#define AP_CONN_STATE_MAX_ 13 - -/** True iff the AP_CONN_STATE_* value <b>s</b> means that the corresponding - * edge connection is not attached to any circuit. */ -#define AP_CONN_STATE_IS_UNATTACHED(s) \ - ((s) <= AP_CONN_STATE_CIRCUIT_WAIT || (s) == AP_CONN_STATE_NATD_WAIT) - -#define DIR_CONN_STATE_MIN_ 1 -/** State for connection to directory server: waiting for connect(). */ -#define DIR_CONN_STATE_CONNECTING 1 -/** State for connection to directory server: sending HTTP request. */ -#define DIR_CONN_STATE_CLIENT_SENDING 2 -/** State for connection to directory server: reading HTTP response. */ -#define DIR_CONN_STATE_CLIENT_READING 3 -/** State for connection to directory server: happy and finished. */ -#define DIR_CONN_STATE_CLIENT_FINISHED 4 -/** State for connection at directory server: waiting for HTTP request. */ -#define DIR_CONN_STATE_SERVER_COMMAND_WAIT 5 -/** State for connection at directory server: sending HTTP response. */ -#define DIR_CONN_STATE_SERVER_WRITING 6 -#define DIR_CONN_STATE_MAX_ 6 - -/** True iff the purpose of <b>conn</b> means that it's a server-side - * directory connection. */ -#define DIR_CONN_IS_SERVER(conn) ((conn)->purpose == DIR_PURPOSE_SERVER) - -#define CONTROL_CONN_STATE_MIN_ 1 -/** State for a control connection: Authenticated and accepting v1 commands. */ -#define CONTROL_CONN_STATE_OPEN 1 -/** State for a control connection: Waiting for authentication; speaking - * protocol v1. */ -#define CONTROL_CONN_STATE_NEEDAUTH 2 -#define CONTROL_CONN_STATE_MAX_ 2 - -#define DIR_PURPOSE_MIN_ 4 -/** A connection to a directory server: set after a v2 rendezvous - * descriptor is downloaded. */ -#define DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 4 -/** A connection to a directory server: download one or more server - * descriptors. */ -#define DIR_PURPOSE_FETCH_SERVERDESC 6 -/** A connection to a directory server: download one or more extra-info - * documents. */ -#define DIR_PURPOSE_FETCH_EXTRAINFO 7 -/** A connection to a directory server: upload a server descriptor. */ -#define DIR_PURPOSE_UPLOAD_DIR 8 -/** A connection to a directory server: upload a v3 networkstatus vote. */ -#define DIR_PURPOSE_UPLOAD_VOTE 10 -/** A connection to a directory server: upload a v3 consensus signature */ -#define DIR_PURPOSE_UPLOAD_SIGNATURES 11 -/** A connection to a directory server: download one or more v3 networkstatus - * votes. */ -#define DIR_PURPOSE_FETCH_STATUS_VOTE 12 -/** A connection to a directory server: download a v3 detached signatures - * object for a consensus. */ -#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES 13 -/** A connection to a directory server: download a v3 networkstatus - * consensus. */ -#define DIR_PURPOSE_FETCH_CONSENSUS 14 -/** A connection to a directory server: download one or more directory - * authority certificates. */ -#define DIR_PURPOSE_FETCH_CERTIFICATE 15 - -/** Purpose for connection at a directory server. */ -#define DIR_PURPOSE_SERVER 16 -/** A connection to a hidden service directory server: upload a v2 rendezvous - * descriptor. */ -#define DIR_PURPOSE_UPLOAD_RENDDESC_V2 17 -/** A connection to a hidden service directory server: download a v2 rendezvous - * descriptor. */ -#define DIR_PURPOSE_FETCH_RENDDESC_V2 18 -/** A connection to a directory server: download a microdescriptor. */ -#define DIR_PURPOSE_FETCH_MICRODESC 19 -/** A connection to a hidden service directory: upload a v3 descriptor. */ -#define DIR_PURPOSE_UPLOAD_HSDESC 20 -/** A connection to a hidden service directory: fetch a v3 descriptor. */ -#define DIR_PURPOSE_FETCH_HSDESC 21 -/** A connection to a directory server: set after a hidden service descriptor - * is downloaded. */ -#define DIR_PURPOSE_HAS_FETCHED_HSDESC 22 -#define DIR_PURPOSE_MAX_ 22 - -/** True iff <b>p</b> is a purpose corresponding to uploading - * data to a directory server. */ -#define DIR_PURPOSE_IS_UPLOAD(p) \ - ((p)==DIR_PURPOSE_UPLOAD_DIR || \ - (p)==DIR_PURPOSE_UPLOAD_VOTE || \ - (p)==DIR_PURPOSE_UPLOAD_SIGNATURES || \ - (p)==DIR_PURPOSE_UPLOAD_RENDDESC_V2 || \ - (p)==DIR_PURPOSE_UPLOAD_HSDESC) - -#define EXIT_PURPOSE_MIN_ 1 -/** This exit stream wants to do an ordinary connect. */ -#define EXIT_PURPOSE_CONNECT 1 -/** This exit stream wants to do a resolve (either normal or reverse). */ -#define EXIT_PURPOSE_RESOLVE 2 -#define EXIT_PURPOSE_MAX_ 2 - -/* !!!! If any connection purpose is ever over 31, we must grow the type - * field in connection_t. */ - -/** Circuit state: I'm the origin, still haven't done all my handshakes. */ -#define CIRCUIT_STATE_BUILDING 0 -/** Circuit state: Waiting to process the onionskin. */ -#define CIRCUIT_STATE_ONIONSKIN_PENDING 1 -/** Circuit state: I'd like to deliver a create, but my n_chan is still - * connecting. */ -#define CIRCUIT_STATE_CHAN_WAIT 2 -/** Circuit state: the circuit is open but we don't want to actually use it - * until we find out if a better guard will be available. - */ -#define CIRCUIT_STATE_GUARD_WAIT 3 -/** Circuit state: onionskin(s) processed, ready to send/receive cells. */ -#define CIRCUIT_STATE_OPEN 4 - -#define CIRCUIT_PURPOSE_MIN_ 1 - -/* these circuits were initiated elsewhere */ -#define CIRCUIT_PURPOSE_OR_MIN_ 1 -/** OR-side circuit purpose: normal circuit, at OR. */ -#define CIRCUIT_PURPOSE_OR 1 -/** OR-side circuit purpose: At OR, from the service, waiting for intro from - * clients. */ -#define CIRCUIT_PURPOSE_INTRO_POINT 2 -/** OR-side circuit purpose: At OR, from the client, waiting for the service. - */ -#define CIRCUIT_PURPOSE_REND_POINT_WAITING 3 -/** OR-side circuit purpose: At OR, both circuits have this purpose. */ -#define CIRCUIT_PURPOSE_REND_ESTABLISHED 4 -#define CIRCUIT_PURPOSE_OR_MAX_ 4 - -/* these circuits originate at this node */ - -/* here's how circ client-side purposes work: - * normal circuits are C_GENERAL. - * circuits that are c_introducing are either on their way to - * becoming open, or they are open and waiting for a - * suitable rendcirc before they send the intro. - * circuits that are c_introduce_ack_wait have sent the intro, - * but haven't gotten a response yet. - * circuits that are c_establish_rend are either on their way - * to becoming open, or they are open and have sent the - * establish_rendezvous cell but haven't received an ack. - * circuits that are c_rend_ready are open and have received a - * rend ack, but haven't heard from the service yet. if they have a - * buildstate->pending_final_cpath then they're expecting a - * cell from the service, else they're not. - * circuits that are c_rend_ready_intro_acked are open, and - * some intro circ has sent its intro and received an ack. - * circuits that are c_rend_joined are open, have heard from - * the service, and are talking to it. - */ -/** Client-side circuit purpose: Normal circuit, with cpath. */ -#define CIRCUIT_PURPOSE_C_GENERAL 5 -#define CIRCUIT_PURPOSE_C_HS_MIN_ 6 -/** Client-side circuit purpose: at the client, connecting to intro point. */ -#define CIRCUIT_PURPOSE_C_INTRODUCING 6 -/** Client-side circuit purpose: at the client, sent INTRODUCE1 to intro point, - * waiting for ACK/NAK. */ -#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7 -/** Client-side circuit purpose: at the client, introduced and acked, closing. - */ -#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED 8 -/** Client-side circuit purpose: at the client, waiting for ack. */ -#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 9 -/** Client-side circuit purpose: at the client, waiting for the service. */ -#define CIRCUIT_PURPOSE_C_REND_READY 10 -/** Client-side circuit purpose: at the client, waiting for the service, - * INTRODUCE has been acknowledged. */ -#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED 11 -/** Client-side circuit purpose: at the client, rendezvous established. */ -#define CIRCUIT_PURPOSE_C_REND_JOINED 12 -/** This circuit is used for getting hsdirs */ -#define CIRCUIT_PURPOSE_C_HSDIR_GET 13 -#define CIRCUIT_PURPOSE_C_HS_MAX_ 13 -/** This circuit is used for build time measurement only */ -#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT 14 -#define CIRCUIT_PURPOSE_C_MAX_ 14 - -#define CIRCUIT_PURPOSE_S_HS_MIN_ 15 -/** Hidden-service-side circuit purpose: at the service, waiting for - * introductions. */ -#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 15 -/** Hidden-service-side circuit purpose: at the service, successfully - * established intro. */ -#define CIRCUIT_PURPOSE_S_INTRO 16 -/** Hidden-service-side circuit purpose: at the service, connecting to rend - * point. */ -#define CIRCUIT_PURPOSE_S_CONNECT_REND 17 -/** Hidden-service-side circuit purpose: at the service, rendezvous - * established. */ -#define CIRCUIT_PURPOSE_S_REND_JOINED 18 -/** This circuit is used for uploading hsdirs */ -#define CIRCUIT_PURPOSE_S_HSDIR_POST 19 -#define CIRCUIT_PURPOSE_S_HS_MAX_ 19 - -/** A testing circuit; not meant to be used for actual traffic. */ -#define CIRCUIT_PURPOSE_TESTING 20 -/** A controller made this circuit and Tor should not use it. */ -#define CIRCUIT_PURPOSE_CONTROLLER 21 -/** This circuit is used for path bias probing only */ -#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING 22 - -/** This circuit is used for vanguards/restricted paths. - * - * This type of circuit is *only* created preemptively and never - * on-demand. When an HS operation needs to take place (e.g. connect to an - * intro point), these circuits are then cannibalized and repurposed to the - * actual needed HS purpose. */ -#define CIRCUIT_PURPOSE_HS_VANGUARDS 23 - -#define CIRCUIT_PURPOSE_MAX_ 23 -/** A catch-all for unrecognized purposes. Currently we don't expect - * to make or see any circuits with this purpose. */ -#define CIRCUIT_PURPOSE_UNKNOWN 255 - -/** True iff the circuit purpose <b>p</b> is for a circuit that - * originated at this node. */ -#define CIRCUIT_PURPOSE_IS_ORIGIN(p) ((p)>CIRCUIT_PURPOSE_OR_MAX_) -/** True iff the circuit purpose <b>p</b> is for a circuit that originated - * here to serve as a client. (Hidden services don't count here.) */ -#define CIRCUIT_PURPOSE_IS_CLIENT(p) \ - ((p)> CIRCUIT_PURPOSE_OR_MAX_ && \ - (p)<=CIRCUIT_PURPOSE_C_MAX_) -/** True iff the circuit_t <b>c</b> is actually an origin_circuit_t. */ -#define CIRCUIT_IS_ORIGIN(c) (CIRCUIT_PURPOSE_IS_ORIGIN((c)->purpose)) -/** True iff the circuit purpose <b>p</b> is for an established rendezvous - * circuit. */ -#define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \ - ((p) == CIRCUIT_PURPOSE_C_REND_JOINED || \ - (p) == CIRCUIT_PURPOSE_S_REND_JOINED) -/** True iff the circuit_t c is actually an or_circuit_t */ -#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC) - -/** True iff this circuit purpose should count towards the global - * pending rate limit (set by MaxClientCircuitsPending). We count all - * general purpose circuits, as well as the first step of client onion - * service connections (HSDir gets). */ -#define CIRCUIT_PURPOSE_COUNTS_TOWARDS_MAXPENDING(p) \ - ((p) == CIRCUIT_PURPOSE_C_GENERAL || \ - (p) == CIRCUIT_PURPOSE_C_HSDIR_GET) - /** How many circuits do we want simultaneously in-progress to handle * a given stream? */ #define MIN_CIRCUITS_HANDLING_STREAM 2 @@ -699,13 +246,6 @@ typedef enum { * connection_mark_unattached_ap(). */ #define END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED 2048 -/** Reason for remapping an AP connection's address: we have a cached - * answer. */ -#define REMAP_STREAM_SOURCE_CACHE 1 -/** Reason for remapping an AP connection's address: the exit node told us an - * answer. */ -#define REMAP_STREAM_SOURCE_EXIT 2 - /* 'type' values to use in RESOLVED cells. Specified in tor-spec.txt. */ #define RESOLVED_TYPE_HOSTNAME 0 #define RESOLVED_TYPE_IPV4 4 @@ -895,18 +435,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 @@ -1040,131 +569,6 @@ typedef struct channel_s channel_t; typedef struct channel_listener_s channel_listener_t; -/* channel states for channel_t */ - -typedef enum { - /* - * Closed state - channel is inactive - * - * Permitted transitions from: - * - CHANNEL_STATE_CLOSING - * Permitted transitions to: - * - CHANNEL_STATE_OPENING - */ - CHANNEL_STATE_CLOSED = 0, - /* - * Opening state - channel is trying to connect - * - * Permitted transitions from: - * - CHANNEL_STATE_CLOSED - * Permitted transitions to: - * - CHANNEL_STATE_CLOSING - * - CHANNEL_STATE_ERROR - * - CHANNEL_STATE_OPEN - */ - CHANNEL_STATE_OPENING, - /* - * Open state - channel is active and ready for use - * - * Permitted transitions from: - * - CHANNEL_STATE_MAINT - * - CHANNEL_STATE_OPENING - * Permitted transitions to: - * - CHANNEL_STATE_CLOSING - * - CHANNEL_STATE_ERROR - * - CHANNEL_STATE_MAINT - */ - CHANNEL_STATE_OPEN, - /* - * Maintenance state - channel is temporarily offline for subclass specific - * maintenance activities such as TLS renegotiation. - * - * Permitted transitions from: - * - CHANNEL_STATE_OPEN - * Permitted transitions to: - * - CHANNEL_STATE_CLOSING - * - CHANNEL_STATE_ERROR - * - CHANNEL_STATE_OPEN - */ - CHANNEL_STATE_MAINT, - /* - * Closing state - channel is shutting down - * - * Permitted transitions from: - * - CHANNEL_STATE_MAINT - * - CHANNEL_STATE_OPEN - * Permitted transitions to: - * - CHANNEL_STATE_CLOSED, - * - CHANNEL_STATE_ERROR - */ - CHANNEL_STATE_CLOSING, - /* - * Error state - channel has experienced a permanent error - * - * Permitted transitions from: - * - CHANNEL_STATE_CLOSING - * - CHANNEL_STATE_MAINT - * - CHANNEL_STATE_OPENING - * - CHANNEL_STATE_OPEN - * Permitted transitions to: - * - None - */ - CHANNEL_STATE_ERROR, - /* - * Placeholder for maximum state value - */ - CHANNEL_STATE_LAST -} channel_state_t; - -/* channel listener states for channel_listener_t */ - -typedef enum { - /* - * Closed state - channel listener is inactive - * - * Permitted transitions from: - * - CHANNEL_LISTENER_STATE_CLOSING - * Permitted transitions to: - * - CHANNEL_LISTENER_STATE_LISTENING - */ - CHANNEL_LISTENER_STATE_CLOSED = 0, - /* - * Listening state - channel listener is listening for incoming - * connections - * - * Permitted transitions from: - * - CHANNEL_LISTENER_STATE_CLOSED - * Permitted transitions to: - * - CHANNEL_LISTENER_STATE_CLOSING - * - CHANNEL_LISTENER_STATE_ERROR - */ - CHANNEL_LISTENER_STATE_LISTENING, - /* - * Closing state - channel listener is shutting down - * - * Permitted transitions from: - * - CHANNEL_LISTENER_STATE_LISTENING - * Permitted transitions to: - * - CHANNEL_LISTENER_STATE_CLOSED, - * - CHANNEL_LISTENER_STATE_ERROR - */ - CHANNEL_LISTENER_STATE_CLOSING, - /* - * Error state - channel listener has experienced a permanent error - * - * Permitted transitions from: - * - CHANNEL_STATE_CLOSING - * - CHANNEL_STATE_LISTENING - * Permitted transitions to: - * - None - */ - CHANNEL_LISTENER_STATE_ERROR, - /* - * Placeholder for maximum state value - */ - CHANNEL_LISTENER_STATE_LAST -} channel_listener_state_t; - /* TLS channel stuff */ typedef struct channel_tls_s channel_tls_t; @@ -1173,66 +577,13 @@ 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 <b>payload</b> */ - uint16_t payload_len; - /** Payload of this cell */ - uint8_t payload[FLEXIBLE_ARRAY_MEMBER]; -} var_cell_t; - -/** A parsed Extended ORPort message. */ -typedef struct ext_or_cmd_t { - uint16_t cmd; /** Command type */ - uint16_t len; /** Body length */ - 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; +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; +typedef struct ext_or_cmd_t ext_or_cmd_t; /** Beginning of a RELAY cell payload. */ typedef struct { @@ -1244,198 +595,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; - -/* Values for connection_t.magic: used to make sure that downcasts (casts from -* connection_t to foo_connection_t) are safe. */ -#define BASE_CONNECTION_MAGIC 0x7C3C304Eu -#define OR_CONNECTION_MAGIC 0x7D31FF03u -#define EDGE_CONNECTION_MAGIC 0xF0374013u -#define ENTRY_CONNECTION_MAGIC 0xbb4a5703 -#define DIR_CONNECTION_MAGIC 0x9988ffeeu -#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; +typedef struct entry_port_cfg_t entry_port_cfg_t; +typedef struct server_port_cfg_t server_port_cfg_t; /** Minimum length of the random part of an AUTH_CHALLENGE cell. */ #define OR_AUTH_CHALLENGE_LEN 32 @@ -1496,100 +657,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 <b>ed_rsa_crosscert</b> 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 */ @@ -1606,427 +675,23 @@ 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 <b>addr</b> field is prone to - * getting overridden by the address from the router - * descriptor matching <b>identity_digest</b>. */ - - /** Should this connection be used for extending circuits to the server - * matching the <b>identity_digest</b> 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); -} +typedef struct addr_policy_t addr_policy_t; -/** What action type does an address policy indicate: accept or reject? */ -typedef enum { - ADDR_POLICY_ACCEPT=1, - ADDR_POLICY_REJECT=2, -} addr_policy_action_t; -#define addr_policy_action_bitfield_t ENUM_BF(addr_policy_action_t) - -/** A reference-counted address policy rule. */ -typedef struct addr_policy_t { - int refcnt; /**< Reference count */ - /** What to do when the policy matches.*/ - addr_policy_action_bitfield_t policy_type:2; - unsigned int is_private:1; /**< True iff this is the pseudo-address, - * "private". */ - unsigned int is_canonical:1; /**< True iff this policy is the canonical - * copy (stored in a hash table to avoid - * duplication of common policies) */ - maskbits_t maskbits; /**< Accept/reject all addresses <b>a</b> such that the - * first <b>maskbits</b> bits of <b>a</b> match - * <b>addr</b>. */ - /** Base address to accept or reject. - * - * Note that wildcards are treated - * differntly depending on address family. An AF_UNSPEC address means - * "All addresses, IPv4 or IPv6." An AF_INET address with maskbits==0 means - * "All IPv4 addresses" and an AF_INET6 address with maskbits == 0 means - * "All IPv6 addresses". - **/ - tor_addr_t addr; - uint16_t prt_min; /**< Lowest port number to accept/reject. */ - 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 <b>dir</b> (not counting its NUL). */ - size_t dir_compressed_len; /**< Length of <b>dir_compressed</b>. */ - 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. */ @@ -2079,59 +744,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 - * <b>schedule</b>, which can be different depending on whether the object is - * being downloaded from an authority or a mirror (<b>want_authority</b>). - * <b>next_attempt_at</b> contains the next time we will attempt to download - * the object. - * For schedules that <b>increment_on</b> failure, <b>n_download_failures</b> - * 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, <b>n_download_failures</b> is incremented, - * the new delay value is looked up from the schedule, and - * <b>next_attempt_at</b> 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 <b>increment_on</b> attempt, <b>n_download_attempts</b> - * is used to determine the position in the schedule. Every time a - * connection attempt is made, <b>n_download_attempts</b> is incremented, - * the new delay value is looked up from the schedule, and - * <b>next_attempt_at</b> 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 @@ -2141,53 +754,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; @@ -2229,448 +796,17 @@ 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; - -/** A single entry in a parsed policy summary, describing a range of ports. */ -typedef struct short_policy_entry_t { - uint16_t min_port, max_port; -} short_policy_entry_t; - -/** A short_poliy_t is the parsed version of a policy summary. */ -typedef struct short_policy_t { - /** True if the members of 'entries' are port ranges to accept; false if - * they are port ranges to reject */ - unsigned int is_accept : 1; - /** The actual number of values in 'entries'. */ - unsigned int n_entries : 31; - /** An array of 0 or more short_policy_entry_t values, each describing a - * range of ports that this policy accepts or rejects (depending on the - * value of is_accept). - */ - 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 <b>bodylen</b>. */ - char *body; - /** The length of the microdescriptor in <b>body</b>. */ - 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 <b>signature</b> */ - 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; - -/** Enumerates the possible seriousness values of a networkstatus document. */ -typedef enum { - NS_TYPE_VOTE, - NS_TYPE_CONSENSUS, - NS_TYPE_OPINION, -} networkstatus_type_t; +typedef struct routerinfo_t routerinfo_t; +typedef struct extrainfo_t extrainfo_t; +typedef struct routerstatus_t routerstatus_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 recognized flavors of a consensus networkstatus document. All * flavors of a consensus are generated from the same set of votes, but they @@ -2683,190 +819,12 @@ 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; - -/** Allowable types of desc_store_t. */ -typedef enum store_type_t { - ROUTER_STORE = 0, - 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 <b>signing_key</b> */ - 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 networkstatus_t networkstatus_t; +typedef struct ns_detached_signatures_t ns_detached_signatures_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. @@ -2891,133 +849,19 @@ typedef enum { #define ALL_DIRINFO ((dirinfo_type_t)((1<<7)-1)) -#define CRYPT_PATH_MAGIC 0x70127012u - -struct fast_handshake_state_t; -struct ntor_handshake_state_t; #define ONION_HANDSHAKE_TYPE_TAP 0x0000 #define ONION_HANDSHAKE_TYPE_FAST 0x0001 #define ONION_HANDSHAKE_TYPE_NTOR 0x0002 #define MAX_ONION_HANDSHAKE_TYPE 0x0002 -typedef struct { - uint16_t tag; - union { - struct fast_handshake_state_t *fast; - crypto_dh_t *tap; - struct ntor_handshake_state_t *ntor; - } 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; -#define CPATH_KEY_MATERIAL_LEN (20*2+16*2) +typedef struct onion_handshake_state_t onion_handshake_state_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 DH_KEY_LEN DH_BYTES +#define CPATH_KEY_MATERIAL_LEN (20*2+16*2) -/** 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; - -/** "magic" value for an origin_circuit_t */ -#define ORIGIN_CIRCUIT_MAGIC 0x35315243u -/** "magic" value for an or_circuit_t */ -#define OR_CIRCUIT_MAGIC 0x98ABC04Fu -/** "magic" value for a circuit that would have been freed by circuit_free, - * but which we're keeping around until a cpuworker reply arrives. See - * circuit_free() for more documentation. */ -#define DEAD_CIRCUIT_MAGIC 0xdeadc14c +typedef struct cpath_build_state_t cpath_build_state_t; struct create_cell_t; @@ -3034,506 +878,17 @@ 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. */ #define MAX_RELAY_EARLY_CELLS_PER_CIRCUIT 8 -/** - * Describes the circuit building process in simplified terms based - * on the path bias accounting state for a circuit. - * - * NOTE: These state values are enumerated in the order for which we - * expect circuits to transition through them. If you add states, - * you need to preserve this overall ordering. The various pathbias - * state transition and accounting functions (pathbias_mark_* and - * pathbias_count_*) contain ordinal comparisons to enforce proper - * state transitions for corrections. - * - * This state machine and the associated logic was created to prevent - * miscounting due to unknown cases of circuit reuse. See also tickets - * #6475 and #7802. - */ -typedef enum { - /** This circuit is "new". It has not yet completed a first hop - * or been counted by the path bias code. */ - PATH_STATE_NEW_CIRC = 0, - /** This circuit has completed one/two hops, and has been counted by - * the path bias logic. */ - PATH_STATE_BUILD_ATTEMPTED = 1, - /** This circuit has been completely built */ - PATH_STATE_BUILD_SUCCEEDED = 2, - /** Did we try to attach any SOCKS streams or hidserv introductions to - * this circuit? - * - * Note: If we ever implement end-to-end stream timing through test - * stream probes (#5707), we must *not* set this for those probes - * (or any other automatic streams) because the adversary could - * just tag at a later point. - */ - PATH_STATE_USE_ATTEMPTED = 3, - /** Did any SOCKS streams or hidserv introductions actually succeed on - * this circuit? - * - * If any streams detatch/fail from this circuit, the code transitions - * the circuit back to PATH_STATE_USE_ATTEMPTED to ensure we probe. See - * pathbias_mark_use_rollback() for that. - */ - PATH_STATE_USE_SUCCEEDED = 4, - - /** - * This is a special state to indicate that we got a corrupted - * relay cell on a circuit and we don't intend to probe it. - */ - PATH_STATE_USE_FAILED = 5, - - /** - * This is a special state to indicate that we already counted - * the circuit. Used to guard against potential state machine - * violations. - */ - PATH_STATE_ALREADY_COUNTED = 6, -} path_state_t; +typedef enum path_state_t 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 <em>attached</em> 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 <em>ever</em> 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 @@ -3542,49 +897,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 <b>node</b> 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 */ - /** @name Isolation flags Ways to isolate client streams @@ -3621,1227 +933,20 @@ 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 * to pick its own port. */ #define CFG_AUTO_PORT 0xc4005e -/** Enumeration of outbound address configuration types: - * Exit-only, OR-only, or both */ -typedef enum {OUTBOUND_ADDR_EXIT, OUTBOUND_ADDR_OR, - OUTBOUND_ADDR_EXIT_AND_OR, - OUTBOUND_ADDR_MAX} outbound_addr_t; - -/** Configuration options for a Tor process. */ -typedef struct { - uint32_t magic_; - - /** What should the tor process actually do? */ - enum { - CMD_RUN_TOR=0, CMD_LIST_FINGERPRINT, CMD_HASH_PASSWORD, - CMD_VERIFY_CONFIG, CMD_RUN_UNITTESTS, CMD_DUMP_CONFIG, - CMD_KEYGEN, - CMD_KEY_EXPIRATION, - } command; - char *command_arg; /**< Argument for command-line option. */ - - config_line_t *Logs; /**< New-style list of configuration lines - * for logs */ - int LogTimeGranularity; /**< Log resolution in milliseconds. */ - - int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which - * each log message occurs? */ - int TruncateLogFile; /**< Boolean: Should we truncate the log file - before we start writing? */ - char *SyslogIdentityTag; /**< Identity tag to add for syslog logging. */ - char *AndroidIdentityTag; /**< Identity tag to add for Android logging. */ - - char *DebugLogFile; /**< Where to send verbose log messages. */ - char *DataDirectory_option; /**< Where to store long-term data, as - * configured by the user. */ - char *DataDirectory; /**< Where to store long-term data, as modified. */ - int DataDirectoryGroupReadable; /**< Boolean: Is the DataDirectory g+r? */ - - char *KeyDirectory_option; /**< Where to store keys, as - * configured by the user. */ - char *KeyDirectory; /**< Where to store keys data, as modified. */ - int KeyDirectoryGroupReadable; /**< Boolean: Is the KeyDirectory g+r? */ - - char *CacheDirectory_option; /**< Where to store cached data, as - * configured by the user. */ - char *CacheDirectory; /**< Where to store cached data, as modified. */ - int CacheDirectoryGroupReadable; /**< Boolean: Is the CacheDirectory g+r? */ - - char *Nickname; /**< OR only: nickname of this onion router. */ - char *Address; /**< OR only: configured address for this onion router. */ - char *PidFile; /**< Where to store PID of Tor process. */ - - routerset_t *ExitNodes; /**< Structure containing nicknames, digests, - * country codes and IP address patterns of ORs to - * consider as exits. */ - routerset_t *EntryNodes;/**< Structure containing nicknames, digests, - * country codes and IP address patterns of ORs to - * consider as entry points. */ - int StrictNodes; /**< Boolean: When none of our EntryNodes or ExitNodes - * are up, or we need to access a node in ExcludeNodes, - * do we just fail instead? */ - routerset_t *ExcludeNodes;/**< Structure containing nicknames, digests, - * country codes and IP address patterns of ORs - * not to use in circuits. But see StrictNodes - * above. */ - routerset_t *ExcludeExitNodes;/**< Structure containing nicknames, digests, - * country codes and IP address patterns of - * ORs not to consider as exits. */ - - /** Union of ExcludeNodes and ExcludeExitNodes */ - routerset_t *ExcludeExitNodesUnion_; - - int DisableAllSwap; /**< Boolean: Attempt to call mlockall() on our - * process for all current and future memory. */ - - config_line_t *ExitPolicy; /**< Lists of exit policy components. */ - int ExitPolicyRejectPrivate; /**< Should we not exit to reserved private - * addresses, and our own published addresses? - */ - int ExitPolicyRejectLocalInterfaces; /**< Should we not exit to local - * interface addresses? - * Includes OutboundBindAddresses and - * configured ports. */ - int ReducedExitPolicy; /**<Should we use the Reduced Exit Policy? */ - config_line_t *SocksPolicy; /**< Lists of socks policy components */ - config_line_t *DirPolicy; /**< Lists of dir policy components */ - /** Local address to bind outbound sockets */ - config_line_t *OutboundBindAddress; - /** Local address to bind outbound relay sockets */ - config_line_t *OutboundBindAddressOR; - /** Local address to bind outbound exit sockets */ - config_line_t *OutboundBindAddressExit; - /** Addresses derived from the various OutboundBindAddress lines. - * [][0] is IPv4, [][1] is IPv6 - */ - tor_addr_t OutboundBindAddresses[OUTBOUND_ADDR_MAX][2]; - /** Directory server only: which versions of - * Tor should we tell users to run? */ - config_line_t *RecommendedVersions; - config_line_t *RecommendedClientVersions; - config_line_t *RecommendedServerVersions; - config_line_t *RecommendedPackages; - /** Whether dirservers allow router descriptors with private IPs. */ - int DirAllowPrivateAddresses; - /** Whether routers accept EXTEND cells to routers with private IPs. */ - int ExtendAllowPrivateAddresses; - char *User; /**< Name of user to run Tor as. */ - config_line_t *ORPort_lines; /**< Ports to listen on for OR connections. */ - /** Ports to listen on for extended OR connections. */ - config_line_t *ExtORPort_lines; - /** Ports to listen on for SOCKS connections. */ - config_line_t *SocksPort_lines; - /** Ports to listen on for transparent pf/netfilter connections. */ - config_line_t *TransPort_lines; - char *TransProxyType; /**< What kind of transparent proxy - * implementation are we using? */ - /** Parsed value of TransProxyType. */ - enum { - TPT_DEFAULT, - TPT_PF_DIVERT, - TPT_IPFW, - TPT_TPROXY, - } TransProxyType_parsed; - config_line_t *NATDPort_lines; /**< Ports to listen on for transparent natd - * connections. */ - /** Ports to listen on for HTTP Tunnel connections. */ - config_line_t *HTTPTunnelPort_lines; - config_line_t *ControlPort_lines; /**< Ports to listen on for control - * connections. */ - config_line_t *ControlSocket; /**< List of Unix Domain Sockets to listen on - * for control connections. */ - - int ControlSocketsGroupWritable; /**< Boolean: Are control sockets g+rw? */ - int UnixSocksGroupWritable; /**< Boolean: Are SOCKS Unix sockets g+rw? */ - /** Ports to listen on for directory connections. */ - config_line_t *DirPort_lines; - config_line_t *DNSPort_lines; /**< Ports to listen on for DNS requests. */ - - /* MaxMemInQueues value as input by the user. We clean this up to be - * MaxMemInQueues. */ - uint64_t MaxMemInQueues_raw; - uint64_t MaxMemInQueues;/**< If we have more memory than this allocated - * for queues and buffers, run the OOM handler */ - /** Above this value, consider ourselves low on RAM. */ - uint64_t MaxMemInQueues_low_threshold; - - /** @name port booleans - * - * Derived booleans: For server ports and ControlPort, true iff there is a - * non-listener port on an AF_INET or AF_INET6 address of the given type - * configured in one of the _lines options above. - * For client ports, also true if there is a unix socket configured. - * If you are checking for client ports, you may want to use: - * SocksPort_set || TransPort_set || NATDPort_set || DNSPort_set || - * HTTPTunnelPort_set - * rather than SocksPort_set. - * - * @{ - */ - unsigned int ORPort_set : 1; - unsigned int SocksPort_set : 1; - unsigned int TransPort_set : 1; - unsigned int NATDPort_set : 1; - unsigned int ControlPort_set : 1; - unsigned int DirPort_set : 1; - unsigned int DNSPort_set : 1; - unsigned int ExtORPort_set : 1; - unsigned int HTTPTunnelPort_set : 1; - /**@}*/ - - int AssumeReachable; /**< Whether to publish our descriptor regardless. */ - int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */ - int V3AuthoritativeDir; /**< Boolean: is this an authoritative directory - * for version 3 directories? */ - int VersioningAuthoritativeDir; /**< Boolean: is this an authoritative - * directory that's willing to recommend - * versions? */ - int BridgeAuthoritativeDir; /**< Boolean: is this an authoritative directory - * that aggregates bridge descriptors? */ - - /** If set on a bridge relay, it will include this value on a new - * "bridge-distribution-request" line in its bridge descriptor. */ - char *BridgeDistribution; - - /** If set on a bridge authority, it will answer requests on its dirport - * for bridge statuses -- but only if the requests use this password. */ - char *BridgePassword; - /** If BridgePassword is set, this is a SHA256 digest of the basic http - * authenticator for it. Used so we can do a time-independent comparison. */ - char *BridgePassword_AuthDigest_; - - int UseBridges; /**< Boolean: should we start all circuits with a bridge? */ - config_line_t *Bridges; /**< List of bootstrap bridge addresses. */ - - config_line_t *ClientTransportPlugin; /**< List of client - transport plugins. */ - - config_line_t *ServerTransportPlugin; /**< List of client - transport plugins. */ - - /** List of TCP/IP addresses that transports should listen at. */ - config_line_t *ServerTransportListenAddr; - - /** List of options that must be passed to pluggable transports. */ - config_line_t *ServerTransportOptions; - - int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make - * this explicit so we can change how we behave in the - * future. */ - - /** Boolean: if we know the bridge's digest, should we get new - * descriptors from the bridge authorities or from the bridge itself? */ - int UpdateBridgesFromAuthority; - - int AvoidDiskWrites; /**< Boolean: should we never cache things to disk? - * Not used yet. */ - int ClientOnly; /**< Boolean: should we never evolve into a server role? */ - - int ReducedConnectionPadding; /**< Boolean: Should we try to keep connections - open shorter and pad them less against - connection-level traffic analysis? */ - /** Autobool: if auto, then connection padding will be negotiated by client - * and server. If 0, it will be fully disabled. If 1, the client will still - * pad to the server regardless of server support. */ - int ConnectionPadding; - - /** To what authority types do we publish our descriptor? Choices are - * "v1", "v2", "v3", "bridge", or "". */ - smartlist_t *PublishServerDescriptor; - /** A bitfield of authority types, derived from PublishServerDescriptor. */ - dirinfo_type_t PublishServerDescriptor_; - /** Boolean: do we publish hidden service descriptors to the HS auths? */ - int PublishHidServDescriptors; - int FetchServerDescriptors; /**< Do we fetch server descriptors as normal? */ - int FetchHidServDescriptors; /**< and hidden service descriptors? */ - - int MinUptimeHidServDirectoryV2; /**< As directory authority, accept hidden - * service directories after what time? */ - - int FetchUselessDescriptors; /**< Do we fetch non-running descriptors too? */ - int AllDirActionsPrivate; /**< Should every directory action be sent - * through a Tor circuit? */ - - /** Run in 'tor2web mode'? (I.e. only make client connections to hidden - * services, and use a single hop for all hidden-service-related - * circuits.) */ - int Tor2webMode; - - /** A routerset that should be used when picking RPs for HS circuits. */ - routerset_t *Tor2webRendezvousPoints; - - /** A routerset that should be used when picking middle nodes for HS - * circuits. */ - routerset_t *HSLayer2Nodes; - - /** A routerset that should be used when picking third-hop nodes for HS - * circuits. */ - routerset_t *HSLayer3Nodes; - - /** Onion Services in HiddenServiceSingleHopMode make one-hop (direct) - * circuits between the onion service server, and the introduction and - * rendezvous points. (Onion service descriptors are still posted using - * 3-hop paths, to avoid onion service directories blocking the service.) - * This option makes every hidden service instance hosted by - * this tor instance a Single Onion Service. - * HiddenServiceSingleHopMode requires HiddenServiceNonAnonymousMode to be - * set to 1. - * Use rend_service_allow_non_anonymous_connection() or - * rend_service_reveal_startup_time() instead of using this option directly. - */ - int HiddenServiceSingleHopMode; - /* Makes hidden service clients and servers non-anonymous on this tor - * instance. Allows the non-anonymous HiddenServiceSingleHopMode. Enables - * non-anonymous behaviour in the hidden service protocol. - * Use rend_service_non_anonymous_mode_enabled() instead of using this option - * directly. - */ - int HiddenServiceNonAnonymousMode; - - int ConnLimit; /**< Demanded minimum number of simultaneous connections. */ - int ConnLimit_; /**< Maximum allowed number of simultaneous connections. */ - int ConnLimit_high_thresh; /**< start trying to lower socket usage if we - * have this many. */ - int ConnLimit_low_thresh; /**< try to get down to here after socket - * exhaustion. */ - int RunAsDaemon; /**< If true, run in the background. (Unix only) */ - int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */ - smartlist_t *FirewallPorts; /**< Which ports our firewall allows - * (strings). */ - config_line_t *ReachableAddresses; /**< IP:ports our firewall allows. */ - config_line_t *ReachableORAddresses; /**< IP:ports for OR conns. */ - config_line_t *ReachableDirAddresses; /**< IP:ports for Dir conns. */ - - int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */ - uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */ - - /** Whether we should drop exit streams from Tors that we don't know are - * relays. One of "0" (never refuse), "1" (always refuse), or "-1" (do - * what the consensus says, defaulting to 'refuse' if the consensus says - * nothing). */ - int RefuseUnknownExits; - - /** Application ports that require all nodes in circ to have sufficient - * uptime. */ - smartlist_t *LongLivedPorts; - /** Application ports that are likely to be unencrypted and - * unauthenticated; we reject requests for them to prevent the - * user from screwing up and leaking plaintext secrets to an - * observer somewhere on the Internet. */ - smartlist_t *RejectPlaintextPorts; - /** Related to RejectPlaintextPorts above, except this config option - * controls whether we warn (in the log and via a controller status - * event) every time a risky connection is attempted. */ - smartlist_t *WarnPlaintextPorts; - /** Should we try to reuse the same exit node for a given host */ - smartlist_t *TrackHostExits; - int TrackHostExitsExpire; /**< Number of seconds until we expire an - * addressmap */ - config_line_t *AddressMap; /**< List of address map directives. */ - int AutomapHostsOnResolve; /**< If true, when we get a resolve request for a - * hostname ending with one of the suffixes in - * <b>AutomapHostsSuffixes</b>, map it to a - * virtual address. */ - /** List of suffixes for <b>AutomapHostsOnResolve</b>. The special value - * "." means "match everything." */ - smartlist_t *AutomapHostsSuffixes; - int RendPostPeriod; /**< How often do we post each rendezvous service - * descriptor? Remember to publish them independently. */ - int KeepalivePeriod; /**< How often do we send padding cells to keep - * connections alive? */ - int SocksTimeout; /**< How long do we let a socks connection wait - * unattached before we fail it? */ - int LearnCircuitBuildTimeout; /**< If non-zero, we attempt to learn a value - * for CircuitBuildTimeout based on timeout - * history. Use circuit_build_times_disabled() - * rather than checking this value directly. */ - int CircuitBuildTimeout; /**< Cull non-open circuits that were born at - * least this many seconds ago. Used until - * adaptive algorithm learns a new value. */ - int CircuitsAvailableTimeout; /**< Try to have an open circuit for at - least this long after last activity */ - int CircuitStreamTimeout; /**< If non-zero, detach streams from circuits - * and try a new circuit if the stream has been - * waiting for this many seconds. If zero, use - * our default internal timeout schedule. */ - int MaxOnionQueueDelay; /*< DOCDOC */ - int NewCircuitPeriod; /**< How long do we use a circuit before building - * a new one? */ - int MaxCircuitDirtiness; /**< Never use circs that were first used more than - this interval ago. */ - uint64_t BandwidthRate; /**< How much bandwidth, on average, are we willing - * to use in a second? */ - uint64_t BandwidthBurst; /**< How much bandwidth, at maximum, are we willing - * to use in a second? */ - uint64_t MaxAdvertisedBandwidth; /**< How much bandwidth are we willing to - * tell other nodes we have? */ - uint64_t RelayBandwidthRate; /**< How much bandwidth, on average, are we - * willing to use for all relayed conns? */ - uint64_t RelayBandwidthBurst; /**< How much bandwidth, at maximum, will we - * use in a second for all relayed conns? */ - uint64_t PerConnBWRate; /**< Long-term bw on a single TLS conn, if set. */ - uint64_t PerConnBWBurst; /**< Allowed burst on a single TLS conn, if set. */ - int NumCPUs; /**< How many CPUs should we try to use? */ - config_line_t *RendConfigLines; /**< List of configuration lines - * for rendezvous services. */ - config_line_t *HidServAuth; /**< List of configuration lines for client-side - * authorizations for hidden services */ - char *ContactInfo; /**< Contact info to be published in the directory. */ - - int HeartbeatPeriod; /**< Log heartbeat messages after this many seconds - * have passed. */ - int MainloopStats; /**< Log main loop statistics as part of the - * heartbeat messages. */ - - char *HTTPProxy; /**< hostname[:port] to use as http proxy, if any. */ - tor_addr_t HTTPProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */ - uint16_t HTTPProxyPort; /**< Parsed port for http proxy, if any. */ - char *HTTPProxyAuthenticator; /**< username:password string, if any. */ - - char *HTTPSProxy; /**< hostname[:port] to use as https proxy, if any. */ - tor_addr_t HTTPSProxyAddr; /**< Parsed addr for https proxy, if any. */ - uint16_t HTTPSProxyPort; /**< Parsed port for https proxy, if any. */ - char *HTTPSProxyAuthenticator; /**< username:password string, if any. */ - - char *Socks4Proxy; /**< hostname:port to use as a SOCKS4 proxy, if any. */ - tor_addr_t Socks4ProxyAddr; /**< Derived from Socks4Proxy. */ - uint16_t Socks4ProxyPort; /**< Derived from Socks4Proxy. */ - - char *Socks5Proxy; /**< hostname:port to use as a SOCKS5 proxy, if any. */ - tor_addr_t Socks5ProxyAddr; /**< Derived from Sock5Proxy. */ - uint16_t Socks5ProxyPort; /**< Derived from Socks5Proxy. */ - char *Socks5ProxyUsername; /**< Username for SOCKS5 authentication, if any */ - char *Socks5ProxyPassword; /**< Password for SOCKS5 authentication, if any */ - - /** List of configuration lines for replacement directory authorities. - * If you just want to replace one class of authority at a time, - * use the "Alternate*Authority" options below instead. */ - config_line_t *DirAuthorities; - - /** List of fallback directory servers */ - config_line_t *FallbackDir; - /** Whether to use the default hard-coded FallbackDirs */ - int UseDefaultFallbackDirs; - - /** Weight to apply to all directory authority rates if considering them - * along with fallbackdirs */ - double DirAuthorityFallbackRate; - - /** If set, use these main (currently v3) directory authorities and - * not the default ones. */ - config_line_t *AlternateDirAuthority; - - /** If set, use these bridge authorities and not the default one. */ - config_line_t *AlternateBridgeAuthority; - - config_line_t *MyFamily_lines; /**< Declared family for this OR. */ - config_line_t *MyFamily; /**< Declared family for this OR, normalized */ - config_line_t *NodeFamilies; /**< List of config lines for - * node families */ - smartlist_t *NodeFamilySets; /**< List of parsed NodeFamilies values. */ - config_line_t *AuthDirBadExit; /**< Address policy for descriptors to - * mark as bad exits. */ - config_line_t *AuthDirReject; /**< Address policy for descriptors to - * reject. */ - config_line_t *AuthDirInvalid; /**< Address policy for descriptors to - * never mark as valid. */ - /** @name AuthDir...CC - * - * Lists of country codes to mark as BadExit, or Invalid, or to - * reject entirely. - * - * @{ - */ - smartlist_t *AuthDirBadExitCCs; - smartlist_t *AuthDirInvalidCCs; - smartlist_t *AuthDirRejectCCs; - /**@}*/ - - int AuthDirListBadExits; /**< True iff we should list bad exits, - * and vote for all other exits as good. */ - int AuthDirMaxServersPerAddr; /**< Do not permit more than this - * number of servers per IP address. */ - int AuthDirHasIPv6Connectivity; /**< Boolean: are we on IPv6? */ - int AuthDirPinKeys; /**< Boolean: Do we enforce key-pinning? */ - - /** If non-zero, always vote the Fast flag for any relay advertising - * this amount of capacity or more. */ - uint64_t AuthDirFastGuarantee; - - /** If non-zero, this advertised capacity or more is always sufficient - * to satisfy the bandwidth requirement for the Guard flag. */ - uint64_t AuthDirGuardBWGuarantee; - - char *AccountingStart; /**< How long is the accounting interval, and when - * does it start? */ - uint64_t AccountingMax; /**< How many bytes do we allow per accounting - * interval before hibernation? 0 for "never - * hibernate." */ - /** How do we determine when our AccountingMax has been reached? - * "max" for when in or out reaches AccountingMax - * "sum" for when in plus out reaches AccountingMax - * "in" for when in reaches AccountingMax - * "out" for when out reaches AccountingMax */ - char *AccountingRule_option; - enum { ACCT_MAX, ACCT_SUM, ACCT_IN, ACCT_OUT } AccountingRule; - - /** Base64-encoded hash of accepted passwords for the control system. */ - config_line_t *HashedControlPassword; - /** As HashedControlPassword, but not saved. */ - config_line_t *HashedControlSessionPassword; - - int CookieAuthentication; /**< Boolean: do we enable cookie-based auth for - * the control system? */ - char *CookieAuthFile; /**< Filesystem location of a ControlPort - * authentication cookie. */ - char *ExtORPortCookieAuthFile; /**< Filesystem location of Extended - * ORPort authentication cookie. */ - int CookieAuthFileGroupReadable; /**< Boolean: Is the CookieAuthFile g+r? */ - int ExtORPortCookieAuthFileGroupReadable; /**< Boolean: Is the - * ExtORPortCookieAuthFile g+r? */ - int LeaveStreamsUnattached; /**< Boolean: Does Tor attach new streams to - * circuits itself (0), or does it expect a controller - * to cope? (1) */ - int DisablePredictedCircuits; /**< Boolean: does Tor preemptively - * make circuits in the background (0), - * or not (1)? */ - - /** Process specifier for a controller that ‘owns’ this Tor - * instance. Tor will terminate if its owning controller does. */ - char *OwningControllerProcess; - /** FD specifier for a controller that owns this Tor instance. */ - int OwningControllerFD; - - int ShutdownWaitLength; /**< When we get a SIGINT and we're a server, how - * long do we wait before exiting? */ - char *SafeLogging; /**< Contains "relay", "1", "0" (meaning no scrubbing). */ - - /* Derived from SafeLogging */ - enum { - SAFELOG_SCRUB_ALL, SAFELOG_SCRUB_RELAY, SAFELOG_SCRUB_NONE - } SafeLogging_; - - int Sandbox; /**< Boolean: should sandboxing be enabled? */ - int SafeSocks; /**< Boolean: should we outright refuse application - * connections that use socks4 or socks5-with-local-dns? */ - int ProtocolWarnings; /**< Boolean: when other parties screw up the Tor - * protocol, is it a warn or an info in our logs? */ - int TestSocks; /**< Boolean: when we get a socks connection, do we loudly - * log whether it was DNS-leaking or not? */ - int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware - * acceleration where available? */ - /** Token Bucket Refill resolution in milliseconds. */ - int TokenBucketRefillInterval; - char *AccelName; /**< Optional hardware acceleration engine name. */ - char *AccelDir; /**< Optional hardware acceleration engine search dir. */ - - /** Boolean: Do we try to enter from a smallish number - * of fixed nodes? */ - int UseEntryGuards_option; - /** Internal variable to remember whether we're actually acting on - * UseEntryGuards_option -- when we're a non-anonymous Tor2web client or - * Single Onion Service, it is always false, otherwise we use the value of - * UseEntryGuards_option. */ - int UseEntryGuards; - - int NumEntryGuards; /**< How many entry guards do we try to establish? */ - - /** If 1, we use any guardfraction information we see in the - * consensus. If 0, we don't. If -1, let the consensus parameter - * decide. */ - int UseGuardFraction; - - int NumDirectoryGuards; /**< How many dir guards do we try to establish? - * If 0, use value from NumEntryGuards. */ - int NumPrimaryGuards; /**< How many primary guards do we want? */ - - int RephistTrackTime; /**< How many seconds do we keep rephist info? */ - /** Should we always fetch our dir info on the mirror schedule (which - * means directly from the authorities) no matter our other config? */ - int FetchDirInfoEarly; - - /** Should we fetch our dir info at the start of the consensus period? */ - int FetchDirInfoExtraEarly; - - int DirCache; /**< Cache all directory documents and accept requests via - * tunnelled dir conns from clients. If 1, enabled (default); - * If 0, disabled. */ - - char *VirtualAddrNetworkIPv4; /**< Address and mask to hand out for virtual - * MAPADDRESS requests for IPv4 addresses */ - char *VirtualAddrNetworkIPv6; /**< Address and mask to hand out for virtual - * MAPADDRESS requests for IPv6 addresses */ - int ServerDNSSearchDomains; /**< Boolean: If set, we don't force exit - * addresses to be FQDNs, but rather search for them in - * the local domains. */ - int ServerDNSDetectHijacking; /**< Boolean: If true, check for DNS failure - * hijacking. */ - int ServerDNSRandomizeCase; /**< Boolean: Use the 0x20-hack to prevent - * DNS poisoning attacks. */ - char *ServerDNSResolvConfFile; /**< If provided, we configure our internal - * resolver from the file here rather than from - * /etc/resolv.conf (Unix) or the registry (Windows). */ - char *DirPortFrontPage; /**< This is a full path to a file with an html - disclaimer. This allows a server administrator to show - that they're running Tor and anyone visiting their server - will know this without any specialized knowledge. */ - int DisableDebuggerAttachment; /**< Currently Linux only specific attempt to - disable ptrace; needs BSD testing. */ - /** Boolean: if set, we start even if our resolv.conf file is missing - * or broken. */ - int ServerDNSAllowBrokenConfig; - /** Boolean: if set, then even connections to private addresses will get - * rate-limited. */ - int CountPrivateBandwidth; - smartlist_t *ServerDNSTestAddresses; /**< A list of addresses that definitely - * should be resolvable. Used for - * testing our DNS server. */ - int EnforceDistinctSubnets; /**< If true, don't allow multiple routers in the - * same network zone in the same circuit. */ - int AllowNonRFC953Hostnames; /**< If true, we allow connections to hostnames - * with weird characters. */ - /** If true, we try resolving hostnames with weird characters. */ - int ServerDNSAllowNonRFC953Hostnames; - - /** If true, we try to download extra-info documents (and we serve them, - * if we are a cache). For authorities, this is always true. */ - int DownloadExtraInfo; - - /** If true, we're configured to collect statistics on clients - * requesting network statuses from us as directory. */ - int DirReqStatistics_option; - /** Internal variable to remember whether we're actually acting on - * DirReqStatistics_option -- yes if it's set and we're a server, else no. */ - int DirReqStatistics; - - /** If true, the user wants us to collect statistics on port usage. */ - int ExitPortStatistics; - - /** If true, the user wants us to collect connection statistics. */ - int ConnDirectionStatistics; - - /** If true, the user wants us to collect cell statistics. */ - int CellStatistics; - - /** If true, the user wants us to collect padding statistics. */ - int PaddingStatistics; - - /** If true, the user wants us to collect statistics as entry node. */ - int EntryStatistics; - - /** If true, the user wants us to collect statistics as hidden service - * directory, introduction point, or rendezvous point. */ - int HiddenServiceStatistics_option; - /** Internal variable to remember whether we're actually acting on - * HiddenServiceStatistics_option -- yes if it's set and we're a server, - * else no. */ - int HiddenServiceStatistics; - - /** If true, include statistics file contents in extra-info documents. */ - int ExtraInfoStatistics; - - /** If true, do not believe anybody who tells us that a domain resolves - * to an internal address, or that an internal address has a PTR mapping. - * Helps avoid some cross-site attacks. */ - int ClientDNSRejectInternalAddresses; - - /** If true, do not accept any requests to connect to internal addresses - * over randomly chosen exits. */ - int ClientRejectInternalAddresses; - - /** If true, clients may connect over IPv4. If false, they will avoid - * connecting over IPv4. We enforce this for OR and Dir connections. */ - int ClientUseIPv4; - /** If true, clients may connect over IPv6. If false, they will avoid - * connecting over IPv4. We enforce this for OR and Dir connections. - * Use fascist_firewall_use_ipv6() instead of accessing this value - * directly. */ - int ClientUseIPv6; - /** If true, prefer an IPv6 OR port over an IPv4 one for entry node - * connections. If auto, bridge clients prefer IPv6, and other clients - * prefer IPv4. Use node_ipv6_or_preferred() instead of accessing this value - * directly. */ - int ClientPreferIPv6ORPort; - /** If true, prefer an IPv6 directory port over an IPv4 one for direct - * directory connections. If auto, bridge clients prefer IPv6, and other - * clients prefer IPv4. Use fascist_firewall_prefer_ipv6_dirport() instead of - * accessing this value directly. */ - int ClientPreferIPv6DirPort; - - /** The length of time that we think a consensus should be fresh. */ - int V3AuthVotingInterval; - /** The length of time we think it will take to distribute votes. */ - int V3AuthVoteDelay; - /** The length of time we think it will take to distribute signatures. */ - int V3AuthDistDelay; - /** The number of intervals we think a consensus should be valid. */ - int V3AuthNIntervalsValid; - - /** Should advertise and sign consensuses with a legacy key, for key - * migration purposes? */ - int V3AuthUseLegacyKey; - - /** Location of bandwidth measurement file */ - char *V3BandwidthsFile; - - /** Location of guardfraction file */ - char *GuardfractionFile; - - /** Authority only: key=value pairs that we add to our networkstatus - * consensus vote on the 'params' line. */ - char *ConsensusParams; - - /** Authority only: minimum number of measured bandwidths we must see - * before we only believe measured bandwidths to assign flags. */ - int MinMeasuredBWsForAuthToIgnoreAdvertised; - - /** The length of time that we think an initial consensus should be fresh. - * Only altered on testing networks. */ - int TestingV3AuthInitialVotingInterval; - - /** The length of time we think it will take to distribute initial votes. - * Only altered on testing networks. */ - int TestingV3AuthInitialVoteDelay; - - /** The length of time we think it will take to distribute initial - * signatures. Only altered on testing networks.*/ - int TestingV3AuthInitialDistDelay; - - /** Offset in seconds added to the starting time for consensus - voting. Only altered on testing networks. */ - int TestingV3AuthVotingStartOffset; - - /** If an authority has been around for less than this amount of time, it - * does not believe its reachability information is accurate. Only - * altered on testing networks. */ - int TestingAuthDirTimeToLearnReachability; - - /** Clients don't download any descriptor this recent, since it will - * probably not have propagated to enough caches. Only altered on testing - * networks. */ - int TestingEstimatedDescriptorPropagationTime; - - /** Schedule for when servers should download things in general. Only - * altered on testing networks. */ - int TestingServerDownloadInitialDelay; - - /** Schedule for when clients should download things in general. Only - * altered on testing networks. */ - int TestingClientDownloadInitialDelay; - - /** Schedule for when servers should download consensuses. Only altered - * on testing networks. */ - int TestingServerConsensusDownloadInitialDelay; - - /** Schedule for when clients should download consensuses. Only altered - * on testing networks. */ - int TestingClientConsensusDownloadInitialDelay; - - /** Schedule for when clients should download consensuses from authorities - * if they are bootstrapping (that is, they don't have a usable, reasonably - * live consensus). Only used by clients fetching from a list of fallback - * directory mirrors. - * - * This schedule is incremented by (potentially concurrent) connection - * attempts, unlike other schedules, which are incremented by connection - * failures. Only altered on testing networks. */ - int ClientBootstrapConsensusAuthorityDownloadInitialDelay; - - /** Schedule for when clients should download consensuses from fallback - * directory mirrors if they are bootstrapping (that is, they don't have a - * usable, reasonably live consensus). Only used by clients fetching from a - * list of fallback directory mirrors. - * - * This schedule is incremented by (potentially concurrent) connection - * attempts, unlike other schedules, which are incremented by connection - * failures. Only altered on testing networks. */ - int ClientBootstrapConsensusFallbackDownloadInitialDelay; - - /** Schedule for when clients should download consensuses from authorities - * if they are bootstrapping (that is, they don't have a usable, reasonably - * live consensus). Only used by clients which don't have or won't fetch - * from a list of fallback directory mirrors. - * - * This schedule is incremented by (potentially concurrent) connection - * attempts, unlike other schedules, which are incremented by connection - * failures. Only altered on testing networks. */ - int ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay; - - /** Schedule for when clients should download bridge descriptors. Only - * altered on testing networks. */ - int TestingBridgeDownloadInitialDelay; - - /** Schedule for when clients should download bridge descriptors when they - * have no running bridges. Only altered on testing networks. */ - int TestingBridgeBootstrapDownloadInitialDelay; - - /** When directory clients have only a few descriptors to request, they - * batch them until they have more, or until this amount of time has - * passed. Only altered on testing networks. */ - int TestingClientMaxIntervalWithoutRequest; - - /** How long do we let a directory connection stall before expiring - * it? Only altered on testing networks. */ - int TestingDirConnectionMaxStall; - - /** How many simultaneous in-progress connections will we make when trying - * to fetch a consensus before we wait for one to complete, timeout, or - * error out? Only altered on testing networks. */ - int ClientBootstrapConsensusMaxInProgressTries; - - /** If true, we take part in a testing network. Change the defaults of a - * couple of other configuration options and allow to change the values - * of certain configuration options. */ - int TestingTorNetwork; - - /** Minimum value for the Exit flag threshold on testing networks. */ - uint64_t TestingMinExitFlagThreshold; - - /** Minimum value for the Fast flag threshold on testing networks. */ - uint64_t TestingMinFastFlagThreshold; - - /** Relays in a testing network which should be voted Exit - * regardless of exit policy. */ - routerset_t *TestingDirAuthVoteExit; - int TestingDirAuthVoteExitIsStrict; - - /** Relays in a testing network which should be voted Guard - * regardless of uptime and bandwidth. */ - routerset_t *TestingDirAuthVoteGuard; - int TestingDirAuthVoteGuardIsStrict; - - /** Relays in a testing network which should be voted HSDir - * regardless of uptime and DirPort. */ - routerset_t *TestingDirAuthVoteHSDir; - int TestingDirAuthVoteHSDirIsStrict; - - /** Enable CONN_BW events. Only altered on testing networks. */ - int TestingEnableConnBwEvent; - - /** Enable CELL_STATS events. Only altered on testing networks. */ - int TestingEnableCellStatsEvent; - - /** If true, and we have GeoIP data, and we're a bridge, keep a per-country - * count of how many client addresses have contacted us so that we can help - * the bridge authority guess which countries have blocked access to us. */ - int BridgeRecordUsageByCountry; - - /** Optionally, IPv4 and IPv6 GeoIP data. */ - char *GeoIPFile; - char *GeoIPv6File; - - /** Autobool: if auto, then any attempt to Exclude{Exit,}Nodes a particular - * country code will exclude all nodes in ?? and A1. If true, all nodes in - * ?? and A1 are excluded. Has no effect if we don't know any GeoIP data. */ - int GeoIPExcludeUnknown; - - /** If true, SIGHUP should reload the torrc. Sometimes controllers want - * to make this false. */ - int ReloadTorrcOnSIGHUP; - - /* The main parameter for picking circuits within a connection. - * - * If this value is positive, when picking a cell to relay on a connection, - * we always relay from the circuit whose weighted cell count is lowest. - * Cells are weighted exponentially such that if one cell is sent - * 'CircuitPriorityHalflife' seconds before another, it counts for half as - * much. - * - * If this value is zero, we're disabling the cell-EWMA algorithm. - * - * If this value is negative, we're using the default approach - * according to either Tor or a parameter set in the consensus. - */ - double CircuitPriorityHalflife; - - /** Set to true if the TestingTorNetwork configuration option is set. - * This is used so that options_validate() has a chance to realize that - * the defaults have changed. */ - int UsingTestNetworkDefaults_; - - /** If 1, we try to use microdescriptors to build circuits. If 0, we don't. - * If -1, Tor decides. */ - int UseMicrodescriptors; - - /** File where we should write the ControlPort. */ - char *ControlPortWriteToFile; - /** Should that file be group-readable? */ - int ControlPortFileGroupReadable; - -#define MAX_MAX_CLIENT_CIRCUITS_PENDING 1024 - /** Maximum number of non-open general-purpose origin circuits to allow at - * once. */ - int MaxClientCircuitsPending; - - /** If 1, we always send optimistic data when it's supported. If 0, we - * never use it. If -1, we do what the consensus says. */ - int OptimisticData; - - /** If 1, we accept and launch no external network connections, except on - * control ports. */ - int DisableNetwork; - - /** - * Parameters for path-bias detection. - * @{ - * These options override the default behavior of Tor's (**currently - * experimental**) path bias detection algorithm. To try to find broken or - * misbehaving guard nodes, Tor looks for nodes where more than a certain - * fraction of circuits through that guard fail to get built. - * - * The PathBiasCircThreshold option controls how many circuits we need to - * build through a guard before we make these checks. The - * PathBiasNoticeRate, PathBiasWarnRate and PathBiasExtremeRate options - * control what fraction of circuits must succeed through a guard so we - * won't write log messages. If less than PathBiasExtremeRate circuits - * succeed *and* PathBiasDropGuards is set to 1, we disable use of that - * guard. - * - * When we have seen more than PathBiasScaleThreshold circuits through a - * guard, we scale our observations by 0.5 (governed by the consensus) so - * that new observations don't get swamped by old ones. - * - * By default, or if a negative value is provided for one of these options, - * Tor uses reasonable defaults from the networkstatus consensus document. - * If no defaults are available there, these options default to 150, .70, - * .50, .30, 0, and 300 respectively. - */ - int PathBiasCircThreshold; - double PathBiasNoticeRate; - double PathBiasWarnRate; - double PathBiasExtremeRate; - int PathBiasDropGuards; - int PathBiasScaleThreshold; - /** @} */ - - /** - * Parameters for path-bias use detection - * @{ - * Similar to the above options, these options override the default behavior - * of Tor's (**currently experimental**) path use bias detection algorithm. - * - * Where as the path bias parameters govern thresholds for successfully - * building circuits, these four path use bias parameters govern thresholds - * only for circuit usage. Circuits which receive no stream usage are not - * counted by this detection algorithm. A used circuit is considered - * successful if it is capable of carrying streams or otherwise receiving - * well-formed responses to RELAY cells. - * - * By default, or if a negative value is provided for one of these options, - * Tor uses reasonable defaults from the networkstatus consensus document. - * If no defaults are available there, these options default to 20, .80, - * .60, and 100, respectively. - */ - int PathBiasUseThreshold; - double PathBiasNoticeUseRate; - double PathBiasExtremeUseRate; - int PathBiasScaleUseThreshold; - /** @} */ - - int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */ - - /** Fraction: */ - double PathsNeededToBuildCircuits; - - /** What expiry time shall we place on our SSL certs? "0" means we - * should guess a suitable value. */ - int SSLKeyLifetime; - - /** How long (seconds) do we keep a guard before picking a new one? */ - int GuardLifetime; - - /** Is this an exit node? This is a tristate, where "1" means "yes, and use - * the default exit policy if none is given" and "0" means "no; exit policy - * is 'reject *'" and "auto" (-1) means "same as 1, but warn the user." - * - * XXXX Eventually, the default will be 0. */ - int ExitRelay; - - /** For how long (seconds) do we declare our signing keys to be valid? */ - int SigningKeyLifetime; - /** For how long (seconds) do we declare our link keys to be valid? */ - int TestingLinkCertLifetime; - /** For how long (seconds) do we declare our auth keys to be valid? */ - int TestingAuthKeyLifetime; - - /** How long before signing keys expire will we try to make a new one? */ - int TestingSigningKeySlop; - /** How long before link keys expire will we try to make a new one? */ - int TestingLinkKeySlop; - /** How long before auth keys expire will we try to make a new one? */ - int TestingAuthKeySlop; - - /** Force use of offline master key features: never generate a master - * ed25519 identity key except from tor --keygen */ - int OfflineMasterKey; - - enum { - FORCE_PASSPHRASE_AUTO=0, - FORCE_PASSPHRASE_ON, - FORCE_PASSPHRASE_OFF - } keygen_force_passphrase; - int use_keygen_passphrase_fd; - int keygen_passphrase_fd; - int change_key_passphrase; - char *master_key_fname; - - /** Autobool: Do we try to retain capabilities if we can? */ - int KeepBindCapabilities; - - /** Maximum total size of unparseable descriptors to log during the - * lifetime of this Tor process. - */ - uint64_t MaxUnparseableDescSizeToLog; - - /** Bool (default: 1): Switch for the shared random protocol. Only - * relevant to a directory authority. If off, the authority won't - * participate in the protocol. If on (default), a flag is added to the - * vote indicating participation. */ - int AuthDirSharedRandomness; - - /** If 1, we skip all OOS checks. */ - int DisableOOSCheck; - - /** Autobool: Should we include Ed25519 identities in extend2 cells? - * If -1, we should do whatever the consensus parameter says. */ - int ExtendByEd25519ID; - - /** Bool (default: 1): When testing routerinfos as a directory authority, - * do we enforce Ed25519 identity match? */ - /* NOTE: remove this option someday. */ - int AuthDirTestEd25519LinkKeys; - - /** Bool (default: 0): Tells if a %include was used on torrc */ - int IncludeUsed; - - /** The seconds after expiration which we as a relay should keep old - * consensuses around so that we can generate diffs from them. If 0, - * use the default. */ - int MaxConsensusAgeForDiffs; - - /** Bool (default: 0). Tells Tor to never try to exec another program. - */ - int NoExec; - - /** Have the KIST scheduler run every X milliseconds. If less than zero, do - * not use the KIST scheduler but use the old vanilla scheduler instead. If - * zero, do what the consensus says and fall back to using KIST as if this is - * set to "10 msec" if the consensus doesn't say anything. */ - int KISTSchedRunInterval; - - /** A multiplier for the KIST per-socket limit calculation. */ - double KISTSockBufSizeFactor; - - /** The list of scheduler type string ordered by priority that is first one - * has to be tried first. Default: KIST,KISTLite,Vanilla */ - smartlist_t *Schedulers; - /* An ordered list of scheduler_types mapped from Schedulers. */ - smartlist_t *SchedulerTypes_; - - /** List of files that were opened by %include in torrc and torrc-defaults */ - smartlist_t *FilesOpenedByIncludes; - - /** If true, Tor shouldn't install any posix signal handlers, since it is - * running embedded inside another process. - */ - int DisableSignalHandlers; - - /** Autobool: Is the circuit creation DoS mitigation subsystem enabled? */ - int DoSCircuitCreationEnabled; - /** Minimum concurrent connection needed from one single address before any - * defense is used. */ - int DoSCircuitCreationMinConnections; - /** Circuit rate used to refill the token bucket. */ - int DoSCircuitCreationRate; - /** Maximum allowed burst of circuits. Reaching that value, the address is - * detected as malicious and a defense might be used. */ - int DoSCircuitCreationBurst; - /** When an address is marked as malicous, what defense should be used - * against it. See the dos_cc_defense_type_t enum. */ - int DoSCircuitCreationDefenseType; - /** For how much time (in seconds) the defense is applicable for a malicious - * address. A random time delta is added to the defense time of an address - * which will be between 1 second and half of this value. */ - int DoSCircuitCreationDefenseTimePeriod; - - /** Autobool: Is the DoS connection mitigation subsystem enabled? */ - int DoSConnectionEnabled; - /** Maximum concurrent connection allowed per address. */ - int DoSConnectionMaxConcurrentCount; - /** When an address is reaches the maximum count, what defense should be - * used against it. See the dos_conn_defense_type_t enum. */ - int DoSConnectionDefenseType; - - /** Autobool: Do we refuse single hop client rendezvous? */ - int DoSRefuseSingleHopClientRendezvous; -} or_options_t; +typedef struct or_options_t or_options_t; #define LOG_PROTOCOL_WARN (get_protocol_warning_severity_level()) -/** Persistent state for an onion router, as saved to disk. */ -typedef struct { - uint32_t magic_; - /** The time at which we next plan to write the state to the disk. Equal to - * TIME_MAX if there are no savable changes, 0 if there are changes that - * should be saved right away. */ - time_t next_write; - - /** When was the state last written to disk? */ - time_t LastWritten; - - /** Fields for accounting bandwidth use. */ - time_t AccountingIntervalStart; - uint64_t AccountingBytesReadInInterval; - uint64_t AccountingBytesWrittenInInterval; - int AccountingSecondsActive; - int AccountingSecondsToReachSoftLimit; - time_t AccountingSoftLimitHitAt; - uint64_t AccountingBytesAtSoftLimit; - uint64_t AccountingExpectedUsage; - - /** A list of Entry Guard-related configuration lines. (pre-prop271) */ - config_line_t *EntryGuards; - - /** A list of guard-related configuration lines. (post-prop271) */ - config_line_t *Guard; - - config_line_t *TransportProxies; - - /** Cached revision counters for active hidden services on this host */ - config_line_t *HidServRevCounter; - - /** These fields hold information on the history of bandwidth usage for - * servers. The "Ends" fields hold the time when we last updated the - * bandwidth usage. The "Interval" fields hold the granularity, in seconds, - * of the entries of Values. The "Values" lists hold decimal string - * representations of the number of bytes read or written in each - * interval. The "Maxima" list holds decimal strings describing the highest - * rate achieved during the interval. - */ - time_t BWHistoryReadEnds; - int BWHistoryReadInterval; - smartlist_t *BWHistoryReadValues; - smartlist_t *BWHistoryReadMaxima; - time_t BWHistoryWriteEnds; - int BWHistoryWriteInterval; - smartlist_t *BWHistoryWriteValues; - smartlist_t *BWHistoryWriteMaxima; - time_t BWHistoryDirReadEnds; - int BWHistoryDirReadInterval; - smartlist_t *BWHistoryDirReadValues; - smartlist_t *BWHistoryDirReadMaxima; - time_t BWHistoryDirWriteEnds; - int BWHistoryDirWriteInterval; - smartlist_t *BWHistoryDirWriteValues; - smartlist_t *BWHistoryDirWriteMaxima; - - /** Build time histogram */ - config_line_t * BuildtimeHistogram; - int TotalBuildTimes; - int CircuitBuildAbandonedCount; - - /** What version of Tor wrote this state file? */ - char *TorVersion; - - /** Holds any unrecognized values we found in the state file, in the order - * in which we found them. */ - config_line_t *ExtraLines; - - /** When did we last rotate our onion key? "0" for 'no idea'. */ - time_t LastRotatedOnionKey; -} or_state_t; - -#define MAX_SOCKS_REPLY_LEN 1024 +typedef struct or_state_t or_state_t; + #define MAX_SOCKS_ADDR_LEN 256 -#define SOCKS_NO_AUTH 0x00 -#define SOCKS_USER_PASS 0x02 - -/** Please open a TCP connection to this addr:port. */ -#define SOCKS_COMMAND_CONNECT 0x01 -/** Please turn this FQDN into an IP address, privately. */ -#define SOCKS_COMMAND_RESOLVE 0xF0 -/** Please turn this IP address into an FQDN, privately. */ -#define SOCKS_COMMAND_RESOLVE_PTR 0xF1 - -/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */ -#define SOCKS_COMMAND_IS_CONNECT(c) (((c)==SOCKS_COMMAND_CONNECT) || 0) -#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 <b>reply</b>. */ - 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 **********************/ @@ -4855,120 +960,10 @@ struct socks_request_t { #define BW_MIN_WEIGHT_SCALE 1 #define BW_MAX_WEIGHT_SCALE INT32_MAX -/** Total size of the circuit timeout history to accumulate. - * 1000 is approx 2.5 days worth of continual-use circuits. */ -#define CBT_NCIRCUITS_TO_OBSERVE 1000 - -/** Width of the histogram bins in milliseconds */ -#define CBT_BIN_WIDTH ((build_time_t)50) - -/** Number of modes to use in the weighted-avg computation of Xm */ -#define CBT_DEFAULT_NUM_XM_MODES 3 -#define CBT_MIN_NUM_XM_MODES 1 -#define CBT_MAX_NUM_XM_MODES 20 - -/** A build_time_t is milliseconds */ -typedef uint32_t build_time_t; - -/** - * CBT_BUILD_ABANDONED is our flag value to represent a force-closed - * circuit (Aka a 'right-censored' pareto value). - */ -#define CBT_BUILD_ABANDONED ((build_time_t)(INT32_MAX-1)) -#define CBT_BUILD_TIME_MAX ((build_time_t)(INT32_MAX)) - -/** Save state every 10 circuits */ -#define CBT_SAVE_STATE_EVERY 10 - -/* Circuit build times consensus parameters */ - -/** - * How long to wait before actually closing circuits that take too long to - * build in terms of CDF quantile. - */ -#define CBT_DEFAULT_CLOSE_QUANTILE 95 -#define CBT_MIN_CLOSE_QUANTILE CBT_MIN_QUANTILE_CUTOFF -#define CBT_MAX_CLOSE_QUANTILE CBT_MAX_QUANTILE_CUTOFF - -/** - * How many circuits count as recent when considering if the - * connection has gone gimpy or changed. - */ -#define CBT_DEFAULT_RECENT_CIRCUITS 20 -#define CBT_MIN_RECENT_CIRCUITS 3 -#define CBT_MAX_RECENT_CIRCUITS 1000 - -/** - * Maximum count of timeouts that finish the first hop in the past - * RECENT_CIRCUITS before calculating a new timeout. - * - * This tells us whether to abandon timeout history and set - * the timeout back to whatever circuit_build_times_get_initial_timeout() - * gives us. - */ -#define CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT (CBT_DEFAULT_RECENT_CIRCUITS*9/10) -#define CBT_MIN_MAX_RECENT_TIMEOUT_COUNT 3 -#define CBT_MAX_MAX_RECENT_TIMEOUT_COUNT 10000 - -/** Minimum circuits before estimating a timeout */ -#define CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE 100 -#define CBT_MIN_MIN_CIRCUITS_TO_OBSERVE 1 -#define CBT_MAX_MIN_CIRCUITS_TO_OBSERVE 10000 - -/** Cutoff percentile on the CDF for our timeout estimation. */ -#define CBT_DEFAULT_QUANTILE_CUTOFF 80 -#define CBT_MIN_QUANTILE_CUTOFF 10 -#define CBT_MAX_QUANTILE_CUTOFF 99 -double circuit_build_times_quantile_cutoff(void); - -/** How often in seconds should we build a test circuit */ -#define CBT_DEFAULT_TEST_FREQUENCY 10 -#define CBT_MIN_TEST_FREQUENCY 1 -#define CBT_MAX_TEST_FREQUENCY INT32_MAX - -/** Lowest allowable value for CircuitBuildTimeout in milliseconds */ -#define CBT_DEFAULT_TIMEOUT_MIN_VALUE (1500) -#define CBT_MIN_TIMEOUT_MIN_VALUE 500 -#define CBT_MAX_TIMEOUT_MIN_VALUE INT32_MAX - -/** Initial circuit build timeout in milliseconds */ -#define CBT_DEFAULT_TIMEOUT_INITIAL_VALUE (60*1000) -#define CBT_MIN_TIMEOUT_INITIAL_VALUE CBT_MIN_TIMEOUT_MIN_VALUE -#define CBT_MAX_TIMEOUT_INITIAL_VALUE INT32_MAX -int32_t circuit_build_times_initial_timeout(void); - -#if CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT < CBT_MIN_MAX_RECENT_TIMEOUT_COUNT -#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 ***************************/ -/** An error from options_trial_assign() or options_init_from_string(). */ -typedef enum setopt_err_t { - SETOPT_OK = 0, - SETOPT_ERR_MISC = -1, - SETOPT_ERR_PARSE = -2, - SETOPT_ERR_TRANSITION = -3, - SETOPT_ERR_SETTING = -4, -} setopt_err_t; - /********************************* connection_edge.c *************************/ /** Enumerates possible origins of a client-side address mapping. */ @@ -4995,269 +990,21 @@ typedef enum { } addressmap_entry_source_t; #define addressmap_entry_source_bitfield_t ENUM_BF(addressmap_entry_source_t) -/********************************* control.c ***************************/ - -/** Used to indicate the type of a circuit event passed to the controller. - * The various types are defined in control-spec.txt */ -typedef enum circuit_status_event_t { - CIRC_EVENT_LAUNCHED = 0, - CIRC_EVENT_BUILT = 1, - CIRC_EVENT_EXTENDED = 2, - CIRC_EVENT_FAILED = 3, - CIRC_EVENT_CLOSED = 4, -} circuit_status_event_t; - -/** Used to indicate the type of a CIRC_MINOR event passed to the controller. - * The various types are defined in control-spec.txt . */ -typedef enum circuit_status_minor_event_t { - CIRC_MINOR_EVENT_PURPOSE_CHANGED, - CIRC_MINOR_EVENT_CANNIBALIZED, -} circuit_status_minor_event_t; - -/** Used to indicate the type of a stream event passed to the controller. - * The various types are defined in control-spec.txt */ -typedef enum stream_status_event_t { - STREAM_EVENT_SENT_CONNECT = 0, - STREAM_EVENT_SENT_RESOLVE = 1, - STREAM_EVENT_SUCCEEDED = 2, - STREAM_EVENT_FAILED = 3, - STREAM_EVENT_CLOSED = 4, - STREAM_EVENT_NEW = 5, - STREAM_EVENT_NEW_RESOLVE = 6, - STREAM_EVENT_FAILED_RETRIABLE = 7, - STREAM_EVENT_REMAP = 8 -} stream_status_event_t; - -/** Used to indicate the type of an OR connection event passed to the - * controller. The various types are defined in control-spec.txt */ -typedef enum or_conn_status_event_t { - OR_CONN_EVENT_LAUNCHED = 0, - OR_CONN_EVENT_CONNECTED = 1, - OR_CONN_EVENT_FAILED = 2, - OR_CONN_EVENT_CLOSED = 3, - OR_CONN_EVENT_NEW = 4, -} or_conn_status_event_t; - -/** Used to indicate the type of a buildtime event */ -typedef enum buildtimeout_set_event_t { - BUILDTIMEOUT_SET_EVENT_COMPUTED = 0, - BUILDTIMEOUT_SET_EVENT_RESET = 1, - BUILDTIMEOUT_SET_EVENT_SUSPENDED = 2, - BUILDTIMEOUT_SET_EVENT_DISCARD = 3, - BUILDTIMEOUT_SET_EVENT_RESUME = 4 -} buildtimeout_set_event_t; - -/** Execute the statement <b>stmt</b>, which may log events concerning the - * connection <b>conn</b>. To prevent infinite loops, disable log messages - * being sent to controllers if <b>conn</b> is a control connection. - * - * Stmt must not contain any return or goto statements. - */ -#define CONN_LOG_PROTECT(conn, stmt) \ - STMT_BEGIN \ - int _log_conn_is_control; \ - tor_assert(conn); \ - _log_conn_is_control = (conn->type == CONN_TYPE_CONTROL); \ - if (_log_conn_is_control) \ - disable_control_logging(); \ - STMT_BEGIN stmt; STMT_END; \ - if (_log_conn_is_control) \ - enable_control_logging(); \ - STMT_END - -/** Enum describing various stages of bootstrapping, for use with controller - * bootstrap status events. The values range from 0 to 100. */ -typedef enum { - BOOTSTRAP_STATUS_UNDEF=-1, - BOOTSTRAP_STATUS_STARTING=0, - BOOTSTRAP_STATUS_CONN_DIR=5, - BOOTSTRAP_STATUS_HANDSHAKE=-2, - BOOTSTRAP_STATUS_HANDSHAKE_DIR=10, - BOOTSTRAP_STATUS_ONEHOP_CREATE=15, - BOOTSTRAP_STATUS_REQUESTING_STATUS=20, - BOOTSTRAP_STATUS_LOADING_STATUS=25, - BOOTSTRAP_STATUS_LOADING_KEYS=40, - BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS=45, - BOOTSTRAP_STATUS_LOADING_DESCRIPTORS=50, - BOOTSTRAP_STATUS_CONN_OR=80, - BOOTSTRAP_STATUS_HANDSHAKE_OR=85, - BOOTSTRAP_STATUS_CIRCUIT_CREATE=90, - 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. - */ -typedef enum { - /** For use in a v2 opinion */ - NS_V2, - /** For use in a consensus networkstatus document (ns flavor) */ - NS_V3_CONSENSUS, - /** For use in a vote networkstatus document */ - NS_V3_VOTE, - /** For passing to the controlport in response to a GETINFO request */ - NS_CONTROL_PORT, - /** For use in a consensus networkstatus document (microdesc flavor) */ - 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) */ +#define WRITE_STATS_INTERVAL (24*60*60) /********************************* 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; - -/********************************* geoip.c **************************/ - -/** Indicates an action that we might be noting geoip statistics on. - * Note that if we're noticing CONNECT, we're a bridge, and if we're noticing - * the others, we're not. - */ -typedef enum { - /** We've noticed a connection as a bridge relay or entry guard. */ - GEOIP_CLIENT_CONNECT = 0, - /** We've served a networkstatus consensus as a directory server. */ - GEOIP_CLIENT_NETWORKSTATUS = 1, -} geoip_client_action_t; -/** Indicates either a positive reply or a reason for rejectng a network - * status request that will be included in geoip statistics. */ -typedef enum { - /** Request is answered successfully. */ - GEOIP_SUCCESS = 0, - /** V3 network status is not signed by a sufficient number of requested - * authorities. */ - GEOIP_REJECT_NOT_ENOUGH_SIGS = 1, - /** Requested network status object is unavailable. */ - GEOIP_REJECT_UNAVAILABLE = 2, - /** Requested network status not found. */ - GEOIP_REJECT_NOT_FOUND = 3, - /** Network status has not been modified since If-Modified-Since time. */ - GEOIP_REJECT_NOT_MODIFIED = 4, - /** Directory is busy. */ - GEOIP_REJECT_BUSY = 5, -} geoip_ns_response_t; -#define GEOIP_NS_RESPONSE_NUM 6 - -/** Directory requests that we are measuring can be either direct or - * tunneled. */ -typedef enum { - DIRREQ_DIRECT = 0, - DIRREQ_TUNNELED = 1, -} dirreq_type_t; - -/** Possible states for either direct or tunneled directory requests that - * are relevant for determining network status download times. */ -typedef enum { - /** Found that the client requests a network status; applies to both - * direct and tunneled requests; initial state of a request that we are - * measuring. */ - DIRREQ_IS_FOR_NETWORK_STATUS = 0, - /** Finished writing a network status to the directory connection; - * applies to both direct and tunneled requests; completes a direct - * request. */ - DIRREQ_FLUSHING_DIR_CONN_FINISHED = 1, - /** END cell sent to circuit that initiated a tunneled request. */ - DIRREQ_END_CELL_SENT = 2, - /** Flushed last cell from queue of the circuit that initiated a - * tunneled request to the outbuf of the OR connection. */ - DIRREQ_CIRC_QUEUE_FLUSHED = 3, - /** Flushed last byte from buffer of the channel belonging to the - * circuit that initiated a tunneled request; completes a tunneled - * request. */ - DIRREQ_CHANNEL_BUFFER_FLUSHED = 4 -} dirreq_state_t; - -#define WRITE_STATS_INTERVAL (24*60*60) +typedef struct vote_timing_t vote_timing_t; /********************************* microdesc.c *************************/ typedef struct microdesc_cache_t microdesc_cache_t; -/********************************* networkstatus.c *********************/ - -/** Possible statuses of a version of Tor, given opinions from the directory - * servers. */ -typedef enum version_status_t { - VS_RECOMMENDED=0, /**< This version is listed as recommended. */ - VS_OLD=1, /**< This version is older than any recommended version. */ - VS_NEW=2, /**< This version is newer than any recommended version. */ - VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version - * in its series, but later recommended versions exist. - */ - VS_UNRECOMMENDED=4, /**< This version is not recommended (general case). */ - VS_EMPTY=5, /**< The version list was empty; no agreed-on versions. */ - VS_UNKNOWN, /**< We have no idea. */ -} version_status_t; - -/********************************* policies.c ************************/ - -/** Outcome of applying an address policy to an address. */ -typedef enum { - /** The address was accepted */ - ADDR_POLICY_ACCEPTED=0, - /** The address was rejected */ - ADDR_POLICY_REJECTED=-1, - /** Part of the address was unknown, but as far as we can tell, it was - * accepted. */ - ADDR_POLICY_PROBABLY_ACCEPTED=1, - /** Part of the address was unknown, but as far as we can tell, it was - * rejected. */ - ADDR_POLICY_PROBABLY_REJECTED=2, -} addr_policy_result_t; - -/********************************* rephist.c ***************************/ - -/** Possible public/private key operations in Tor: used to keep track of where - * we're spending our time. */ -typedef enum { - SIGN_DIR, SIGN_RTR, - VERIFY_DIR, VERIFY_RTR, - ENC_ONIONSKIN, DEC_ONIONSKIN, - TLS_HANDSHAKE_C, TLS_HANDSHAKE_S, - REND_CLIENT, REND_MID, REND_SERVER, -} pk_op_t; - /********************************* 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 @@ -5290,245 +1037,18 @@ 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) #define ROUTER_MAX_DECLARED_BANDWIDTH INT32_MAX -/* Flags for pick_directory_server() and pick_trusteddirserver(). */ -/** Flag to indicate that we should not automatically be willing to use - * ourself to answer a directory request. - * Passed to router_pick_directory_server (et al).*/ -#define PDS_ALLOW_SELF (1<<0) -/** Flag to indicate that if no servers seem to be up, we should mark all - * directory servers as up and try again. - * Passed to router_pick_directory_server (et al).*/ -#define PDS_RETRY_IF_NO_SERVERS (1<<1) -/** Flag to indicate that we should not exclude directory servers that - * our ReachableAddress settings would exclude. This usually means that - * we're going to connect to the server over Tor, and so we don't need to - * worry about our firewall telling us we can't. - * Passed to router_pick_directory_server (et al).*/ -#define PDS_IGNORE_FASCISTFIREWALL (1<<2) -/** Flag to indicate that we should not use any directory authority to which - * we have an existing directory connection for downloading server descriptors - * or extrainfo documents. - * - * Passed to router_pick_directory_server (et al) - */ -#define PDS_NO_EXISTING_SERVERDESC_FETCH (1<<3) -/** Flag to indicate that we should not use any directory authority to which - * we have an existing directory connection for downloading microdescs. - * - * Passed to router_pick_directory_server (et al) - */ -#define PDS_NO_EXISTING_MICRODESC_FETCH (1<<4) - -/** Possible ways to weight routers when choosing one randomly. See - * routerlist_sl_choose_by_bandwidth() for more information.*/ -typedef enum bandwidth_weight_rule_t { - NO_WEIGHTING, WEIGHT_FOR_EXIT, WEIGHT_FOR_MID, WEIGHT_FOR_GUARD, - WEIGHT_FOR_DIR -} bandwidth_weight_rule_t; - -/** Flags to be passed to control router_choose_random_node() to indicate what - * kind of nodes to pick according to what algorithm. */ -typedef enum { - CRN_NEED_UPTIME = 1<<0, - CRN_NEED_CAPACITY = 1<<1, - CRN_NEED_GUARD = 1<<2, - /* XXXX not used, apparently. */ - CRN_WEIGHT_AS_EXIT = 1<<5, - CRN_NEED_DESC = 1<<6, - /* On clients, only provide nodes that satisfy ClientPreferIPv6OR */ - CRN_PREF_ADDR = 1<<7, - /* On clients, only provide nodes that we can connect to directly, based on - * our firewall rules */ - CRN_DIRECT_CONN = 1<<8, - /* On clients, only provide nodes with HSRend >= 2 protocol version which - * is required for hidden service version >= 3. */ - CRN_RENDEZVOUS_V3 = 1<<9, -} router_crn_flags_t; - -/** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */ -typedef enum was_router_added_t { - /* Router was added successfully. */ - ROUTER_ADDED_SUCCESSFULLY = 1, - /* Extrainfo document was rejected because no corresponding router - * descriptor was found OR router descriptor was rejected because - * it was incompatible with its extrainfo document. */ - ROUTER_BAD_EI = -1, - /* Router descriptor was rejected because it is already known. */ - ROUTER_IS_ALREADY_KNOWN = -2, - /* General purpose router was rejected, because it was not listed - * in consensus. */ - ROUTER_NOT_IN_CONSENSUS = -3, - /* Router was neither in directory consensus nor in any of - * networkstatus documents. Caching it to access later. - * (Applies to fetched descriptors only.) */ - ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4, - /* Router was rejected by directory authority. */ - ROUTER_AUTHDIR_REJECTS = -5, - /* Bridge descriptor was rejected because such bridge was not one - * of the bridges we have listed in our configuration. */ - ROUTER_WAS_NOT_WANTED = -6, - /* Router descriptor was rejected because it was older than - * OLD_ROUTER_DESC_MAX_AGE. */ - ROUTER_WAS_TOO_OLD = -7, /* note contrast with 'NOT_NEW' */ - /* DOCDOC */ - 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..158a5314ef --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef OR_CIRCUIT_ST_H +#define OR_CIRCUIT_ST_H + +#include "or/or.h" + +#include "or/circuit_st.h" +#include "or/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..dbfe7528b0 --- /dev/null +++ b/src/or/or_connection_st.h @@ -0,0 +1,92 @@ +/* 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 OR_CONNECTION_ST_H +#define OR_CONNECTION_ST_H + +#include "or/connection_st.h" +#include "common/token_bucket.h" + +struct tor_tls_t; + +/** 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). */ + + struct 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 <b>addr</b> field is prone to + * getting overridden by the address from the router + * descriptor matching <b>identity_digest</b>. */ + + /** Should this connection be used for extending circuits to the server + * matching the <b>identity_digest</b> 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..38e798b5e2 --- /dev/null +++ b/src/or/or_handshake_certs_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef OR_HANDSHAKE_CERTS_ST +#define OR_HANDSHAKE_CERTS_ST + +struct tor_x509_cert_t; + +/** 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. */ + struct 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. */ + struct tor_x509_cert_t *link_cert; + /** A self-signed identity certificate: the RSA identity key signed + * with itself. */ + struct 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 <b>ed_rsa_crosscert</b> 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..4ee095d9af --- /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-2018, 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/or_options_st.h b/src/or/or_options_st.h new file mode 100644 index 0000000000..0c0c5d32bb --- /dev/null +++ b/src/or/or_options_st.h @@ -0,0 +1,1077 @@ +/* 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 TOR_OR_OPTIONS_ST_H +#define TOR_OR_OPTIONS_ST_H + +#include "lib/cc/torint.h" +#include "lib/net/address.h" + +struct smartlist_t; +struct config_line_t; + +/** Enumeration of outbound address configuration types: + * Exit-only, OR-only, or both */ +typedef enum {OUTBOUND_ADDR_EXIT, OUTBOUND_ADDR_OR, + OUTBOUND_ADDR_EXIT_AND_OR, + OUTBOUND_ADDR_MAX} outbound_addr_t; + +/** Configuration options for a Tor process. */ +struct or_options_t { + uint32_t magic_; + + /** What should the tor process actually do? */ + enum { + CMD_RUN_TOR=0, CMD_LIST_FINGERPRINT, CMD_HASH_PASSWORD, + CMD_VERIFY_CONFIG, CMD_RUN_UNITTESTS, CMD_DUMP_CONFIG, + CMD_KEYGEN, + CMD_KEY_EXPIRATION, + } command; + char *command_arg; /**< Argument for command-line option. */ + + struct config_line_t *Logs; /**< New-style list of configuration lines + * for logs */ + int LogTimeGranularity; /**< Log resolution in milliseconds. */ + + int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which + * each log message occurs? */ + int TruncateLogFile; /**< Boolean: Should we truncate the log file + before we start writing? */ + char *SyslogIdentityTag; /**< Identity tag to add for syslog logging. */ + char *AndroidIdentityTag; /**< Identity tag to add for Android logging. */ + + char *DebugLogFile; /**< Where to send verbose log messages. */ + char *DataDirectory_option; /**< Where to store long-term data, as + * configured by the user. */ + char *DataDirectory; /**< Where to store long-term data, as modified. */ + int DataDirectoryGroupReadable; /**< Boolean: Is the DataDirectory g+r? */ + + char *KeyDirectory_option; /**< Where to store keys, as + * configured by the user. */ + char *KeyDirectory; /**< Where to store keys data, as modified. */ + int KeyDirectoryGroupReadable; /**< Boolean: Is the KeyDirectory g+r? */ + + char *CacheDirectory_option; /**< Where to store cached data, as + * configured by the user. */ + char *CacheDirectory; /**< Where to store cached data, as modified. */ + int CacheDirectoryGroupReadable; /**< Boolean: Is the CacheDirectory g+r? */ + + char *Nickname; /**< OR only: nickname of this onion router. */ + char *Address; /**< OR only: configured address for this onion router. */ + char *PidFile; /**< Where to store PID of Tor process. */ + + routerset_t *ExitNodes; /**< Structure containing nicknames, digests, + * country codes and IP address patterns of ORs to + * consider as exits. */ + routerset_t *EntryNodes;/**< Structure containing nicknames, digests, + * country codes and IP address patterns of ORs to + * consider as entry points. */ + int StrictNodes; /**< Boolean: When none of our EntryNodes or ExitNodes + * are up, or we need to access a node in ExcludeNodes, + * do we just fail instead? */ + routerset_t *ExcludeNodes;/**< Structure containing nicknames, digests, + * country codes and IP address patterns of ORs + * not to use in circuits. But see StrictNodes + * above. */ + routerset_t *ExcludeExitNodes;/**< Structure containing nicknames, digests, + * country codes and IP address patterns of + * ORs not to consider as exits. */ + + /** Union of ExcludeNodes and ExcludeExitNodes */ + routerset_t *ExcludeExitNodesUnion_; + + int DisableAllSwap; /**< Boolean: Attempt to call mlockall() on our + * process for all current and future memory. */ + + struct config_line_t *ExitPolicy; /**< Lists of exit policy components. */ + int ExitPolicyRejectPrivate; /**< Should we not exit to reserved private + * addresses, and our own published addresses? + */ + int ExitPolicyRejectLocalInterfaces; /**< Should we not exit to local + * interface addresses? + * Includes OutboundBindAddresses and + * configured ports. */ + int ReducedExitPolicy; /**<Should we use the Reduced Exit Policy? */ + struct config_line_t *SocksPolicy; /**< Lists of socks policy components */ + struct config_line_t *DirPolicy; /**< Lists of dir policy components */ + /** Local address to bind outbound sockets */ + struct config_line_t *OutboundBindAddress; + /** Local address to bind outbound relay sockets */ + struct config_line_t *OutboundBindAddressOR; + /** Local address to bind outbound exit sockets */ + struct config_line_t *OutboundBindAddressExit; + /** Addresses derived from the various OutboundBindAddress lines. + * [][0] is IPv4, [][1] is IPv6 + */ + tor_addr_t OutboundBindAddresses[OUTBOUND_ADDR_MAX][2]; + /** Directory server only: which versions of + * Tor should we tell users to run? */ + struct config_line_t *RecommendedVersions; + struct config_line_t *RecommendedClientVersions; + struct config_line_t *RecommendedServerVersions; + struct config_line_t *RecommendedPackages; + /** Whether dirservers allow router descriptors with private IPs. */ + int DirAllowPrivateAddresses; + /** Whether routers accept EXTEND cells to routers with private IPs. */ + int ExtendAllowPrivateAddresses; + char *User; /**< Name of user to run Tor as. */ + /** Ports to listen on for OR connections. */ + struct config_line_t *ORPort_lines; + /** Ports to listen on for extended OR connections. */ + struct config_line_t *ExtORPort_lines; + /** Ports to listen on for SOCKS connections. */ + struct config_line_t *SocksPort_lines; + /** Ports to listen on for transparent pf/netfilter connections. */ + struct config_line_t *TransPort_lines; + char *TransProxyType; /**< What kind of transparent proxy + * implementation are we using? */ + /** Parsed value of TransProxyType. */ + enum { + TPT_DEFAULT, + TPT_PF_DIVERT, + TPT_IPFW, + TPT_TPROXY, + } TransProxyType_parsed; + /** Ports to listen on for transparent natd connections. */ + struct config_line_t *NATDPort_lines; + /** Ports to listen on for HTTP Tunnel connections. */ + struct config_line_t *HTTPTunnelPort_lines; + struct config_line_t *ControlPort_lines; /**< Ports to listen on for control + * connections. */ + /** List of Unix Domain Sockets to listen on for control connections. */ + struct config_line_t *ControlSocket; + + int ControlSocketsGroupWritable; /**< Boolean: Are control sockets g+rw? */ + int UnixSocksGroupWritable; /**< Boolean: Are SOCKS Unix sockets g+rw? */ + /** Ports to listen on for directory connections. */ + struct config_line_t *DirPort_lines; + /** Ports to listen on for DNS requests. */ + struct config_line_t *DNSPort_lines; + + /* MaxMemInQueues value as input by the user. We clean this up to be + * MaxMemInQueues. */ + uint64_t MaxMemInQueues_raw; + uint64_t MaxMemInQueues;/**< If we have more memory than this allocated + * for queues and buffers, run the OOM handler */ + /** Above this value, consider ourselves low on RAM. */ + uint64_t MaxMemInQueues_low_threshold; + + /** @name port booleans + * + * Derived booleans: For server ports and ControlPort, true iff there is a + * non-listener port on an AF_INET or AF_INET6 address of the given type + * configured in one of the _lines options above. + * For client ports, also true if there is a unix socket configured. + * If you are checking for client ports, you may want to use: + * SocksPort_set || TransPort_set || NATDPort_set || DNSPort_set || + * HTTPTunnelPort_set + * rather than SocksPort_set. + * + * @{ + */ + unsigned int ORPort_set : 1; + unsigned int SocksPort_set : 1; + unsigned int TransPort_set : 1; + unsigned int NATDPort_set : 1; + unsigned int ControlPort_set : 1; + unsigned int DirPort_set : 1; + unsigned int DNSPort_set : 1; + unsigned int ExtORPort_set : 1; + unsigned int HTTPTunnelPort_set : 1; + /**@}*/ + + int AssumeReachable; /**< Whether to publish our descriptor regardless. */ + int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */ + int V3AuthoritativeDir; /**< Boolean: is this an authoritative directory + * for version 3 directories? */ + int VersioningAuthoritativeDir; /**< Boolean: is this an authoritative + * directory that's willing to recommend + * versions? */ + int BridgeAuthoritativeDir; /**< Boolean: is this an authoritative directory + * that aggregates bridge descriptors? */ + + /** If set on a bridge relay, it will include this value on a new + * "bridge-distribution-request" line in its bridge descriptor. */ + char *BridgeDistribution; + + /** If set on a bridge authority, it will answer requests on its dirport + * for bridge statuses -- but only if the requests use this password. */ + char *BridgePassword; + /** If BridgePassword is set, this is a SHA256 digest of the basic http + * authenticator for it. Used so we can do a time-independent comparison. */ + char *BridgePassword_AuthDigest_; + + int UseBridges; /**< Boolean: should we start all circuits with a bridge? */ + struct config_line_t *Bridges; /**< List of bootstrap bridge addresses. */ + + struct config_line_t *ClientTransportPlugin; /**< List of client + transport plugins. */ + + struct config_line_t *ServerTransportPlugin; /**< List of client + transport plugins. */ + + /** List of TCP/IP addresses that transports should listen at. */ + struct config_line_t *ServerTransportListenAddr; + + /** List of options that must be passed to pluggable transports. */ + struct config_line_t *ServerTransportOptions; + + int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make + * this explicit so we can change how we behave in the + * future. */ + + /** Boolean: if we know the bridge's digest, should we get new + * descriptors from the bridge authorities or from the bridge itself? */ + int UpdateBridgesFromAuthority; + + int AvoidDiskWrites; /**< Boolean: should we never cache things to disk? + * Not used yet. */ + int ClientOnly; /**< Boolean: should we never evolve into a server role? */ + + int ReducedConnectionPadding; /**< Boolean: Should we try to keep connections + open shorter and pad them less against + connection-level traffic analysis? */ + /** Autobool: if auto, then connection padding will be negotiated by client + * and server. If 0, it will be fully disabled. If 1, the client will still + * pad to the server regardless of server support. */ + int ConnectionPadding; + + /** To what authority types do we publish our descriptor? Choices are + * "v1", "v2", "v3", "bridge", or "". */ + struct smartlist_t *PublishServerDescriptor; + /** A bitfield of authority types, derived from PublishServerDescriptor. */ + dirinfo_type_t PublishServerDescriptor_; + /** Boolean: do we publish hidden service descriptors to the HS auths? */ + int PublishHidServDescriptors; + int FetchServerDescriptors; /**< Do we fetch server descriptors as normal? */ + int FetchHidServDescriptors; /**< and hidden service descriptors? */ + + int MinUptimeHidServDirectoryV2; /**< As directory authority, accept hidden + * service directories after what time? */ + + int FetchUselessDescriptors; /**< Do we fetch non-running descriptors too? */ + int AllDirActionsPrivate; /**< Should every directory action be sent + * through a Tor circuit? */ + + /** Run in 'tor2web mode'? (I.e. only make client connections to hidden + * services, and use a single hop for all hidden-service-related + * circuits.) */ + int Tor2webMode; + + /** A routerset that should be used when picking RPs for HS circuits. */ + routerset_t *Tor2webRendezvousPoints; + + /** A routerset that should be used when picking middle nodes for HS + * circuits. */ + routerset_t *HSLayer2Nodes; + + /** A routerset that should be used when picking third-hop nodes for HS + * circuits. */ + routerset_t *HSLayer3Nodes; + + /** Onion Services in HiddenServiceSingleHopMode make one-hop (direct) + * circuits between the onion service server, and the introduction and + * rendezvous points. (Onion service descriptors are still posted using + * 3-hop paths, to avoid onion service directories blocking the service.) + * This option makes every hidden service instance hosted by + * this tor instance a Single Onion Service. + * HiddenServiceSingleHopMode requires HiddenServiceNonAnonymousMode to be + * set to 1. + * Use rend_service_allow_non_anonymous_connection() or + * rend_service_reveal_startup_time() instead of using this option directly. + */ + int HiddenServiceSingleHopMode; + /* Makes hidden service clients and servers non-anonymous on this tor + * instance. Allows the non-anonymous HiddenServiceSingleHopMode. Enables + * non-anonymous behaviour in the hidden service protocol. + * Use rend_service_non_anonymous_mode_enabled() instead of using this option + * directly. + */ + int HiddenServiceNonAnonymousMode; + + int ConnLimit; /**< Demanded minimum number of simultaneous connections. */ + int ConnLimit_; /**< Maximum allowed number of simultaneous connections. */ + int ConnLimit_high_thresh; /**< start trying to lower socket usage if we + * have this many. */ + int ConnLimit_low_thresh; /**< try to get down to here after socket + * exhaustion. */ + int RunAsDaemon; /**< If true, run in the background. (Unix only) */ + int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */ + struct smartlist_t *FirewallPorts; /**< Which ports our firewall allows + * (strings). */ + /** IP:ports our firewall allows. */ + struct config_line_t *ReachableAddresses; + struct config_line_t *ReachableORAddresses; /**< IP:ports for OR conns. */ + struct config_line_t *ReachableDirAddresses; /**< IP:ports for Dir conns. */ + + int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */ + uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */ + + /** Whether we should drop exit streams from Tors that we don't know are + * relays. One of "0" (never refuse), "1" (always refuse), or "-1" (do + * what the consensus says, defaulting to 'refuse' if the consensus says + * nothing). */ + int RefuseUnknownExits; + + /** Application ports that require all nodes in circ to have sufficient + * uptime. */ + struct smartlist_t *LongLivedPorts; + /** Application ports that are likely to be unencrypted and + * unauthenticated; we reject requests for them to prevent the + * user from screwing up and leaking plaintext secrets to an + * observer somewhere on the Internet. */ + struct smartlist_t *RejectPlaintextPorts; + /** Related to RejectPlaintextPorts above, except this config option + * controls whether we warn (in the log and via a controller status + * event) every time a risky connection is attempted. */ + struct smartlist_t *WarnPlaintextPorts; + /** Should we try to reuse the same exit node for a given host */ + struct smartlist_t *TrackHostExits; + int TrackHostExitsExpire; /**< Number of seconds until we expire an + * addressmap */ + struct config_line_t *AddressMap; /**< List of address map directives. */ + int AutomapHostsOnResolve; /**< If true, when we get a resolve request for a + * hostname ending with one of the suffixes in + * <b>AutomapHostsSuffixes</b>, map it to a + * virtual address. */ + /** List of suffixes for <b>AutomapHostsOnResolve</b>. The special value + * "." means "match everything." */ + struct smartlist_t *AutomapHostsSuffixes; + int RendPostPeriod; /**< How often do we post each rendezvous service + * descriptor? Remember to publish them independently. */ + int KeepalivePeriod; /**< How often do we send padding cells to keep + * connections alive? */ + int SocksTimeout; /**< How long do we let a socks connection wait + * unattached before we fail it? */ + int LearnCircuitBuildTimeout; /**< If non-zero, we attempt to learn a value + * for CircuitBuildTimeout based on timeout + * history. Use circuit_build_times_disabled() + * rather than checking this value directly. */ + int CircuitBuildTimeout; /**< Cull non-open circuits that were born at + * least this many seconds ago. Used until + * adaptive algorithm learns a new value. */ + int CircuitsAvailableTimeout; /**< Try to have an open circuit for at + least this long after last activity */ + int CircuitStreamTimeout; /**< If non-zero, detach streams from circuits + * and try a new circuit if the stream has been + * waiting for this many seconds. If zero, use + * our default internal timeout schedule. */ + int MaxOnionQueueDelay; /*< DOCDOC */ + int NewCircuitPeriod; /**< How long do we use a circuit before building + * a new one? */ + int MaxCircuitDirtiness; /**< Never use circs that were first used more than + this interval ago. */ + uint64_t BandwidthRate; /**< How much bandwidth, on average, are we willing + * to use in a second? */ + uint64_t BandwidthBurst; /**< How much bandwidth, at maximum, are we willing + * to use in a second? */ + uint64_t MaxAdvertisedBandwidth; /**< How much bandwidth are we willing to + * tell other nodes we have? */ + uint64_t RelayBandwidthRate; /**< How much bandwidth, on average, are we + * willing to use for all relayed conns? */ + uint64_t RelayBandwidthBurst; /**< How much bandwidth, at maximum, will we + * use in a second for all relayed conns? */ + uint64_t PerConnBWRate; /**< Long-term bw on a single TLS conn, if set. */ + uint64_t PerConnBWBurst; /**< Allowed burst on a single TLS conn, if set. */ + int NumCPUs; /**< How many CPUs should we try to use? */ + struct config_line_t *RendConfigLines; /**< List of configuration lines + * for rendezvous services. */ + struct config_line_t *HidServAuth; /**< List of configuration lines for + * client-side authorizations for hidden + * services */ + char *ContactInfo; /**< Contact info to be published in the directory. */ + + int HeartbeatPeriod; /**< Log heartbeat messages after this many seconds + * have passed. */ + int MainloopStats; /**< Log main loop statistics as part of the + * heartbeat messages. */ + + char *HTTPProxy; /**< hostname[:port] to use as http proxy, if any. */ + tor_addr_t HTTPProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */ + uint16_t HTTPProxyPort; /**< Parsed port for http proxy, if any. */ + char *HTTPProxyAuthenticator; /**< username:password string, if any. */ + + char *HTTPSProxy; /**< hostname[:port] to use as https proxy, if any. */ + tor_addr_t HTTPSProxyAddr; /**< Parsed addr for https proxy, if any. */ + uint16_t HTTPSProxyPort; /**< Parsed port for https proxy, if any. */ + char *HTTPSProxyAuthenticator; /**< username:password string, if any. */ + + char *Socks4Proxy; /**< hostname:port to use as a SOCKS4 proxy, if any. */ + tor_addr_t Socks4ProxyAddr; /**< Derived from Socks4Proxy. */ + uint16_t Socks4ProxyPort; /**< Derived from Socks4Proxy. */ + + char *Socks5Proxy; /**< hostname:port to use as a SOCKS5 proxy, if any. */ + tor_addr_t Socks5ProxyAddr; /**< Derived from Sock5Proxy. */ + uint16_t Socks5ProxyPort; /**< Derived from Socks5Proxy. */ + char *Socks5ProxyUsername; /**< Username for SOCKS5 authentication, if any */ + char *Socks5ProxyPassword; /**< Password for SOCKS5 authentication, if any */ + + /** List of configuration lines for replacement directory authorities. + * If you just want to replace one class of authority at a time, + * use the "Alternate*Authority" options below instead. */ + struct config_line_t *DirAuthorities; + + /** List of fallback directory servers */ + struct config_line_t *FallbackDir; + /** Whether to use the default hard-coded FallbackDirs */ + int UseDefaultFallbackDirs; + + /** Weight to apply to all directory authority rates if considering them + * along with fallbackdirs */ + double DirAuthorityFallbackRate; + + /** If set, use these main (currently v3) directory authorities and + * not the default ones. */ + struct config_line_t *AlternateDirAuthority; + + /** If set, use these bridge authorities and not the default one. */ + struct config_line_t *AlternateBridgeAuthority; + + struct config_line_t *MyFamily_lines; /**< Declared family for this OR. */ + struct config_line_t *MyFamily; /**< Declared family for this OR, + normalized */ + struct config_line_t *NodeFamilies; /**< List of config lines for + * node families */ + /** List of parsed NodeFamilies values. */ + struct smartlist_t *NodeFamilySets; + struct config_line_t *AuthDirBadExit; /**< Address policy for descriptors to + * mark as bad exits. */ + struct config_line_t *AuthDirReject; /**< Address policy for descriptors to + * reject. */ + struct config_line_t *AuthDirInvalid; /**< Address policy for descriptors to + * never mark as valid. */ + /** @name AuthDir...CC + * + * Lists of country codes to mark as BadExit, or Invalid, or to + * reject entirely. + * + * @{ + */ + struct smartlist_t *AuthDirBadExitCCs; + struct smartlist_t *AuthDirInvalidCCs; + struct smartlist_t *AuthDirRejectCCs; + /**@}*/ + + int AuthDirListBadExits; /**< True iff we should list bad exits, + * and vote for all other exits as good. */ + int AuthDirMaxServersPerAddr; /**< Do not permit more than this + * number of servers per IP address. */ + int AuthDirHasIPv6Connectivity; /**< Boolean: are we on IPv6? */ + int AuthDirPinKeys; /**< Boolean: Do we enforce key-pinning? */ + + /** If non-zero, always vote the Fast flag for any relay advertising + * this amount of capacity or more. */ + uint64_t AuthDirFastGuarantee; + + /** If non-zero, this advertised capacity or more is always sufficient + * to satisfy the bandwidth requirement for the Guard flag. */ + uint64_t AuthDirGuardBWGuarantee; + + char *AccountingStart; /**< How long is the accounting interval, and when + * does it start? */ + uint64_t AccountingMax; /**< How many bytes do we allow per accounting + * interval before hibernation? 0 for "never + * hibernate." */ + /** How do we determine when our AccountingMax has been reached? + * "max" for when in or out reaches AccountingMax + * "sum" for when in plus out reaches AccountingMax + * "in" for when in reaches AccountingMax + * "out" for when out reaches AccountingMax */ + char *AccountingRule_option; + enum { ACCT_MAX, ACCT_SUM, ACCT_IN, ACCT_OUT } AccountingRule; + + /** Base64-encoded hash of accepted passwords for the control system. */ + struct config_line_t *HashedControlPassword; + /** As HashedControlPassword, but not saved. */ + struct config_line_t *HashedControlSessionPassword; + + int CookieAuthentication; /**< Boolean: do we enable cookie-based auth for + * the control system? */ + char *CookieAuthFile; /**< Filesystem location of a ControlPort + * authentication cookie. */ + char *ExtORPortCookieAuthFile; /**< Filesystem location of Extended + * ORPort authentication cookie. */ + int CookieAuthFileGroupReadable; /**< Boolean: Is the CookieAuthFile g+r? */ + int ExtORPortCookieAuthFileGroupReadable; /**< Boolean: Is the + * ExtORPortCookieAuthFile g+r? */ + int LeaveStreamsUnattached; /**< Boolean: Does Tor attach new streams to + * circuits itself (0), or does it expect a controller + * to cope? (1) */ + int DisablePredictedCircuits; /**< Boolean: does Tor preemptively + * make circuits in the background (0), + * or not (1)? */ + + /** Process specifier for a controller that ‘owns’ this Tor + * instance. Tor will terminate if its owning controller does. */ + char *OwningControllerProcess; + /** FD specifier for a controller that owns this Tor instance. */ + int OwningControllerFD; + + int ShutdownWaitLength; /**< When we get a SIGINT and we're a server, how + * long do we wait before exiting? */ + char *SafeLogging; /**< Contains "relay", "1", "0" (meaning no scrubbing). */ + + /* Derived from SafeLogging */ + enum { + SAFELOG_SCRUB_ALL, SAFELOG_SCRUB_RELAY, SAFELOG_SCRUB_NONE + } SafeLogging_; + + int Sandbox; /**< Boolean: should sandboxing be enabled? */ + int SafeSocks; /**< Boolean: should we outright refuse application + * connections that use socks4 or socks5-with-local-dns? */ + int ProtocolWarnings; /**< Boolean: when other parties screw up the Tor + * protocol, is it a warn or an info in our logs? */ + int TestSocks; /**< Boolean: when we get a socks connection, do we loudly + * log whether it was DNS-leaking or not? */ + int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware + * acceleration where available? */ + /** Token Bucket Refill resolution in milliseconds. */ + int TokenBucketRefillInterval; + char *AccelName; /**< Optional hardware acceleration engine name. */ + char *AccelDir; /**< Optional hardware acceleration engine search dir. */ + + /** Boolean: Do we try to enter from a smallish number + * of fixed nodes? */ + int UseEntryGuards_option; + /** Internal variable to remember whether we're actually acting on + * UseEntryGuards_option -- when we're a non-anonymous Tor2web client or + * Single Onion Service, it is always false, otherwise we use the value of + * UseEntryGuards_option. */ + int UseEntryGuards; + + int NumEntryGuards; /**< How many entry guards do we try to establish? */ + + /** If 1, we use any guardfraction information we see in the + * consensus. If 0, we don't. If -1, let the consensus parameter + * decide. */ + int UseGuardFraction; + + int NumDirectoryGuards; /**< How many dir guards do we try to establish? + * If 0, use value from NumEntryGuards. */ + int NumPrimaryGuards; /**< How many primary guards do we want? */ + + int RephistTrackTime; /**< How many seconds do we keep rephist info? */ + /** Should we always fetch our dir info on the mirror schedule (which + * means directly from the authorities) no matter our other config? */ + int FetchDirInfoEarly; + + /** Should we fetch our dir info at the start of the consensus period? */ + int FetchDirInfoExtraEarly; + + int DirCache; /**< Cache all directory documents and accept requests via + * tunnelled dir conns from clients. If 1, enabled (default); + * If 0, disabled. */ + + char *VirtualAddrNetworkIPv4; /**< Address and mask to hand out for virtual + * MAPADDRESS requests for IPv4 addresses */ + char *VirtualAddrNetworkIPv6; /**< Address and mask to hand out for virtual + * MAPADDRESS requests for IPv6 addresses */ + int ServerDNSSearchDomains; /**< Boolean: If set, we don't force exit + * addresses to be FQDNs, but rather search for them in + * the local domains. */ + int ServerDNSDetectHijacking; /**< Boolean: If true, check for DNS failure + * hijacking. */ + int ServerDNSRandomizeCase; /**< Boolean: Use the 0x20-hack to prevent + * DNS poisoning attacks. */ + char *ServerDNSResolvConfFile; /**< If provided, we configure our internal + * resolver from the file here rather than from + * /etc/resolv.conf (Unix) or the registry (Windows). */ + char *DirPortFrontPage; /**< This is a full path to a file with an html + disclaimer. This allows a server administrator to show + that they're running Tor and anyone visiting their server + will know this without any specialized knowledge. */ + int DisableDebuggerAttachment; /**< Currently Linux only specific attempt to + disable ptrace; needs BSD testing. */ + /** Boolean: if set, we start even if our resolv.conf file is missing + * or broken. */ + int ServerDNSAllowBrokenConfig; + /** Boolean: if set, then even connections to private addresses will get + * rate-limited. */ + int CountPrivateBandwidth; + /** A list of addresses that definitely should be resolvable. Used for + * testing our DNS server. */ + struct smartlist_t *ServerDNSTestAddresses; + int EnforceDistinctSubnets; /**< If true, don't allow multiple routers in the + * same network zone in the same circuit. */ + int AllowNonRFC953Hostnames; /**< If true, we allow connections to hostnames + * with weird characters. */ + /** If true, we try resolving hostnames with weird characters. */ + int ServerDNSAllowNonRFC953Hostnames; + + /** If true, we try to download extra-info documents (and we serve them, + * if we are a cache). For authorities, this is always true. */ + int DownloadExtraInfo; + + /** If true, we're configured to collect statistics on clients + * requesting network statuses from us as directory. */ + int DirReqStatistics_option; + /** Internal variable to remember whether we're actually acting on + * DirReqStatistics_option -- yes if it's set and we're a server, else no. */ + int DirReqStatistics; + + /** If true, the user wants us to collect statistics on port usage. */ + int ExitPortStatistics; + + /** If true, the user wants us to collect connection statistics. */ + int ConnDirectionStatistics; + + /** If true, the user wants us to collect cell statistics. */ + int CellStatistics; + + /** If true, the user wants us to collect padding statistics. */ + int PaddingStatistics; + + /** If true, the user wants us to collect statistics as entry node. */ + int EntryStatistics; + + /** If true, the user wants us to collect statistics as hidden service + * directory, introduction point, or rendezvous point. */ + int HiddenServiceStatistics_option; + /** Internal variable to remember whether we're actually acting on + * HiddenServiceStatistics_option -- yes if it's set and we're a server, + * else no. */ + int HiddenServiceStatistics; + + /** If true, include statistics file contents in extra-info documents. */ + int ExtraInfoStatistics; + + /** If true, do not believe anybody who tells us that a domain resolves + * to an internal address, or that an internal address has a PTR mapping. + * Helps avoid some cross-site attacks. */ + int ClientDNSRejectInternalAddresses; + + /** If true, do not accept any requests to connect to internal addresses + * over randomly chosen exits. */ + int ClientRejectInternalAddresses; + + /** If true, clients may connect over IPv4. If false, they will avoid + * connecting over IPv4. We enforce this for OR and Dir connections. */ + int ClientUseIPv4; + /** If true, clients may connect over IPv6. If false, they will avoid + * connecting over IPv4. We enforce this for OR and Dir connections. + * Use fascist_firewall_use_ipv6() instead of accessing this value + * directly. */ + int ClientUseIPv6; + /** If true, prefer an IPv6 OR port over an IPv4 one for entry node + * connections. If auto, bridge clients prefer IPv6, and other clients + * prefer IPv4. Use node_ipv6_or_preferred() instead of accessing this value + * directly. */ + int ClientPreferIPv6ORPort; + /** If true, prefer an IPv6 directory port over an IPv4 one for direct + * directory connections. If auto, bridge clients prefer IPv6, and other + * clients prefer IPv4. Use fascist_firewall_prefer_ipv6_dirport() instead of + * accessing this value directly. */ + int ClientPreferIPv6DirPort; + + /** The length of time that we think a consensus should be fresh. */ + int V3AuthVotingInterval; + /** The length of time we think it will take to distribute votes. */ + int V3AuthVoteDelay; + /** The length of time we think it will take to distribute signatures. */ + int V3AuthDistDelay; + /** The number of intervals we think a consensus should be valid. */ + int V3AuthNIntervalsValid; + + /** Should advertise and sign consensuses with a legacy key, for key + * migration purposes? */ + int V3AuthUseLegacyKey; + + /** Location of bandwidth measurement file */ + char *V3BandwidthsFile; + + /** Location of guardfraction file */ + char *GuardfractionFile; + + /** Authority only: key=value pairs that we add to our networkstatus + * consensus vote on the 'params' line. */ + char *ConsensusParams; + + /** Authority only: minimum number of measured bandwidths we must see + * before we only believe measured bandwidths to assign flags. */ + int MinMeasuredBWsForAuthToIgnoreAdvertised; + + /** The length of time that we think an initial consensus should be fresh. + * Only altered on testing networks. */ + int TestingV3AuthInitialVotingInterval; + + /** The length of time we think it will take to distribute initial votes. + * Only altered on testing networks. */ + int TestingV3AuthInitialVoteDelay; + + /** The length of time we think it will take to distribute initial + * signatures. Only altered on testing networks.*/ + int TestingV3AuthInitialDistDelay; + + /** Offset in seconds added to the starting time for consensus + voting. Only altered on testing networks. */ + int TestingV3AuthVotingStartOffset; + + /** If an authority has been around for less than this amount of time, it + * does not believe its reachability information is accurate. Only + * altered on testing networks. */ + int TestingAuthDirTimeToLearnReachability; + + /** Clients don't download any descriptor this recent, since it will + * probably not have propagated to enough caches. Only altered on testing + * networks. */ + int TestingEstimatedDescriptorPropagationTime; + + /** Schedule for when servers should download things in general. Only + * altered on testing networks. */ + int TestingServerDownloadInitialDelay; + + /** Schedule for when clients should download things in general. Only + * altered on testing networks. */ + int TestingClientDownloadInitialDelay; + + /** Schedule for when servers should download consensuses. Only altered + * on testing networks. */ + int TestingServerConsensusDownloadInitialDelay; + + /** Schedule for when clients should download consensuses. Only altered + * on testing networks. */ + int TestingClientConsensusDownloadInitialDelay; + + /** Schedule for when clients should download consensuses from authorities + * if they are bootstrapping (that is, they don't have a usable, reasonably + * live consensus). Only used by clients fetching from a list of fallback + * directory mirrors. + * + * This schedule is incremented by (potentially concurrent) connection + * attempts, unlike other schedules, which are incremented by connection + * failures. Only altered on testing networks. */ + int ClientBootstrapConsensusAuthorityDownloadInitialDelay; + + /** Schedule for when clients should download consensuses from fallback + * directory mirrors if they are bootstrapping (that is, they don't have a + * usable, reasonably live consensus). Only used by clients fetching from a + * list of fallback directory mirrors. + * + * This schedule is incremented by (potentially concurrent) connection + * attempts, unlike other schedules, which are incremented by connection + * failures. Only altered on testing networks. */ + int ClientBootstrapConsensusFallbackDownloadInitialDelay; + + /** Schedule for when clients should download consensuses from authorities + * if they are bootstrapping (that is, they don't have a usable, reasonably + * live consensus). Only used by clients which don't have or won't fetch + * from a list of fallback directory mirrors. + * + * This schedule is incremented by (potentially concurrent) connection + * attempts, unlike other schedules, which are incremented by connection + * failures. Only altered on testing networks. */ + int ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay; + + /** Schedule for when clients should download bridge descriptors. Only + * altered on testing networks. */ + int TestingBridgeDownloadInitialDelay; + + /** Schedule for when clients should download bridge descriptors when they + * have no running bridges. Only altered on testing networks. */ + int TestingBridgeBootstrapDownloadInitialDelay; + + /** When directory clients have only a few descriptors to request, they + * batch them until they have more, or until this amount of time has + * passed. Only altered on testing networks. */ + int TestingClientMaxIntervalWithoutRequest; + + /** How long do we let a directory connection stall before expiring + * it? Only altered on testing networks. */ + int TestingDirConnectionMaxStall; + + /** How many simultaneous in-progress connections will we make when trying + * to fetch a consensus before we wait for one to complete, timeout, or + * error out? Only altered on testing networks. */ + int ClientBootstrapConsensusMaxInProgressTries; + + /** If true, we take part in a testing network. Change the defaults of a + * couple of other configuration options and allow to change the values + * of certain configuration options. */ + int TestingTorNetwork; + + /** Minimum value for the Exit flag threshold on testing networks. */ + uint64_t TestingMinExitFlagThreshold; + + /** Minimum value for the Fast flag threshold on testing networks. */ + uint64_t TestingMinFastFlagThreshold; + + /** Relays in a testing network which should be voted Exit + * regardless of exit policy. */ + routerset_t *TestingDirAuthVoteExit; + int TestingDirAuthVoteExitIsStrict; + + /** Relays in a testing network which should be voted Guard + * regardless of uptime and bandwidth. */ + routerset_t *TestingDirAuthVoteGuard; + int TestingDirAuthVoteGuardIsStrict; + + /** Relays in a testing network which should be voted HSDir + * regardless of uptime and DirPort. */ + routerset_t *TestingDirAuthVoteHSDir; + int TestingDirAuthVoteHSDirIsStrict; + + /** Enable CONN_BW events. Only altered on testing networks. */ + int TestingEnableConnBwEvent; + + /** Enable CELL_STATS events. Only altered on testing networks. */ + int TestingEnableCellStatsEvent; + + /** If true, and we have GeoIP data, and we're a bridge, keep a per-country + * count of how many client addresses have contacted us so that we can help + * the bridge authority guess which countries have blocked access to us. */ + int BridgeRecordUsageByCountry; + + /** Optionally, IPv4 and IPv6 GeoIP data. */ + char *GeoIPFile; + char *GeoIPv6File; + + /** Autobool: if auto, then any attempt to Exclude{Exit,}Nodes a particular + * country code will exclude all nodes in ?? and A1. If true, all nodes in + * ?? and A1 are excluded. Has no effect if we don't know any GeoIP data. */ + int GeoIPExcludeUnknown; + + /** If true, SIGHUP should reload the torrc. Sometimes controllers want + * to make this false. */ + int ReloadTorrcOnSIGHUP; + + /* The main parameter for picking circuits within a connection. + * + * If this value is positive, when picking a cell to relay on a connection, + * we always relay from the circuit whose weighted cell count is lowest. + * Cells are weighted exponentially such that if one cell is sent + * 'CircuitPriorityHalflife' seconds before another, it counts for half as + * much. + * + * If this value is zero, we're disabling the cell-EWMA algorithm. + * + * If this value is negative, we're using the default approach + * according to either Tor or a parameter set in the consensus. + */ + double CircuitPriorityHalflife; + + /** Set to true if the TestingTorNetwork configuration option is set. + * This is used so that options_validate() has a chance to realize that + * the defaults have changed. */ + int UsingTestNetworkDefaults_; + + /** If 1, we try to use microdescriptors to build circuits. If 0, we don't. + * If -1, Tor decides. */ + int UseMicrodescriptors; + + /** File where we should write the ControlPort. */ + char *ControlPortWriteToFile; + /** Should that file be group-readable? */ + int ControlPortFileGroupReadable; + +#define MAX_MAX_CLIENT_CIRCUITS_PENDING 1024 + /** Maximum number of non-open general-purpose origin circuits to allow at + * once. */ + int MaxClientCircuitsPending; + + /** If 1, we always send optimistic data when it's supported. If 0, we + * never use it. If -1, we do what the consensus says. */ + int OptimisticData; + + /** If 1, we accept and launch no external network connections, except on + * control ports. */ + int DisableNetwork; + + /** + * Parameters for path-bias detection. + * @{ + * These options override the default behavior of Tor's (**currently + * experimental**) path bias detection algorithm. To try to find broken or + * misbehaving guard nodes, Tor looks for nodes where more than a certain + * fraction of circuits through that guard fail to get built. + * + * The PathBiasCircThreshold option controls how many circuits we need to + * build through a guard before we make these checks. The + * PathBiasNoticeRate, PathBiasWarnRate and PathBiasExtremeRate options + * control what fraction of circuits must succeed through a guard so we + * won't write log messages. If less than PathBiasExtremeRate circuits + * succeed *and* PathBiasDropGuards is set to 1, we disable use of that + * guard. + * + * When we have seen more than PathBiasScaleThreshold circuits through a + * guard, we scale our observations by 0.5 (governed by the consensus) so + * that new observations don't get swamped by old ones. + * + * By default, or if a negative value is provided for one of these options, + * Tor uses reasonable defaults from the networkstatus consensus document. + * If no defaults are available there, these options default to 150, .70, + * .50, .30, 0, and 300 respectively. + */ + int PathBiasCircThreshold; + double PathBiasNoticeRate; + double PathBiasWarnRate; + double PathBiasExtremeRate; + int PathBiasDropGuards; + int PathBiasScaleThreshold; + /** @} */ + + /** + * Parameters for path-bias use detection + * @{ + * Similar to the above options, these options override the default behavior + * of Tor's (**currently experimental**) path use bias detection algorithm. + * + * Where as the path bias parameters govern thresholds for successfully + * building circuits, these four path use bias parameters govern thresholds + * only for circuit usage. Circuits which receive no stream usage are not + * counted by this detection algorithm. A used circuit is considered + * successful if it is capable of carrying streams or otherwise receiving + * well-formed responses to RELAY cells. + * + * By default, or if a negative value is provided for one of these options, + * Tor uses reasonable defaults from the networkstatus consensus document. + * If no defaults are available there, these options default to 20, .80, + * .60, and 100, respectively. + */ + int PathBiasUseThreshold; + double PathBiasNoticeUseRate; + double PathBiasExtremeUseRate; + int PathBiasScaleUseThreshold; + /** @} */ + + int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */ + + /** Fraction: */ + double PathsNeededToBuildCircuits; + + /** What expiry time shall we place on our SSL certs? "0" means we + * should guess a suitable value. */ + int SSLKeyLifetime; + + /** How long (seconds) do we keep a guard before picking a new one? */ + int GuardLifetime; + + /** Is this an exit node? This is a tristate, where "1" means "yes, and use + * the default exit policy if none is given" and "0" means "no; exit policy + * is 'reject *'" and "auto" (-1) means "same as 1, but warn the user." + * + * XXXX Eventually, the default will be 0. */ + int ExitRelay; + + /** For how long (seconds) do we declare our signing keys to be valid? */ + int SigningKeyLifetime; + /** For how long (seconds) do we declare our link keys to be valid? */ + int TestingLinkCertLifetime; + /** For how long (seconds) do we declare our auth keys to be valid? */ + int TestingAuthKeyLifetime; + + /** How long before signing keys expire will we try to make a new one? */ + int TestingSigningKeySlop; + /** How long before link keys expire will we try to make a new one? */ + int TestingLinkKeySlop; + /** How long before auth keys expire will we try to make a new one? */ + int TestingAuthKeySlop; + + /** Force use of offline master key features: never generate a master + * ed25519 identity key except from tor --keygen */ + int OfflineMasterKey; + + enum { + FORCE_PASSPHRASE_AUTO=0, + FORCE_PASSPHRASE_ON, + FORCE_PASSPHRASE_OFF + } keygen_force_passphrase; + int use_keygen_passphrase_fd; + int keygen_passphrase_fd; + int change_key_passphrase; + char *master_key_fname; + + /** Autobool: Do we try to retain capabilities if we can? */ + int KeepBindCapabilities; + + /** Maximum total size of unparseable descriptors to log during the + * lifetime of this Tor process. + */ + uint64_t MaxUnparseableDescSizeToLog; + + /** Bool (default: 1): Switch for the shared random protocol. Only + * relevant to a directory authority. If off, the authority won't + * participate in the protocol. If on (default), a flag is added to the + * vote indicating participation. */ + int AuthDirSharedRandomness; + + /** If 1, we skip all OOS checks. */ + int DisableOOSCheck; + + /** Autobool: Should we include Ed25519 identities in extend2 cells? + * If -1, we should do whatever the consensus parameter says. */ + int ExtendByEd25519ID; + + /** Bool (default: 1): When testing routerinfos as a directory authority, + * do we enforce Ed25519 identity match? */ + /* NOTE: remove this option someday. */ + int AuthDirTestEd25519LinkKeys; + + /** Bool (default: 0): Tells if a %include was used on torrc */ + int IncludeUsed; + + /** The seconds after expiration which we as a relay should keep old + * consensuses around so that we can generate diffs from them. If 0, + * use the default. */ + int MaxConsensusAgeForDiffs; + + /** Bool (default: 0). Tells Tor to never try to exec another program. + */ + int NoExec; + + /** Have the KIST scheduler run every X milliseconds. If less than zero, do + * not use the KIST scheduler but use the old vanilla scheduler instead. If + * zero, do what the consensus says and fall back to using KIST as if this is + * set to "10 msec" if the consensus doesn't say anything. */ + int KISTSchedRunInterval; + + /** A multiplier for the KIST per-socket limit calculation. */ + double KISTSockBufSizeFactor; + + /** The list of scheduler type string ordered by priority that is first one + * has to be tried first. Default: KIST,KISTLite,Vanilla */ + struct smartlist_t *Schedulers; + /* An ordered list of scheduler_types mapped from Schedulers. */ + struct smartlist_t *SchedulerTypes_; + + /** List of files that were opened by %include in torrc and torrc-defaults */ + struct smartlist_t *FilesOpenedByIncludes; + + /** If true, Tor shouldn't install any posix signal handlers, since it is + * running embedded inside another process. + */ + int DisableSignalHandlers; + + /** Autobool: Is the circuit creation DoS mitigation subsystem enabled? */ + int DoSCircuitCreationEnabled; + /** Minimum concurrent connection needed from one single address before any + * defense is used. */ + int DoSCircuitCreationMinConnections; + /** Circuit rate used to refill the token bucket. */ + int DoSCircuitCreationRate; + /** Maximum allowed burst of circuits. Reaching that value, the address is + * detected as malicious and a defense might be used. */ + int DoSCircuitCreationBurst; + /** When an address is marked as malicous, what defense should be used + * against it. See the dos_cc_defense_type_t enum. */ + int DoSCircuitCreationDefenseType; + /** For how much time (in seconds) the defense is applicable for a malicious + * address. A random time delta is added to the defense time of an address + * which will be between 1 second and half of this value. */ + int DoSCircuitCreationDefenseTimePeriod; + + /** Autobool: Is the DoS connection mitigation subsystem enabled? */ + int DoSConnectionEnabled; + /** Maximum concurrent connection allowed per address. */ + int DoSConnectionMaxConcurrentCount; + /** When an address is reaches the maximum count, what defense should be + * used against it. See the dos_conn_defense_type_t enum. */ + int DoSConnectionDefenseType; + + /** Autobool: Do we refuse single hop client rendezvous? */ + int DoSRefuseSingleHopClientRendezvous; +}; + +#endif diff --git a/src/or/or_state_st.h b/src/or/or_state_st.h new file mode 100644 index 0000000000..f1d5f981f1 --- /dev/null +++ b/src/or/or_state_st.h @@ -0,0 +1,86 @@ +/* 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 TOR_OR_STATE_ST_H +#define TOR_OR_STATE_ST_H + +#include "lib/cc/torint.h" +struct smartlist_t; + +/** Persistent state for an onion router, as saved to disk. */ +struct or_state_t { + uint32_t magic_; + /** The time at which we next plan to write the state to the disk. Equal to + * TIME_MAX if there are no savable changes, 0 if there are changes that + * should be saved right away. */ + time_t next_write; + + /** When was the state last written to disk? */ + time_t LastWritten; + + /** Fields for accounting bandwidth use. */ + time_t AccountingIntervalStart; + uint64_t AccountingBytesReadInInterval; + uint64_t AccountingBytesWrittenInInterval; + int AccountingSecondsActive; + int AccountingSecondsToReachSoftLimit; + time_t AccountingSoftLimitHitAt; + uint64_t AccountingBytesAtSoftLimit; + uint64_t AccountingExpectedUsage; + + /** A list of Entry Guard-related configuration lines. (pre-prop271) */ + struct config_line_t *EntryGuards; + + /** A list of guard-related configuration lines. (post-prop271) */ + struct config_line_t *Guard; + + struct config_line_t *TransportProxies; + + /** Cached revision counters for active hidden services on this host */ + struct config_line_t *HidServRevCounter; + + /** These fields hold information on the history of bandwidth usage for + * servers. The "Ends" fields hold the time when we last updated the + * bandwidth usage. The "Interval" fields hold the granularity, in seconds, + * of the entries of Values. The "Values" lists hold decimal string + * representations of the number of bytes read or written in each + * interval. The "Maxima" list holds decimal strings describing the highest + * rate achieved during the interval. + */ + time_t BWHistoryReadEnds; + int BWHistoryReadInterval; + struct smartlist_t *BWHistoryReadValues; + struct smartlist_t *BWHistoryReadMaxima; + time_t BWHistoryWriteEnds; + int BWHistoryWriteInterval; + struct smartlist_t *BWHistoryWriteValues; + struct smartlist_t *BWHistoryWriteMaxima; + time_t BWHistoryDirReadEnds; + int BWHistoryDirReadInterval; + struct smartlist_t *BWHistoryDirReadValues; + struct smartlist_t *BWHistoryDirReadMaxima; + time_t BWHistoryDirWriteEnds; + int BWHistoryDirWriteInterval; + struct smartlist_t *BWHistoryDirWriteValues; + struct smartlist_t *BWHistoryDirWriteMaxima; + + /** Build time histogram */ + struct config_line_t * BuildtimeHistogram; + int TotalBuildTimes; + int CircuitBuildAbandonedCount; + + /** What version of Tor wrote this state file? */ + char *TorVersion; + + /** Holds any unrecognized values we found in the state file, in the order + * in which we found them. */ + struct config_line_t *ExtraLines; + + /** When did we last rotate our onion key? "0" for 'no idea'. */ + time_t LastRotatedOnionKey; +}; + +#endif diff --git a/src/or/origin_circuit_st.h b/src/or/origin_circuit_st.h new file mode 100644 index 0000000000..b885725edb --- /dev/null +++ b/src/or/origin_circuit_st.h @@ -0,0 +1,290 @@ +/* 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 ORIGIN_CIRCUIT_ST_H +#define ORIGIN_CIRCUIT_ST_H + +#include "or/or.h" + +#include "or/circuit_st.h" + +struct onion_queue_t; + +/** + * Describes the circuit building process in simplified terms based + * on the path bias accounting state for a circuit. + * + * NOTE: These state values are enumerated in the order for which we + * expect circuits to transition through them. If you add states, + * you need to preserve this overall ordering. The various pathbias + * state transition and accounting functions (pathbias_mark_* and + * pathbias_count_*) contain ordinal comparisons to enforce proper + * state transitions for corrections. + * + * This state machine and the associated logic was created to prevent + * miscounting due to unknown cases of circuit reuse. See also tickets + * #6475 and #7802. + */ +enum path_state_t { + /** This circuit is "new". It has not yet completed a first hop + * or been counted by the path bias code. */ + PATH_STATE_NEW_CIRC = 0, + /** This circuit has completed one/two hops, and has been counted by + * the path bias logic. */ + PATH_STATE_BUILD_ATTEMPTED = 1, + /** This circuit has been completely built */ + PATH_STATE_BUILD_SUCCEEDED = 2, + /** Did we try to attach any SOCKS streams or hidserv introductions to + * this circuit? + * + * Note: If we ever implement end-to-end stream timing through test + * stream probes (#5707), we must *not* set this for those probes + * (or any other automatic streams) because the adversary could + * just tag at a later point. + */ + PATH_STATE_USE_ATTEMPTED = 3, + /** Did any SOCKS streams or hidserv introductions actually succeed on + * this circuit? + * + * If any streams detatch/fail from this circuit, the code transitions + * the circuit back to PATH_STATE_USE_ATTEMPTED to ensure we probe. See + * pathbias_mark_use_rollback() for that. + */ + PATH_STATE_USE_SUCCEEDED = 4, + + /** + * This is a special state to indicate that we got a corrupted + * relay cell on a circuit and we don't intend to probe it. + */ + PATH_STATE_USE_FAILED = 5, + + /** + * This is a special state to indicate that we already counted + * the circuit. Used to guard against potential state machine + * violations. + */ + PATH_STATE_ALREADY_COUNTED = 6, +}; + +/** 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 <em>attached</em> 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 <em>ever</em> 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/parsecommon.c b/src/or/parsecommon.c index 9bd00e17ce..4340f28225 100644 --- a/src/or/parsecommon.c +++ b/src/or/parsecommon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -6,9 +6,17 @@ * \brief Common code to parse and validate various type of descriptors. **/ -#include "parsecommon.h" -#include "torlog.h" -#include "util_format.h" +#include "or/parsecommon.h" +#include "lib/log/torlog.h" +#include "lib/log/util_bug.h" +#include "lib/encoding/binascii.h" +#include "lib/container/smartlist.h" +#include "lib/string/util_string.h" +#include "lib/string/printf.h" +#include "lib/memarea/memarea.h" +#include "lib/crypt_ops/crypto.h" + +#include <string.h> #define MIN_ANNOTATION A_PURPOSE #define MAX_ANNOTATION A_UNKNOWN_ @@ -448,4 +456,3 @@ find_all_by_keyword(const smartlist_t *s, directory_keyword k) }); return out; } - diff --git a/src/or/parsecommon.h b/src/or/parsecommon.h index d33faf8ec7..d0f3810c0b 100644 --- a/src/or/parsecommon.h +++ b/src/or/parsecommon.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,9 +9,11 @@ #ifndef TOR_PARSECOMMON_H #define TOR_PARSECOMMON_H -#include "container.h" -#include "crypto.h" -#include "memarea.h" +#include <stddef.h> + +struct smartlist_t; +struct crypto_pk_t; +struct memarea_t; /** Enumeration of possible token types. The ones starting with K_ correspond * to directory 'keywords'. A_ is for an annotation, R or C is related to @@ -205,7 +207,7 @@ typedef struct directory_token_t { size_t object_size; /**< Bytes in object_body */ char *object_body; /**< Contents of object, base64-decoded. */ - crypto_pk_t *key; /**< For public keys only. Heap-allocated. */ + struct crypto_pk_t *key; /**< For public keys only. Heap-allocated. */ char *error; /**< For ERR_ tokens only. */ } directory_token_t; @@ -297,26 +299,26 @@ typedef struct token_rule_t { void token_clear(directory_token_t *tok); -int tokenize_string(memarea_t *area, +int tokenize_string(struct memarea_t *area, const char *start, const char *end, - smartlist_t *out, + struct smartlist_t *out, token_rule_t *table, int flags); -directory_token_t *get_next_token(memarea_t *area, +directory_token_t *get_next_token(struct memarea_t *area, const char **s, const char *eos, token_rule_t *table); -directory_token_t *find_by_keyword_(smartlist_t *s, +directory_token_t *find_by_keyword_(struct smartlist_t *s, directory_keyword keyword, const char *keyword_str); #define find_by_keyword(s, keyword) \ find_by_keyword_((s), (keyword), #keyword) -directory_token_t *find_opt_by_keyword(const smartlist_t *s, +directory_token_t *find_opt_by_keyword(const struct smartlist_t *s, directory_keyword keyword); -smartlist_t * find_all_by_keyword(const smartlist_t *s, directory_keyword k); +struct smartlist_t * find_all_by_keyword(const struct smartlist_t *s, + directory_keyword k); #endif /* !defined(TOR_PARSECOMMON_H) */ - diff --git a/src/or/periodic.c b/src/or/periodic.c index 92fa677f8f..0cbf359b2e 100644 --- a/src/or/periodic.c +++ b/src/or/periodic.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Tor Project, Inc. */ +/* Copyright (c) 2015-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,11 +11,12 @@ * that they fire. See periodic_events[] in main.c for examples. */ -#include "or.h" -#include "compat_libevent.h" -#include "config.h" -#include "main.h" -#include "periodic.h" +#include "or/or.h" +#include "common/compat_libevent.h" +#include "or/config.h" +#include "or/main.h" +#include "or/periodic.h" +#include "common/compat_libevent.h" /** We disable any interval greater than this number of seconds, on the * grounds that it is probably an absolute time mistakenly passed in as a @@ -169,4 +170,3 @@ periodic_event_disable(periodic_event_item_t *event) mainloop_event_cancel(event->ev); event->enabled = 0; } - diff --git a/src/or/periodic.h b/src/or/periodic.h index e8208b2475..4c8c3c96cc 100644 --- a/src/or/periodic.h +++ b/src/or/periodic.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Tor Project, Inc. */ +/* Copyright (c) 2015-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PERIODIC_H diff --git a/src/or/policies.c b/src/or/policies.c index 1210ca687d..53e00e8083 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,18 +17,27 @@ #define POLICIES_PRIVATE -#include "or.h" -#include "bridges.h" -#include "config.h" -#include "dirserv.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "router.h" -#include "routerparse.h" -#include "geoip.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/config.h" +#include "or/dirserv.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/router.h" +#include "or/routerparse.h" +#include "or/geoip.h" #include "ht.h" +#include "lib/encoding/confline.h" + +#include "or/addr_policy_st.h" +#include "or/dir_server_st.h" +#include "or/microdesc_st.h" +#include "or/node_st.h" +#include "or/port_cfg_st.h" +#include "or/routerinfo_st.h" +#include "or/routerstatus_st.h" /** Policy that addresses for incoming SOCKS connections must match. */ static smartlist_t *socks_policy = NULL; @@ -2401,7 +2410,7 @@ policy_summary_item_split(policy_summary_item_t* old, uint16_t new_starts) #define REJECT_CUTOFF_SCALE_IPV4 (0) /* Ports are rejected in an IPv4 summary if they are rejected in more than two * IPv4 /8 address blocks */ -#define REJECT_CUTOFF_COUNT_IPV4 (U64_LITERAL(1) << \ +#define REJECT_CUTOFF_COUNT_IPV4 (UINT64_C(1) << \ (IPV4_BITS - REJECT_CUTOFF_SCALE_IPV4 - 7)) #define IPV6_BITS (128) @@ -2413,7 +2422,7 @@ policy_summary_item_split(policy_summary_item_t* old, uint16_t new_starts) * some scattered smaller blocks) have been allocated to the RIRs. * Network providers are typically allocated one or more IPv6 /32s. */ -#define REJECT_CUTOFF_COUNT_IPV6 (U64_LITERAL(1) << \ +#define REJECT_CUTOFF_COUNT_IPV6 (UINT64_C(1) << \ (IPV6_BITS - REJECT_CUTOFF_SCALE_IPV6 - 16)) /** Split an exit policy summary so that prt_min and prt_max @@ -2508,7 +2517,7 @@ policy_summary_reject(smartlist_t *summary, * in the range. */ count = UINT64_MAX; } else { - count = (U64_LITERAL(1) << (addrbits - scale - maskbits)); + count = (UINT64_C(1) << (addrbits - scale - maskbits)); } tor_assert_nonfatal_once(count > 0); while (i < smartlist_len(summary) && @@ -3136,4 +3145,3 @@ policies_free_all(void) } HT_CLEAR(policy_map, &policy_root); } - diff --git a/src/or/policies.h b/src/or/policies.h index 4879acdd8d..7da3ba031f 100644 --- a/src/or/policies.h +++ b/src/or/policies.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -34,6 +34,39 @@ typedef enum firewall_connection_t { typedef int exit_policy_parser_cfg_t; +/** Outcome of applying an address policy to an address. */ +typedef enum { + /** The address was accepted */ + ADDR_POLICY_ACCEPTED=0, + /** The address was rejected */ + ADDR_POLICY_REJECTED=-1, + /** Part of the address was unknown, but as far as we can tell, it was + * accepted. */ + ADDR_POLICY_PROBABLY_ACCEPTED=1, + /** Part of the address was unknown, but as far as we can tell, it was + * rejected. */ + ADDR_POLICY_PROBABLY_REJECTED=2, +} addr_policy_result_t; + +/** A single entry in a parsed policy summary, describing a range of ports. */ +typedef struct short_policy_entry_t { + uint16_t min_port, max_port; +} short_policy_entry_t; + +/** A short_poliy_t is the parsed version of a policy summary. */ +typedef struct short_policy_t { + /** True if the members of 'entries' are port ranges to accept; false if + * they are port ranges to reject */ + unsigned int is_accept : 1; + /** The actual number of values in 'entries'. */ + unsigned int n_entries : 31; + /** An array of 0 or more short_policy_entry_t values, each describing a + * range of ports that this policy accepts or rejects (depending on the + * value of is_accept). + */ + short_policy_entry_t entries[FLEXIBLE_ARRAY_MEMBER]; +} short_policy_t; + int firewall_is_fascist_or(void); int firewall_is_fascist_dir(void); int fascist_firewall_use_ipv6(const or_options_t *options); @@ -88,7 +121,8 @@ int policies_parse_exit_policy_from_options( uint32_t local_address, const tor_addr_t *ipv6_local_address, smartlist_t **result); -int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest, +struct config_line_t; +int policies_parse_exit_policy(struct config_line_t *cfg, smartlist_t **dest, exit_policy_parser_cfg_t options, const smartlist_t *configured_addresses); void policies_parse_exit_policy_reject_private( @@ -151,4 +185,3 @@ STATIC const tor_addr_port_t * fascist_firewall_choose_address( #endif /* defined(POLICIES_PRIVATE) */ #endif /* !defined(TOR_POLICIES_H) */ - diff --git a/src/or/port_cfg_st.h b/src/or/port_cfg_st.h new file mode 100644 index 0000000000..86a3b963bc --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef PORT_CFG_ST_H +#define PORT_CFG_ST_H + +#include "or/entry_port_cfg_st.h" +#include "or/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..41554bd1b0 100644 --- a/src/or/proto_cell.c +++ b/src/or/proto_cell.c @@ -1,14 +1,16 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" -#include "buffers.h" -#include "proto_cell.h" +#include "or/or.h" +#include "lib/container/buffers.h" +#include "or/proto_cell.h" -#include "connection_or.h" +#include "or/connection_or.h" + +#include "or/var_cell_st.h" /** True iff the cell command <b>command</b> is one that implies a * variable-length cell in Tor link protocol <b>linkproto</b>. */ diff --git a/src/or/proto_cell.h b/src/or/proto_cell.h index bbc14b9a02..b29645e41d 100644 --- a/src/or/proto_cell.h +++ b/src/or/proto_cell.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PROTO_CELL_H diff --git a/src/or/proto_control0.c b/src/or/proto_control0.c index c17ba34948..34e7ddb8d9 100644 --- a/src/or/proto_control0.c +++ b/src/or/proto_control0.c @@ -1,12 +1,12 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" -#include "buffers.h" -#include "proto_control0.h" +#include "or/or.h" +#include "lib/container/buffers.h" +#include "or/proto_control0.h" /** Return 1 iff buf looks more like it has an (obsolete) v0 controller * command on it than any valid v1 controller command. */ diff --git a/src/or/proto_control0.h b/src/or/proto_control0.h index 0cc8eacad0..b80dc6c8f8 100644 --- a/src/or/proto_control0.h +++ b/src/or/proto_control0.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PROTO_CONTROL0_H diff --git a/src/or/proto_ext_or.c b/src/or/proto_ext_or.c index 057cf109ec..f30d876231 100644 --- a/src/or/proto_ext_or.c +++ b/src/or/proto_ext_or.c @@ -1,13 +1,13 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" -#include "buffers.h" -#include "ext_orport.h" -#include "proto_ext_or.h" +#include "or/or.h" +#include "lib/container/buffers.h" +#include "or/ext_orport.h" +#include "or/proto_ext_or.h" /** The size of the header of an Extended ORPort message: 2 bytes for * COMMAND, 2 bytes for BODYLEN */ diff --git a/src/or/proto_ext_or.h b/src/or/proto_ext_or.h index cc504d18e3..708a45974b 100644 --- a/src/or/proto_ext_or.h +++ b/src/or/proto_ext_or.h @@ -1,17 +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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PROTO_EXT_OR_H #define TOR_PROTO_EXT_OR_H struct buf_t; -struct ext_or_cmt_t; + +/** A parsed Extended ORPort message. */ +typedef struct ext_or_cmd_t { + uint16_t cmd; /** Command type */ + uint16_t len; /** Body length */ + char body[FLEXIBLE_ARRAY_MEMBER]; /** Message body */ +} ext_or_cmd_t; int fetch_ext_or_command_from_buf(struct buf_t *buf, struct ext_or_cmd_t **out); #endif /* !defined(TOR_PROTO_EXT_OR_H) */ - diff --git a/src/or/proto_http.c b/src/or/proto_http.c index 3762429e1e..ecc669e3a4 100644 --- a/src/or/proto_http.c +++ b/src/or/proto_http.c @@ -1,13 +1,13 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define PROTO_HTTP_PRIVATE -#include "or.h" -#include "buffers.h" -#include "proto_http.h" +#include "or/or.h" +#include "lib/container/buffers.h" +#include "or/proto_http.h" /** Return true if <b>cmd</b> looks like a HTTP (proxy) request. */ int diff --git a/src/or/proto_http.h b/src/or/proto_http.h index 805686070f..587e435ede 100644 --- a/src/or/proto_http.h +++ b/src/or/proto_http.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PROTO_HTTP_H diff --git a/src/or/proto_socks.c b/src/or/proto_socks.c index 57a7d1cd64..f5e6ce581b 100644 --- a/src/or/proto_socks.c +++ b/src/or/proto_socks.c @@ -1,18 +1,21 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" -#include "addressmap.h" -#include "buffers.h" -#include "control.h" -#include "config.h" -#include "crypto_util.h" -#include "ext_orport.h" -#include "proto_socks.h" -#include "reasons.h" +#include "or/or.h" +#include "or/addressmap.h" +#include "lib/container/buffers.h" +#include "or/connection.h" +#include "or/control.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/ext_orport.h" +#include "or/proto_socks.h" +#include "or/reasons.h" + +#include "or/socks_request_st.h" static void socks_request_set_socks5_error(socks_request_t *req, socks5_reply_status_t reason); @@ -708,4 +711,3 @@ parse_socks_client(const uint8_t *data, size_t datalen, return -1; /* LCOV_EXCL_STOP */ } - diff --git a/src/or/proto_socks.h b/src/or/proto_socks.h index 02e0aca7e9..53de288f65 100644 --- a/src/or/proto_socks.h +++ b/src/or/proto_socks.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PROTO_SOCKS_H @@ -19,4 +19,3 @@ int fetch_from_buf_socks(struct buf_t *buf, socks_request_t *req, int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason); #endif /* !defined(TOR_PROTO_SOCKS_H) */ - diff --git a/src/or/protover.c b/src/or/protover.c index 0e8902196d..f63c134565 100644 --- a/src/or/protover.c +++ b/src/or/protover.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -23,9 +23,9 @@ #define PROTOVER_PRIVATE -#include "or.h" -#include "protover.h" -#include "routerparse.h" +#include "or/or.h" +#include "or/protover.h" +#include "or/routerparse.h" #ifndef HAVE_RUST diff --git a/src/or/protover.h b/src/or/protover.h index c46a13de66..7319d2f8c4 100644 --- a/src/or/protover.h +++ b/src/or/protover.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,7 +9,10 @@ #ifndef TOR_PROTOVER_H #define TOR_PROTOVER_H -#include "container.h" +#include <stdbool.h> +#include "lib/cc/torint.h" +#include "lib/testsupport/testsupport.h" +struct smartlist_t; /** The first version of Tor that included "proto" entries in its * descriptors. Authorities should use this to decide whether to @@ -47,7 +50,7 @@ int protover_all_supported(const char *s, char **missing); int protover_is_supported_here(protocol_type_t pr, uint32_t ver); const char *protover_get_supported_protocols(void); -char *protover_compute_vote(const smartlist_t *list_of_proto_strings, +char *protover_compute_vote(const struct smartlist_t *list_of_proto_strings, int threshold); const char *protover_compute_for_old_tor(const char *version); int protocol_list_supports_protocol(const char *list, protocol_type_t tp, @@ -75,12 +78,12 @@ typedef struct proto_entry_t { */ char *name; /** Smartlist of proto_range_t */ - smartlist_t *ranges; + struct smartlist_t *ranges; } proto_entry_t; #if !defined(HAVE_RUST) && defined(TOR_UNIT_TESTS) -STATIC smartlist_t *parse_protocol_list(const char *s); -STATIC char *encode_protocol_list(const smartlist_t *sl); +STATIC struct smartlist_t *parse_protocol_list(const char *s); +STATIC char *encode_protocol_list(const struct smartlist_t *sl); STATIC const char *protocol_type_to_str(protocol_type_t pr); STATIC int str_to_protocol_type(const char *s, protocol_type_t *pr_out); STATIC void proto_entry_free_(proto_entry_t *entry); @@ -92,4 +95,3 @@ STATIC void proto_entry_free_(proto_entry_t *entry); #endif /* defined(PROTOVER_PRIVATE) */ #endif /* !defined(TOR_PROTOVER_H) */ - diff --git a/src/or/protover_rust.c b/src/or/protover_rust.c index 99304f8b51..bd2f88b98e 100644 --- a/src/or/protover_rust.c +++ b/src/or/protover_rust.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* Copyright (c) 2016-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* @@ -7,8 +7,8 @@ * and safe translation/handling between the Rust/C boundary. */ -#include "or.h" -#include "protover.h" +#include "or/or.h" +#include "or/protover.h" #ifdef HAVE_RUST diff --git a/src/or/reasons.c b/src/or/reasons.c index ce1259b8f3..7d8dcf374c 100644 --- a/src/or/reasons.c +++ b/src/or/reasons.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,9 +14,11 @@ * to another. **/ -#include "or.h" -#include "config.h" -#include "reasons.h" +#include "or/or.h" +#include "or/config.h" +#include "or/reasons.h" +#include "or/routerlist.h" +#include "lib/tls/tortls.h" /***************************** Edge (stream) reasons **********************/ @@ -493,4 +495,3 @@ end_reason_to_http_connect_response_line(int endreason) return "HTTP/1.0 500 Internal Server Error (weird end reason)\r\n\r\n"; } } - diff --git a/src/or/reasons.h b/src/or/reasons.h index 3d6ba8fc83..b815463b74 100644 --- a/src/or/reasons.h +++ b/src/or/reasons.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,6 +12,9 @@ #ifndef TOR_REASONS_H #define TOR_REASONS_H +#include "common/socks5_status.h" +enum bandwidth_weight_rule_t; + const char *stream_end_reason_to_control_string(int reason); const char *stream_end_reason_to_string(int reason); socks5_reply_status_t stream_end_reason_to_socks5_response(int reason); @@ -29,4 +32,3 @@ const char *bandwidth_weight_rule_to_string(enum bandwidth_weight_rule_t rule); const char *end_reason_to_http_connect_response_line(int endreason); #endif /* !defined(TOR_REASONS_H) */ - diff --git a/src/or/relay.c b/src/or/relay.c index 3632678af6..e8e1762b40 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -46,40 +46,55 @@ **/ #define RELAY_PRIVATE -#include "or.h" -#include "addressmap.h" -#include "backtrace.h" -#include "buffers.h" -#include "channel.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "compress.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "connection_or.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "geoip.h" -#include "hs_cache.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "onion.h" -#include "policies.h" -#include "reasons.h" -#include "relay.h" -#include "relay_crypto.h" -#include "rendcache.h" -#include "rendcommon.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "scheduler.h" -#include "rephist.h" +#include "or/or.h" +#include "or/addressmap.h" +#include "lib/err/backtrace.h" +#include "lib/container/buffers.h" +#include "or/channel.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "lib/compress/compress.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/connection_or.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/geoip.h" +#include "or/hs_cache.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/onion.h" +#include "or/policies.h" +#include "or/reasons.h" +#include "or/relay.h" +#include "or/relay_crypto.h" +#include "or/rendcache.h" +#include "or/rendcommon.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/scheduler.h" +#include "or/rephist.h" + +#include "or/cell_st.h" +#include "or/cell_queue_st.h" +#include "or/cpath_build_state_st.h" +#include "or/dir_connection_st.h" +#include "or/destroy_cell_queue_st.h" +#include "or/entry_connection_st.h" +#include "or/extend_info_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" +#include "or/routerinfo_st.h" +#include "or/socks_request_st.h" + +#include "lib/intmath/weakrng.h" static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, @@ -1783,15 +1798,15 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, return 0; } - /* Don't allow the other endpoint to request more than our maximim - * (ie initial) stream SENDME window worth of data. Well-behaved + /* Don't allow the other endpoint to request more than our maximum + * (i.e. initial) stream SENDME window worth of data. Well-behaved * stock clients will not request more than this max (as per the check * in the while loop of connection_edge_consider_sending_sendme()). */ if (conn->package_window + STREAMWINDOW_INCREMENT > STREAMWINDOW_START_MAX) { static struct ratelim_t stream_warn_ratelim = RATELIM_INIT(600); - log_fn_ratelim(&stream_warn_ratelim,LOG_PROTOCOL_WARN, LD_PROTOCOL, + log_fn_ratelim(&stream_warn_ratelim, LOG_PROTOCOL_WARN, LD_PROTOCOL, "Unexpected stream sendme cell. Closing circ (window %d).", conn->package_window); return -END_CIRC_REASON_TORPROTOCOL; @@ -3071,4 +3086,3 @@ circuit_queue_streams_are_blocked(circuit_t *circ) return circ->streams_blocked_on_p_chan; } } - diff --git a/src/or/relay.h b/src/or/relay.h index ce0969b46c..db7f17b96c 100644 --- a/src/or/relay.h +++ b/src/or/relay.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/relay_crypto.c b/src/or/relay_crypto.c index 530c8e5828..1fcfae0b3a 100644 --- a/src/or/relay_crypto.c +++ b/src/or/relay_crypto.c @@ -4,12 +4,18 @@ * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.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 "or/or.h" +#include "or/circuitlist.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN +#include "or/relay.h" +#include "or/relay_crypto.h" + +#include "or/cell_st.h" +#include "or/or_circuit_st.h" +#include "or/origin_circuit_st.h" /** Update digest from the payload of cell. Assign integrity part to * cell. @@ -324,4 +330,3 @@ relay_crypto_assert_ok(const relay_crypto_t *crypto) tor_assert(crypto->f_digest); tor_assert(crypto->b_digest); } - diff --git a/src/or/relay_crypto.h b/src/or/relay_crypto.h index 66ae02cee9..67da93344f 100644 --- a/src/or/relay_crypto.h +++ b/src/or/relay_crypto.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/relay_crypto_st.h b/src/or/relay_crypto_st.h new file mode 100644 index 0000000000..f186e182f0 --- /dev/null +++ b/src/or/relay_crypto_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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef RELAY_CRYPTO_ST_H +#define RELAY_CRYPTO_ST_H + +#define crypto_cipher_t aes_cnt_cipher +struct crypto_cipher_t; +struct crypto_digest_t; + +struct relay_crypto_t { + /* crypto environments */ + /** Encryption key and counter for cells heading towards the OR at this + * step. */ + struct crypto_cipher_t *f_crypto; + /** Encryption key and counter for cells heading back from the OR at this + * step. */ + struct crypto_cipher_t *b_crypto; + + /** Digest state for cells heading towards the OR at this step. */ + struct crypto_digest_t *f_digest; /* for integrity checking */ + /** Digest state for cells heading away from the OR at this step. */ + struct crypto_digest_t *b_digest; + +}; +#undef crypto_cipher_t + +#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..7ccf9771e1 --- /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-2018, 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..0555ef6728 --- /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-2018, 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..89fe5ef2b3 --- /dev/null +++ b/src/or/rend_intro_point_st.h @@ -0,0 +1,76 @@ +/* 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 REND_INTRO_POINT_ST_H +#define REND_INTRO_POINT_ST_H + +struct replaycache_t; +struct crypto_pk_t; + +/** 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. */ + struct 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. */ + struct 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..8ea8a62305 --- /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-2018, 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 d27e1c293f..c18920154e 100644 --- a/src/or/rendcache.c +++ b/src/or/rendcache.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Tor Project, Inc. */ +/* Copyright (c) 2015-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -7,13 +7,17 @@ **/ #define RENDCACHE_PRIVATE -#include "rendcache.h" +#include "or/rendcache.h" -#include "config.h" -#include "rephist.h" -#include "routerlist.h" -#include "routerparse.h" -#include "rendcommon.h" +#include "or/config.h" +#include "or/rephist.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/rendcommon.h" + +#include "or/extend_info_st.h" +#include "or/rend_intro_point_st.h" +#include "or/rend_service_descriptor_st.h" /** Map from service id (as generated by rend_get_service_id) to * rend_cache_entry_t. */ @@ -908,9 +912,7 @@ rend_cache_store_v2_desc_as_client(const char *desc, if (n_intro_points <= 0) { log_warn(LD_REND, "Failed to parse introduction points. Either the " "service has published a corrupt descriptor or you have " - "provided invalid authorization data, or (maybe!) the " - "server is deliberately serving broken data in an attempt " - "to crash you with bug 21018."); + "provided invalid authorization data."); goto err; } else if (n_intro_points > MAX_INTRO_POINTS) { log_warn(LD_REND, "Found too many introduction points on a hidden " diff --git a/src/or/rendcache.h b/src/or/rendcache.h index 8b6fd5b671..bb075409ec 100644 --- a/src/or/rendcache.h +++ b/src/or/rendcache.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Tor Project, Inc. */ +/* Copyright (c) 2015-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,8 +9,8 @@ #ifndef TOR_RENDCACHE_H #define TOR_RENDCACHE_H -#include "or.h" -#include "rendcommon.h" +#include "or/or.h" +#include "or/rendcommon.h" /** How old do we let hidden service descriptors get before discarding * them as too old? */ diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 7ef12a4faf..d4262f2f38 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -7,31 +7,43 @@ * \brief Client code to access location-hidden services. **/ -#include "or.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "connection_edge.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "hs_circuit.h" -#include "hs_client.h" -#include "hs_common.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "relay.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerset.h" +#include "or/or.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/connection_edge.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/hs_circuit.h" +#include "or/hs_client.h" +#include "or/hs_common.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/relay.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerset.h" +#include "lib/encoding/confline.h" + +#include "or/cpath_build_state_st.h" +#include "or/crypt_path_st.h" +#include "or/dir_connection_st.h" +#include "or/entry_connection_st.h" +#include "or/extend_info_st.h" +#include "or/origin_circuit_st.h" +#include "or/rend_intro_point_st.h" +#include "or/rend_service_descriptor_st.h" +#include "or/routerstatus_st.h" static extend_info_t *rend_client_get_random_intro_impl( const rend_cache_entry_t *rend_query, @@ -248,7 +260,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc, } if (crypto_dh_get_public(cpath->rend_dh_handshake_state, tmp+dh_offset, - DH_KEY_LEN)<0) { + DH1024_KEY_LEN)<0) { log_warn(LD_BUG, "Internal error: couldn't extract g^x."); status = -2; goto perm_err; @@ -259,7 +271,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc, r = crypto_pk_obsolete_public_hybrid_encrypt(intro_key, payload+DIGEST_LEN, sizeof(payload)-DIGEST_LEN, tmp, - (int)(dh_offset+DH_KEY_LEN), + (int)(dh_offset+DH1024_KEY_LEN), PK_PKCS1_OAEP_PADDING, 0); if (r<0) { log_warn(LD_BUG,"Internal error: hybrid pk encrypt failed."); @@ -864,7 +876,7 @@ int rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request, size_t request_len) { - if (request_len != DH_KEY_LEN+DIGEST_LEN) { + if (request_len != DH1024_KEY_LEN+DIGEST_LEN) { log_warn(LD_PROTOCOL,"Incorrect length (%d) on RENDEZVOUS2 cell.", (int)request_len); goto err; @@ -1243,4 +1255,3 @@ rend_client_non_anonymous_mode_enabled(const or_options_t *options) return 0; #endif /* defined(NON_ANONYMOUS_MODE_ENABLED) */ } - diff --git a/src/or/rendclient.h b/src/or/rendclient.h index e8495ce09c..77395d6cb8 100644 --- a/src/or/rendclient.h +++ b/src/or/rendclient.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,7 @@ #ifndef TOR_RENDCLIENT_H #define TOR_RENDCLIENT_H -#include "rendcache.h" +#include "or/rendcache.h" void rend_client_purge_state(void); diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index f3fa2f64d1..928dda0128 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -10,25 +10,37 @@ #define RENDCOMMON_PRIVATE -#include "or.h" -#include "circuitbuild.h" -#include "circuituse.h" -#include "config.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "hs_client.h" -#include "hs_common.h" -#include "hs_intropoint.h" -#include "networkstatus.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendmid.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" +#include "or/or.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/hs_client.h" +#include "or/hs_common.h" +#include "or/hs_intropoint.h" +#include "or/networkstatus.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendmid.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/replaycache.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" + +#include "or/cpath_build_state_st.h" +#include "or/crypt_path_st.h" +#include "or/extend_info_st.h" +#include "or/networkstatus_st.h" +#include "or/origin_circuit_st.h" +#include "or/rend_encoded_v2_service_descriptor_st.h" +#include "or/rend_intro_point_st.h" +#include "or/rend_service_descriptor_st.h" +#include "or/routerstatus_st.h" /** Return 0 if one and two are the same service ids, else -1 or 1 */ int @@ -1042,4 +1054,3 @@ rend_circuit_pk_digest_eq(const origin_circuit_t *ocirc, match: return 1; } - diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index 1ed0f62609..4ea35f88c2 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/rendmid.c b/src/or/rendmid.c index c4a34ca62c..38c1c52e43 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -7,18 +7,20 @@ * \brief Implement introductions points and rendezvous points. **/ -#include "or.h" -#include "channel.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "crypto.h" -#include "dos.h" -#include "relay.h" -#include "rendmid.h" -#include "rephist.h" -#include "hs_circuitmap.h" -#include "hs_intropoint.h" +#include "or/or.h" +#include "or/channel.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto.h" +#include "or/dos.h" +#include "or/relay.h" +#include "or/rendmid.h" +#include "or/rephist.h" +#include "or/hs_circuitmap.h" +#include "or/hs_intropoint.h" + +#include "or/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. @@ -155,7 +157,8 @@ rend_mid_introduce_legacy(or_circuit_t *circ, const uint8_t *request, * to revise this protocol anyway. */ if (request_len < (DIGEST_LEN+(MAX_NICKNAME_LEN+1)+REND_COOKIE_LEN+ - DH_KEY_LEN+CIPHER_KEY_LEN+PKCS1_OAEP_PADDING_OVERHEAD)) { + DH1024_KEY_LEN+CIPHER_KEY_LEN+ + PKCS1_OAEP_PADDING_OVERHEAD)) { log_warn(LD_PROTOCOL, "Impossibly short INTRODUCE1 cell on circuit %u; " "responding with nack.", (unsigned)circ->p_circ_id); @@ -365,4 +368,3 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, circuit_mark_for_close(TO_CIRCUIT(circ), reason); return -1; } - diff --git a/src/or/rendmid.h b/src/or/rendmid.h index 6cc1fc8d95..907a0c6a73 100644 --- a/src/or/rendmid.h +++ b/src/or/rendmid.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 92c323b10d..8e094b593c 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,32 +9,57 @@ #define RENDSERVICE_PRIVATE -#include "or.h" -#include "circpathbias.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "directory.h" -#include "hs_common.h" -#include "hs_config.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "rendclient.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "router.h" -#include "relay.h" -#include "rephist.h" -#include "replaycache.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" +#include "or/or.h" +#include "or/circpathbias.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/directory.h" +#include "or/hs_common.h" +#include "or/hs_config.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/rendclient.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/router.h" +#include "or/relay.h" +#include "or/rephist.h" +#include "or/replaycache.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "lib/encoding/confline.h" + +#include "or/cpath_build_state_st.h" +#include "or/crypt_path_st.h" +#include "or/crypt_path_reference_st.h" +#include "or/edge_connection_st.h" +#include "or/extend_info_st.h" +#include "or/networkstatus_st.h" +#include "or/origin_circuit_st.h" +#include "or/rend_authorized_client_st.h" +#include "or/rend_encoded_v2_service_descriptor_st.h" +#include "or/rend_intro_point_st.h" +#include "or/rend_service_descriptor_st.h" +#include "or/routerstatus_st.h" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif struct rend_service_t; static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro, @@ -1992,7 +2017,7 @@ rend_service_receive_introduction(origin_circuit_t *circuit, * part 1. */ replay = replaycache_add_test_and_elapsed( service->accepted_intro_dh_parts, - parsed_req->dh, DH_KEY_LEN, + parsed_req->dh, DH1024_KEY_LEN, &elapsed); if (replay) { @@ -2042,7 +2067,7 @@ rend_service_receive_introduction(origin_circuit_t *circuit, } if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, (char *)(parsed_req->dh), - DH_KEY_LEN, keys, + DH1024_KEY_LEN, keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) { log_warn(LD_BUG, "Internal error: couldn't complete DH handshake"); reason = END_CIRC_REASON_INTERNAL; @@ -2323,7 +2348,7 @@ rend_service_begin_parse_intro(const uint8_t *request, /* min key length plus digest length plus nickname length */ if (request_len < (DIGEST_LEN + REND_COOKIE_LEN + (MAX_NICKNAME_LEN + 1) + - DH_KEY_LEN + 42)) { + DH1024_KEY_LEN + 42)) { if (err_msg_out) { tor_asprintf(&err_msg, "got a truncated INTRODUCE%d cell", @@ -2859,14 +2884,14 @@ rend_service_parse_intro_plaintext( */ ver_invariant_len = intro->plaintext_len - ver_specific_len; - if (ver_invariant_len < REND_COOKIE_LEN + DH_KEY_LEN) { + if (ver_invariant_len < REND_COOKIE_LEN + DH1024_KEY_LEN) { tor_asprintf(&err_msg, "decrypted plaintext of INTRODUCE%d cell was truncated (%ld bytes)", (int)(intro->type), (long)(intro->plaintext_len)); status = -5; goto err; - } else if (ver_invariant_len > REND_COOKIE_LEN + DH_KEY_LEN) { + } else if (ver_invariant_len > REND_COOKIE_LEN + DH1024_KEY_LEN) { tor_asprintf(&err_msg, "decrypted plaintext of INTRODUCE%d cell was too long (%ld bytes)", (int)(intro->type), @@ -2879,7 +2904,7 @@ rend_service_parse_intro_plaintext( REND_COOKIE_LEN); memcpy(intro->dh, intro->plaintext + ver_specific_len + REND_COOKIE_LEN, - DH_KEY_LEN); + DH1024_KEY_LEN); } /* Flag it as being fully parsed */ @@ -3436,12 +3461,12 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */ memcpy(buf, rend_cookie, REND_COOKIE_LEN); if (crypto_dh_get_public(hop->rend_dh_handshake_state, - buf+REND_COOKIE_LEN, DH_KEY_LEN)<0) { + buf+REND_COOKIE_LEN, DH1024_KEY_LEN)<0) { log_warn(LD_GENERAL,"Couldn't get DH public key."); reason = END_CIRC_REASON_INTERNAL; goto err; } - memcpy(buf+REND_COOKIE_LEN+DH_KEY_LEN, hop->rend_circ_nonce, + memcpy(buf+REND_COOKIE_LEN+DH1024_KEY_LEN, hop->rend_circ_nonce, DIGEST_LEN); /* Send the cell */ @@ -4424,4 +4449,3 @@ set_rend_rend_service_staging_list(smartlist_t *new_list) } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/rendservice.h b/src/or/rendservice.h index cc872ab575..35962df7f3 100644 --- a/src/or/rendservice.h +++ b/src/or/rendservice.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,14 +12,15 @@ #ifndef TOR_RENDSERVICE_H #define TOR_RENDSERVICE_H -#include "or.h" -#include "hs_service.h" +#include "or/or.h" +#include "or/hs_service.h" -typedef struct rend_intro_cell_s rend_intro_cell_t; +typedef struct rend_intro_cell_t rend_intro_cell_t; +struct config_line_t; /* This can be used for both INTRODUCE1 and INTRODUCE2 */ -struct rend_intro_cell_s { +struct rend_intro_cell_t { /* Is this an INTRODUCE1 or INTRODUCE2? (set to 1 or 2) */ uint8_t type; /* Public key digest */ @@ -58,7 +59,7 @@ struct rend_intro_cell_s { /* Rendezvous cookie */ uint8_t rc[REND_COOKIE_LEN]; /* Diffie-Hellman data */ - uint8_t dh[DH_KEY_LEN]; + uint8_t dh[DH1024_KEY_LEN]; }; #ifdef RENDSERVICE_PRIVATE @@ -138,7 +139,7 @@ STATIC void rend_service_prune_list_impl_(void); #endif /* defined(RENDSERVICE_PRIVATE) */ int rend_num_services(void); -int rend_config_service(const config_line_t *line_, +int rend_config_service(const struct config_line_t *line_, const or_options_t *options, hs_service_config_t *config); void rend_service_prune_list(void); @@ -218,4 +219,3 @@ int rend_service_reveal_startup_time(const or_options_t *options); int rend_service_non_anonymous_mode_enabled(const or_options_t *options); #endif /* !defined(TOR_RENDSERVICE_H) */ - diff --git a/src/or/rephist.c b/src/or/rephist.c index c7117bad63..6607c25964 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -74,20 +74,33 @@ * (The "rephist" name originally stood for "reputation and history". ) **/ -#include "or.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "crypto_rand.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" +#include "or/or.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" #include "ht.h" -#include "channelpadding.h" -#include "connection_or.h" -#include "statefile.h" +#include "or/channelpadding.h" +#include "or/connection_or.h" +#include "or/statefile.h" + +#include "or/networkstatus_st.h" +#include "or/or_circuit_st.h" +#include "or/or_state_st.h" + +#include "lib/container/bloomfilt.h" +#include "lib/container/order.h" +#include "lib/math/fp.h" +#include "lib/math/laplace.h" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif static void bw_arrays_init(void); static void predicted_ports_alloc(void); @@ -1210,9 +1223,9 @@ rep_hist_bandwidth_assess(void) r = find_largest_max(read_array); w = find_largest_max(write_array); if (r>w) - return (int)(U64_TO_DBL(w)/NUM_SECS_ROLLING_MEASURE); + return (int)(((double)w)/NUM_SECS_ROLLING_MEASURE); else - return (int)(U64_TO_DBL(r)/NUM_SECS_ROLLING_MEASURE); + return (int)(((double)r)/NUM_SECS_ROLLING_MEASURE); } /** Print the bandwidth history of b (either [dir-]read_array or @@ -1258,9 +1271,9 @@ rep_hist_fill_bandwidth_history(char *buf, size_t len, const bw_array_t *b) total = cutoff; if (n==(b->num_maxes_set-1)) - tor_snprintf(cp, len-(cp-buf), U64_FORMAT, U64_PRINTF_ARG(total)); + tor_snprintf(cp, len-(cp-buf), "%"PRIu64, (total)); else - tor_snprintf(cp, len-(cp-buf), U64_FORMAT",", U64_PRINTF_ARG(total)); + tor_snprintf(cp, len-(cp-buf), "%"PRIu64",", (total)); cp += strlen(cp); } return cp-buf; @@ -1372,17 +1385,17 @@ rep_hist_update_bwhist_state_section(or_state_t *state, for (j=0; j < b->num_maxes_set; ++j,++i) { if (i >= NUM_TOTALS) i = 0; - smartlist_add_asprintf(*s_values, U64_FORMAT, - U64_PRINTF_ARG(b->totals[i] & ~0x3ff)); + smartlist_add_asprintf(*s_values, "%"PRIu64, + (b->totals[i] & ~0x3ff)); maxval = b->maxima[i] / NUM_SECS_ROLLING_MEASURE; - smartlist_add_asprintf(*s_maxima, U64_FORMAT, - U64_PRINTF_ARG(maxval & ~0x3ff)); + smartlist_add_asprintf(*s_maxima, "%"PRIu64, + (maxval & ~0x3ff)); } - smartlist_add_asprintf(*s_values, U64_FORMAT, - U64_PRINTF_ARG(b->total_in_period & ~0x3ff)); + smartlist_add_asprintf(*s_values, "%"PRIu64, + (b->total_in_period & ~0x3ff)); maxval = b->max_total / NUM_SECS_ROLLING_MEASURE; - smartlist_add_asprintf(*s_maxima, U64_FORMAT, - U64_PRINTF_ARG(maxval & ~0x3ff)); + smartlist_add_asprintf(*s_maxima, "%"PRIu64, + (maxval & ~0x3ff)); } /** Update <b>state</b> with the newest bandwidth history. Done before @@ -1956,8 +1969,8 @@ rep_hist_format_exit_stats(time_t now) exit_bytes_written[cur_port], EXIT_STATS_ROUND_UP_BYTES); num /= 1024; - smartlist_add_asprintf(written_strings, "%d="U64_FORMAT, - cur_port, U64_PRINTF_ARG(num)); + smartlist_add_asprintf(written_strings, "%d=%"PRIu64, + cur_port, (num)); other_written -= exit_bytes_written[cur_port]; } if (exit_bytes_read[cur_port] > 0) { @@ -1965,8 +1978,8 @@ rep_hist_format_exit_stats(time_t now) exit_bytes_read[cur_port], EXIT_STATS_ROUND_UP_BYTES); num /= 1024; - smartlist_add_asprintf(read_strings, "%d="U64_FORMAT, - cur_port, U64_PRINTF_ARG(num)); + smartlist_add_asprintf(read_strings, "%d=%"PRIu64, + cur_port, (num)); other_read -= exit_bytes_read[cur_port]; } if (exit_streams[cur_port] > 0) { @@ -1982,13 +1995,13 @@ rep_hist_format_exit_stats(time_t now) other_written = round_uint64_to_next_multiple_of(other_written, EXIT_STATS_ROUND_UP_BYTES); other_written /= 1024; - smartlist_add_asprintf(written_strings, "other="U64_FORMAT, - U64_PRINTF_ARG(other_written)); + smartlist_add_asprintf(written_strings, "other=%"PRIu64, + (other_written)); other_read = round_uint64_to_next_multiple_of(other_read, EXIT_STATS_ROUND_UP_BYTES); other_read /= 1024; - smartlist_add_asprintf(read_strings, "other="U64_FORMAT, - U64_PRINTF_ARG(other_read)); + smartlist_add_asprintf(read_strings, "other=%"PRIu64, + (other_read)); other_streams = round_uint32_to_next_multiple_of(other_streams, EXIT_STATS_ROUND_UP_STREAMS); smartlist_add_asprintf(streams_strings, "other=%u", other_streams); @@ -2248,8 +2261,8 @@ rep_hist_format_buffer_stats(time_t now) time_in_queue_strings = smartlist_new(); for (i = 0; i < SHARES; i++) { smartlist_add_asprintf(processed_cells_strings, - U64_FORMAT, !circs_in_share[i] ? 0 : - U64_PRINTF_ARG(processed_cells[i] / + "%"PRIu64, !circs_in_share[i] ? 0 : + (processed_cells[i] / circs_in_share[i])); } for (i = 0; i < SHARES; i++) { @@ -2916,14 +2929,14 @@ rep_hist_format_hs_stats(time_t now) format_iso_time(t, now); tor_asprintf(&hs_stats_string, "hidserv-stats-end %s (%d s)\n" - "hidserv-rend-relayed-cells "I64_FORMAT" delta_f=%d " + "hidserv-rend-relayed-cells %"PRId64" delta_f=%d " "epsilon=%.2f bin_size=%d\n" - "hidserv-dir-onions-seen "I64_FORMAT" delta_f=%d " + "hidserv-dir-onions-seen %"PRId64" delta_f=%d " "epsilon=%.2f bin_size=%d\n", t, (unsigned) (now - start_of_hs_stats_interval), - I64_PRINTF_ARG(obfuscated_cells_seen), REND_CELLS_DELTA_F, + (obfuscated_cells_seen), REND_CELLS_DELTA_F, REND_CELLS_EPSILON, REND_CELLS_BIN_SIZE, - I64_PRINTF_ARG(obfuscated_onions_seen), + (obfuscated_onions_seen), ONIONS_SEEN_DELTA_F, ONIONS_SEEN_EPSILON, ONIONS_SEEN_BIN_SIZE); @@ -3109,33 +3122,33 @@ rep_hist_get_padding_count_lines(void) } tor_asprintf(&result, "padding-counts %s (%d s)" - " bin-size="U64_FORMAT - " write-drop="U64_FORMAT - " write-pad="U64_FORMAT - " write-total="U64_FORMAT - " read-drop="U64_FORMAT - " read-pad="U64_FORMAT - " read-total="U64_FORMAT - " enabled-read-pad="U64_FORMAT - " enabled-read-total="U64_FORMAT - " enabled-write-pad="U64_FORMAT - " enabled-write-total="U64_FORMAT - " max-chanpad-timers="U64_FORMAT + " bin-size=%"PRIu64 + " write-drop=%"PRIu64 + " write-pad=%"PRIu64 + " write-total=%"PRIu64 + " read-drop=%"PRIu64 + " read-pad=%"PRIu64 + " read-total=%"PRIu64 + " enabled-read-pad=%"PRIu64 + " enabled-read-total=%"PRIu64 + " enabled-write-pad=%"PRIu64 + " enabled-write-total=%"PRIu64 + " max-chanpad-timers=%"PRIu64 "\n", padding_published.first_published_at, REPHIST_CELL_PADDING_COUNTS_INTERVAL, - U64_PRINTF_ARG(ROUND_CELL_COUNTS_TO), - U64_PRINTF_ARG(padding_published.write_drop_cell_count), - U64_PRINTF_ARG(padding_published.write_pad_cell_count), - U64_PRINTF_ARG(padding_published.write_cell_count), - U64_PRINTF_ARG(padding_published.read_drop_cell_count), - U64_PRINTF_ARG(padding_published.read_pad_cell_count), - U64_PRINTF_ARG(padding_published.read_cell_count), - U64_PRINTF_ARG(padding_published.enabled_read_pad_cell_count), - U64_PRINTF_ARG(padding_published.enabled_read_cell_count), - U64_PRINTF_ARG(padding_published.enabled_write_pad_cell_count), - U64_PRINTF_ARG(padding_published.enabled_write_cell_count), - U64_PRINTF_ARG(padding_published.maximum_chanpad_timers) + (uint64_t)ROUND_CELL_COUNTS_TO, + (padding_published.write_drop_cell_count), + (padding_published.write_pad_cell_count), + (padding_published.write_cell_count), + (padding_published.read_drop_cell_count), + (padding_published.read_pad_cell_count), + (padding_published.read_cell_count), + (padding_published.enabled_read_pad_cell_count), + (padding_published.enabled_read_cell_count), + (padding_published.enabled_write_pad_cell_count), + (padding_published.enabled_write_cell_count), + (padding_published.maximum_chanpad_timers) ); return result; @@ -3149,22 +3162,22 @@ rep_hist_log_link_protocol_counts(void) { log_notice(LD_HEARTBEAT, "Since startup, we have initiated " - U64_FORMAT" v1 connections, " - U64_FORMAT" v2 connections, " - U64_FORMAT" v3 connections, and " - U64_FORMAT" v4 connections; and received " - U64_FORMAT" v1 connections, " - U64_FORMAT" v2 connections, " - U64_FORMAT" v3 connections, and " - U64_FORMAT" v4 connections.", - U64_PRINTF_ARG(link_proto_count[1][1]), - U64_PRINTF_ARG(link_proto_count[2][1]), - U64_PRINTF_ARG(link_proto_count[3][1]), - U64_PRINTF_ARG(link_proto_count[4][1]), - U64_PRINTF_ARG(link_proto_count[1][0]), - U64_PRINTF_ARG(link_proto_count[2][0]), - U64_PRINTF_ARG(link_proto_count[3][0]), - U64_PRINTF_ARG(link_proto_count[4][0])); + "%"PRIu64" v1 connections, " + "%"PRIu64" v2 connections, " + "%"PRIu64" v3 connections, and " + "%"PRIu64" v4 connections; and received " + "%"PRIu64" v1 connections, " + "%"PRIu64" v2 connections, " + "%"PRIu64" v3 connections, and " + "%"PRIu64" v4 connections.", + (link_proto_count[1][1]), + (link_proto_count[2][1]), + (link_proto_count[3][1]), + (link_proto_count[4][1]), + (link_proto_count[1][0]), + (link_proto_count[2][0]), + (link_proto_count[3][0]), + (link_proto_count[4][0])); } /** Free all storage held by the OR/link history caches, by the @@ -3205,4 +3218,3 @@ rep_hist_free_all(void) tor_assert_nonfatal(rephist_total_alloc == 0); tor_assert_nonfatal_once(rephist_total_num == 0); } - diff --git a/src/or/rephist.h b/src/or/rephist.h index 5072721592..06a5e48211 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/replaycache.c b/src/or/replaycache.c index a9a6709937..b5cc6a2823 100644 --- a/src/or/replaycache.c +++ b/src/or/replaycache.c @@ -1,4 +1,4 @@ - /* Copyright (c) 2012-2017, The Tor Project, Inc. */ + /* Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,8 +21,8 @@ #define REPLAYCACHE_PRIVATE -#include "or.h" -#include "replaycache.h" +#include "or/or.h" +#include "or/replaycache.h" /** Free the replaycache r and all of its entries. */ diff --git a/src/or/replaycache.h b/src/or/replaycache.h index 81a8d907fd..3118a88a1a 100644 --- a/src/or/replaycache.h +++ b/src/or/replaycache.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Tor Project, Inc. */ +/* Copyright (c) 2012-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,11 +9,11 @@ #ifndef TOR_REPLAYCACHE_H #define TOR_REPLAYCACHE_H -typedef struct replaycache_s replaycache_t; +typedef struct replaycache_t replaycache_t; #ifdef REPLAYCACHE_PRIVATE -struct replaycache_s { +struct replaycache_t { /* Scrub interval */ time_t scrub_interval; /* Last scrubbed */ @@ -65,4 +65,3 @@ int replaycache_add_test_and_elapsed( void replaycache_scrub_if_needed(replaycache_t *r); #endif /* !defined(TOR_REPLAYCACHE_H) */ - diff --git a/src/or/router.c b/src/or/router.c index 3879863e82..44af1e3108 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1,43 +1,60 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ROUTER_PRIVATE -#include "or.h" -#include "circuitbuild.h" -#include "circuitlist.h" -#include "circuituse.h" -#include "config.h" -#include "connection.h" -#include "control.h" -#include "crypto_rand.h" -#include "crypto_util.h" -#include "crypto_curve25519.h" -#include "directory.h" -#include "dirserv.h" -#include "dns.h" -#include "geoip.h" -#include "hibernate.h" -#include "main.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "protover.h" -#include "relay.h" -#include "rephist.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "routerparse.h" -#include "statefile.h" -#include "torcert.h" -#include "transports.h" -#include "routerset.h" - -#include "dirauth/mode.h" +#include "or/or.h" +#include "or/circuitbuild.h" +#include "or/circuitlist.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/crypt_ops/crypto_curve25519.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/dns.h" +#include "or/geoip.h" +#include "or/hibernate.h" +#include "or/main.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/protover.h" +#include "or/relay.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/statefile.h" +#include "or/torcert.h" +#include "or/transports.h" +#include "or/routerset.h" + +#include "or/dirauth/mode.h" + +#include "or/authority_cert_st.h" +#include "or/crypt_path_st.h" +#include "or/dir_connection_st.h" +#include "or/dir_server_st.h" +#include "or/extend_info_st.h" +#include "or/extrainfo_st.h" +#include "or/node_st.h" +#include "or/origin_circuit_st.h" +#include "or/or_state_st.h" +#include "or/port_cfg_st.h" +#include "or/routerinfo_st.h" + +#include "lib/osinfo/uname.h" +#include "lib/tls/tortls.h" +#include "lib/encoding/confline.h" +#include "lib/crypt_ops/crypto_format.h" /** * \file router.c @@ -1342,10 +1359,10 @@ router_should_be_dirserver(const or_options_t *options, int dir_port) interval_length = 1; } log_info(LD_GENERAL, "Calculating whether to advertise %s: effective " - "bwrate: %u, AccountingMax: "U64_FORMAT", " + "bwrate: %u, AccountingMax: %"PRIu64", " "accounting interval length %d", dir_port ? "dirport" : "begindir", - effective_bw, U64_PRINTF_ARG(options->AccountingMax), + effective_bw, (options->AccountingMax), interval_length); acc_bytes = options->AccountingMax; @@ -3813,4 +3830,3 @@ router_get_all_orports(const routerinfo_t *ri) fake_node.ri = (routerinfo_t *)ri; return node_get_all_orports(&fake_node); } - diff --git a/src/or/router.h b/src/or/router.h index 752f2f2dbe..51ac365798 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,7 +12,10 @@ #ifndef TOR_ROUTER_H #define TOR_ROUTER_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" + +struct curve25519_keypair_t; +struct ed25519_keypair_t; #define TOR_ROUTERINFO_ERROR_NO_EXT_ADDR (-1) #define TOR_ROUTERINFO_ERROR_CANNOT_PARSE (-2) @@ -107,10 +110,10 @@ MOCK_DECL(int,router_pick_published_address,(const or_options_t *options, int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e); int router_rebuild_descriptor(int force); char *router_dump_router_to_string(routerinfo_t *router, - const crypto_pk_t *ident_key, - const crypto_pk_t *tap_key, - const curve25519_keypair_t *ntor_keypair, - const ed25519_keypair_t *signing_keypair); + const crypto_pk_t *ident_key, + const crypto_pk_t *tap_key, + const struct curve25519_keypair_t *ntor_keypair, + const struct ed25519_keypair_t *signing_keypair); char *router_dump_exit_policy_to_string(const routerinfo_t *router, int include_ipv4, int include_ipv6); @@ -126,7 +129,7 @@ int router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport); int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo, crypto_pk_t *ident_key, - const ed25519_keypair_t *signing_keypair); + const struct ed25519_keypair_t *signing_keypair); int is_legal_nickname(const char *s); int is_legal_nickname_or_hexdigest(const char *s); int is_legal_hexdigest(const char *s); @@ -156,4 +159,3 @@ STATIC int router_write_fingerprint(int hashed); #endif #endif /* !defined(TOR_ROUTER_H) */ - diff --git a/src/or/routerinfo_st.h b/src/or/routerinfo_st.h new file mode 100644 index 0000000000..89a7702b30 --- /dev/null +++ b/src/or/routerinfo_st.h @@ -0,0 +1,108 @@ +/* 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 ROUTERINFO_ST_H +#define ROUTERINFO_ST_H + +#include "or/signed_descriptor_st.h" + +struct curve25519_public_key_t; + +/** 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 */ + struct 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/routerkeys.c b/src/or/routerkeys.c index 43460da8cc..bb04a8b220 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,17 +14,25 @@ * (TODO: The keys in router.c should go here too.) */ -#include "or.h" -#include "config.h" -#include "crypto_util.h" -#include "router.h" -#include "crypto_pwbox.h" -#include "routerkeys.h" -#include "torcert.h" +#include "or/or.h" +#include "or/config.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/torcert.h" + +#include "lib/crypt_ops/crypto_pwbox.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/term/getpass.h" +#include "lib/tls/tortls.h" +#include "lib/crypt_ops/crypto_format.h" #define ENC_KEY_HEADER "Boxed Ed25519 key" #define ENC_KEY_TAG "master" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + /* DOCDOC */ static ssize_t do_getpass(const char *prompt, char *buf, size_t buflen, @@ -44,7 +52,7 @@ do_getpass(const char *prompt, char *buf, size_t buflen, if (options->use_keygen_passphrase_fd) { twice = 0; fd = options->keygen_passphrase_fd; - length = read_all(fd, buf, buflen-1, 0); + length = read_all_from_fd(fd, buf, buflen-1); if (length >= 0) buf[length] = 0; goto done_reading; @@ -1403,4 +1411,3 @@ routerkeys_free_all(void) rsa_ed_crosscert = NULL; // redundant rsa_ed_crosscert_len = 0; } - diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h index 3e67952ea0..a6f06f6e20 100644 --- a/src/or/routerkeys.h +++ b/src/or/routerkeys.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_ROUTERKEYS_H #define TOR_ROUTERKEYS_H -#include "crypto_ed25519.h" +#include "lib/crypt_ops/crypto_ed25519.h" #define INIT_ED_KEY_CREATE (1u<<0) #define INIT_ED_KEY_REPLACE (1u<<1) diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 2f27af7f06..76a236ff20 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -91,39 +91,59 @@ **/ #define ROUTERLIST_PRIVATE -#include "or.h" -#include "backtrace.h" -#include "bridges.h" -#include "crypto_ed25519.h" -#include "circuitstats.h" -#include "config.h" -#include "connection.h" -#include "control.h" -#include "crypto_rand.h" -#include "directory.h" -#include "dirserv.h" -#include "entrynodes.h" -#include "fp_pair.h" -#include "geoip.h" -#include "hibernate.h" -#include "main.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "nodelist.h" -#include "policies.h" -#include "reasons.h" -#include "rendcommon.h" -#include "rendservice.h" -#include "rephist.h" -#include "router.h" -#include "routerlist.h" -#include "routerparse.h" -#include "routerset.h" -#include "sandbox.h" -#include "torcert.h" - -#include "dirauth/dirvote.h" -#include "dirauth/mode.h" +#include "or/or.h" +#include "lib/err/backtrace.h" +#include "or/bridges.h" +#include "lib/crypt_ops/crypto_ed25519.h" +#include "lib/crypt_ops/crypto_format.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/control.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "or/directory.h" +#include "or/dirserv.h" +#include "or/entrynodes.h" +#include "or/fp_pair.h" +#include "or/geoip.h" +#include "or/hibernate.h" +#include "or/main.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/reasons.h" +#include "or/rendcommon.h" +#include "or/rendservice.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "or/routerset.h" +#include "lib/sandbox/sandbox.h" +#include "or/torcert.h" +#include "lib/math/fp.h" + +#include "or/dirauth/dirvote.h" +#include "or/dirauth/mode.h" + +#include "or/authority_cert_st.h" +#include "or/dir_connection_st.h" +#include "or/dir_server_st.h" +#include "or/document_signature_st.h" +#include "or/extrainfo_st.h" +#include "or/networkstatus_st.h" +#include "or/networkstatus_voter_info_st.h" +#include "or/node_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/vote_routerstatus_st.h" + +#include "lib/crypt_ops/digestset.h" + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif // #define DEBUG_ROUTERLIST @@ -2746,10 +2766,15 @@ compute_weighted_bandwidths(const smartlist_t *sl, /** For all nodes in <b>sl</b>, return the fraction of those nodes, weighted * by their weighted bandwidths with rule <b>rule</b>, for which we have - * descriptors. */ + * descriptors. + * + * If <b>for_direct_connect</b> is true, we intend to connect to the node + * directly, as the first hop of a circuit; otherwise, we intend to connect + * to it indirectly, or use it as if we were connecting to it indirectly. */ double frac_nodes_with_descriptors(const smartlist_t *sl, - bandwidth_weight_rule_t rule) + bandwidth_weight_rule_t rule, + int for_direct_conn) { double *bandwidths = NULL; double total, present; @@ -2761,7 +2786,7 @@ frac_nodes_with_descriptors(const smartlist_t *sl, total <= 0.0) { int n_with_descs = 0; SMARTLIST_FOREACH(sl, const node_t *, node, { - if (node_has_any_descriptor(node)) + if (node_has_preferred_descriptor(node, for_direct_conn)) n_with_descs++; }); tor_free(bandwidths); @@ -2770,7 +2795,7 @@ frac_nodes_with_descriptors(const smartlist_t *sl, present = 0.0; SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) { - if (node_has_any_descriptor(node)) + if (node_has_preferred_descriptor(node, for_direct_conn)) present += bandwidths[node_sl_idx]; } SMARTLIST_FOREACH_END(node); @@ -3328,10 +3353,10 @@ dump_routerlist_mem_usage(int severity) olddescs += sd->signed_descriptor_len); tor_log(severity, LD_DIR, - "In %d live descriptors: "U64_FORMAT" bytes. " - "In %d old descriptors: "U64_FORMAT" bytes.", - smartlist_len(routerlist->routers), U64_PRINTF_ARG(livedescs), - smartlist_len(routerlist->old_routers), U64_PRINTF_ARG(olddescs)); + "In %d live descriptors: %"PRIu64" bytes. " + "In %d old descriptors: %"PRIu64" bytes.", + smartlist_len(routerlist->routers), (livedescs), + smartlist_len(routerlist->old_routers), (olddescs)); } /** Debugging helper: If <b>idx</b> is nonnegative, assert that <b>ri</b> is @@ -4098,7 +4123,8 @@ routerlist_remove_old_cached_routers_with_id(time_t now, signed_descriptor_t *r_next; lifespans[i-lo].idx = i; if (r->last_listed_as_valid_until >= now || - (retain && digestset_contains(retain, r->signed_descriptor_digest))) { + (retain && digestset_probably_contains(retain, + r->signed_descriptor_digest))) { must_keep[i-lo] = 1; } if (i < hi) { @@ -4193,7 +4219,7 @@ routerlist_remove_old_routers(void) router = smartlist_get(routerlist->routers, i); if (router->cache_info.published_on <= cutoff && router->cache_info.last_listed_as_valid_until < now && - !digestset_contains(retain, + !digestset_probably_contains(retain, router->cache_info.signed_descriptor_digest)) { /* Too old: remove it. (If we're a cache, just move it into * old_routers.) */ @@ -4214,7 +4240,7 @@ routerlist_remove_old_routers(void) sd = smartlist_get(routerlist->old_routers, i); if (sd->published_on <= cutoff && sd->last_listed_as_valid_until < now && - !digestset_contains(retain, sd->signed_descriptor_digest)) { + !digestset_probably_contains(retain, sd->signed_descriptor_digest)) { /* Too old. Remove it. */ routerlist_remove_old(routerlist, sd, i--); } @@ -5820,4 +5846,3 @@ refresh_all_country_info(void) nodelist_refresh_countries(); } - diff --git a/src/or/routerlist.h b/src/or/routerlist.h index 83f4d1002f..4b7406364f 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -11,7 +11,91 @@ #ifndef TOR_ROUTERLIST_H #define TOR_ROUTERLIST_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" + +/** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */ +typedef enum was_router_added_t { + /* Router was added successfully. */ + ROUTER_ADDED_SUCCESSFULLY = 1, + /* Extrainfo document was rejected because no corresponding router + * descriptor was found OR router descriptor was rejected because + * it was incompatible with its extrainfo document. */ + ROUTER_BAD_EI = -1, + /* Router descriptor was rejected because it is already known. */ + ROUTER_IS_ALREADY_KNOWN = -2, + /* General purpose router was rejected, because it was not listed + * in consensus. */ + ROUTER_NOT_IN_CONSENSUS = -3, + /* Router was neither in directory consensus nor in any of + * networkstatus documents. Caching it to access later. + * (Applies to fetched descriptors only.) */ + ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4, + /* Router was rejected by directory authority. */ + ROUTER_AUTHDIR_REJECTS = -5, + /* Bridge descriptor was rejected because such bridge was not one + * of the bridges we have listed in our configuration. */ + ROUTER_WAS_NOT_WANTED = -6, + /* Router descriptor was rejected because it was older than + * OLD_ROUTER_DESC_MAX_AGE. */ + ROUTER_WAS_TOO_OLD = -7, /* note contrast with 'NOT_NEW' */ + /* DOCDOC */ + ROUTER_CERTS_EXPIRED = -8 +} was_router_added_t; + +/** Flags to be passed to control router_choose_random_node() to indicate what + * kind of nodes to pick according to what algorithm. */ +typedef enum router_crn_flags_t { + CRN_NEED_UPTIME = 1<<0, + CRN_NEED_CAPACITY = 1<<1, + CRN_NEED_GUARD = 1<<2, + /* XXXX not used, apparently. */ + CRN_WEIGHT_AS_EXIT = 1<<5, + CRN_NEED_DESC = 1<<6, + /* On clients, only provide nodes that satisfy ClientPreferIPv6OR */ + CRN_PREF_ADDR = 1<<7, + /* On clients, only provide nodes that we can connect to directly, based on + * our firewall rules */ + CRN_DIRECT_CONN = 1<<8, + /* On clients, only provide nodes with HSRend >= 2 protocol version which + * is required for hidden service version >= 3. */ + CRN_RENDEZVOUS_V3 = 1<<9, +} router_crn_flags_t; + +/** Possible ways to weight routers when choosing one randomly. See + * routerlist_sl_choose_by_bandwidth() for more information.*/ +typedef enum bandwidth_weight_rule_t { + NO_WEIGHTING, WEIGHT_FOR_EXIT, WEIGHT_FOR_MID, WEIGHT_FOR_GUARD, + WEIGHT_FOR_DIR +} bandwidth_weight_rule_t; + +/* Flags for pick_directory_server() and pick_trusteddirserver(). */ +/** Flag to indicate that we should not automatically be willing to use + * ourself to answer a directory request. + * Passed to router_pick_directory_server (et al).*/ +#define PDS_ALLOW_SELF (1<<0) +/** Flag to indicate that if no servers seem to be up, we should mark all + * directory servers as up and try again. + * Passed to router_pick_directory_server (et al).*/ +#define PDS_RETRY_IF_NO_SERVERS (1<<1) +/** Flag to indicate that we should not exclude directory servers that + * our ReachableAddress settings would exclude. This usually means that + * we're going to connect to the server over Tor, and so we don't need to + * worry about our firewall telling us we can't. + * Passed to router_pick_directory_server (et al).*/ +#define PDS_IGNORE_FASCISTFIREWALL (1<<2) +/** Flag to indicate that we should not use any directory authority to which + * we have an existing directory connection for downloading server descriptors + * or extrainfo documents. + * + * Passed to router_pick_directory_server (et al) + */ +#define PDS_NO_EXISTING_SERVERDESC_FETCH (1<<3) +/** Flag to indicate that we should not use any directory authority to which + * we have an existing directory connection for downloading microdescs. + * + * Passed to router_pick_directory_server (et al) + */ +#define PDS_NO_EXISTING_MICRODESC_FETCH (1<<4) int get_n_authorities(dirinfo_type_t type); int trusted_dirs_reload_certs(void); @@ -74,7 +158,8 @@ uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router); const node_t *node_sl_choose_by_bandwidth(const smartlist_t *sl, bandwidth_weight_rule_t rule); double frac_nodes_with_descriptors(const smartlist_t *sl, - bandwidth_weight_rule_t rule); + bandwidth_weight_rule_t rule, + int for_direct_conn); const node_t *router_choose_random_node(smartlist_t *excludedsmartlist, struct routerset_t *excludedset, @@ -260,4 +345,3 @@ STATIC int router_is_already_dir_fetching(const tor_addr_port_t *ap, #endif /* defined(ROUTERLIST_PRIVATE) */ #endif /* !defined(TOR_ROUTERLIST_H) */ - diff --git a/src/or/routerlist_st.h b/src/or/routerlist_st.h new file mode 100644 index 0000000000..0b94a4dfcd --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef ROUTERLIST_ST_H +#define ROUTERLIST_ST_H + +#include "or/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..273666046b 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -55,34 +55,58 @@ #define ROUTERPARSE_PRIVATE -#include "or.h" -#include "circuitstats.h" -#include "config.h" -#include "crypto_util.h" -#include "dirauth/shared_random.h" -#include "dirserv.h" -#include "entrynodes.h" -#include "memarea.h" -#include "microdesc.h" -#include "networkstatus.h" -#include "parsecommon.h" -#include "policies.h" -#include "protover.h" -#include "rendcommon.h" -#include "rephist.h" -#include "router.h" -#include "routerkeys.h" -#include "routerlist.h" -#include "routerparse.h" -#include "sandbox.h" -#include "shared_random_client.h" -#include "torcert.h" -#include "voting_schedule.h" +#include "or/or.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/dirauth/shared_random.h" +#include "or/dirserv.h" +#include "or/entrynodes.h" +#include "lib/memarea/memarea.h" +#include "or/microdesc.h" +#include "or/networkstatus.h" +#include "or/parsecommon.h" +#include "or/policies.h" +#include "or/protover.h" +#include "or/rendcommon.h" +#include "or/rephist.h" +#include "or/router.h" +#include "or/routerkeys.h" +#include "or/routerlist.h" +#include "or/routerparse.h" +#include "lib/sandbox/sandbox.h" +#include "or/shared_random_client.h" +#include "or/torcert.h" +#include "or/voting_schedule.h" + +#include "or/dirauth/dirvote.h" + +#include "or/addr_policy_st.h" +#include "or/authority_cert_st.h" +#include "or/document_signature_st.h" +#include "or/extend_info_st.h" +#include "or/extrainfo_st.h" +#include "or/microdesc_st.h" +#include "or/networkstatus_st.h" +#include "or/networkstatus_voter_info_st.h" +#include "or/ns_detached_signatures_st.h" +#include "or/rend_authorized_client_st.h" +#include "or/rend_intro_point_st.h" +#include "or/rend_service_descriptor_st.h" +#include "or/routerinfo_st.h" +#include "or/routerlist_st.h" +#include "or/tor_version_st.h" +#include "or/vote_microdesc_hash_st.h" +#include "or/vote_routerstatus_st.h" + +#include "lib/container/bloomfilt.h" #undef log #include <math.h> - -#include "dirauth/dirvote.h" +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif /****************************************************************************/ @@ -855,8 +879,8 @@ dump_desc_populate_fifo_from_directory(const char *dirname) /* Log some stats */ log_info(LD_DIR, "Reloaded unparseable descriptor dump FIFO with %d dump(s) " - "totaling " U64_FORMAT " bytes", - smartlist_len(descs_dumped), U64_PRINTF_ARG(len_descs_dumped)); + "totaling %"PRIu64 " bytes", + smartlist_len(descs_dumped), (len_descs_dumped)); } /* Free the original list */ @@ -2705,7 +2729,7 @@ routerstatus_parse_entry_from_string(memarea_t *area, for (i=0; i < tok->n_args; ++i) { int p = smartlist_string_pos(vote->known_flags, tok->args[i]); if (p >= 0) { - vote_rs->flags |= (U64_LITERAL(1)<<p); + vote_rs->flags |= (UINT64_C(1)<<p); } else { log_warn(LD_DIR, "Flags line had a flag %s not listed in known_flags.", escaped(tok->args[i])); @@ -2928,8 +2952,8 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) // We use > 1 as the check for these because they are computed as integers. // Sometimes there are rounding errors. if (fabs(Wmm - weight_scale) > 1) { - log_warn(LD_BUG, "Wmm=%f != "I64_FORMAT, - Wmm, I64_PRINTF_ARG(weight_scale)); + log_warn(LD_BUG, "Wmm=%f != %"PRId64, + Wmm, (weight_scale)); valid = 0; } @@ -2949,20 +2973,20 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) } if (fabs(Wgg + Wmg - weight_scale) > 0.001*weight_scale) { - log_warn(LD_BUG, "Wgg=%f != "I64_FORMAT" - Wmg=%f", Wgg, - I64_PRINTF_ARG(weight_scale), Wmg); + log_warn(LD_BUG, "Wgg=%f != %"PRId64" - Wmg=%f", Wgg, + (weight_scale), Wmg); valid = 0; } if (fabs(Wee + Wme - weight_scale) > 0.001*weight_scale) { - log_warn(LD_BUG, "Wee=%f != "I64_FORMAT" - Wme=%f", Wee, - I64_PRINTF_ARG(weight_scale), Wme); + log_warn(LD_BUG, "Wee=%f != %"PRId64" - Wme=%f", Wee, + (weight_scale), Wme); valid = 0; } if (fabs(Wgd + Wmd + Wed - weight_scale) > 0.001*weight_scale) { - log_warn(LD_BUG, "Wgd=%f + Wmd=%f + Wed=%f != "I64_FORMAT, - Wgd, Wmd, Wed, I64_PRINTF_ARG(weight_scale)); + log_warn(LD_BUG, "Wgd=%f + Wmd=%f + Wed=%f != %"PRId64, + Wgd, Wmd, Wed, (weight_scale)); valid = 0; } @@ -3020,36 +3044,36 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Mtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Mtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Mtotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3076,12 +3100,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (Rtotal > Stotal) { log_warn(LD_DIR, "Bw Weight Failure for %s: Rtotal %f > Stotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Rtotal, Stotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3089,12 +3113,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (3*Rtotal > T) { log_warn(LD_DIR, "Bw Weight Failure for %s: 3*Rtotal %f > T " - I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT - " D="I64_FORMAT" T="I64_FORMAT". " + "%"PRId64". G=%"PRId64" M=%"PRId64" E=%"PRId64 + " D=%"PRId64" T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", - casename, Rtotal*3, I64_PRINTF_ARG(T), - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + casename, Rtotal*3, (T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3102,12 +3126,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (3*Stotal > T) { log_warn(LD_DIR, "Bw Weight Failure for %s: 3*Stotal %f > T " - I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT - " D="I64_FORMAT" T="I64_FORMAT". " + "%"PRId64". G=%"PRId64" M=%"PRId64" E=%"PRId64 + " D=%"PRId64" T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", - casename, Stotal*3, I64_PRINTF_ARG(T), - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + casename, Stotal*3, (T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3115,13 +3139,13 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (3*Mtotal < T) { log_warn(LD_DIR, "Bw Weight Failure for %s: 3*Mtotal %f < T " - I64_FORMAT". " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "%"PRId64". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", - casename, Mtotal*3, I64_PRINTF_ARG(T), - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + casename, Mtotal*3, (T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3134,36 +3158,36 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Mtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Mtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Mtotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3171,12 +3195,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3201,12 +3225,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (3*Stotal > T) { log_warn(LD_DIR, "Bw Weight Failure for %s: 3*Stotal %f > T " - I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT - " D="I64_FORMAT" T="I64_FORMAT". " + "%"PRId64". G=%"PRId64" M=%"PRId64" E=%"PRId64 + " D=%"PRId64" T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", - casename, Stotal*3, I64_PRINTF_ARG(T), - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + casename, Stotal*3, (T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3214,12 +3238,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (fabs(NStotal-Mtotal) > 0.01*MAX(NStotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: NStotal %f != Mtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, NStotal, Mtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3228,12 +3252,12 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (3*NStotal < T) { log_warn(LD_DIR, "Bw Weight Failure for %s: 3*NStotal %f < T " - I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT - " E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT". " + "%"PRId64". G=%"PRId64" M=%"PRId64 + " E=%"PRId64" D=%"PRId64" T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", - casename, NStotal*3, I64_PRINTF_ARG(T), - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + casename, NStotal*3, (T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -3243,36 +3267,36 @@ networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method) if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Mtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Mtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Etotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Etotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) { log_warn(LD_DIR, "Bw Weight Failure for %s: Mtotal %f != Gtotal %f. " - "G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT - " T="I64_FORMAT". " + "G=%"PRId64" M=%"PRId64" E=%"PRId64" D=%"PRId64 + " T=%"PRId64". " "Wgg=%f Wgd=%f Wmg=%f Wme=%f Wmd=%f Wee=%f Wed=%f", casename, Mtotal, Gtotal, - I64_PRINTF_ARG(G), I64_PRINTF_ARG(M), I64_PRINTF_ARG(E), - I64_PRINTF_ARG(D), I64_PRINTF_ARG(T), + (G), (M), (E), + (D), (T), Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed); valid = 0; } @@ -5667,4 +5691,3 @@ routerparse_free_all(void) { dump_desc_fifo_cleanup(); } - diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 418fd3acdb..87c2a75aa5 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,6 +12,22 @@ #ifndef TOR_ROUTERPARSE_H #define TOR_ROUTERPARSE_H +/** Possible statuses of a version of Tor, given opinions from the directory + * servers. */ +typedef enum version_status_t { + VS_RECOMMENDED=0, /**< This version is listed as recommended. */ + VS_OLD=1, /**< This version is older than any recommended version. */ + VS_NEW=2, /**< This version is newer than any recommended version. */ + VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version + * in its series, but later recommended versions exist. + */ + VS_UNRECOMMENDED=4, /**< This version is not recommended (general case). */ + VS_EMPTY=5, /**< The version list was empty; no agreed-on versions. */ + VS_UNKNOWN, /**< We have no idea. */ +} version_status_t; + +enum networkstatus_type_t; + int router_get_router_hash(const char *s, size_t s_len, char *digest); int router_get_dir_hash(const char *s, char *digest); int router_get_networkstatus_v3_hashes(const char *s, @@ -43,6 +59,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); @@ -64,8 +81,8 @@ void dump_distinct_digest_count(int severity); int compare_vote_routerstatus_entries(const void **_a, const void **_b); int networkstatus_verify_bw_weights(networkstatus_t *ns, int); networkstatus_t *networkstatus_parse_vote_from_string(const char *s, - const char **eos_out, - networkstatus_type_t ns_type); + const char **eos_out, + enum networkstatus_type_t ns_type); ns_detached_signatures_t *networkstatus_parse_detached_signatures( const char *s, const char *eos); @@ -142,4 +159,3 @@ STATIC void summarize_protover_flags(protover_summary_flags_t *out, #define ED_DESC_SIGNATURE_PREFIX "Tor router descriptor signature v1" #endif /* !defined(TOR_ROUTERPARSE_H) */ - diff --git a/src/or/routerset.c b/src/or/routerset.c index a2599b316c..285ef9d821 100644 --- a/src/or/routerset.c +++ b/src/or/routerset.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. - * Copyright (c) 2001-2004, Roger Dingledine. +n * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,14 +27,20 @@ #define ROUTERSET_PRIVATE -#include "or.h" -#include "bridges.h" -#include "geoip.h" -#include "nodelist.h" -#include "policies.h" -#include "router.h" -#include "routerparse.h" -#include "routerset.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/geoip.h" +#include "or/nodelist.h" +#include "or/policies.h" +#include "or/router.h" +#include "or/routerparse.h" +#include "or/routerset.h" + +#include "or/addr_policy_st.h" +#include "or/extend_info_st.h" +#include "or/node_st.h" +#include "or/routerinfo_st.h" +#include "or/routerstatus_st.h" /** Return a new empty routerset. */ routerset_t * @@ -455,4 +461,3 @@ routerset_free_(routerset_t *routerset) bitarray_free(routerset->countries); tor_free(routerset); } - diff --git a/src/or/routerset.h b/src/or/routerset.h index 53e8c66c5e..8a13ca042a 100644 --- a/src/or/routerset.h +++ b/src/or/routerset.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -45,6 +45,8 @@ void routerset_free_(routerset_t *routerset); int routerset_len(const routerset_t *set); #ifdef ROUTERSET_PRIVATE +#include "lib/container/bitarray.h" + STATIC char * routerset_get_countryname(const char *c); STATIC int routerset_contains(const routerset_t *set, const tor_addr_t *addr, uint16_t orport, @@ -85,4 +87,3 @@ struct routerset_t { }; #endif /* defined(ROUTERSET_PRIVATE) */ #endif /* !defined(TOR_ROUTERSET_H) */ - diff --git a/src/or/routerstatus_st.h b/src/or/routerstatus_st.h new file mode 100644 index 0000000000..3de4a40ae4 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef ROUTERSTATUS_ST_H +#define ROUTERSTATUS_ST_H + +#include "or/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..7c423064c7 100644 --- a/src/or/scheduler.c +++ b/src/or/scheduler.c @@ -1,17 +1,20 @@ -/* Copyright (c) 2013-2017, The Tor Project, Inc. */ +/* Copyright (c) 2013-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" -#include "config.h" +#include "or/or.h" +#include "or/config.h" -#include "compat_libevent.h" +#include "common/compat_libevent.h" #define SCHEDULER_PRIVATE_ #define SCHEDULER_KIST_PRIVATE -#include "scheduler.h" -#include "main.h" -#include "buffers.h" +#include "or/scheduler.h" +#include "or/main.h" +#include "lib/container/buffers.h" #define TOR_CHANNEL_INTERNAL_ -#include "channeltls.h" +#include "or/channeltls.h" +#include "common/compat_libevent.h" + +#include "or/or_connection_st.h" /** * \file scheduler.c @@ -763,4 +766,3 @@ scheduler_touch_channel(channel_t *chan) } #endif /* defined(TOR_UNIT_TESTS) */ - diff --git a/src/or/scheduler.h b/src/or/scheduler.h index 08b02e286f..856923f9a7 100644 --- a/src/or/scheduler.h +++ b/src/or/scheduler.h @@ -1,4 +1,4 @@ -/* * Copyright (c) 2017, The Tor Project, Inc. */ +/* * Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,9 +9,9 @@ #ifndef TOR_SCHEDULER_H #define TOR_SCHEDULER_H -#include "or.h" -#include "channel.h" -#include "testsupport.h" +#include "or/or.h" +#include "or/channel.h" +#include "lib/testsupport/testsupport.h" /** Scheduler type, we build an ordered list with those values from the * parsed strings in Schedulers. The reason to do such a thing is so we can diff --git a/src/or/scheduler_kist.c b/src/or/scheduler_kist.c index c6e9b72c48..5a45ccab88 100644 --- a/src/or/scheduler_kist.c +++ b/src/or/scheduler_kist.c @@ -1,21 +1,28 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define SCHEDULER_KIST_PRIVATE -#include "or.h" -#include "buffers.h" -#include "config.h" -#include "connection.h" -#include "networkstatus.h" +#include "or/or.h" +#include "lib/container/buffers.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/networkstatus.h" #define TOR_CHANNEL_INTERNAL_ -#include "channel.h" -#include "channeltls.h" +#include "or/channel.h" +#include "or/channeltls.h" #define SCHEDULER_PRIVATE_ -#include "scheduler.h" +#include "or/scheduler.h" +#include "lib/math/fp.h" + +#include "or/or_connection_st.h" #define TLS_PER_CELL_OVERHEAD 29 +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif + #ifdef HAVE_KIST_SUPPORT /* Kernel interface needed for KIST. */ #include <netinet/tcp.h> @@ -833,4 +840,3 @@ scheduler_can_use_kist(void) } #endif /* defined(HAVE_KIST_SUPPORT) */ - diff --git a/src/or/scheduler_vanilla.c b/src/or/scheduler_vanilla.c index b674d8256c..e05bebb37c 100644 --- a/src/or/scheduler_vanilla.c +++ b/src/or/scheduler_vanilla.c @@ -1,12 +1,12 @@ -/* Copyright (c) 2017, The Tor Project, Inc. */ +/* Copyright (c) 2017-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ -#include "or.h" -#include "config.h" +#include "or/or.h" +#include "or/config.h" #define TOR_CHANNEL_INTERNAL_ -#include "channel.h" +#include "or/channel.h" #define SCHEDULER_PRIVATE_ -#include "scheduler.h" +#include "or/scheduler.h" /***************************************************************************** * Other internal data @@ -72,9 +72,9 @@ vanilla_scheduler_run(void) n_cells = channel_num_cells_writeable(chan); if (n_cells > 0) { log_debug(LD_SCHED, - "Scheduler saw pending channel " U64_FORMAT " at %p with " + "Scheduler saw pending channel %"PRIu64 " at %p with " "%d cells writeable", - U64_PRINTF_ARG(chan->global_identifier), chan, n_cells); + (chan->global_identifier), chan, n_cells); flushed = 0; while (flushed < n_cells) { @@ -97,9 +97,9 @@ vanilla_scheduler_run(void) if (!to_readd) to_readd = smartlist_new(); smartlist_add(to_readd, chan); log_debug(LD_SCHED, - "Channel " U64_FORMAT " at %p " + "Channel %"PRIu64 " at %p " "is still pending", - U64_PRINTF_ARG(chan->global_identifier), + (chan->global_identifier), chan); } else { /* It's waiting to be able to write more */ @@ -125,14 +125,14 @@ vanilla_scheduler_run(void) log_debug(LD_SCHED, "Scheduler flushed %d cells onto pending channel " - U64_FORMAT " at %p", - (int)flushed, U64_PRINTF_ARG(chan->global_identifier), + "%"PRIu64 " at %p", + (int)flushed, (chan->global_identifier), chan); } else { log_info(LD_SCHED, - "Scheduler saw pending channel " U64_FORMAT " at %p with " + "Scheduler saw pending channel %"PRIu64 " at %p with " "no cells writeable", - U64_PRINTF_ARG(chan->global_identifier), chan); + (chan->global_identifier), chan); /* Put it back to WAITING_TO_WRITE */ scheduler_set_channel_state(chan, SCHED_CHAN_WAITING_TO_WRITE); } diff --git a/src/or/server_port_cfg_st.h b/src/or/server_port_cfg_st.h new file mode 100644 index 0000000000..e1a9ca496a --- /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-2018, 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..9a6c0f6644 100644 --- a/src/or/shared_random_client.c +++ b/src/or/shared_random_client.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,13 +9,15 @@ **/ #define SHARED_RANDOM_CLIENT_PRIVATE -#include "shared_random_client.h" +#include "or/shared_random_client.h" -#include "config.h" -#include "voting_schedule.h" -#include "networkstatus.h" -#include "util.h" -#include "util_format.h" +#include "or/config.h" +#include "or/voting_schedule.h" +#include "or/networkstatus.h" +#include "common/util.h" +#include "lib/encoding/binascii.h" + +#include "or/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. */ diff --git a/src/or/shared_random_client.h b/src/or/shared_random_client.h index 89c608d45f..079829496c 100644 --- a/src/or/shared_random_client.h +++ b/src/or/shared_random_client.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -10,7 +10,7 @@ #define TOR_SHARED_RANDOM_CLIENT_H /* Dirauth module. */ -#include "dirauth/shared_random.h" +#include "or/dirauth/shared_random.h" /* Helper functions. */ void sr_srv_encode(char *dst, size_t dst_len, const sr_srv_t *srv); diff --git a/src/or/signed_descriptor_st.h b/src/or/signed_descriptor_st.h new file mode 100644 index 0000000000..90cd4a2703 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef SIGNED_DESCRIPTOR_ST_H +#define SIGNED_DESCRIPTOR_ST_H + +#include "or/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..d7b979c3eb --- /dev/null +++ b/src/or/socks_request_st.h @@ -0,0 +1,75 @@ +/* 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 SOCKS_REQUEST_ST_H +#define SOCKS_REQUEST_ST_H + +#define MAX_SOCKS_REPLY_LEN 1024 + +#define SOCKS_NO_AUTH 0x00 +#define SOCKS_USER_PASS 0x02 + +/** Please open a TCP connection to this addr:port. */ +#define SOCKS_COMMAND_CONNECT 0x01 +/** Please turn this FQDN into an IP address, privately. */ +#define SOCKS_COMMAND_RESOLVE 0xF0 +/** Please turn this IP address into an FQDN, privately. */ +#define SOCKS_COMMAND_RESOLVE_PTR 0xF1 + +/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */ +#define SOCKS_COMMAND_IS_CONNECT(c) (((c)==SOCKS_COMMAND_CONNECT) || 0) +#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 <b>reply</b>. */ + 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/statefile.c b/src/or/statefile.c index c81ea44e06..e9db1ff069 100644 --- a/src/or/statefile.c +++ b/src/or/statefile.c @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -29,19 +29,26 @@ */ #define STATEFILE_PRIVATE -#include "or.h" -#include "circuitstats.h" -#include "config.h" -#include "confparse.h" -#include "connection.h" -#include "control.h" -#include "entrynodes.h" -#include "hibernate.h" -#include "main.h" -#include "rephist.h" -#include "router.h" -#include "sandbox.h" -#include "statefile.h" +#include "or/or.h" +#include "or/circuitstats.h" +#include "or/config.h" +#include "or/confparse.h" +#include "or/connection.h" +#include "or/control.h" +#include "or/entrynodes.h" +#include "or/hibernate.h" +#include "or/main.h" +#include "or/rephist.h" +#include "or/router.h" +#include "lib/sandbox/sandbox.h" +#include "or/statefile.h" +#include "lib/encoding/confline.h" + +#include "or/or_state_st.h" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /** A list of state-file "abbreviations," for compatibility. */ static config_abbrev_t state_abbrevs_[] = { @@ -708,4 +715,3 @@ or_state_free_all(void) or_state_free(global_state); global_state = NULL; } - diff --git a/src/or/statefile.h b/src/or/statefile.h index 5aa2ca9320..e996d5b6e6 100644 --- a/src/or/statefile.h +++ b/src/or/statefile.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_STATEFILE_H @@ -20,11 +20,11 @@ void or_state_free_all(void); void or_state_mark_dirty(or_state_t *state, time_t when); #ifdef STATEFILE_PRIVATE -STATIC config_line_t *get_transport_in_state_by_name(const char *transport); +STATIC struct config_line_t *get_transport_in_state_by_name( + const char *transport); STATIC void or_state_free_(or_state_t *state); #define or_state_free(st) FREE_AND_NULL(or_state_t, or_state_free_, (st)) STATIC or_state_t *or_state_new(void); #endif #endif /* !defined(TOR_STATEFILE_H) */ - diff --git a/src/or/status.c b/src/or/status.c index 4b8033d114..2259b3aae7 100644 --- a/src/or/status.c +++ b/src/or/status.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2017, The Tor Project, Inc. */ +/* Copyright (c) 2010-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,24 +14,28 @@ #define STATUS_PRIVATE -#include "or.h" -#include "circuituse.h" -#include "config.h" -#include "status.h" -#include "nodelist.h" -#include "relay.h" -#include "router.h" -#include "circuitlist.h" -#include "main.h" -#include "rephist.h" -#include "hibernate.h" -#include "statefile.h" -#include "hs_stats.h" -#include "hs_service.h" -#include "dos.h" +#include "or/or.h" +#include "or/circuituse.h" +#include "or/config.h" +#include "or/status.h" +#include "or/nodelist.h" +#include "or/relay.h" +#include "or/router.h" +#include "or/circuitlist.h" +#include "or/main.h" +#include "or/rephist.h" +#include "or/hibernate.h" +#include "or/statefile.h" +#include "or/hs_stats.h" +#include "or/hs_service.h" +#include "or/dos.h" + +#include "or/or_state_st.h" +#include "or/routerinfo_st.h" +#include "lib/tls/tortls.h" static void log_accounting(const time_t now, const or_options_t *options); -#include "geoip.h" +#include "or/geoip.h" /** Return the total number of circuits. */ STATIC int @@ -75,12 +79,12 @@ bytes_to_usage(uint64_t bytes) char *bw_string = NULL; if (bytes < (1<<20)) { /* Less than a megabyte. */ - tor_asprintf(&bw_string, U64_FORMAT" kB", U64_PRINTF_ARG(bytes>>10)); + tor_asprintf(&bw_string, "%"PRIu64" kB", (bytes>>10)); } else if (bytes < (1<<30)) { /* Megabytes. Let's add some precision. */ - double bw = U64_TO_DBL(bytes); + double bw = ((double)bytes); tor_asprintf(&bw_string, "%.2f MB", bw/(1<<20)); } else { /* Gigabytes. */ - double bw = U64_TO_DBL(bytes); + double bw = ((double)bytes); tor_asprintf(&bw_string, "%.2f GB", bw/(1<<30)); } @@ -148,8 +152,8 @@ log_heartbeat(time_t now) double fullness_pct = 100; if (stats_n_data_cells_packaged && !hibernating) { fullness_pct = - 100*(U64_TO_DBL(stats_n_data_bytes_packaged) / - U64_TO_DBL(stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)); + 100*(((double)stats_n_data_bytes_packaged) / + ((double)stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)); } const double overhead_pct = ( r - 1.0 ) * 100.0; @@ -186,12 +190,12 @@ log_heartbeat(time_t now) const uint64_t main_loop_idle_count = get_main_loop_idle_count(); log_fn(LOG_NOTICE, LD_HEARTBEAT, "Main event loop statistics: " - U64_FORMAT " successful returns, " - U64_FORMAT " erroneous returns, and " - U64_FORMAT " idle returns.", - U64_PRINTF_ARG(main_loop_success_count), - U64_PRINTF_ARG(main_loop_error_count), - U64_PRINTF_ARG(main_loop_idle_count)); + "%"PRIu64 " successful returns, " + "%"PRIu64 " erroneous returns, and " + "%"PRIu64 " idle returns.", + (main_loop_success_count), + (main_loop_error_count), + (main_loop_idle_count)); } /** Now, if we are an HS service, log some stats about our usage */ @@ -245,4 +249,3 @@ log_accounting(const time_t now, const or_options_t *options) tor_free(acc_max); tor_free(remaining); } - diff --git a/src/or/status.h b/src/or/status.h index 49da6abc0f..7258ed5939 100644 --- a/src/or/status.h +++ b/src/or/status.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2010-2017, The Tor Project, Inc. */ +/* Copyright (c) 2010-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_STATUS_H #define TOR_STATUS_H -#include "testsupport.h" +#include "lib/testsupport/testsupport.h" int log_heartbeat(time_t now); diff --git a/src/or/tor_api.c b/src/or/tor_api.c index 4260cc88f4..efedf2dc78 100644 --- a/src/or/tor_api.c +++ b/src/or/tor_api.c @@ -1,15 +1,15 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * \file tor_api.c **/ -#include "tor_api.h" -#include "tor_api_internal.h" +#include "or/tor_api.h" +#include "or/tor_api_internal.h" // Include this after the above headers, to insure that they don't // depend on anything else. diff --git a/src/or/tor_api.h b/src/or/tor_api.h index 6d4a9518e0..ead9493c1f 100644 --- a/src/or/tor_api.h +++ b/src/or/tor_api.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/or/tor_api_internal.h b/src/or/tor_api_internal.h index 10b6278b7b..2c392a68de 100644 --- a/src/or/tor_api_internal.h +++ b/src/or/tor_api_internal.h @@ -1,7 +1,7 @@ /* 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. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_API_INTERNAL_H diff --git a/src/or/tor_main.c b/src/or/tor_main.c index 703669ac99..8c497fff8a 100644 --- a/src/or/tor_main.c +++ b/src/or/tor_main.c @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/or/tor_version_st.h b/src/or/tor_version_st.h new file mode 100644 index 0000000000..5950c5d5c4 --- /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-2018, 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..269fa66cea 100644 --- a/src/or/torcert.c +++ b/src/or/torcert.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,15 +25,17 @@ * that one is authority_cert_t, and it's mostly handled in routerlist.c. */ -#include "or.h" -#include "config.h" -#include "crypto_util.h" -#include "torcert.h" -#include "ed25519_cert.h" -#include "torlog.h" -#include "util.h" -#include "compat.h" -#include "link_handshake.h" +#include "or/or.h" +#include "or/config.h" +#include "lib/crypt_ops/crypto_util.h" +#include "or/torcert.h" +#include "trunnel/ed25519_cert.h" +#include "lib/log/torlog.h" +#include "common/util.h" +#include "trunnel/link_handshake.h" +#include "lib/tls/tortls.h" + +#include "or/or_handshake_certs_st.h" /** Helper for tor_cert_create(): signs any 32 bytes, not just an ed25519 * key. @@ -167,7 +169,7 @@ tor_cert_parse(const uint8_t *encoded, const size_t len) memcpy(cert->signed_key.pubkey, parsed->certified_key, 32); int64_t valid_until_64 = ((int64_t)parsed->exp_field) * 3600; -#if SIZEOF_TIME_T < SIZEOF_INT64_T +#if SIZEOF_TIME_T < 8 if (valid_until_64 > TIME_MAX) valid_until_64 = TIME_MAX - 1; #endif @@ -722,4 +724,3 @@ tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out) tor_free(ed_cert_b64); return ret; } - diff --git a/src/or/torcert.h b/src/or/torcert.h index 18ca60b5a8..5fa97679df 100644 --- a/src/or/torcert.h +++ b/src/or/torcert.h @@ -1,10 +1,10 @@ -/* Copyright (c) 2014-2017, The Tor Project, Inc. */ +/* Copyright (c) 2014-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TORCERT_H_INCLUDED #define TORCERT_H_INCLUDED -#include "crypto_ed25519.h" +#include "lib/crypt_ops/crypto_ed25519.h" #define SIGNED_KEY_TYPE_ED25519 0x01 @@ -49,6 +49,8 @@ typedef struct tor_cert_st { unsigned cert_valid : 1; } tor_cert_t; +struct tor_tls_t; + tor_cert_t *tor_cert_create(const ed25519_keypair_t *signing_key, uint8_t cert_type, const ed25519_public_key_t *signed_key, @@ -90,15 +92,15 @@ void or_handshake_certs_free_(or_handshake_certs_t *certs); FREE_AND_NULL(or_handshake_certs_t, or_handshake_certs_free_, (certs)) int or_handshake_certs_rsa_ok(int severity, or_handshake_certs_t *certs, - tor_tls_t *tls, + struct tor_tls_t *tls, time_t now); int or_handshake_certs_ed25519_ok(int severity, or_handshake_certs_t *certs, - tor_tls_t *tls, + struct tor_tls_t *tls, time_t now); void or_handshake_certs_check_both(int severity, or_handshake_certs_t *certs, - tor_tls_t *tls, + struct tor_tls_t *tls, time_t now, const ed25519_public_key_t **ed_id_out, const common_digests_t **rsa_id_out); @@ -106,4 +108,3 @@ void or_handshake_certs_check_both(int severity, int tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out); #endif /* !defined(TORCERT_H_INCLUDED) */ - diff --git a/src/or/transports.c b/src/or/transports.c index 614fc81da8..ff51ff00eb 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Tor Project, Inc. */ +/* Copyright (c) 2011-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -90,17 +90,21 @@ **/ #define PT_PRIVATE -#include "or.h" -#include "bridges.h" -#include "config.h" -#include "circuitbuild.h" -#include "transports.h" -#include "util.h" -#include "router.h" -#include "statefile.h" -#include "connection_or.h" -#include "ext_orport.h" -#include "control.h" +#include "or/or.h" +#include "or/bridges.h" +#include "or/config.h" +#include "or/connection.h" +#include "or/circuitbuild.h" +#include "or/transports.h" +#include "common/util.h" +#include "or/router.h" +#include "or/statefile.h" +#include "or/connection_or.h" +#include "or/ext_orport.h" +#include "or/control.h" + +#include "lib/process/env.h" +#include "lib/process/subprocess.h" static process_environment_t * create_managed_proxy_environment(const managed_proxy_t *mp); @@ -1697,3 +1701,39 @@ pt_free_all(void) } } +/** Return a newly allocated string equal to <b>string</b>, except that every + * character in <b>chars_to_escape</b> is preceded by a backslash. */ +char * +tor_escape_str_for_pt_args(const char *string, const char *chars_to_escape) +{ + char *new_string = NULL; + char *new_cp = NULL; + size_t length, new_length; + + tor_assert(string); + + length = strlen(string); + + if (!length) /* If we were given the empty string, return the same. */ + return tor_strdup(""); + /* (new_length > SIZE_MAX) => ((length * 2) + 1 > SIZE_MAX) => + (length*2 > SIZE_MAX - 1) => (length > (SIZE_MAX - 1)/2) */ + if (length > (SIZE_MAX - 1)/2) /* check for overflow */ + return NULL; + + /* this should be enough even if all characters must be escaped */ + new_length = (length * 2) + 1; + + new_string = new_cp = tor_malloc(new_length); + + while (*string) { + if (strchr(chars_to_escape, *string)) + *new_cp++ = '\\'; + + *new_cp++ = *string++; + } + + *new_cp = '\0'; /* NUL-terminate the new string */ + + return new_string; +} diff --git a/src/or/transports.h b/src/or/transports.h index 022b926a03..d304dcd485 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2017, The Tor Project, Inc. */ + * Copyright (c) 2007-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -66,6 +66,9 @@ char *pt_stringify_socks_args(const smartlist_t *socks_args); char *pt_get_socks_args_for_proxy_addrport(const tor_addr_t *addr, uint16_t port); +char *tor_escape_str_for_pt_args(const char *string, + const char *chars_to_escape); + #ifdef PT_PRIVATE /** State of the managed proxy configuration protocol. */ enum pt_proto_state { @@ -78,6 +81,8 @@ enum pt_proto_state { PT_PROTO_FAILED_LAUNCH /* failed while launching */ }; +struct process_handle_t; + /** Structure containing information of a managed proxy. */ typedef struct { enum pt_proto_state conf_state; /* the current configuration state */ @@ -90,7 +95,7 @@ typedef struct { int is_server; /* is it a server proxy? */ /* A pointer to the process handle of this managed proxy. */ - process_handle_t *process_handle; + struct process_handle_t *process_handle; int pid; /* The Process ID this managed proxy is using. */ @@ -140,4 +145,3 @@ STATIC void free_execve_args(char **arg); #endif /* defined(PT_PRIVATE) */ #endif /* !defined(TOR_TRANSPORTS_H) */ - diff --git a/src/or/var_cell_st.h b/src/or/var_cell_st.h new file mode 100644 index 0000000000..514afc44b1 --- /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-2018, 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 <b>payload</b> */ + 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..31fc98040e --- /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-2018, 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..1b85737df8 --- /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-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef VOTE_ROUTERSTATUS_ST_H +#define VOTE_ROUTERSTATUS_ST_H + +#include "or/routerstatus_st.h" +#include "lib/defs/x25519_sizes.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..14c13eed28 --- /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-2018, 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 d230a6dbcd..6edde3f229 100644 --- a/src/or/voting_schedule.c +++ b/src/or/voting_schedule.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,11 +9,13 @@ **/ #define VOTING_SCHEDULE_PRIVATE -#include "voting_schedule.h" +#include "or/voting_schedule.h" -#include "or.h" -#include "config.h" -#include "networkstatus.h" +#include "or/or.h" +#include "or/config.h" +#include "or/networkstatus.h" + +#include "or/networkstatus_st.h" /* ===== * Vote scheduling diff --git a/src/or/voting_schedule.h b/src/or/voting_schedule.h index 087701408e..0f27d36d52 100644 --- a/src/or/voting_schedule.h +++ b/src/or/voting_schedule.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Tor Project, Inc. */ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,7 +9,7 @@ #ifndef TOR_VOTING_SCHEDULE_H #define TOR_VOTING_SCHEDULE_H -#include "or.h" +#include "or/or.h" /** Scheduling information for a voting interval. */ typedef struct { |