Browse Source

Merge branch 'split_or_h'

Nick Mathewson 5 years ago
parent
commit
104c2e9e7e
100 changed files with 2713 additions and 1064 deletions
  1. 5 0
      changes/split_or_h
  2. 2 0
      src/or/addressmap.c
  3. 32 0
      src/or/authority_cert_st.h
  4. 5 0
      src/or/bridges.c
  5. 25 0
      src/or/cached_dir_st.h
  6. 28 0
      src/or/cell_queue_st.h
  7. 20 0
      src/or/cell_st.h
  8. 2 0
      src/or/channel.c
  9. 3 0
      src/or/channelpadding.c
  10. 9 0
      src/or/channeltls.c
  11. 6 0
      src/or/circpathbias.c
  12. 172 0
      src/or/circuit_st.h
  13. 11 0
      src/or/circuitbuild.c
  14. 34 0
      src/or/circuitlist.c
  15. 9 0
      src/or/circuitlist.h
  16. 4 0
      src/or/circuitmux.c
  17. 3 0
      src/or/circuitstats.c
  18. 15 0
      src/or/circuitstats.h
  19. 9 0
      src/or/circuituse.c
  20. 5 0
      src/or/command.c
  21. 3 0
      src/or/config.c
  22. 51 0
      src/or/connection.c
  23. 7 40
      src/or/connection.h
  24. 34 0
      src/or/connection_edge.c
  25. 5 1
      src/or/connection_edge.h
  26. 17 0
      src/or/connection_or.c
  27. 2 0
      src/or/connection_or.h
  28. 132 0
      src/or/connection_st.h
  29. 3 0
      src/or/consdiffmgr.c
  30. 27 0
      src/or/control.c
  31. 2 0
      src/or/control.h
  32. 46 0
      src/or/control_connection_st.h
  33. 38 0
      src/or/cpath_build_state_st.h
  34. 2 0
      src/or/cpuworker.c
  35. 23 0
      src/or/crypt_path_reference_st.h
  36. 56 0
      src/or/crypt_path_st.h
  37. 34 0
      src/or/desc_store_st.h
  38. 27 0
      src/or/destroy_cell_queue_st.h
  39. 66 0
      src/or/dir_connection_st.h
  40. 55 0
      src/or/dir_server_st.h
  41. 3 0
      src/or/dirauth/dircollate.c
  42. 15 0
      src/or/dirauth/dirvote.c
  43. 3 0
      src/or/dirauth/shared_random.c
  44. 41 0
      src/or/directory.c
  45. 4 23
      src/or/directory.h
  46. 10 0
      src/or/dirserv.c
  47. 8 0
      src/or/dirserv.h
  48. 4 0
      src/or/dns.c
  49. 6 0
      src/or/dnsserv.c
  50. 29 0
      src/or/document_signature_st.h
  51. 3 0
      src/or/dos.c
  52. 65 0
      src/or/download_status_st.h
  53. 77 0
      src/or/edge_connection_st.h
  54. 100 0
      src/or/entry_connection_st.h
  55. 54 0
      src/or/entry_port_cfg_st.h
  56. 3 0
      src/or/entrynodes.c
  57. 2 0
      src/or/ext_orport.c
  58. 28 0
      src/or/extend_info_st.h
  59. 30 0
      src/or/extrainfo_st.h
  60. 6 0
      src/or/fp_pair.h
  61. 2 0
      src/or/hibernate.c
  62. 2 0
      src/or/hs_cache.c
  63. 2 0
      src/or/hs_cell.c
  64. 5 0
      src/or/hs_circuit.c
  65. 3 0
      src/or/hs_circuitmap.c
  66. 6 0
      src/or/hs_client.c
  67. 6 0
      src/or/hs_common.c
  68. 3 0
      src/or/hs_control.c
  69. 2 0
      src/or/hs_descriptor.c
  70. 2 0
      src/or/hs_intropoint.c
  71. 8 0
      src/or/hs_service.c
  72. 24 0
      src/or/hsdir_index_st.h
  73. 52 1
      src/or/include.am
  74. 25 0
      src/or/listener_connection_st.h
  75. 8 0
      src/or/main.c
  76. 5 0
      src/or/microdesc.c
  77. 71 0
      src/or/microdesc_st.h
  78. 13 0
      src/or/networkstatus.c
  79. 23 0
      src/or/networkstatus_sr_info_st.h
  80. 95 0
      src/or/networkstatus_st.h
  81. 31 0
      src/or/networkstatus_voter_info_st.h
  82. 102 0
      src/or/node_st.h
  83. 17 0
      src/or/nodelist.c
  84. 1 0
      src/or/nodelist.h
  85. 22 0
      src/or/ns_detached_signatures_st.h
  86. 4 0
      src/or/onion.c
  87. 28 999
      src/or/or.h
  88. 80 0
      src/or/or_circuit_st.h
  89. 90 0
      src/or/or_connection_st.h
  90. 39 0
      src/or/or_handshake_certs_st.h
  91. 78 0
      src/or/or_handshake_state_st.h
  92. 235 0
      src/or/origin_circuit_st.h
  93. 7 0
      src/or/policies.c
  94. 35 0
      src/or/port_cfg_st.h
  95. 2 0
      src/or/proto_cell.c
  96. 2 0
      src/or/proto_socks.c
  97. 13 0
      src/or/relay.c
  98. 5 0
      src/or/relay_crypto.c
  99. 27 0
      src/or/relay_crypto_st.h
  100. 18 0
      src/or/rend_authorized_client_st.h

+ 5 - 0
changes/split_or_h

@@ -0,0 +1,5 @@
+  o Code simplification and refactoring:
+    - Many structures have been removed from the centralized "or.h" header,
+      and moved into their own headers.  This will allow us to reduce
+      the number of places in the code that rely on each structure's
+      contents and layout. Closes ticket 26383.

+ 2 - 0
src/or/addressmap.c

@@ -26,6 +26,8 @@
 #include "nodelist.h"
 #include "routerset.h"
 
+#include "entry_connection_st.h"
+
 /** A client-side struct to remember requests to rewrite addresses
  * to new addresses. These structs are stored in the hash table
  * "addressmap" below.

+ 32 - 0
src/or/authority_cert_st.h

@@ -0,0 +1,32 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef AUTHORITY_CERT_ST_H
+#define AUTHORITY_CERT_ST_H
+
+#include "signed_descriptor_st.h"
+
+/** Certificate for v3 directory protocol: binds long-term authority identity
+ * keys to medium-term authority signing keys. */
+struct authority_cert_t {
+  /** Information relating to caching this cert on disk and looking it up. */
+  signed_descriptor_t cache_info;
+  /** This authority's long-term authority identity key. */
+  crypto_pk_t *identity_key;
+  /** This authority's medium-term signing key. */
+  crypto_pk_t *signing_key;
+  /** The digest of <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
+

+ 5 - 0
src/or/bridges.c

@@ -27,6 +27,11 @@
 #include "routerset.h"
 #include "transports.h"
 
+#include "extend_info_st.h"
+#include "node_st.h"
+#include "routerinfo_st.h"
+#include "routerstatus_st.h"
+
 /** Information about a configured bridge. Currently this just matches the
  * ones in the torrc file, but one day we may be able to learn about new
  * bridges on our own, and remember them in the state file. */

+ 25 - 0
src/or/cached_dir_st.h

@@ -0,0 +1,25 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CACHED_DIR_ST_H
+#define CACHED_DIR_ST_H
+
+/** A cached_dir_t represents a cacheable directory object, along with its
+ * compressed form. */
+struct cached_dir_t {
+  char *dir; /**< Contents of this object, NUL-terminated. */
+  char *dir_compressed; /**< Compressed contents of this object. */
+  size_t dir_len; /**< Length of <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
+

+ 28 - 0
src/or/cell_queue_st.h

@@ -0,0 +1,28 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef PACKED_CELL_ST_H
+#define PACKED_CELL_ST_H
+
+/** A cell as packed for writing to the network. */
+struct packed_cell_t {
+  /** Next cell queued on this circuit. */
+  TOR_SIMPLEQ_ENTRY(packed_cell_t) next;
+  char body[CELL_MAX_NETWORK_SIZE]; /**< Cell as packed for network. */
+  uint32_t inserted_timestamp; /**< Time (in timestamp units) when this cell
+                                * was inserted */
+};
+
+/** A queue of cells on a circuit, waiting to be added to the
+ * or_connection_t's outbuf. */
+struct cell_queue_t {
+  /** Linked list of packed_cell_t*/
+  TOR_SIMPLEQ_HEAD(cell_simpleq, packed_cell_t) head;
+  int n; /**< The number of cells in the queue. */
+};
+
+#endif
+

+ 20 - 0
src/or/cell_st.h

@@ -0,0 +1,20 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CELL_ST_H
+#define CELL_ST_H
+
+/** Parsed onion routing cell.  All communication between nodes
+ * is via cells. */
+struct cell_t {
+  circid_t circ_id; /**< Circuit which received the cell. */
+  uint8_t command; /**< Type of the cell: one of CELL_PADDING, CELL_CREATE,
+                    * CELL_DESTROY, etc */
+  uint8_t payload[CELL_PAYLOAD_SIZE]; /**< Cell body. */
+};
+
+#endif
+

+ 2 - 0
src/or/channel.c

@@ -80,6 +80,8 @@
 #include "networkstatus.h"
 #include "rendservice.h"
 
+#include "cell_queue_st.h"
+
 /* Global lists of channels */
 
 /* All channel_t instances */

+ 3 - 0
src/or/channelpadding.c

@@ -23,6 +23,9 @@
 #include "compat_time.h"
 #include "rendservice.h"
 
+#include "cell_st.h"
+#include "or_connection_st.h"
+
 STATIC int32_t channelpadding_get_netflow_inactive_timeout_ms(
                                                            const channel_t *);
 STATIC int channelpadding_send_disable_command(channel_t *);

+ 9 - 0
src/or/channeltls.c

@@ -60,6 +60,15 @@
 #include "channelpadding_negotiation.h"
 #include "channelpadding.h"
 
+#include "cell_st.h"
+#include "cell_queue_st.h"
+#include "extend_info_st.h"
+#include "or_connection_st.h"
+#include "or_handshake_certs_st.h"
+#include "or_handshake_state_st.h"
+#include "routerinfo_st.h"
+#include "var_cell_st.h"
+
 /** How many CELL_PADDING cells have we received, ever? */
 uint64_t stats_n_padding_cells_processed = 0;
 /** How many CELL_VERSIONS cells have we received, ever? */

+ 6 - 0
src/or/circpathbias.c

@@ -35,6 +35,12 @@
 #include "networkstatus.h"
 #include "relay.h"
 
+#include "cell_st.h"
+#include "cpath_build_state_st.h"
+#include "crypt_path_st.h"
+#include "extend_info_st.h"
+#include "origin_circuit_st.h"
+
 static void pathbias_count_successful_close(origin_circuit_t *circ);
 static void pathbias_count_collapse(origin_circuit_t *circ);
 static void pathbias_count_use_failed(origin_circuit_t *circ);

+ 172 - 0
src/or/circuit_st.h

@@ -0,0 +1,172 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CIRCUIT_ST_H
+#define CIRCUIT_ST_H
+
+#include "or.h"
+
+#include "cell_queue_st.h"
+
+/**
+ * A circuit is a path over the onion routing
+ * network. Applications can connect to one end of the circuit, and can
+ * create exit connections at the other end of the circuit. AP and exit
+ * connections have only one circuit associated with them (and thus these
+ * connection types are closed when the circuit is closed), whereas
+ * OR connections multiplex many circuits at once, and stay standing even
+ * when there are no circuits running over them.
+ *
+ * A circuit_t structure can fill one of two roles.  First, a or_circuit_t
+ * links two connections together: either an edge connection and an OR
+ * connection, or two OR connections.  (When joined to an OR connection, a
+ * circuit_t affects only cells sent to a particular circID on that
+ * connection.  When joined to an edge connection, a circuit_t affects all
+ * data.)
+
+ * Second, an origin_circuit_t holds the cipher keys and state for sending data
+ * along a given circuit.  At the OP, it has a sequence of ciphers, each
+ * of which is shared with a single OR along the circuit.  Separate
+ * ciphers are used for data going "forward" (away from the OP) and
+ * "backward" (towards the OP).  At the OR, a circuit has only two stream
+ * ciphers: one for data going forward, and one for data going backward.
+ */
+struct circuit_t {
+  uint32_t magic; /**< For memory and type debugging: must equal
+                   * ORIGIN_CIRCUIT_MAGIC or OR_CIRCUIT_MAGIC. */
+
+  /** The channel that is next in this circuit. */
+  channel_t *n_chan;
+
+  /**
+   * The circuit_id used in the next (forward) hop of this circuit;
+   * this is unique to n_chan, but this ordered pair is globally
+   * unique:
+   *
+   * (n_chan->global_identifier, n_circ_id)
+   */
+  circid_t n_circ_id;
+
+  /**
+   * Circuit mux associated with n_chan to which this circuit is attached;
+   * NULL if we have no n_chan.
+   */
+  circuitmux_t *n_mux;
+
+  /** Queue of cells waiting to be transmitted on n_chan */
+  cell_queue_t n_chan_cells;
+
+  /**
+   * The hop to which we want to extend this circuit.  Should be NULL if
+   * the circuit has attached to a channel.
+   */
+  extend_info_t *n_hop;
+
+  /** True iff we are waiting for n_chan_cells to become less full before
+   * allowing p_streams to add any more cells. (Origin circuit only.) */
+  unsigned int streams_blocked_on_n_chan : 1;
+  /** True iff we are waiting for p_chan_cells to become less full before
+   * allowing n_streams to add any more cells. (OR circuit only.) */
+  unsigned int streams_blocked_on_p_chan : 1;
+
+  /** True iff we have queued a delete backwards on this circuit, but not put
+   * it on the output buffer. */
+  unsigned int p_delete_pending : 1;
+  /** True iff we have queued a delete forwards on this circuit, but not put
+   * it on the output buffer. */
+  unsigned int n_delete_pending : 1;
+
+  /** True iff this circuit has received a DESTROY cell in either direction */
+  unsigned int received_destroy : 1;
+
+  uint8_t state; /**< Current status of this circuit. */
+  uint8_t purpose; /**< Why are we creating this circuit? */
+
+  /** How many relay data cells can we package (read from edge streams)
+   * on this circuit before we receive a circuit-level sendme cell asking
+   * for more? */
+  int package_window;
+  /** How many relay data cells will we deliver (write to edge streams)
+   * on this circuit? When deliver_window gets low, we send some
+   * circuit-level sendme cells to indicate that we're willing to accept
+   * more. */
+  int deliver_window;
+
+  /** Temporary field used during circuits_handle_oom. */
+  uint32_t age_tmp;
+
+  /** For storage while n_chan is pending (state CIRCUIT_STATE_CHAN_WAIT). */
+  struct create_cell_t *n_chan_create_cell;
+
+  /** When did circuit construction actually begin (ie send the
+   * CREATE cell or begin cannibalization).
+   *
+   * Note: This timer will get reset if we decide to cannibalize
+   * a circuit. It may also get reset during certain phases of hidden
+   * service circuit use.
+   *
+   * We keep this timestamp with a higher resolution than most so that the
+   * circuit-build-time tracking code can get millisecond resolution.
+   */
+  struct timeval timestamp_began;
+
+  /** This timestamp marks when the init_circuit_base constructor ran. */
+  struct timeval timestamp_created;
+
+  /** When the circuit was first used, or 0 if the circuit is clean.
+   *
+   * XXXX Note that some code will artificially adjust this value backward
+   * in time in order to indicate that a circuit shouldn't be used for new
+   * streams, but that it can stay alive as long as it has streams on it.
+   * That's a kludge we should fix.
+   *
+   * XXX The CBT code uses this field to record when HS-related
+   * circuits entered certain states.  This usage probably won't
+   * interfere with this field's primary purpose, but we should
+   * document it more thoroughly to make sure of that.
+   *
+   * XXX The SocksPort option KeepaliveIsolateSOCKSAuth will artificially
+   * adjust this value forward each time a suitable stream is attached to an
+   * already constructed circuit, potentially keeping the circuit alive
+   * indefinitely.
+   */
+  time_t timestamp_dirty;
+
+  uint16_t marked_for_close; /**< Should we close this circuit at the end of
+                              * the main loop? (If true, holds the line number
+                              * where this circuit was marked.) */
+  const char *marked_for_close_file; /**< For debugging: in which file was this
+                                      * circuit marked for close? */
+  /** For what reason (See END_CIRC_REASON...) is this circuit being closed?
+   * This field is set in circuit_mark_for_close and used later in
+   * circuit_about_to_free. */
+  int marked_for_close_reason;
+  /** As marked_for_close_reason, but reflects the underlying reason for
+   * closing this circuit.
+   */
+  int marked_for_close_orig_reason;
+
+  /** Unique ID for measuring tunneled network status requests. */
+  uint64_t dirreq_id;
+
+  /** Index in smartlist of all circuits (global_circuitlist). */
+  int global_circuitlist_idx;
+
+  /** Various statistics about cells being added to or removed from this
+   * circuit's queues; used only if CELL_STATS events are enabled and
+   * cleared after being sent to control port. */
+  smartlist_t *testing_cell_stats;
+
+  /** If set, points to an HS token that this circuit might be carrying.
+   *  Used by the HS circuitmap.  */
+  hs_token_t *hs_token;
+  /** Hashtable node: used to look up the circuit by its HS token using the HS
+      circuitmap. */
+  HT_ENTRY(circuit_t) hs_circuitmap_node;
+};
+
+#endif
+

+ 11 - 0
src/or/circuitbuild.c

@@ -65,6 +65,17 @@
 #include "routerset.h"
 #include "transports.h"
 
+#include "cell_st.h"
+#include "cpath_build_state_st.h"
+#include "entry_connection_st.h"
+#include "extend_info_st.h"
+#include "node_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+#include "microdesc_st.h"
+#include "routerinfo_st.h"
+#include "routerstatus_st.h"
+
 static channel_t * channel_connect_for_circuit(const tor_addr_t *addr,
                                             uint16_t port,
                                             const char *id_digest,

+ 34 - 0
src/or/circuitlist.c

@@ -67,6 +67,7 @@
 #include "control.h"
 #include "crypto_rand.h"
 #include "crypto_util.h"
+#include "directory.h"
 #include "entrynodes.h"
 #include "main.h"
 #include "hs_circuit.h"
@@ -91,6 +92,14 @@
 
 #include "ht.h"
 
+#include "cpath_build_state_st.h"
+#include "crypt_path_reference_st.h"
+#include "dir_connection_st.h"
+#include "edge_connection_st.h"
+#include "extend_info_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+
 /********* START VARIABLES **********/
 
 /** A global list of all circuits at this hop. */
@@ -126,6 +135,31 @@ static int any_opened_circs_cached_val = 0;
 
 /********* END VARIABLES ************/
 
+or_circuit_t *
+TO_OR_CIRCUIT(circuit_t *x)
+{
+  tor_assert(x->magic == OR_CIRCUIT_MAGIC);
+  return DOWNCAST(or_circuit_t, x);
+}
+const or_circuit_t *
+CONST_TO_OR_CIRCUIT(const circuit_t *x)
+{
+  tor_assert(x->magic == OR_CIRCUIT_MAGIC);
+  return DOWNCAST(or_circuit_t, x);
+}
+origin_circuit_t *
+TO_ORIGIN_CIRCUIT(circuit_t *x)
+{
+  tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
+  return DOWNCAST(origin_circuit_t, x);
+}
+const origin_circuit_t *
+CONST_TO_ORIGIN_CIRCUIT(const circuit_t *x)
+{
+  tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
+  return DOWNCAST(origin_circuit_t, x);
+}
+
 /** A map from channel and circuit ID to circuit.  (Lookup performance is
  * very important here, since we need to do it every time a cell arrives.) */
 typedef struct chan_circid_circuit_map_t {

+ 9 - 0
src/or/circuitlist.h

@@ -15,6 +15,15 @@
 #include "testsupport.h"
 #include "hs_ident.h"
 
+/** Convert a circuit_t* to a pointer to the enclosing or_circuit_t.  Assert
+ * if the cast is impossible. */
+or_circuit_t *TO_OR_CIRCUIT(circuit_t *);
+const or_circuit_t *CONST_TO_OR_CIRCUIT(const circuit_t *);
+/** Convert a circuit_t* to a pointer to the enclosing origin_circuit_t.
+ * Assert if the cast is impossible. */
+origin_circuit_t *TO_ORIGIN_CIRCUIT(circuit_t *);
+const origin_circuit_t *CONST_TO_ORIGIN_CIRCUIT(const circuit_t *);
+
 MOCK_DECL(smartlist_t *, circuit_get_global_list, (void));
 smartlist_t *circuit_get_global_origin_circuit_list(void);
 int circuit_any_opened_circuits(void);

+ 4 - 0
src/or/circuitmux.c

@@ -75,6 +75,10 @@
 #include "circuitmux.h"
 #include "relay.h"
 
+#include "cell_queue_st.h"
+#include "destroy_cell_queue_st.h"
+#include "or_circuit_st.h"
+
 /*
  * Private typedefs for circuitmux.c
  */

+ 3 - 0
src/or/circuitstats.c

@@ -41,6 +41,9 @@
 #include "circuitlist.h"
 #include "circuituse.h"
 
+#include "crypt_path_st.h"
+#include "origin_circuit_st.h"
+
 #undef log
 #include <math.h>
 

+ 15 - 0
src/or/circuitstats.h

@@ -73,6 +73,21 @@ int circuit_build_times_network_check_live(const circuit_build_times_t *cbt);
 void circuit_build_times_network_circ_success(circuit_build_times_t *cbt);
 
 #ifdef CIRCUITSTATS_PRIVATE
+/** Information about the state of our local network connection */
+typedef struct {
+  /** The timestamp we last completed a TLS handshake or received a cell */
+  time_t network_last_live;
+  /** If the network is not live, how many timeouts has this caused? */
+  int nonlive_timeouts;
+  /** Circular array of circuits that have made it to the first hop. Slot is
+   * 1 if circuit timed out, 0 if circuit succeeded */
+  int8_t *timeouts_after_firsthop;
+  /** Number of elements allocated for the above array */
+  int num_recent_circs;
+  /** Index into circular array. */
+  int after_firsthop_idx;
+} network_liveness_t;
+
 /** Structure for circuit build times history */
 struct circuit_build_times_s {
   /** The circular array of recorded build times in milliseconds */

+ 9 - 0
src/or/circuituse.c

@@ -40,6 +40,7 @@
 #include "connection.h"
 #include "connection_edge.h"
 #include "control.h"
+#include "directory.h"
 #include "entrynodes.h"
 #include "hs_common.h"
 #include "hs_client.h"
@@ -56,6 +57,14 @@
 #include "router.h"
 #include "routerlist.h"
 
+#include "cpath_build_state_st.h"
+#include "dir_connection_st.h"
+#include "entry_connection_st.h"
+#include "extend_info_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+#include "socks_request_st.h"
+
 static void circuit_expire_old_circuits_clientside(void);
 static void circuit_increment_failure_count(void);
 

+ 5 - 0
src/or/command.c

@@ -56,6 +56,11 @@
 #include "router.h"
 #include "routerlist.h"
 
+#include "cell_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+#include "var_cell_st.h"
+
 /** How many CELL_CREATE cells have we received, ever? */
 uint64_t stats_n_create_cells_processed = 0;
 /** How many CELL_CREATED cells have we received, ever? */

+ 3 - 0
src/or/config.c

@@ -116,6 +116,9 @@
 #include "dirauth/dirvote.h"
 #include "dirauth/mode.h"
 
+#include "connection_st.h"
+#include "port_cfg_st.h"
+
 #ifdef HAVE_SYSTEMD
 #   if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
 /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse

+ 51 - 0
src/or/connection.c

@@ -113,6 +113,15 @@
 #include <sys/un.h>
 #endif
 
+#include "dir_connection_st.h"
+#include "control_connection_st.h"
+#include "entry_connection_st.h"
+#include "listener_connection_st.h"
+#include "or_connection_st.h"
+#include "port_cfg_st.h"
+#include "routerinfo_st.h"
+#include "socks_request_st.h"
+
 static connection_t *connection_listener_new(
                                const struct sockaddr *listensockaddr,
                                socklen_t listensocklen, int type,
@@ -167,6 +176,27 @@ static smartlist_t *outgoing_addrs = NULL;
 
 /**************************************************************/
 
+/** Convert a connection_t* to an listener_connection_t*; assert if the cast
+ * is invalid. */
+listener_connection_t *
+TO_LISTENER_CONN(connection_t *c)
+{
+  tor_assert(c->magic == LISTENER_CONNECTION_MAGIC);
+  return DOWNCAST(listener_connection_t, c);
+}
+
+size_t
+connection_get_inbuf_len(connection_t *conn)
+{
+  return conn->inbuf ? buf_datalen(conn->inbuf) : 0;
+}
+
+size_t
+connection_get_outbuf_len(connection_t *conn)
+{
+    return conn->outbuf ? buf_datalen(conn->outbuf) : 0;
+}
+
 /**
  * Return the human-readable name for the connection type <b>type</b>
  */
@@ -4108,6 +4138,13 @@ connection_write_to_buf_impl_,(const char *string, size_t len,
   connection_write_to_buf_commit(conn, written);
 }
 
+void
+connection_buf_add_compress(const char *string, size_t len,
+                            dir_connection_t *conn, int done)
+{
+  connection_write_to_buf_impl_(string, len, TO_CONN(conn), done ? -1 : 1);
+}
+
 /**
  * Add all bytes from <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,
@@ -4812,6 +4849,20 @@ kill_conn_list_for_oos, (smartlist_t *conns))
              smartlist_len(conns));
 }
 
+/** Check if a connection is on the way out so the OOS handler doesn't try
+ * to kill more than it needs. */
+int
+connection_is_moribund(connection_t *conn)
+{
+  if (conn != NULL &&
+      (conn->conn_array_index < 0 ||
+       conn->marked_for_close)) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
 /** Out-of-Sockets handler; n_socks is the current number of open
  * sockets, and failed is non-zero if a socket exhaustion related
  * error immediately preceded this call.  This is where to do

+ 7 - 40
src/or/connection.h

@@ -12,6 +12,8 @@
 #ifndef TOR_CONNECTION_H
 #define TOR_CONNECTION_H
 
+listener_connection_t *TO_LISTENER_CONN(connection_t *);
+
 /* XXXX For buf_datalen in inline function */
 #include "buffers.h"
 
@@ -150,39 +152,17 @@ MOCK_DECL(void, connection_write_to_buf_impl_,
 /* DOCDOC connection_write_to_buf */
 static void connection_buf_add(const char *string, size_t len,
                                     connection_t *conn);
-/* DOCDOC connection_write_to_buf_compress */
-static void connection_buf_add_compress(const char *string, size_t len,
-                                             dir_connection_t *conn, int done);
 static inline void
 connection_buf_add(const char *string, size_t len, connection_t *conn)
 {
   connection_write_to_buf_impl_(string, len, conn, 0);
 }
-static inline void
-connection_buf_add_compress(const char *string, size_t len,
-                                 dir_connection_t *conn, int done)
-{
-  connection_write_to_buf_impl_(string, len, TO_CONN(conn), done ? -1 : 1);
-}
+void connection_buf_add_compress(const char *string, size_t len,
+                                 dir_connection_t *conn, int done);
 void connection_buf_add_buf(connection_t *conn, buf_t *buf);
 
-/* DOCDOC connection_get_inbuf_len */
-static size_t connection_get_inbuf_len(connection_t *conn);
-/* DOCDOC connection_get_outbuf_len */
-static size_t connection_get_outbuf_len(connection_t *conn);
-
-static inline size_t
-connection_get_inbuf_len(connection_t *conn)
-{
-  return conn->inbuf ? buf_datalen(conn->inbuf) : 0;
-}
-
-static inline size_t
-connection_get_outbuf_len(connection_t *conn)
-{
-    return conn->outbuf ? buf_datalen(conn->outbuf) : 0;
-}
-
+size_t connection_get_inbuf_len(connection_t *conn);
+size_t connection_get_outbuf_len(connection_t *conn);
 connection_t *connection_get_by_global_id(uint64_t id);
 
 connection_t *connection_get_by_type(int type);
@@ -259,20 +239,7 @@ MOCK_DECL(void, clock_skew_warning,
            log_domain_mask_t domain, const char *received,
            const char *source));
 
-/** Check if a connection is on the way out so the OOS handler doesn't try
- * to kill more than it needs. */
-static inline int
-connection_is_moribund(connection_t *conn)
-{
-  if (conn != NULL &&
-      (conn->conn_array_index < 0 ||
-       conn->marked_for_close)) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
+int connection_is_moribund(connection_t *conn);
 void connection_check_oos(int n_socks, int failed);
 
 #ifdef CONNECTION_PRIVATE

+ 34 - 0
src/or/connection_edge.c

@@ -97,6 +97,16 @@
 #include "routerset.h"
 #include "circuitbuild.h"
 
+#include "cell_st.h"
+#include "cpath_build_state_st.h"
+#include "dir_connection_st.h"
+#include "entry_connection_st.h"
+#include "extend_info_st.h"
+#include "node_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+#include "socks_request_st.h"
+
 #ifdef HAVE_LINUX_TYPES_H
 #include <linux/types.h>
 #endif
@@ -137,6 +147,30 @@ static int connection_exit_connect_dir(edge_connection_t *exitconn);
 static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
 static int connection_ap_supports_optimistic_data(const entry_connection_t *);
 
+/** Convert a connection_t* to an edge_connection_t*; assert if the cast is
+ * invalid. */
+edge_connection_t *
+TO_EDGE_CONN(connection_t *c)
+{
+  tor_assert(c->magic == EDGE_CONNECTION_MAGIC ||
+             c->magic == ENTRY_CONNECTION_MAGIC);
+  return DOWNCAST(edge_connection_t, c);
+}
+
+entry_connection_t *
+TO_ENTRY_CONN(connection_t *c)
+{
+  tor_assert(c->magic == ENTRY_CONNECTION_MAGIC);
+  return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_.base_);
+}
+
+entry_connection_t *
+EDGE_TO_ENTRY_CONN(edge_connection_t *c)
+{
+  tor_assert(c->base_.magic == ENTRY_CONNECTION_MAGIC);
+  return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_);
+}
+
 /** An AP stream has failed/finished. If it hasn't already sent back
  * a socks reply, send one now (based on endreason). Also set
  * has_sent_end to 1, and mark the conn.

+ 5 - 1
src/or/connection_edge.h

@@ -14,7 +14,11 @@
 
 #include "testsupport.h"
 
-#define connection_mark_unattached_ap(conn, endreason) \
+edge_connection_t *TO_EDGE_CONN(connection_t *);
+entry_connection_t *TO_ENTRY_CONN(connection_t *);
+entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *);
+
+#define connection_mark_unattached_ap(conn, endreason)                  \
   connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__)
 
 MOCK_DECL(void,connection_mark_unattached_ap_,

+ 17 - 0
src/or/connection_or.c

@@ -61,6 +61,14 @@
 #include "torcert.h"
 #include "channelpadding.h"
 
+#include "cell_st.h"
+#include "cell_queue_st.h"
+#include "or_connection_st.h"
+#include "or_handshake_certs_st.h"
+#include "or_handshake_state_st.h"
+#include "routerinfo_st.h"
+#include "var_cell_st.h"
+
 static int connection_tls_finish_handshake(or_connection_t *conn);
 static int connection_or_launch_v3_or_handshake(or_connection_t *conn);
 static int connection_or_process_cells_from_inbuf(or_connection_t *conn);
@@ -86,6 +94,15 @@ static void connection_or_check_canonicity(or_connection_t *conn,
 
 /**************************************************************/
 
+/** Convert a connection_t* to an or_connection_t*; assert if the cast is
+ * invalid. */
+or_connection_t *
+TO_OR_CONN(connection_t *c)
+{
+  tor_assert(c->magic == OR_CONNECTION_MAGIC);
+  return DOWNCAST(or_connection_t, c);
+}
+
 /** Global map between Extended ORPort identifiers and OR
  *  connections. */
 static digestmap_t *orconn_ext_or_id_map = NULL;

+ 2 - 0
src/or/connection_or.h

@@ -12,6 +12,8 @@
 #ifndef TOR_CONNECTION_OR_H
 #define TOR_CONNECTION_OR_H
 
+or_connection_t *TO_OR_CONN(connection_t *);
+
 void connection_or_clear_identity(or_connection_t *conn);
 void connection_or_clear_identity_map(void);
 void clear_broken_connection_map(int disable);

+ 132 - 0
src/or/connection_st.h

@@ -0,0 +1,132 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CONNECTION_ST_H
+#define CONNECTION_ST_H
+
+struct buf_t;
+
+/** Description of a connection to another host or process, and associated
+ * data.
+ *
+ * A connection is named based on what it's connected to -- an "OR
+ * connection" has a Tor node on the other end, an "exit
+ * connection" has a website or other server on the other end, and an
+ * "AP connection" has an application proxy (and thus a user) on the
+ * other end.
+ *
+ * Every connection has a type and a state.  Connections never change
+ * their type, but can go through many state changes in their lifetime.
+ *
+ * Every connection has two associated input and output buffers.
+ * Listeners don't use them.  For non-listener connections, incoming
+ * data is appended to conn->inbuf, and outgoing data is taken from
+ * conn->outbuf.  Connections differ primarily in the functions called
+ * to fill and drain these buffers.
+ */
+typedef struct connection_t {
+  uint32_t magic; /**< For memory debugging: must equal one of
+                   * *_CONNECTION_MAGIC. */
+
+  uint8_t state; /**< Current state of this connection. */
+  unsigned int type:5; /**< What kind of connection is this? */
+  unsigned int purpose:5; /**< Only used for DIR and EXIT types currently. */
+
+  /* The next fields are all one-bit booleans. Some are only applicable to
+   * connection subtypes, but we hold them here anyway, to save space.
+   */
+  unsigned int read_blocked_on_bw:1; /**< Boolean: should we start reading
+                            * again once the bandwidth throttler allows it? */
+  unsigned int write_blocked_on_bw:1; /**< Boolean: should we start writing
+                             * again once the bandwidth throttler allows
+                             * writes? */
+  unsigned int hold_open_until_flushed:1; /**< Despite this connection's being
+                                      * marked for close, do we flush it
+                                      * before closing it? */
+  unsigned int inbuf_reached_eof:1; /**< Boolean: did read() return 0 on this
+                                     * conn? */
+  /** Set to 1 when we're inside connection_flushed_some to keep us from
+   * calling connection_handle_write() recursively. */
+  unsigned int in_flushed_some:1;
+  /** True if connection_handle_write is currently running on this connection.
+   */
+  unsigned int in_connection_handle_write:1;
+
+  /* For linked connections:
+   */
+  unsigned int linked:1; /**< True if there is, or has been, a linked_conn. */
+  /** True iff we'd like to be notified about read events from the
+   * linked conn. */
+  unsigned int reading_from_linked_conn:1;
+  /** True iff we're willing to write to the linked conn. */
+  unsigned int writing_to_linked_conn:1;
+  /** True iff we're currently able to read on the linked conn, and our
+   * read_event should be made active with libevent. */
+  unsigned int active_on_link:1;
+  /** True iff we've called connection_close_immediate() on this linked
+   * connection. */
+  unsigned int linked_conn_is_closed:1;
+
+  /** CONNECT/SOCKS proxy client handshake state (for outgoing connections). */
+  unsigned int proxy_state:4;
+
+  /** Our socket; set to TOR_INVALID_SOCKET if this connection is closed,
+   * or has no socket. */
+  tor_socket_t s;
+  int conn_array_index; /**< Index into the global connection array. */
+
+  struct event *read_event; /**< Libevent event structure. */
+  struct event *write_event; /**< Libevent event structure. */
+  struct buf_t *inbuf; /**< Buffer holding data read over this connection. */
+  struct buf_t *outbuf; /**< Buffer holding data to write over this
+                         * connection. */
+  size_t outbuf_flushlen; /**< How much data should we try to flush from the
+                           * outbuf? */
+  time_t timestamp_last_read_allowed; /**< When was the last time libevent said
+                                       * we could read? */
+  time_t timestamp_last_write_allowed; /**< When was the last time libevent
+                                        * said we could write? */
+
+  time_t timestamp_created; /**< When was this connection_t created? */
+
+  int socket_family; /**< Address family of this connection's socket.  Usually
+                      * AF_INET, but it can also be AF_UNIX, or AF_INET6 */
+  tor_addr_t addr; /**< IP that socket "s" is directly connected to;
+                    * may be the IP address for a proxy or pluggable transport,
+                    * see "address" for the address of the final destination.
+                    */
+  uint16_t port; /**< If non-zero, port that socket "s" is directly connected
+                  * to; may be the port for a proxy or pluggable transport,
+                  * see "address" for the port at the final destination. */
+  uint16_t marked_for_close; /**< Should we close this conn on the next
+                              * iteration of the main loop? (If true, holds
+                              * the line number where this connection was
+                              * marked.) */
+  const char *marked_for_close_file; /**< For debugging: in which file were
+                                      * we marked for close? */
+  char *address; /**< FQDN (or IP) and port of the final destination for this
+                  * connection; this is always the remote address, it is
+                  * passed to a proxy or pluggable transport if one in use.
+                  * See "addr" and "port" for the address that socket "s" is
+                  * directly connected to.
+                  * strdup into this, because free_connection() frees it. */
+  /** Another connection that's connected to this one in lieu of a socket. */
+  struct connection_t *linked_conn;
+
+  /** Unique identifier for this connection on this Tor instance. */
+  uint64_t global_identifier;
+
+  /** Bytes read since last call to control_event_conn_bandwidth_used().
+   * Only used if we're configured to emit CONN_BW events. */
+  uint32_t n_read_conn_bw;
+
+  /** Bytes written since last call to control_event_conn_bandwidth_used().
+   * Only used if we're configured to emit CONN_BW events. */
+  uint32_t n_written_conn_bw;
+} connection_t;
+
+#endif
+

+ 3 - 0
src/or/consdiffmgr.c

@@ -23,6 +23,9 @@
 #include "routerparse.h"
 #include "workqueue.h"
 
+#include "networkstatus_st.h"
+#include "networkstatus_voter_info_st.h"
+
 /**
  * Labels to apply to items in the conscache object.
  *

+ 27 - 0
src/or/control.c

@@ -81,6 +81,24 @@
 #include "routerparse.h"
 #include "shared_random_client.h"
 
+#include "cached_dir_st.h"
+#include "control_connection_st.h"
+#include "cpath_build_state_st.h"
+#include "entry_connection_st.h"
+#include "extrainfo_st.h"
+#include "networkstatus_st.h"
+#include "node_st.h"
+#include "or_connection_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+#include "microdesc_st.h"
+#include "rend_authorized_client_st.h"
+#include "rend_encoded_v2_service_descriptor_st.h"
+#include "rend_service_descriptor_st.h"
+#include "routerinfo_st.h"
+#include "routerlist_st.h"
+#include "socks_request_st.h"
+
 #ifndef _WIN32
 #include <pwd.h>
 #include <sys/resource.h>
@@ -226,6 +244,15 @@ static void flush_queued_events_cb(mainloop_event_t *event, void *arg);
 static char * download_status_to_string(const download_status_t *dl);
 static void control_get_bytes_rw_last_sec(uint64_t *r, uint64_t *w);
 
+/** Convert a connection_t* to an control_connection_t*; assert if the cast is
+ * invalid. */
+control_connection_t *
+TO_CONTROL_CONN(connection_t *c)
+{
+  tor_assert(c->magic == CONTROL_CONNECTION_MAGIC);
+  return DOWNCAST(control_connection_t, c);
+}
+
 /** Given a control event code for a message event, return the corresponding
  * log severity. */
 static inline int

+ 2 - 0
src/or/control.h

@@ -12,6 +12,8 @@
 #ifndef TOR_CONTROL_H
 #define TOR_CONTROL_H
 
+control_connection_t *TO_CONTROL_CONN(connection_t *);
+
 void control_initialize_event_queue(void);
 
 void control_update_global_event_mask(void);

+ 46 - 0
src/or/control_connection_st.h

@@ -0,0 +1,46 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CONTROL_CONNECTION_ST_H
+#define CONTROL_CONNECTION_ST_H
+
+#include "or.h"
+#include "connection_st.h"
+
+/** Subtype of connection_t for an connection to a controller. */
+struct control_connection_t {
+  connection_t base_;
+
+  uint64_t event_mask; /**< Bitfield: which events does this controller
+                        * care about?
+                        * EVENT_MAX_ is >31, so we need a 64 bit mask */
+
+  /** True if we have sent a protocolinfo reply on this connection. */
+  unsigned int have_sent_protocolinfo:1;
+  /** True if we have received a takeownership command on this
+   * connection. */
+  unsigned int is_owning_control_connection:1;
+
+  /** List of ephemeral onion services belonging to this connection. */
+  smartlist_t *ephemeral_onion_services;
+
+  /** If we have sent an AUTHCHALLENGE reply on this connection and
+   * have not received a successful AUTHENTICATE command, points to
+   * the value which the client must send to authenticate itself;
+   * otherwise, NULL. */
+  char *safecookie_client_hash;
+
+  /** Amount of space allocated in incoming_cmd. */
+  uint32_t incoming_cmd_len;
+  /** Number of bytes currently stored in incoming_cmd. */
+  uint32_t incoming_cmd_cur_len;
+  /** A control command that we're reading from the inbuf, but which has not
+   * yet arrived completely. */
+  char *incoming_cmd;
+};
+
+#endif
+

+ 38 - 0
src/or/cpath_build_state_st.h

@@ -0,0 +1,38 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CIRCUIT_BUILD_STATE_ST_ST_H
+#define CIRCUIT_BUILD_STATE_ST_ST_H
+
+/** Information used to build a circuit. */
+struct cpath_build_state_t {
+  /** Intended length of the final circuit. */
+  int desired_path_len;
+  /** How to extend to the planned exit node. */
+  extend_info_t *chosen_exit;
+  /** Whether every node in the circ must have adequate uptime. */
+  unsigned int need_uptime : 1;
+  /** Whether every node in the circ must have adequate capacity. */
+  unsigned int need_capacity : 1;
+  /** Whether the last hop was picked with exiting in mind. */
+  unsigned int is_internal : 1;
+  /** Did we pick this as a one-hop tunnel (not safe for other streams)?
+   * These are for encrypted dir conns that exit to this router, not
+   * for arbitrary exits from the circuit. */
+  unsigned int onehop_tunnel : 1;
+  /** The crypt_path_t to append after rendezvous: used for rendezvous. */
+  crypt_path_t *pending_final_cpath;
+  /** A ref-counted reference to the crypt_path_t to append after
+   * rendezvous; used on the service side. */
+  crypt_path_reference_t *service_pending_final_cpath_ref;
+  /** How many times has building a circuit for this task failed? */
+  int failure_count;
+  /** At what time should we give up on this task? */
+  time_t expiry_time;
+};
+
+#endif
+

+ 2 - 0
src/or/cpuworker.c

@@ -32,6 +32,8 @@
 #include "router.h"
 #include "workqueue.h"
 
+#include "or_circuit_st.h"
+
 static void queue_pending_tasks(void);
 
 typedef struct worker_state_s {

+ 23 - 0
src/or/crypt_path_reference_st.h

@@ -0,0 +1,23 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CRYPT_PATH_REFERENCE_ST_H
+#define CRYPT_PATH_REFERENCE_ST_H
+
+/** A reference-counted pointer to a crypt_path_t, used only to share
+ * the final rendezvous cpath to be used on a service-side rendezvous
+ * circuit among multiple circuits built in parallel to the same
+ * destination rendezvous point. */
+struct crypt_path_reference_t {
+  /** The reference count. */
+  unsigned int refcount;
+  /** The pointer.  Set to NULL when the crypt_path_t is put into use
+   * on an opened rendezvous circuit. */
+  crypt_path_t *cpath;
+};
+
+#endif
+

+ 56 - 0
src/or/crypt_path_st.h

@@ -0,0 +1,56 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef CRYPT_PATH_ST_H
+#define CRYPT_PATH_ST_H
+
+#include "relay_crypto_st.h"
+
+/** Holds accounting information for a single step in the layered encryption
+ * performed by a circuit.  Used only at the client edge of a circuit. */
+struct crypt_path_t {
+  uint32_t magic;
+
+  /** Cryptographic state used for encrypting and authenticating relay
+   * cells to and from this hop. */
+  relay_crypto_t crypto;
+
+  /** Current state of the handshake as performed with the OR at this
+   * step. */
+  onion_handshake_state_t handshake_state;
+  /** Diffie-hellman handshake state for performing an introduction
+   * operations */
+  crypto_dh_t *rend_dh_handshake_state;
+
+  /** Negotiated key material shared with the OR at this step. */
+  char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */
+
+  /** Information to extend to the OR at this step. */
+  extend_info_t *extend_info;
+
+  /** Is the circuit built to this step?  Must be one of:
+   *    - CPATH_STATE_CLOSED (The circuit has not been extended to this step)
+   *    - CPATH_STATE_AWAITING_KEYS (We have sent an EXTEND/CREATE to this step
+   *      and not received an EXTENDED/CREATED)
+   *    - CPATH_STATE_OPEN (The circuit has been extended to this step) */
+  uint8_t state;
+#define CPATH_STATE_CLOSED 0
+#define CPATH_STATE_AWAITING_KEYS 1
+#define CPATH_STATE_OPEN 2
+  struct crypt_path_t *next; /**< Link to next crypt_path_t in the circuit.
+                              * (The list is circular, so the last node
+                              * links to the first.) */
+  struct crypt_path_t *prev; /**< Link to previous crypt_path_t in the
+                              * circuit. */
+
+  int package_window; /**< How many cells are we allowed to originate ending
+                       * at this step? */
+  int deliver_window; /**< How many cells are we willing to deliver originating
+                       * at this step? */
+};
+
+#endif
+

+ 34 - 0
src/or/desc_store_st.h

@@ -0,0 +1,34 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef DESC_STORE_ST_H
+#define DESC_STORE_ST_H
+
+/** A 'store' is a set of descriptors saved on disk, with accompanying
+ * journal, mmaped as needed, rebuilt as needed. */
+struct desc_store_t {
+  /** Filename (within DataDir) for the store.  We append .tmp to this
+   * filename for a temporary file when rebuilding the store, and .new to this
+   * filename for the journal. */
+  const char *fname_base;
+  /** Human-readable description of what this store contains. */
+  const char *description;
+
+  tor_mmap_t *mmap; /**< A mmap for the main file in the store. */
+
+  store_type_t type; /**< What's stored in this store? */
+
+  /** The size of the router log, in bytes. */
+  size_t journal_len;
+  /** The size of the router store, in bytes. */
+  size_t store_len;
+  /** Total bytes dropped since last rebuild: this is space currently
+   * used in the cache and the journal that could be freed by a rebuild. */
+  size_t bytes_dropped;
+};
+
+#endif
+

+ 27 - 0
src/or/destroy_cell_queue_st.h

@@ -0,0 +1,27 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef DESTROY_CELL_QUEUE_ST_H
+#define DESTROY_CELL_QUEUE_ST_H
+
+/** A single queued destroy cell. */
+struct destroy_cell_t {
+  TOR_SIMPLEQ_ENTRY(destroy_cell_t) next;
+  circid_t circid;
+  uint32_t inserted_timestamp; /**< Time (in timestamp units) when this cell
+                                * was inserted */
+  uint8_t reason;
+};
+
+/** A queue of destroy cells on a channel. */
+struct destroy_cell_queue_t {
+  /** Linked list of packed_cell_t */
+  TOR_SIMPLEQ_HEAD(dcell_simpleq, destroy_cell_t) head;
+  int n; /**< The number of cells in the queue. */
+};
+
+#endif
+

+ 66 - 0
src/or/dir_connection_st.h

@@ -0,0 +1,66 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef DIR_CONNECTION_ST_H
+#define DIR_CONNECTION_ST_H
+
+#include "connection_st.h"
+
+/** Subtype of connection_t for an "directory connection" -- that is, an HTTP
+ * connection to retrieve or serve directory material. */
+struct dir_connection_t {
+  connection_t base_;
+
+ /** Which 'resource' did we ask the directory for? This is typically the part
+  * of the URL string that defines, relative to the directory conn purpose,
+  * what thing we want.  For example, in router descriptor downloads by
+  * descriptor digest, it contains "d/", then one or more +-separated
+  * fingerprints.
+  **/
+  char *requested_resource;
+  unsigned int dirconn_direct:1; /**< Is this dirconn direct, or via Tor? */
+
+  /** If we're fetching descriptors, what router purpose shall we assign
+   * to them? */
+  uint8_t router_purpose;
+
+  /** List of spooled_resource_t for objects that we're spooling. We use
+   * it from back to front. */
+  smartlist_t *spool;
+  /** The compression object doing on-the-fly compression for spooled data. */
+  tor_compress_state_t *compress_state;
+
+  /** What rendezvous service are we querying for? */
+  rend_data_t *rend_data;
+
+  /* Hidden service connection identifier for dir connections: Used by HS
+     client-side code to fetch HS descriptors, and by the service-side code to
+     upload descriptors. */
+  struct hs_ident_dir_conn_t *hs_ident;
+
+  /** If this is a one-hop connection, tracks the state of the directory guard
+   * for this connection (if any). */
+  struct circuit_guard_state_t *guard_state;
+
+  char identity_digest[DIGEST_LEN]; /**< Hash of the public RSA key for
+                                     * the directory server's signing key. */
+
+  /** Unique ID for directory requests; this used to be in connection_t, but
+   * that's going away and being used on channels instead.  The dirserver still
+   * needs this for the incoming side, so it's moved here. */
+  uint64_t dirreq_id;
+
+#ifdef MEASUREMENTS_21206
+  /** Number of RELAY_DATA cells received. */
+  uint32_t data_cells_received;
+
+  /** Number of RELAY_DATA cells sent. */
+  uint32_t data_cells_sent;
+#endif /* defined(MEASUREMENTS_21206) */
+};
+
+#endif
+

+ 55 - 0
src/or/dir_server_st.h

@@ -0,0 +1,55 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef DIR_SERVER_ST_H
+#define DIR_SERVER_ST_H
+
+#include "torint.h"
+#include "or.h"
+#include "routerstatus_st.h"
+
+/** Represents information about a single trusted or fallback directory
+ * server. */
+typedef struct dir_server_t {
+  char *description;
+  char *nickname;
+  char *address; /**< Hostname. */
+  /* XX/teor - why do we duplicate the address and port fields here and in
+   *           fake_status? Surely we could just use fake_status (#17867). */
+  tor_addr_t ipv6_addr; /**< IPv6 address if present; AF_UNSPEC if not */
+  uint32_t addr; /**< IPv4 address. */
+  uint16_t dir_port; /**< Directory port. */
+  uint16_t or_port; /**< OR port: Used for tunneling connections. */
+  uint16_t ipv6_orport; /**< OR port corresponding to ipv6_addr. */
+  double weight; /** Weight used when selecting this node at random */
+  char digest[DIGEST_LEN]; /**< Digest of identity key. */
+  char v3_identity_digest[DIGEST_LEN]; /**< Digest of v3 (authority only,
+                                        * high-security) identity key. */
+
+  unsigned int is_running:1; /**< True iff we think this server is running. */
+  unsigned int is_authority:1; /**< True iff this is a directory authority
+                                * of some kind. */
+
+  /** True iff this server has accepted the most recent server descriptor
+   * we tried to upload to it. */
+  unsigned int has_accepted_serverdesc:1;
+
+  /** What kind of authority is this? (Bitfield.) */
+  dirinfo_type_t type;
+
+  time_t addr_current_at; /**< When was the document that we derived the
+                           * address information from published? */
+
+  routerstatus_t fake_status; /**< Used when we need to pass this trusted
+                               * dir_server_t to
+                               * directory_request_set_routerstatus.
+                               * as a routerstatus_t.  Not updated by the
+                               * router-status management code!
+                               **/
+} dir_server_t;
+
+#endif
+

+ 3 - 0
src/or/dirauth/dircollate.c

@@ -25,6 +25,9 @@
 #include "dircollate.h"
 #include "dirvote.h"
 
+#include "networkstatus_st.h"
+#include "vote_routerstatus_st.h"
+
 static void dircollator_collate_by_ed25519(dircollator_t *dc);
 
 /** Hashtable entry mapping a pair of digests (actually an ed25519 key and an

+ 15 - 0
src/or/dirauth/dirvote.c

@@ -28,6 +28,21 @@
 #include "dirauth/mode.h"
 #include "dirauth/shared_random_state.h"
 
+#include "authority_cert_st.h"
+#include "cached_dir_st.h"
+#include "dir_server_st.h"
+#include "document_signature_st.h"
+#include "microdesc_st.h"
+#include "networkstatus_st.h"
+#include "networkstatus_voter_info_st.h"
+#include "node_st.h"
+#include "ns_detached_signatures_st.h"
+#include "routerinfo_st.h"
+#include "routerlist_st.h"
+#include "vote_microdesc_hash_st.h"
+#include "vote_routerstatus_st.h"
+#include "vote_timing_st.h"
+
 /**
  * \file dirvote.c
  * \brief Functions to compute directory consensus, and schedule voting.

+ 3 - 0
src/or/dirauth/shared_random.c

@@ -105,6 +105,9 @@
 #include "dirauth/dirvote.h"
 #include "dirauth/mode.h"
 
+#include "authority_cert_st.h"
+#include "networkstatus_st.h"
+
 /* String prefix of shared random values in votes/consensuses. */
 static const char previous_srv_str[] = "shared-rand-previous-value";
 static const char current_srv_str[] = "shared-rand-current-value";

+ 41 - 0
src/or/directory.c

@@ -23,6 +23,7 @@
 #include "directory.h"
 #include "dirserv.h"
 #include "entrynodes.h"
+#include "fp_pair.h"
 #include "geoip.h"
 #include "hs_cache.h"
 #include "hs_common.h"
@@ -53,6 +54,16 @@
 #include "dirauth/mode.h"
 #include "dirauth/shared_random.h"
 
+#include "authority_cert_st.h"
+#include "cached_dir_st.h"
+#include "dir_connection_st.h"
+#include "dir_server_st.h"
+#include "entry_connection_st.h"
+#include "networkstatus_st.h"
+#include "node_st.h"
+#include "rend_service_descriptor_st.h"
+#include "routerinfo_st.h"
+
 /**
  * \file directory.c
  * \brief Code to send and fetch information from directory authorities and
@@ -151,6 +162,15 @@ static void connection_dir_close_consensus_fetches(
 
 /********* END VARIABLES ************/
 
+/** Convert a connection_t* to a dir_connection_t*; assert if the cast is
+ * invalid. */
+dir_connection_t *
+TO_DIR_CONN(connection_t *c)
+{
+  tor_assert(c->magic == DIR_CONNECTION_MAGIC);
+  return DOWNCAST(dir_connection_t, c);
+}
+
 /** Return false if the directory purpose <b>dir_purpose</b>
  * does not require an anonymous (three-hop) connection.
  *
@@ -5613,6 +5633,27 @@ download_status_reset(download_status_t *dls)
   /* Don't reset dls->want_authority or dls->increment_on */
 }
 
+/** Return true iff, as of <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

+ 4 - 23
src/or/directory.h

@@ -14,6 +14,7 @@
 
 #include "hs_ident.h"
 
+dir_connection_t *TO_DIR_CONN(connection_t *c);
 int directories_have_accepted_server_descriptor(void);
 void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
                                   dirinfo_type_t type, const char *payload,
@@ -60,6 +61,7 @@ void directory_request_set_dir_addr_port(directory_request_t *req,
                                          const tor_addr_port_t *p);
 void directory_request_set_directory_id_digest(directory_request_t *req,
                                                const char *digest);
+struct circuit_guard_state_t;
 void directory_request_set_guard_state(directory_request_t *req,
                                        struct circuit_guard_state_t *state);
 void directory_request_set_router_purpose(directory_request_t *req,
@@ -132,30 +134,9 @@ time_t download_status_increment_attempt(download_status_t *dls,
                                     time(NULL))
 
 void download_status_reset(download_status_t *dls);
-static int download_status_is_ready(download_status_t *dls, time_t now);
+int download_status_is_ready(download_status_t *dls, time_t now);
 time_t download_status_get_next_attempt_at(const download_status_t *dls);
-
-/** Return true iff, as of <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);

+ 10 - 0
src/or/dirserv.c

@@ -36,6 +36,16 @@
 
 #include "dirauth/dirvote.h"
 
+#include "cached_dir_st.h"
+#include "dir_connection_st.h"
+#include "extrainfo_st.h"
+#include "microdesc_st.h"
+#include "node_st.h"
+#include "routerinfo_st.h"
+#include "routerlist_st.h"
+#include "tor_version_st.h"
+#include "vote_routerstatus_st.h"
+
 /**
  * \file dirserv.c
  * \brief Directory server core implementation. Manages directory

+ 8 - 0
src/or/dirserv.h

@@ -87,6 +87,14 @@ typedef struct spooled_resource_t {
   off_t cached_dir_offset;
 } spooled_resource_t;
 
+#ifdef DIRSERV_PRIVATE
+typedef struct measured_bw_line_t {
+  char node_id[DIGEST_LEN];
+  char node_hex[MAX_HEX_NICKNAME_LEN+1];
+  long int bw_kb;
+} measured_bw_line_t;
+#endif /* defined(DIRSERV_PRIVATE) */
+
 int connection_dirserv_flushed_some(dir_connection_t *conn);
 
 int dirserv_add_own_fingerprint(crypto_pk_t *pk);

+ 4 - 0
src/or/dns.c

@@ -64,6 +64,10 @@
 #include "router.h"
 #include "ht.h"
 #include "sandbox.h"
+
+#include "edge_connection_st.h"
+#include "or_circuit_st.h"
+
 #include <event2/event.h>
 #include <event2/dns.h>
 

+ 6 - 0
src/or/dnsserv.c

@@ -29,6 +29,12 @@
 #include "control.h"
 #include "main.h"
 #include "policies.h"
+
+#include "control_connection_st.h"
+#include "entry_connection_st.h"
+#include "listener_connection_st.h"
+#include "socks_request_st.h"
+
 #include <event2/dns.h>
 #include <event2/dns_compat.h>
 /* XXXX this implies we want an improved evdns  */

+ 29 - 0
src/or/document_signature_st.h

@@ -0,0 +1,29 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef DOCUMENT_SIGNATURE_ST_H
+#define DOCUMENT_SIGNATURE_ST_H
+
+/** A signature of some document by an authority. */
+struct document_signature_t {
+  /** Declared SHA-1 digest of this voter's identity key */
+  char identity_digest[DIGEST_LEN];
+  /** Declared SHA-1 digest of signing key used by this voter. */
+  char signing_key_digest[DIGEST_LEN];
+  /** Algorithm used to compute the digest of the document. */
+  digest_algorithm_t alg;
+  /** Signature of the signed thing. */
+  char *signature;
+  /** Length of <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
+

+ 3 - 0
src/or/dos.c

@@ -11,6 +11,7 @@
 #include "or.h"
 #include "channel.h"
 #include "config.h"
+#include "connection_or.h"
 #include "crypto_rand.h"
 #include "geoip.h"
 #include "main.h"
@@ -21,6 +22,8 @@
 
 #include "dos.h"
 
+#include "or_connection_st.h"
+
 /*
  * Circuit creation denial of service mitigation.
  *

+ 65 - 0
src/or/download_status_st.h

@@ -0,0 +1,65 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef DOWNLOAD_STATUS_ST_H
+#define DOWNLOAD_STATUS_ST_H
+
+/** Information about our plans for retrying downloads for a downloadable
+ * directory object.
+ * Each type of downloadable directory object has a corresponding retry
+ * <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
+

+ 77 - 0
src/or/edge_connection_st.h

@@ -0,0 +1,77 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef EDGE_CONNECTION_ST_H
+#define EDGE_CONNECTION_ST_H
+
+#include "or.h"
+
+#include "connection_st.h"
+
+/** Subtype of connection_t for an "edge connection" -- that is, an entry (ap)
+ * connection, or an exit. */
+struct edge_connection_t {
+  connection_t base_;
+
+  struct edge_connection_t *next_stream; /**< Points to the next stream at this
+                                          * edge, if any */
+  int package_window; /**< How many more relay cells can I send into the
+                       * circuit? */
+  int deliver_window; /**< How many more relay cells can end at me? */
+
+  struct circuit_t *on_circuit; /**< The circuit (if any) that this edge
+                                 * connection is using. */
+
+  /** A pointer to which node in the circ this conn exits at.  Set for AP
+   * connections and for hidden service exit connections. */
+  struct crypt_path_t *cpath_layer;
+  /** What rendezvous service are we querying for (if an AP) or providing (if
+   * an exit)? */
+  rend_data_t *rend_data;
+
+  /* Hidden service connection identifier for edge connections. Used by the HS
+   * client-side code to identify client SOCKS connections and by the
+   * service-side code to match HS circuits with their streams. */
+  struct hs_ident_edge_conn_t *hs_ident;
+
+  uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit
+                         * connection.  Exit connections only. */
+  uint32_t begincell_flags; /** Flags sent or received in the BEGIN cell
+                             * for this connection */
+
+  streamid_t stream_id; /**< The stream ID used for this edge connection on its
+                         * circuit */
+
+  /** The reason why this connection is closing; passed to the controller. */
+  uint16_t end_reason;
+
+  /** Bytes read since last call to control_event_stream_bandwidth_used() */
+  uint32_t n_read;
+
+  /** Bytes written since last call to control_event_stream_bandwidth_used() */
+  uint32_t n_written;
+
+  /** True iff this connection is for a DNS request only. */
+  unsigned int is_dns_request:1;
+  /** True iff this connection is for a PTR DNS request. (exit only) */
+  unsigned int is_reverse_dns_lookup:1;
+
+  unsigned int edge_has_sent_end:1; /**< For debugging; only used on edge
+                         * connections.  Set once we've set the stream end,
+                         * and check in connection_about_to_close_connection().
+                         */
+  /** True iff we've blocked reading until the circuit has fewer queued
+   * cells. */
+  unsigned int edge_blocked_on_circ:1;
+
+  /** Unique ID for directory requests; this used to be in connection_t, but
+   * that's going away and being used on channels instead.  We still tag
+   * edge connections with dirreq_id from circuits, so it's copied here. */
+  uint64_t dirreq_id;
+};
+
+#endif
+

+ 100 - 0
src/or/entry_connection_st.h

@@ -0,0 +1,100 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef ENTRY_CONNECTION_ST_H
+#define ENTRY_CONNECTION_ST_H
+
+#include "edge_connection_st.h"
+
+/** Subtype of edge_connection_t for an "entry connection" -- that is, a SOCKS
+ * connection, a DNS request, a TransPort connection or a NATD connection */
+struct entry_connection_t {
+  struct edge_connection_t edge_;
+
+  /** Nickname of planned exit node -- used with .exit support. */
+  /* XXX prop220: we need to make chosen_exit_name able to encode Ed IDs too.
+   * That's logically part of the UI parts for prop220 though. */
+  char *chosen_exit_name;
+
+  socks_request_t *socks_request; /**< SOCKS structure describing request (AP
+                                   * only.) */
+
+  /* === Isolation related, AP only. === */
+  entry_port_cfg_t entry_cfg;
+  /** AP only: The newnym epoch in which we created this connection. */
+  unsigned nym_epoch;
+
+  /** AP only: The original requested address before we rewrote it. */
+  char *original_dest_address;
+  /* Other fields to isolate on already exist.  The ClientAddr is addr.  The
+     ClientProtocol is a combination of type and socks_request->
+     socks_version.  SocksAuth is socks_request->username/password.
+     DestAddr is in socks_request->address. */
+
+  /** Number of times we've reassigned this application connection to
+   * a new circuit. We keep track because the timeout is longer if we've
+   * already retried several times. */
+  uint8_t num_socks_retries;
+
+  /** For AP connections only: buffer for data that we have sent
+   * optimistically, which we might need to re-send if we have to
+   * retry this connection. */
+  struct buf_t *pending_optimistic_data;
+  /* For AP connections only: buffer for data that we previously sent
+  * optimistically which we are currently re-sending as we retry this
+  * connection. */
+  struct buf_t *sending_optimistic_data;
+
+  /** If this is a DNSPort connection, this field holds the pending DNS
+   * request that we're going to try to answer.  */
+  struct evdns_server_request *dns_server_request;
+
+#define DEBUGGING_17659
+
+#ifdef DEBUGGING_17659
+  uint16_t marked_pending_circ_line;
+  const char *marked_pending_circ_file;
+#endif
+
+#define NUM_CIRCUITS_LAUNCHED_THRESHOLD 10
+  /** Number of times we've launched a circuit to handle this stream. If
+    * it gets too high, that could indicate an inconsistency between our
+    * "launch a circuit to handle this stream" logic and our "attach our
+    * stream to one of the available circuits" logic. */
+  unsigned int num_circuits_launched:4;
+
+  /** True iff this stream must attach to a one-hop circuit (e.g. for
+   * begin_dir). */
+  unsigned int want_onehop:1;
+  /** True iff this stream should use a BEGIN_DIR relay command to establish
+   * itself rather than BEGIN (either via onehop or via a whole circuit). */
+  unsigned int use_begindir:1;
+
+  /** For AP connections only. If 1, and we fail to reach the chosen exit,
+   * stop requiring it. */
+  unsigned int chosen_exit_optional:1;
+  /** For AP connections only. If non-zero, this exit node was picked as
+   * a result of the TrackHostExit, and the value decrements every time
+   * we fail to complete a circuit to our chosen exit -- if it reaches
+   * zero, abandon the associated mapaddress. */
+  unsigned int chosen_exit_retries:3;
+
+  /** True iff this is an AP connection that came from a transparent or
+   * NATd connection */
+  unsigned int is_transparent_ap:1;
+
+  /** For AP connections only: Set if this connection's target exit node
+   * allows optimistic data (that is, data sent on this stream before
+   * the exit has sent a CONNECTED cell) and we have chosen to use it.
+   */
+  unsigned int may_use_optimistic_data : 1;
+};
+
+/** Cast a entry_connection_t subtype pointer to a edge_connection_t **/
+#define ENTRY_TO_EDGE_CONN(c) (&(((c))->edge_))
+
+#endif
+

+ 54 - 0
src/or/entry_port_cfg_st.h

@@ -0,0 +1,54 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef ENTRY_PORT_CFG_ST_H
+#define ENTRY_PORT_CFG_ST_H
+
+#include "torint.h"
+#include "or.h"
+
+struct entry_port_cfg_t {
+  /* Client port types (socks, dns, trans, natd) only: */
+  uint8_t isolation_flags; /**< Zero or more isolation flags */
+  int session_group; /**< A session group, or -1 if this port is not in a
+                      * session group. */
+
+  /* Socks only: */
+  /** When both no-auth and user/pass are advertised by a SOCKS client, select
+   * no-auth. */
+  unsigned int socks_prefer_no_auth : 1;
+  /** When ISO_SOCKSAUTH is in use, Keep-Alive circuits indefinitely. */
+  unsigned int socks_iso_keep_alive : 1;
+
+  /* Client port types only: */
+  unsigned int ipv4_traffic : 1;
+  unsigned int ipv6_traffic : 1;
+  unsigned int prefer_ipv6 : 1;
+  unsigned int dns_request : 1;
+  unsigned int onion_traffic : 1;
+
+  /** For a socks listener: should we cache IPv4/IPv6 DNS information that
+   * exit nodes tell us?
+   *
+   * @{ */
+  unsigned int cache_ipv4_answers : 1;
+  unsigned int cache_ipv6_answers : 1;
+  /** @} */
+  /** For a socks listeners: if we find an answer in our client-side DNS cache,
+   * should we use it?
+   *
+   * @{ */
+  unsigned int use_cached_ipv4_answers : 1;
+  unsigned int use_cached_ipv6_answers : 1;
+  /** @} */
+  /** For socks listeners: When we can automap an address to IPv4 or IPv6,
+   * do we prefer IPv6? */
+  unsigned int prefer_ipv6_virtaddr : 1;
+
+};
+
+#endif
+

+ 3 - 0
src/or/entrynodes.c

@@ -139,6 +139,9 @@
 #include "transports.h"
 #include "statefile.h"
 
+#include "node_st.h"
+#include "origin_circuit_st.h"
+
 /** A list of existing guard selection contexts. */
 static smartlist_t *guard_contexts = NULL;
 /** The currently enabled guard selection context. */

+ 2 - 0
src/or/ext_orport.c

@@ -29,6 +29,8 @@
 #include "proto_ext_or.h"
 #include "util.h"
 
+#include "or_connection_st.h"
+
 /** Allocate and return a structure capable of holding an Extended
  *  ORPort message of body length <b>len</b>. */
 ext_or_cmd_t *

+ 28 - 0
src/or/extend_info_st.h

@@ -0,0 +1,28 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef EXTEND_INFO_ST_H
+#define EXTEND_INFO_ST_H
+
+/** Information on router used when extending a circuit. We don't need a
+ * full routerinfo_t to extend: we only need addr:port:keyid to build an OR
+ * connection, and onion_key to create the onionskin. Note that for onehop
+ * general-purpose tunnels, the onion_key is NULL. */
+struct extend_info_t {
+  char nickname[MAX_HEX_NICKNAME_LEN+1]; /**< This router's nickname for
+                                          * display. */
+  /** Hash of this router's RSA identity key. */
+  char identity_digest[DIGEST_LEN];
+  /** Ed25519 identity for this router, if any. */
+  ed25519_public_key_t ed_identity;
+  uint16_t port; /**< OR port. */
+  tor_addr_t addr; /**< IP address. */
+  crypto_pk_t *onion_key; /**< Current onionskin key. */
+  curve25519_public_key_t curve25519_onion_key;
+};
+
+#endif
+

+ 30 - 0
src/or/extrainfo_st.h

@@ -0,0 +1,30 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef EXTRAINFO_ST_H
+#define EXTRAINFO_ST_H
+
+#include "signed_descriptor_st.h"
+
+/** Information needed to keep and cache a signed extra-info document. */
+struct extrainfo_t {
+  signed_descriptor_t cache_info;
+  /** SHA256 digest of this document */
+  uint8_t digest256[DIGEST256_LEN];
+  /** The router's nickname. */
+  char nickname[MAX_NICKNAME_LEN+1];
+  /** True iff we found the right key for this extra-info, verified the
+   * signature, and found it to be bad. */
+  unsigned int bad_sig : 1;
+  /** If present, we didn't have the right key to verify this extra-info,
+   * so this is a copy of the signature in the document. */
+  char *pending_sig;
+  /** Length of pending_sig. */
+  size_t pending_sig_len;
+};
+
+#endif
+

+ 6 - 0
src/or/fp_pair.h

@@ -9,6 +9,12 @@
 #ifndef _TOR_FP_PAIR_H
 #define _TOR_FP_PAIR_H
 
+/** A pair of digests created by dir_split_resource_info_fingerprint_pairs() */
+typedef struct {
+  char first[DIGEST_LEN];
+  char second[DIGEST_LEN];
+} fp_pair_t;
+
 /*
  * Declare fp_pair_map_t functions and structs
  */

+ 2 - 0
src/or/hibernate.c

@@ -42,6 +42,8 @@ hibernating, phase 2:
 #include "router.h"
 #include "statefile.h"
 
+#include "or_connection_st.h"
+
 /** Are we currently awake, asleep, running out of bandwidth, or shutting
  * down? */
 static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL;

+ 2 - 0
src/or/hs_cache.c

@@ -21,6 +21,8 @@
 
 #include "hs_cache.h"
 
+#include "networkstatus_st.h"
+
 static int cached_client_descriptor_has_expired(time_t now,
            const hs_cache_client_descriptor_t *cached_desc);
 

+ 2 - 0
src/or/hs_cell.c

@@ -16,6 +16,8 @@
 #include "hs_cell.h"
 #include "hs_ntor.h"
 
+#include "origin_circuit_st.h"
+
 /* Trunnel. */
 #include "ed25519_cert.h"
 #include "hs/cell_common.h"

+ 5 - 0
src/or/hs_circuit.c

@@ -33,6 +33,11 @@
 #include "hs/cell_common.h"
 #include "hs/cell_establish_intro.h"
 
+#include "cpath_build_state_st.h"
+#include "crypt_path_st.h"
+#include "node_st.h"
+#include "origin_circuit_st.h"
+
 /* A circuit is about to become an e2e rendezvous circuit. Check
  * <b>circ_purpose</b> and ensure that it's properly set. Return true iff
  * circuit purpose is properly set, otherwise return false. */

+ 3 - 0
src/or/hs_circuitmap.c

@@ -18,6 +18,9 @@
 #include "circuitlist.h"
 #include "hs_circuitmap.h"
 
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+
 /************************** HS circuitmap code *******************************/
 
 /* This is the hidden service circuitmap. It's a hash table that maps

+ 6 - 0
src/or/hs_client.c

@@ -35,6 +35,12 @@
 #include "router.h"
 #include "routerset.h"
 
+#include "cpath_build_state_st.h"
+#include "dir_connection_st.h"
+#include "entry_connection_st.h"
+#include "extend_info_st.h"
+#include "origin_circuit_st.h"
+
 /* Return a human-readable string for the client fetch status code. */
 static const char *
 fetch_status_to_string(hs_client_fetch_status_t status)

+ 6 - 0
src/or/hs_common.c

@@ -33,6 +33,12 @@
 #include "shared_random_client.h"
 #include "dirauth/shared_random_state.h"
 
+#include "edge_connection_st.h"
+#include "networkstatus_st.h"
+#include "node_st.h"
+#include "origin_circuit_st.h"
+#include "routerstatus_st.h"
+
 /* Trunnel */
 #include "ed25519_cert.h"
 

+ 3 - 0
src/or/hs_control.c

@@ -15,6 +15,9 @@
 #include "hs_service.h"
 #include "nodelist.h"
 
+#include "node_st.h"
+#include "routerstatus_st.h"
+
 /* Send on the control port the "HS_DESC REQUESTED [...]" event.
  *
  * The onion_pk is the onion service public key, base64_blinded_pk is the

+ 2 - 0
src/or/hs_descriptor.c

@@ -67,6 +67,8 @@
 #include "hs_config.h"
 #include "torcert.h" /* tor_cert_encode_ed22519() */
 
+#include "extend_info_st.h"
+
 /* Constant string value used for the descriptor format. */
 #define str_hs_desc "hs-descriptor"
 #define str_desc_cert "descriptor-signing-key-cert"

+ 2 - 0
src/or/hs_intropoint.c

@@ -27,6 +27,8 @@
 #include "hs_intropoint.h"
 #include "hs_common.h"
 
+#include "or_circuit_st.h"
+
 /** Extract the authentication key from an ESTABLISH_INTRO or INTRODUCE1 using
  * the given <b>cell_type</b> from <b>cell</b> and place it in
  * <b>auth_key_out</b>. */

+ 8 - 0
src/or/hs_service.c

@@ -39,6 +39,14 @@
 #include "hs_service.h"
 #include "hs_stats.h"
 
+#include "dir_connection_st.h"
+#include "edge_connection_st.h"
+#include "extend_info_st.h"
+#include "networkstatus_st.h"
+#include "node_st.h"
+#include "origin_circuit_st.h"
+#include "routerstatus_st.h"
+
 /* Trunnel */
 #include "ed25519_cert.h"
 #include "hs/cell_common.h"

+ 24 - 0
src/or/hsdir_index_st.h

@@ -0,0 +1,24 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef HSDIR_INDEX_ST_H
+#define HSDIR_INDEX_ST_H
+
+/* Hidden service directory index used in a node_t which is set once we set
+ * the consensus. */
+struct hsdir_index_t {
+  /* HSDir index to use when fetching a descriptor. */
+  uint8_t fetch[DIGEST256_LEN];
+
+  /* HSDir index used by services to store their first and second
+   * descriptor. The first descriptor is chronologically older than the second
+   * one and uses older TP and SRV values. */
+  uint8_t store_first[DIGEST256_LEN];
+  uint8_t store_second[DIGEST256_LEN];
+};
+
+#endif
+

+ 52 - 1
src/or/include.am

@@ -181,8 +181,11 @@ endif
 
 ORHEADERS = \
 	src/or/addressmap.h				\
+	src/or/authority_cert_st.h			\
 	src/or/auth_dirs.inc				\
 	src/or/bridges.h				\
+	src/or/cell_st.h				\
+	src/or/cell_queue_st.h				\
 	src/or/channel.h				\
 	src/or/channelpadding.h				\
 	src/or/channeltls.h				\
@@ -193,24 +196,42 @@ ORHEADERS = \
 	src/or/circuitmux_ewma.h			\
 	src/or/circuitstats.h				\
 	src/or/circuituse.h				\
+	src/or/circuit_st.h				\
+	src/or/cached_dir_st.h				\
 	src/or/command.h				\
 	src/or/config.h					\
 	src/or/confparse.h				\
 	src/or/connection.h				\
+	src/or/connection_st.h				\
 	src/or/connection_edge.h			\
 	src/or/connection_or.h				\
 	src/or/conscache.h				\
 	src/or/consdiff.h				\
 	src/or/consdiffmgr.h				\
+	src/or/control_connection_st.h			\
 	src/or/control.h				\
+	src/or/cpath_build_state_st.h			\
+	src/or/crypt_path_st.h				\
+	src/or/crypt_path_reference_st.h		\
 	src/or/cpuworker.h				\
+	src/or/desc_store_st.h				\
+	src/or/destroy_cell_queue_st.h			\
 	src/or/directory.h				\
 	src/or/dirserv.h				\
+	src/or/dir_connection_st.h			\
+	src/or/dir_server_st.h				\
+	src/or/document_signature_st.h			\
+	src/or/download_status_st.h			\
 	src/or/dns.h					\
 	src/or/dns_structs.h				\
 	src/or/dnsserv.h				\
 	src/or/dos.h					\
+	src/or/edge_connection_st.h			\
+	src/or/entry_connection_st.h			\
+	src/or/entry_port_cfg_st.h			\
 	src/or/ext_orport.h				\
+	src/or/extend_info_st.h				\
+	src/or/extrainfo_st.h				\
 	src/or/fallback_dirs.inc			\
 	src/or/fp_pair.h				\
 	src/or/geoip.h					\
@@ -231,20 +252,34 @@ ORHEADERS = \
 	src/or/hs_ntor.h				\
 	src/or/hs_stats.h				\
 	src/or/hs_service.h				\
+	src/or/hsdir_index_st.h				\
 	src/or/keypin.h					\
+	src/or/listener_connection_st.h			\
 	src/or/main.h					\
 	src/or/microdesc.h				\
+	src/or/microdesc_st.h				\
 	src/or/networkstatus.h				\
+	src/or/networkstatus_st.h			\
+	src/or/networkstatus_sr_info_st.h		\
+	src/or/networkstatus_voter_info_st.h		\
 	src/or/nodelist.h				\
+	src/or/node_st.h				\
+	src/or/ns_detached_signatures_st.h		\
 	src/or/ntmain.h					\
 	src/or/onion.h					\
 	src/or/onion_fast.h				\
 	src/or/onion_ntor.h				\
 	src/or/onion_tap.h				\
 	src/or/or.h					\
+	src/or/or_circuit_st.h				\
+	src/or/or_connection_st.h			\
+	src/or/or_handshake_certs_st.h			\
+	src/or/or_handshake_state_st.h			\
+	src/or/origin_circuit_st.h			\
 	src/or/transports.h				\
-	src/or/parsecommon.h			\
+	src/or/parsecommon.h				\
 	src/or/periodic.h				\
+	src/or/port_cfg_st.h				\
 	src/or/policies.h				\
 	src/or/protover.h				\
 	src/or/proto_cell.h				\
@@ -255,25 +290,41 @@ ORHEADERS = \
 	src/or/reasons.h				\
 	src/or/relay.h					\
 	src/or/relay_crypto.h				\
+	src/or/relay_crypto_st.h			\
 	src/or/rendcache.h				\
 	src/or/rendclient.h				\
 	src/or/rendcommon.h				\
 	src/or/rendmid.h				\
 	src/or/rendservice.h				\
+	src/or/rend_authorized_client_st.h		\
+	src/or/rend_encoded_v2_service_descriptor_st.h	\
+	src/or/rend_intro_point_st.h			\
+	src/or/rend_service_descriptor_st.h		\
 	src/or/rephist.h				\
 	src/or/replaycache.h				\
 	src/or/router.h					\
+	src/or/routerinfo_st.h				\
 	src/or/routerkeys.h				\
 	src/or/routerlist.h				\
+	src/or/routerlist_st.h				\
 	src/or/routerkeys.h				\
 	src/or/routerset.h				\
 	src/or/routerparse.h				\
+	src/or/routerstatus_st.h			\
 	src/or/scheduler.h				\
+	src/or/server_port_cfg_st.h			\
 	src/or/shared_random_client.h			\
+	src/or/signed_descriptor_st.h			\
+	src/or/socks_request_st.h			\
 	src/or/statefile.h				\
 	src/or/status.h					\
 	src/or/torcert.h				\
 	src/or/tor_api_internal.h			\
+	src/or/tor_version_st.h				\
+	src/or/var_cell_st.h				\
+	src/or/vote_microdesc_hash_st.h			\
+	src/or/vote_routerstatus_st.h			\
+	src/or/vote_timing_st.h				\
 	src/or/voting_schedule.h
 
 # We add the headers of the modules even though they are disabled so we can

+ 25 - 0
src/or/listener_connection_st.h

@@ -0,0 +1,25 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef LISTENER_CONNECTION_ST_H
+#define LISTENER_CONNECTION_ST_H
+
+#include "connection_st.h"
+
+/** Subtype of connection_t; used for a listener socket. */
+struct listener_connection_t {
+  connection_t base_;
+
+  /** If the connection is a CONN_TYPE_AP_DNS_LISTENER, this field points
+   * to the evdns_server_port it uses to listen to and answer connections. */
+  struct evdns_server_port *dns_server_port;
+
+  entry_port_cfg_t entry_cfg;
+
+};
+
+#endif
+

+ 8 - 0
src/or/main.c

@@ -122,6 +122,14 @@
 #include "dirauth/mode.h"
 #include "dirauth/shared_random.h"
 
+#include "cell_st.h"
+#include "entry_connection_st.h"
+#include "networkstatus_st.h"
+#include "or_connection_st.h"
+#include "port_cfg_st.h"
+#include "routerinfo_st.h"
+#include "socks_request_st.h"
+
 #ifdef HAVE_SYSTEMD
 #   if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
 /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse

+ 5 - 0
src/or/microdesc.c

@@ -22,6 +22,11 @@
 #include "routerlist.h"
 #include "routerparse.h"
 
+#include "microdesc_st.h"
+#include "networkstatus_st.h"
+#include "node_st.h"
+#include "routerstatus_st.h"
+
 /** A data structure to hold a bunch of cached microdescriptors.  There are
  * two active files in the cache: a "cache file" that we mmap, and a "journal
  * file" that we append to.  Periodically, we rebuild the cache file to hold

+ 71 - 0
src/or/microdesc_st.h

@@ -0,0 +1,71 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef MICRODESC_ST_H
+#define MICRODESC_ST_H
+
+/** A microdescriptor is the smallest amount of information needed to build a
+ * circuit through a router.  They are generated by the directory authorities,
+ * using information from the uploaded routerinfo documents.  They are not
+ * self-signed, but are rather authenticated by having their hash in a signed
+ * networkstatus document. */
+struct microdesc_t {
+  /** Hashtable node, used to look up the microdesc by its digest. */
+  HT_ENTRY(microdesc_t) node;
+
+  /* Cache information */
+
+  /**  When was this microdescriptor last listed in a consensus document?
+   * Once a microdesc has been unlisted long enough, we can drop it.
+   */
+  time_t last_listed;
+  /** Where is this microdescriptor currently stored? */
+  saved_location_bitfield_t saved_location : 3;
+  /** If true, do not attempt to cache this microdescriptor on disk. */
+  unsigned int no_save : 1;
+  /** If true, this microdesc has an entry in the microdesc_map */
+  unsigned int held_in_map : 1;
+  /** Reference count: how many node_ts have a reference to this microdesc? */
+  unsigned int held_by_nodes;
+
+  /** If saved_location == SAVED_IN_CACHE, this field holds the offset of the
+   * microdescriptor in the cache. */
+  off_t off;
+
+  /* The string containing the microdesc. */
+
+  /** A pointer to the encoded body of the microdescriptor.  If the
+   * saved_location is SAVED_IN_CACHE, then the body is a pointer into an
+   * mmap'd region.  Otherwise, it is a malloc'd string.  The string might not
+   * be NUL-terminated; take the length from <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;
+};
+
+#endif
+

+ 13 - 0
src/or/networkstatus.c

@@ -74,6 +74,19 @@
 #include "dirauth/mode.h"
 #include "dirauth/shared_random.h"
 
+#include "authority_cert_st.h"
+#include "dir_connection_st.h"
+#include "dir_server_st.h"
+#include "document_signature_st.h"
+#include "networkstatus_st.h"
+#include "networkstatus_voter_info_st.h"
+#include "ns_detached_signatures_st.h"
+#include "node_st.h"
+#include "routerinfo_st.h"
+#include "routerlist_st.h"
+#include "vote_microdesc_hash_st.h"
+#include "vote_routerstatus_st.h"
+
 /** Most recently received and validated v3 "ns"-flavored consensus network
  * status. */
 STATIC networkstatus_t *current_ns_consensus = NULL;

+ 23 - 0
src/or/networkstatus_sr_info_st.h

@@ -0,0 +1,23 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef NETWORKSTATUS_SR_INFO_ST_H
+#define NETWORKSTATUS_SR_INFO_ST_H
+
+struct networkstatus_sr_info_t {
+  /* Indicate if the dirauth partitipates in the SR protocol with its vote.
+   * This is tied to the SR flag in the vote. */
+  unsigned int participate:1;
+  /* Both vote and consensus: Current and previous SRV. If list is empty,
+   * this means none were found in either the consensus or vote. */
+  struct sr_srv_t *previous_srv;
+  struct sr_srv_t *current_srv;
+  /* Vote only: List of commitments. */
+  smartlist_t *commits;
+};
+
+#endif
+

+ 95 - 0
src/or/networkstatus_st.h

@@ -0,0 +1,95 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef NETWORKSTATUS_ST_H
+#define NETWORKSTATUS_ST_H
+
+#include "networkstatus_sr_info_st.h"
+
+/** A common structure to hold a v3 network status vote, or a v3 network
+ * status consensus. */
+struct networkstatus_t {
+  networkstatus_type_t type; /**< Vote, consensus, or opinion? */
+  consensus_flavor_t flavor; /**< If a consensus, what kind? */
+  unsigned int has_measured_bws : 1;/**< True iff this networkstatus contains
+                                     * measured= bandwidth values. */
+
+  time_t published; /**< Vote only: Time when vote was written. */
+  time_t valid_after; /**< Time after which this vote or consensus applies. */
+  time_t fresh_until; /**< Time before which this is the most recent vote or
+                       * consensus. */
+  time_t valid_until; /**< Time after which this vote or consensus should not
+                       * be used. */
+
+  /** Consensus only: what method was used to produce this consensus? */
+  int consensus_method;
+  /** Vote only: what methods is this voter willing to use? */
+  smartlist_t *supported_methods;
+
+  /** List of 'package' lines describing hashes of downloadable packages */
+  smartlist_t *package_lines;
+
+  /** How long does this vote/consensus claim that authorities take to
+   * distribute their votes to one another? */
+  int vote_seconds;
+  /** How long does this vote/consensus claim that authorities take to
+   * distribute their consensus signatures to one another? */
+  int dist_seconds;
+
+  /** Comma-separated list of recommended client software, or NULL if this
+   * voter has no opinion. */
+  char *client_versions;
+  char *server_versions;
+
+  /** Lists of subprotocol versions which are _recommended_ for relays and
+   * clients, or which are _require_ for relays and clients. Tor shouldn't
+   * make any more network connections if a required protocol is missing.
+   */
+  char *recommended_relay_protocols;
+  char *recommended_client_protocols;
+  char *required_relay_protocols;
+  char *required_client_protocols;
+
+  /** List of flags that this vote/consensus applies to routers.  If a flag is
+   * not listed here, the voter has no opinion on what its value should be. */
+  smartlist_t *known_flags;
+
+  /** List of key=value strings for the parameters in this vote or
+   * consensus, sorted by key. */
+  smartlist_t *net_params;
+
+  /** List of key=value strings for the bw weight parameters in the
+   * consensus. */
+  smartlist_t *weight_params;
+
+  /** List of networkstatus_voter_info_t.  For a vote, only one element
+   * is included.  For a consensus, one element is included for every voter
+   * whose vote contributed to the consensus. */
+  smartlist_t *voters;
+
+  struct authority_cert_t *cert; /**< Vote only: the voter's certificate. */
+
+  /** Digests of this document, as signed. */
+  common_digests_t digests;
+  /** A SHA3-256 digest of the document, not including signatures: used for
+   * consensus diffs */
+  uint8_t digest_sha3_as_signed[DIGEST256_LEN];
+
+  /** List of router statuses, sorted by identity digest.  For a vote,
+   * the elements are vote_routerstatus_t; for a consensus, the elements
+   * are routerstatus_t. */
+  smartlist_t *routerstatus_list;
+
+  /** If present, a map from descriptor digest to elements of
+   * routerstatus_list. */
+  digestmap_t *desc_digest_map;
+
+  /** Contains the shared random protocol data from a vote or consensus. */
+  networkstatus_sr_info_t sr_info;
+};
+
+#endif
+

+ 31 - 0
src/or/networkstatus_voter_info_st.h

@@ -0,0 +1,31 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef NETWORKSTATUS_VOTER_INFO_ST_H
+#define NETWORKSTATUS_VOTER_INFO_ST_H
+
+/** Information about a single voter in a vote or a consensus. */
+typedef struct networkstatus_voter_info_t {
+  /** Declared SHA-1 digest of this voter's identity key */
+  char identity_digest[DIGEST_LEN];
+  char *nickname; /**< Nickname of this voter */
+  /** Digest of this voter's "legacy" identity key, if any.  In vote only; for
+   * consensuses, we treat legacy keys as additional signers. */
+  char legacy_id_digest[DIGEST_LEN];
+  char *address; /**< Address of this voter, in string format. */
+  uint32_t addr; /**< Address of this voter, in IPv4, in host order. */
+  uint16_t dir_port; /**< Directory port of this voter */
+  uint16_t or_port; /**< OR port of this voter */
+  char *contact; /**< Contact information for this voter. */
+  char vote_digest[DIGEST_LEN]; /**< Digest of this voter's vote, as signed. */
+
+  /* Nothing from here on is signed. */
+  /** The signature of the document and the signature's status. */
+  smartlist_t *sigs;
+} networkstatus_voter_info_t;
+
+#endif
+

+ 102 - 0
src/or/node_st.h

@@ -0,0 +1,102 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef NODE_ST_H
+#define NODE_ST_H
+
+#include "hsdir_index_st.h"
+
+/** A node_t represents a Tor router.
+ *
+ * Specifically, a node_t is a Tor router as we are using it: a router that
+ * we are considering for circuits, connections, and so on.  A node_t is a
+ * thin wrapper around the routerstatus, routerinfo, and microdesc for a
+ * single router, and provides a consistent interface for all of them.
+ *
+ * Also, a node_t has mutable state.  While a routerinfo, a routerstatus,
+ * and a microdesc have[*] only the information read from a router
+ * descriptor, a consensus entry, and a microdescriptor (respectively)...
+ * a node_t has flags based on *our own current opinion* of the node.
+ *
+ * [*] Actually, there is some leftover information in each that is mutable.
+ *  We should try to excise that.
+ */
+struct node_t {
+  /* Indexing information */
+
+  /** Used to look up the node_t by its identity digest. */
+  HT_ENTRY(node_t) ht_ent;
+  /** Used to look up the node_t by its ed25519 identity digest. */
+  HT_ENTRY(node_t) ed_ht_ent;
+  /** Position of the node within the list of nodes */
+  int nodelist_idx;
+
+  /** The identity digest of this node_t.  No more than one node_t per
+   * identity may exist at a time. */
+  char identity[DIGEST_LEN];
+
+  /** The ed25519 identity of this node_t. This field is nonzero iff we
+   * currently have an ed25519 identity for this node in either md or ri,
+   * _and_ this node has been inserted to the ed25519-to-node map in the
+   * nodelist.
+   */
+  ed25519_public_key_t ed25519_id;
+
+  microdesc_t *md;
+  routerinfo_t *ri;
+  routerstatus_t *rs;
+
+  /* local info: copied from routerstatus, then possibly frobbed based
+   * on experience.  Authorities set this stuff directly.  Note that
+   * these reflect knowledge of the primary (IPv4) OR port only.  */
+
+  unsigned int is_running:1; /**< As far as we know, is this OR currently
+                              * running? */
+  unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR?
+                            *  (For Authdir: Have we validated this OR?) */
+  unsigned int is_fast:1; /** Do we think this is a fast OR? */
+  unsigned int is_stable:1; /** Do we think this is a stable OR? */
+  unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */
+  unsigned int is_exit:1; /**< Do we think this is an OK exit? */
+  unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
+                               * or otherwise nasty? */
+  unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
+                             * directory according to the authorities. */
+
+  /* Local info: warning state. */
+
+  unsigned int name_lookup_warned:1; /**< Have we warned the user for referring
+                                      * to this (unnamed) router by nickname?
+                                      */
+
+  /** Local info: we treat this node as if it rejects everything */
+  unsigned int rejects_all:1;
+
+  /* Local info: derived. */
+
+  /** True if the IPv6 OR port is preferred over the IPv4 OR port.
+   * XX/teor - can this become out of date if the torrc changes? */
+  unsigned int ipv6_preferred:1;
+
+  /** According to the geoip db what country is this router in? */
+  /* XXXprop186 what is this suppose to mean with multiple OR ports? */
+  country_t country;
+
+  /* The below items are used only by authdirservers for
+   * reachability testing. */
+
+  /** When was the last time we could reach this OR? */
+  time_t last_reachable;        /* IPv4. */
+  time_t last_reachable6;       /* IPv6. */
+
+  /* Hidden service directory index data. This is used by a service or client
+   * in order to know what's the hs directory index for this node at the time
+   * the consensus is set. */
+  struct hsdir_index_t hsdir_index;
+};
+
+#endif
+

+ 17 - 0
src/or/nodelist.c

@@ -68,6 +68,14 @@
 
 #include "dirauth/mode.h"
 
+#include "dir_server_st.h"
+#include "microdesc_st.h"
+#include "networkstatus_st.h"
+#include "node_st.h"
+#include "routerinfo_st.h"
+#include "routerlist_st.h"
+#include "routerstatus_st.h"
+
 static void nodelist_drop_node(node_t *node, int remove_from_ht);
 #define node_free(val) \
   FREE_AND_NULL(node_t, node_free_, (val))
@@ -632,6 +640,15 @@ nodelist_set_consensus(networkstatus_t *ns)
   }
 }
 
+/** Return 1 iff <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)

+ 1 - 0
src/or/nodelist.h

@@ -46,6 +46,7 @@ void node_get_verbose_nickname(const node_t *node,
 void node_get_verbose_nickname_by_id(const char *id_digest,
                                 char *verbose_name_out);
 int node_is_dir(const node_t *node);
+int node_is_good_exit(const node_t *node);
 int node_has_any_descriptor(const node_t *node);
 int node_has_preferred_descriptor(const node_t *node,
                                   int for_direct_connect);

+ 22 - 0
src/or/ns_detached_signatures_st.h

@@ -0,0 +1,22 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef NS_DETACHED_SIGNATURES_ST_H
+#define NS_DETACHED_SIGNATURES_ST_H
+
+/** A set of signatures for a networkstatus consensus.  Unless otherwise
+ * noted, all fields are as for networkstatus_t. */
+struct ns_detached_signatures_t {
+  time_t valid_after;
+  time_t fresh_until;
+  time_t valid_until;
+  strmap_t *digests; /**< Map from flavor name to digestset_t */
+  strmap_t *signatures; /**< Map from flavor name to list of
+                         * document_signature_t */
+};
+
+#endif
+

+ 4 - 0
src/or/onion.c

@@ -77,6 +77,10 @@
 #include "rephist.h"
 #include "router.h"
 
+#include "cell_st.h"
+#include "extend_info_st.h"
+#include "or_circuit_st.h"
+
 // trunnel
 #include "ed25519_cert.h"
 

File diff suppressed because it is too large
+ 28 - 999
src/or/or.h


+ 80 - 0
src/or/or_circuit_st.h

@@ -0,0 +1,80 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef OR_CIRCUIT_ST_H
+#define OR_CIRCUIT_ST_H
+
+#include "or.h"
+
+#include "circuit_st.h"
+#include "crypt_path_st.h"
+
+struct onion_queue_t;
+
+/** An or_circuit_t holds information needed to implement a circuit at an
+ * OR. */
+struct or_circuit_t {
+  circuit_t base_;
+
+  /** Pointer to an entry on the onion queue, if this circuit is waiting for a
+   * chance to give an onionskin to a cpuworker. Used only in onion.c */
+  struct onion_queue_t *onionqueue_entry;
+  /** Pointer to a workqueue entry, if this circuit has given an onionskin to
+   * a cpuworker and is waiting for a response. Used to decide whether it is
+   * safe to free a circuit or if it is still in use by a cpuworker. */
+  struct workqueue_entry_s *workqueue_entry;
+
+  /** The circuit_id used in the previous (backward) hop of this circuit. */
+  circid_t p_circ_id;
+  /** Queue of cells waiting to be transmitted on p_conn. */
+  cell_queue_t p_chan_cells;
+  /** The channel that is previous in this circuit. */
+  channel_t *p_chan;
+  /**
+   * Circuit mux associated with p_chan to which this circuit is attached;
+   * NULL if we have no p_chan.
+   */
+  circuitmux_t *p_mux;
+  /** Linked list of Exit streams associated with this circuit. */
+  edge_connection_t *n_streams;
+  /** Linked list of Exit streams associated with this circuit that are
+   * still being resolved. */
+  edge_connection_t *resolving_streams;
+
+  /** Cryptographic state used for encrypting and authenticating relay
+   * cells to and from this hop. */
+  relay_crypto_t crypto;
+
+  /** Points to spliced circuit if purpose is REND_ESTABLISHED, and circuit
+   * is not marked for close. */
+  struct or_circuit_t *rend_splice;
+
+  /** Stores KH for the handshake. */
+  char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */
+
+  /** How many more relay_early cells can we send on this circuit, according
+   * to the specification? */
+  unsigned int remaining_relay_early_cells : 4;
+
+  /* We have already received an INTRODUCE1 cell on this circuit. */
+  unsigned int already_received_introduce1 : 1;
+
+  /** If set, this circuit carries HS traffic. Consider it in any HS
+   *  statistics. */
+  unsigned int circuit_carries_hs_traffic_stats : 1;
+
+  /** Number of cells that were removed from circuit queue; reset every
+   * time when writing buffer stats to disk. */
+  uint32_t processed_cells;
+
+  /** Total time in milliseconds that cells spent in both app-ward and
+   * exit-ward queues of this circuit; reset every time when writing
+   * buffer stats to disk. */
+  uint64_t total_cell_waiting_time;
+};
+
+#endif
+

+ 90 - 0
src/or/or_connection_st.h

@@ -0,0 +1,90 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef OR_CONNECTION_ST_H
+#define OR_CONNECTION_ST_H
+
+#include "connection_st.h"
+
+/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
+ * cells over TLS. */
+struct or_connection_t {
+  connection_t base_;
+
+  /** Hash of the public RSA key for the other side's identity key, or zeroes
+   * if the other side hasn't shown us a valid identity key. */
+  char identity_digest[DIGEST_LEN];
+
+  /** Extended ORPort connection identifier. */
+  char *ext_or_conn_id;
+  /** This is the ClientHash value we expect to receive from the
+   *  client during the Extended ORPort authentication protocol. We
+   *  compute it upon receiving the ClientNoce from the client, and we
+   *  compare it with the acual ClientHash value sent by the
+   *  client. */
+  char *ext_or_auth_correct_client_hash;
+  /** String carrying the name of the pluggable transport
+   *  (e.g. "obfs2") that is obfuscating this connection. If no
+   *  pluggable transports are used, it's NULL. */
+  char *ext_or_transport;
+
+  char *nickname; /**< Nickname of OR on other side (if any). */
+
+  tor_tls_t *tls; /**< TLS connection state. */
+  int tls_error; /**< Last tor_tls error code. */
+  /** When we last used this conn for any client traffic. If not
+   * recent, we can rate limit it further. */
+
+  /* Channel using this connection */
+  channel_tls_t *chan;
+
+  tor_addr_t real_addr; /**< The actual address that this connection came from
+                       * or went to.  The <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
+

+ 39 - 0
src/or/or_handshake_certs_st.h

@@ -0,0 +1,39 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef OR_HANDSHAKE_CERTS_ST
+#define OR_HANDSHAKE_CERTS_ST
+
+/** Structure to hold all the certificates we've received on an OR connection
+ */
+struct or_handshake_certs_t {
+  /** True iff we originated this connection. */
+  int started_here;
+  /** The cert for the 'auth' RSA key that's supposed to sign the AUTHENTICATE
+   * cell. Signed with the RSA identity key. */
+  tor_x509_cert_t *auth_cert;
+  /** The cert for the 'link' RSA key that was used to negotiate the TLS
+   *  connection.  Signed with the RSA identity key. */
+  tor_x509_cert_t *link_cert;
+  /** A self-signed identity certificate: the RSA identity key signed
+   * with itself.  */
+  tor_x509_cert_t *id_cert;
+  /** The Ed25519 signing key, signed with the Ed25519 identity key. */
+  struct tor_cert_st *ed_id_sign;
+  /** A digest of the X509 link certificate for the TLS connection, signed
+   * with the Ed25519 siging key. */
+  struct tor_cert_st *ed_sign_link;
+  /** The Ed25519 authentication key (that's supposed to sign an AUTHENTICATE
+   * cell) , signed with the Ed25519 siging key. */
+  struct tor_cert_st *ed_sign_auth;
+  /** The Ed25519 identity key, crosssigned with the RSA identity key. */
+  uint8_t *ed_rsa_crosscert;
+  /** The length of <b>ed_rsa_crosscert</b> in bytes */
+  size_t ed_rsa_crosscert_len;
+};
+
+#endif
+

+ 78 - 0
src/or/or_handshake_state_st.h

@@ -0,0 +1,78 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef OR_HANDSHAKE_STATE_ST
+#define OR_HANDSHAKE_STATE_ST
+
+/** Stores flags and information related to the portion of a v2/v3 Tor OR
+ * connection handshake that happens after the TLS handshake is finished.
+ */
+struct or_handshake_state_t {
+  /** When was the VERSIONS cell sent on this connection?  Used to get
+   * an estimate of the skew in the returning NETINFO reply. */
+  time_t sent_versions_at;
+  /** True iff we originated this connection */
+  unsigned int started_here : 1;
+  /** True iff we have received and processed a VERSIONS cell. */
+  unsigned int received_versions : 1;
+  /** True iff we have received and processed an AUTH_CHALLENGE cell */
+  unsigned int received_auth_challenge : 1;
+  /** True iff we have received and processed a CERTS cell. */
+  unsigned int received_certs_cell : 1;
+  /** True iff we have received and processed an AUTHENTICATE cell */
+  unsigned int received_authenticate : 1;
+
+  /* True iff we've received valid authentication to some identity. */
+  unsigned int authenticated : 1;
+  unsigned int authenticated_rsa : 1;
+  unsigned int authenticated_ed25519 : 1;
+
+  /* True iff we have sent a netinfo cell */
+  unsigned int sent_netinfo : 1;
+
+  /** The signing->ed25519 link certificate corresponding to the x509
+   * certificate we used on the TLS connection (if this is a server-side
+   * connection). We make a copy of this here to prevent a race condition
+   * caused by TLS context rotation. */
+  struct tor_cert_st *own_link_cert;
+
+  /** True iff we should feed outgoing cells into digest_sent and
+   * digest_received respectively.
+   *
+   * From the server's side of the v3 handshake, we want to capture everything
+   * from the VERSIONS cell through and including the AUTH_CHALLENGE cell.
+   * From the client's, we want to capture everything from the VERSIONS cell
+   * through but *not* including the AUTHENTICATE cell.
+   *
+   * @{ */
+  unsigned int digest_sent_data : 1;
+  unsigned int digest_received_data : 1;
+  /**@}*/
+
+  /** Identity RSA digest that we have received and authenticated for our peer
+   * on this connection. */
+  uint8_t authenticated_rsa_peer_id[DIGEST_LEN];
+  /** Identity Ed25519 public key that we have received and authenticated for
+   * our peer on this connection. */
+  ed25519_public_key_t authenticated_ed25519_peer_id;
+
+  /** Digests of the cells that we have sent or received as part of a V3
+   * handshake.  Used for making and checking AUTHENTICATE cells.
+   *
+   * @{
+   */
+  crypto_digest_t *digest_sent;
+  crypto_digest_t *digest_received;
+  /** @} */
+
+  /** Certificates that a connection initiator sent us in a CERTS cell; we're
+   * holding on to them until we get an AUTHENTICATE cell.
+   */
+  or_handshake_certs_t *certs;
+};
+
+#endif
+

+ 235 - 0
src/or/origin_circuit_st.h

@@ -0,0 +1,235 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef ORIGIN_CIRCUIT_ST_H
+#define ORIGIN_CIRCUIT_ST_H
+
+#include "or.h"
+
+#include "circuit_st.h"
+
+struct onion_queue_t;
+
+/** An origin_circuit_t holds data necessary to build and use a circuit.
+ */
+struct origin_circuit_t {
+  circuit_t base_;
+
+  /** Linked list of AP streams (or EXIT streams if hidden service)
+   * associated with this circuit. */
+  edge_connection_t *p_streams;
+
+  /** Bytes read on this circuit since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_read_circ_bw;
+
+  /** Bytes written to on this circuit since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_written_circ_bw;
+
+  /** Total known-valid relay cell bytes since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_delivered_read_circ_bw;
+
+  /** Total written relay cell bytes since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_delivered_written_circ_bw;
+
+  /** Total overhead data in all known-valid relay data cells since last
+   * call to control_event_circ_bandwidth_used().  Only used if we're
+   * configured to emit CIRC_BW events. */
+  uint32_t n_overhead_read_circ_bw;
+
+  /** Total written overhead data in all relay data cells since last call to
+   * control_event_circ_bandwidth_used().  Only used if we're configured
+   * to emit CIRC_BW events. */
+  uint32_t n_overhead_written_circ_bw;
+
+  /** Build state for this circuit. It includes the intended path
+   * length, the chosen exit router, rendezvous information, etc.
+   */
+  cpath_build_state_t *build_state;
+  /** The doubly-linked list of crypt_path_t entries, one per hop,
+   * for this circuit. This includes ciphers for each hop,
+   * integrity-checking digests for each hop, and package/delivery
+   * windows for each hop.
+   */
+  crypt_path_t *cpath;
+
+  /** Holds all rendezvous data on either client or service side. */
+  rend_data_t *rend_data;
+
+  /** Holds hidden service identifier on either client or service side. This
+   * is for both introduction and rendezvous circuit. */
+  struct hs_ident_circuit_t *hs_ident;
+
+  /** Holds the data that the entry guard system uses to track the
+   * status of the guard this circuit is using, and thereby to determine
+   * whether this circuit can be used. */
+  struct circuit_guard_state_t *guard_state;
+
+  /** Index into global_origin_circuit_list for this circuit. -1 if not
+   * present. */
+  int global_origin_circuit_list_idx;
+
+  /** How many more relay_early cells can we send on this circuit, according
+   * to the specification? */
+  unsigned int remaining_relay_early_cells : 4;
+
+  /** Set if this circuit is insanely old and we already informed the user */
+  unsigned int is_ancient : 1;
+
+  /** Set if this circuit has already been opened. Used to detect
+   * cannibalized circuits. */
+  unsigned int has_opened : 1;
+
+  /**
+   * Path bias state machine. Used to ensure integrity of our
+   * circuit building and usage accounting. See path_state_t
+   * for more details.
+   */
+  path_state_bitfield_t path_state : 3;
+
+  /* If this flag is set, we should not consider attaching any more
+   * connections to this circuit. */
+  unsigned int unusable_for_new_conns : 1;
+
+  /**
+   * Tristate variable to guard against pathbias miscounting
+   * due to circuit purpose transitions changing the decision
+   * of pathbias_should_count(). This variable is informational
+   * only. The current results of pathbias_should_count() are
+   * the official decision for pathbias accounting.
+   */
+  uint8_t pathbias_shouldcount;
+#define PATHBIAS_SHOULDCOUNT_UNDECIDED 0
+#define PATHBIAS_SHOULDCOUNT_IGNORED   1
+#define PATHBIAS_SHOULDCOUNT_COUNTED   2
+
+  /** For path probing. Store the temporary probe stream ID
+   * for response comparison */
+  streamid_t pathbias_probe_id;
+
+  /** For path probing. Store the temporary probe address nonce
+   * (in host byte order) for response comparison. */
+  uint32_t pathbias_probe_nonce;
+
+  /** Set iff this is a hidden-service circuit which has timed out
+   * according to our current circuit-build timeout, but which has
+   * been kept around because it might still succeed in connecting to
+   * its destination, and which is not a fully-connected rendezvous
+   * circuit.
+   *
+   * (We clear this flag for client-side rendezvous circuits when they
+   * are 'joined' to the other side's rendezvous circuit, so that
+   * connection_ap_handshake_attach_circuit can put client streams on
+   * the circuit.  We also clear this flag for service-side rendezvous
+   * circuits when they are 'joined' to a client's rend circ, but only
+   * for symmetry with the client case.  Client-side introduction
+   * circuits are closed when we get a joined rend circ, and
+   * service-side introduction circuits never have this flag set.) */
+  unsigned int hs_circ_has_timed_out : 1;
+
+  /** Set iff this circuit has been given a relaxed timeout because
+   * no circuits have opened. Used to prevent spamming logs. */
+  unsigned int relaxed_timeout : 1;
+
+  /** Set iff this is a service-side rendezvous circuit for which a
+   * new connection attempt has been launched.  We consider launching
+   * a new service-side rend circ to a client when the previous one
+   * fails; now that we don't necessarily close a service-side rend
+   * circ when we launch a new one to the same client, this flag keeps
+   * us from launching two retries for the same failed rend circ. */
+  unsigned int hs_service_side_rend_circ_has_been_relaunched : 1;
+
+  /** What commands were sent over this circuit that decremented the
+   * RELAY_EARLY counter? This is for debugging task 878. */
+  uint8_t relay_early_commands[MAX_RELAY_EARLY_CELLS_PER_CIRCUIT];
+
+  /** How many RELAY_EARLY cells have been sent over this circuit? This is
+   * for debugging task 878, too. */
+  int relay_early_cells_sent;
+
+  /** The next stream_id that will be tried when we're attempting to
+   * construct a new AP stream originating at this circuit. */
+  streamid_t next_stream_id;
+
+  /* The intro key replaces the hidden service's public key if purpose is
+   * S_ESTABLISH_INTRO or S_INTRO, provided that no unversioned rendezvous
+   * descriptor is used. */
+  crypto_pk_t *intro_key;
+
+  /** Quasi-global identifier for this circuit; used for control.c */
+  /* XXXX NM This can get re-used after 2**32 circuits. */
+  uint32_t global_identifier;
+
+  /** True if we have associated one stream to this circuit, thereby setting
+   * the isolation parameters for this circuit.  Note that this doesn't
+   * necessarily mean that we've <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
+

+ 7 - 0
src/or/policies.c

@@ -30,6 +30,13 @@
 #include "geoip.h"
 #include "ht.h"
 
+#include "dir_server_st.h"
+#include "microdesc_st.h"
+#include "node_st.h"
+#include "port_cfg_st.h"
+#include "routerinfo_st.h"
+#include "routerstatus_st.h"
+
 /** Policy that addresses for incoming SOCKS connections must match. */
 static smartlist_t *socks_policy = NULL;
 /** Policy that addresses for incoming directory connections must match. */

+ 35 - 0
src/or/port_cfg_st.h

@@ -0,0 +1,35 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef PORT_CFG_ST_H
+#define PORT_CFG_ST_H
+
+#include "entry_port_cfg_st.h"
+#include "server_port_cfg_st.h"
+
+/** Configuration for a single port that we're listening on. */
+struct port_cfg_t {
+  tor_addr_t addr; /**< The actual IP to listen on, if !is_unix_addr. */
+  int port; /**< The configured port, or CFG_AUTO_PORT to tell Tor to pick its
+             * own port. */
+  uint8_t type; /**< One of CONN_TYPE_*_LISTENER */
+  unsigned is_unix_addr : 1; /**< True iff this is an AF_UNIX address. */
+
+  unsigned is_group_writable : 1;
+  unsigned is_world_writable : 1;
+  unsigned relax_dirmode_check : 1;
+
+  entry_port_cfg_t entry_cfg;
+
+  server_port_cfg_t server_cfg;
+
+  /* Unix sockets only: */
+  /** Path for an AF_UNIX address */
+  char unix_addr[FLEXIBLE_ARRAY_MEMBER];
+};
+
+#endif
+

+ 2 - 0
src/or/proto_cell.c

@@ -10,6 +10,8 @@
 
 #include "connection_or.h"
 
+#include "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>. */
 static inline int

+ 2 - 0
src/or/proto_socks.c

@@ -14,6 +14,8 @@
 #include "proto_socks.h"
 #include "reasons.h"
 
+#include "socks_request_st.h"
+
 static void socks_request_set_socks5_error(socks_request_t *req,
                               socks5_reply_status_t reason);
 

+ 13 - 0
src/or/relay.c

@@ -63,6 +63,7 @@
 #include "control.h"
 #include "crypto_rand.h"
 #include "crypto_util.h"
+#include "directory.h"
 #include "geoip.h"
 #include "hs_cache.h"
 #include "main.h"
@@ -81,6 +82,18 @@
 #include "scheduler.h"
 #include "rephist.h"
 
+#include "cell_st.h"
+#include "cell_queue_st.h"
+#include "cpath_build_state_st.h"
+#include "dir_connection_st.h"
+#include "destroy_cell_queue_st.h"
+#include "entry_connection_st.h"
+#include "extend_info_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+#include "routerinfo_st.h"
+#include "socks_request_st.h"
+
 static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
                                             cell_direction_t cell_direction,
                                             crypt_path_t *layer_hint);

+ 5 - 0
src/or/relay_crypto.c

@@ -5,12 +5,17 @@
 /* See LICENSE for licensing information */
 
 #include "or.h"
+#include "circuitlist.h"
 #include "config.h"
 #include "crypto_util.h"
 #include "hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN
 #include "relay.h"
 #include "relay_crypto.h"
 
+#include "cell_st.h"
+#include "or_circuit_st.h"
+#include "origin_circuit_st.h"
+
 /** Update digest from the payload of cell. Assign integrity part to
  * cell.
  */

+ 27 - 0
src/or/relay_crypto_st.h

@@ -0,0 +1,27 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef RELAY_CRYPTO_ST_H
+#define RELAY_CRYPTO_ST_H
+
+struct relay_crypto_t {
+  /* crypto environments */
+  /** Encryption key and counter for cells heading towards the OR at this
+   * step. */
+  crypto_cipher_t *f_crypto;
+  /** Encryption key and counter for cells heading back from the OR at this
+   * step. */
+  crypto_cipher_t *b_crypto;
+
+  /** Digest state for cells heading towards the OR at this step. */
+  crypto_digest_t *f_digest; /* for integrity checking */
+  /** Digest state for cells heading away from the OR at this step. */
+  crypto_digest_t *b_digest;
+
+};
+
+#endif
+

+ 18 - 0
src/or/rend_authorized_client_st.h

@@ -0,0 +1,18 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef REND_AUTHORIZED_CLIENT_ST_H
+#define REND_AUTHORIZED_CLIENT_ST_H
+
+/** Hidden-service side configuration of client authorization. */
+struct rend_authorized_client_t {
+  char *client_name;
+  uint8_t descriptor_cookie[REND_DESC_COOKIE_LEN];
+  crypto_pk_t *client_key;
+};
+
+#endif
+

Some files were not shown because too many files changed in this diff