Browse Source

Merge remote-tracking branch 'github/shrink_or_h_more'

Nick Mathewson 5 years ago
parent
commit
77e678c20d
100 changed files with 2502 additions and 2178 deletions
  1. 2 2
      src/lib/compress/compress.h
  2. 1 10
      src/lib/crypt_ops/crypto_curve25519.h
  3. 2 2
      src/lib/crypt_ops/crypto_dh.c
  4. 2 3
      src/lib/crypt_ops/crypto_dh.h
  5. 5 9
      src/lib/crypt_ops/crypto_ed25519.h
  6. 9 11
      src/lib/crypt_ops/crypto_format.h
  7. 13 0
      src/lib/defs/dh_sizes.h
  8. 4 2
      src/lib/defs/include.am
  9. 27 0
      src/lib/defs/x25519_sizes.h
  10. 46 0
      src/or/addr_policy_st.h
  11. 2 2
      src/or/addressmap.c
  12. 2 2
      src/or/bridges.h
  13. 2 1
      src/or/cell_queue_st.h
  14. 1 1
      src/or/channel.c
  15. 149 9
      src/or/channel.h
  16. 1 1
      src/or/channelpadding.c
  17. 2 1
      src/or/channeltls.c
  18. 4 2
      src/or/channeltls.h
  19. 1 2
      src/or/circpathbias.h
  20. 12 2
      src/or/circuit_st.h
  21. 9 5
      src/or/circuitbuild.h
  22. 3 1
      src/or/circuitlist.c
  23. 141 1
      src/or/circuitlist.h
  24. 1 1
      src/or/circuitmux_ewma.c
  25. 2 0
      src/or/circuitstats.c
  26. 86 1
      src/or/circuitstats.h
  27. 14 0
      src/or/config.c
  28. 15 5
      src/or/config.h
  29. 1 0
      src/or/confparse.c
  30. 5 6
      src/or/confparse.h
  31. 10 0
      src/or/connection.c
  32. 85 4
      src/or/connection.h
  33. 1 1
      src/or/connection_edge.c
  34. 48 1
      src/or/connection_edge.h
  35. 4 1
      src/or/connection_or.c
  36. 43 13
      src/or/connection_or.h
  37. 18 0
      src/or/connection_st.h
  38. 1 1
      src/or/conscache.c
  39. 4 5
      src/or/conscache.h
  40. 3 1
      src/or/consdiffmgr.c
  41. 4 3
      src/or/consdiffmgr.h
  42. 9 1
      src/or/control.c
  43. 89 2
      src/or/control.h
  44. 16 2
      src/or/crypt_path_st.h
  45. 6 1
      src/or/desc_store_st.h
  46. 3 2
      src/or/dir_connection_st.h
  47. 2 0
      src/or/dirauth/dirvote.c
  48. 3 1
      src/or/dirauth/shared_random_state.c
  49. 3 4
      src/or/dirauth/shared_random_state.h
  50. 12 1
      src/or/directory.c
  51. 82 6
      src/or/directory.h
  52. 3 0
      src/or/dirserv.c
  53. 18 2
      src/or/dirserv.h
  54. 5 1
      src/or/dns.c
  55. 1 1
      src/or/dnsserv.c
  56. 1 1
      src/or/dos.c
  57. 2 0
      src/or/entrynodes.c
  58. 2 1
      src/or/entrynodes.h
  59. 19 1
      src/or/ext_orport.h
  60. 3 1
      src/or/extend_info_st.h
  61. 58 1
      src/or/geoip.h
  62. 6 1
      src/or/hibernate.c
  63. 1 1
      src/or/hs_cache.c
  64. 13 11
      src/or/hs_cache.h
  65. 7 5
      src/or/hs_circuit.c
  66. 0 1
      src/or/hs_circuitmap.c
  67. 2 3
      src/or/hs_circuitmap.h
  68. 2 1
      src/or/hs_client.c
  69. 0 1
      src/or/hs_common.c
  70. 19 15
      src/or/hs_common.h
  71. 2 1
      src/or/hs_config.c
  72. 1 1
      src/or/hs_control.c
  73. 2 1
      src/or/hs_descriptor.c
  74. 0 4
      src/or/hs_descriptor.h
  75. 1 1
      src/or/hs_intropoint.c
  76. 2 1
      src/or/hs_ntor.c
  77. 23 21
      src/or/hs_ntor.h
  78. 11 1
      src/or/hs_service.c
  79. 4 1
      src/or/include.am
  80. 9 0
      src/or/main.c
  81. 4 3
      src/or/main.h
  82. 7 0
      src/or/microdesc.c
  83. 8 5
      src/or/microdesc_st.h
  84. 5 1
      src/or/networkstatus.c
  85. 7 1
      src/or/networkstatus_st.h
  86. 1 1
      src/or/node_st.h
  87. 9 6
      src/or/nodelist.h
  88. 1 0
      src/or/ntmain.c
  89. 3 3
      src/or/onion.c
  90. 7 4
      src/or/onion.h
  91. 1 1
      src/or/onion_fast.c
  92. 1 1
      src/or/onion_ntor.c
  93. 12 10
      src/or/onion_ntor.h
  94. 10 10
      src/or/onion_tap.c
  95. 10 8
      src/or/onion_tap.h
  96. 17 1906
      src/or/or.h
  97. 4 2
      src/or/or_connection_st.h
  98. 5 4
      src/or/or_handshake_certs_st.h
  99. 1077 0
      src/or/or_options_st.h
  100. 86 0
      src/or/or_state_st.h

+ 2 - 2
src/lib/compress/compress.h

@@ -18,7 +18,7 @@
  * GZIP_METHOD is guaranteed to be supported by the compress/uncompress
  * functions here. Call tor_compress_supports_method() to check if a given
  * compression schema is supported by Tor. */
-typedef enum {
+typedef enum compress_method_t {
   NO_METHOD=0, // This method must be first.
   GZIP_METHOD=1,
   ZLIB_METHOD=2,
@@ -32,7 +32,7 @@ typedef enum {
  * BEST_COMPRESSION saves the most bandwidth; LOW_COMPRESSION saves the most
  * memory.
  **/
-typedef enum {
+typedef enum compression_level_t {
   BEST_COMPRESSION, HIGH_COMPRESSION, MEDIUM_COMPRESSION, LOW_COMPRESSION
 } compression_level_t;
 

+ 1 - 10
src/lib/crypt_ops/crypto_curve25519.h

@@ -8,13 +8,7 @@
 #include "lib/cc/torint.h"
 #include "lib/crypt_ops/crypto_digest.h"
 #include "lib/crypt_ops/crypto_openssl_mgt.h"
-
-/** Length of a curve25519 public key when encoded. */
-#define CURVE25519_PUBKEY_LEN 32
-/** Length of a curve25519 secret key when encoded. */
-#define CURVE25519_SECKEY_LEN 32
-/** Length of the result of a curve25519 handshake. */
-#define CURVE25519_OUTPUT_LEN 32
+#include "lib/defs/x25519_sizes.h"
 
 /** Wrapper type for a curve25519 public key.
  *
@@ -75,8 +69,6 @@ STATIC int curve25519_impl(uint8_t *output, const uint8_t *secret,
 STATIC int curve25519_basepoint_impl(uint8_t *output, const uint8_t *secret);
 #endif /* defined(CRYPTO_CURVE25519_PRIVATE) */
 
-#define CURVE25519_BASE64_PADDED_LEN 44
-
 int curve25519_public_from_base64(curve25519_public_key_t *pkey,
                                   const char *input);
 int curve25519_public_to_base64(char *output,
@@ -86,4 +78,3 @@ void curve25519_set_impl_params(int use_ed);
 void curve25519_init(void);
 
 #endif /* !defined(TOR_CRYPTO_CURVE25519_H) */
-

+ 2 - 2
src/lib/crypt_ops/crypto_dh.c

@@ -344,7 +344,7 @@ crypto_dh_generate_public(crypto_dh_t *dh)
 
 /** Generate g^x as necessary, and write the g^x for the key exchange
  * as a <b>pubkey_len</b>-byte value into <b>pubkey</b>. Return 0 on
- * success, -1 on failure.  <b>pubkey_len</b> must be \>= DH_BYTES.
+ * success, -1 on failure.  <b>pubkey_len</b> must be \>= DH1024_KEY_LEN.
  */
 int
 crypto_dh_get_public(crypto_dh_t *dh, char *pubkey, size_t pubkey_len)
@@ -378,7 +378,7 @@ crypto_dh_get_public(crypto_dh_t *dh, char *pubkey, size_t pubkey_len)
   tor_assert(bytes >= 0);
   if (pubkey_len < (size_t)bytes) {
     log_warn(LD_CRYPTO,
-             "Weird! pubkey_len (%d) was smaller than DH_BYTES (%d)",
+             "Weird! pubkey_len (%d) was smaller than DH1024_KEY_LEN (%d)",
              (int) pubkey_len, bytes);
     return -1;
   }

+ 2 - 3
src/lib/crypt_ops/crypto_dh.h

@@ -14,9 +14,8 @@
 #define TOR_CRYPTO_DH_H
 
 #include "orconfig.h"
-
-/** Length of our DH keys. */
-#define DH_BYTES (1024/8)
+#include "lib/cc/torint.h"
+#include "lib/defs/dh_sizes.h"
 
 typedef struct crypto_dh_t crypto_dh_t;
 

+ 5 - 9
src/lib/crypt_ops/crypto_ed25519.h

@@ -7,24 +7,20 @@
 #include "lib/testsupport/testsupport.h"
 #include "lib/cc/torint.h"
 #include "lib/crypt_ops/crypto_curve25519.h"
-
-#define ED25519_PUBKEY_LEN 32
-#define ED25519_SECKEY_LEN 64
-#define ED25519_SECKEY_SEED_LEN 32
-#define ED25519_SIG_LEN 64
+#include "lib/defs/x25519_sizes.h"
 
 /** An Ed25519 signature. */
-typedef struct {
+typedef struct ed25519_signature_t {
   uint8_t sig[ED25519_SIG_LEN];
 } ed25519_signature_t;
 
 /** An Ed25519 public key */
-typedef struct {
+typedef struct ed25519_public_key_t {
   uint8_t pubkey[ED25519_PUBKEY_LEN];
 } ed25519_public_key_t;
 
 /** An Ed25519 secret key */
-typedef struct {
+typedef struct ed25519_secret_key_t {
   /** Note that we store secret keys in an expanded format that doesn't match
    * the format from standard ed25519.  Ed25519 stores a 32-byte value k and
    * expands it into a 64-byte H(k), using the first 32 bytes for a multiplier
@@ -35,7 +31,7 @@ typedef struct {
 } ed25519_secret_key_t;
 
 /** An Ed25519 keypair. */
-typedef struct {
+typedef struct ed25519_keypair_t {
   ed25519_public_key_t pubkey;
   ed25519_secret_key_t seckey;
 } ed25519_keypair_t;

+ 9 - 11
src/lib/crypt_ops/crypto_format.h

@@ -9,7 +9,10 @@
 
 #include "lib/testsupport/testsupport.h"
 #include "lib/cc/torint.h"
-#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/defs/x25519_sizes.h"
+
+struct ed25519_public_key_t;
+struct ed25519_signature_t;
 
 int crypto_write_tagged_contents_to_file(const char *fname,
                                          const char *typestring,
@@ -23,20 +26,16 @@ ssize_t crypto_read_tagged_contents_from_file(const char *fname,
                                               uint8_t *data_out,
                                               ssize_t data_out_len);
 
-#define ED25519_BASE64_LEN 43
-int ed25519_public_from_base64(ed25519_public_key_t *pkey,
+int ed25519_public_from_base64(struct ed25519_public_key_t *pkey,
                                const char *input);
 int ed25519_public_to_base64(char *output,
-                             const ed25519_public_key_t *pkey);
-const char *ed25519_fmt(const ed25519_public_key_t *pkey);
-
-/* XXXX move these to crypto_format.h */
-#define ED25519_SIG_BASE64_LEN 86
+                             const struct ed25519_public_key_t *pkey);
+const char *ed25519_fmt(const struct ed25519_public_key_t *pkey);
 
-int ed25519_signature_from_base64(ed25519_signature_t *sig,
+int ed25519_signature_from_base64(struct ed25519_signature_t *sig,
                                   const char *input);
 int ed25519_signature_to_base64(char *output,
-                                const ed25519_signature_t *sig);
+                                const struct ed25519_signature_t *sig);
 
 int digest_to_base64(char *d64, const char *digest);
 int digest_from_base64(char *digest, const char *d64);
@@ -44,4 +43,3 @@ int digest256_to_base64(char *d64, const char *digest);
 int digest256_from_base64(char *digest, const char *d64);
 
 #endif /* !defined(TOR_CRYPTO_FORMAT_H) */
-

+ 13 - 0
src/lib/defs/dh_sizes.h

@@ -0,0 +1,13 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_DH_SIZES_H
+#define TOR_DH_SIZES_H
+
+/** Length of our legacy DH keys. */
+#define DH1024_KEY_LEN (1024/8)
+
+#endif

+ 4 - 2
src/lib/defs/include.am

@@ -1,3 +1,5 @@
 
-noinst_HEADERS += \
-	src/lib/defs/digest_sizes.h
+noinst_HEADERS += 			\
+	src/lib/defs/dh_sizes.h 	\
+	src/lib/defs/digest_sizes.h	\
+	src/lib/defs/x25519_sizes.h

+ 27 - 0
src/lib/defs/x25519_sizes.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 TOR_X25519_SIZES_H
+#define TOR_X25519_SIZES_H
+
+/** Length of a curve25519 public key when encoded. */
+#define CURVE25519_PUBKEY_LEN 32
+/** Length of a curve25519 secret key when encoded. */
+#define CURVE25519_SECKEY_LEN 32
+/** Length of the result of a curve25519 handshake. */
+#define CURVE25519_OUTPUT_LEN 32
+
+#define ED25519_PUBKEY_LEN 32
+#define ED25519_SECKEY_LEN 64
+#define ED25519_SECKEY_SEED_LEN 32
+#define ED25519_SIG_LEN 64
+
+#define CURVE25519_BASE64_PADDED_LEN 44
+
+#define ED25519_BASE64_LEN 43
+#define ED25519_SIG_BASE64_LEN 86
+
+#endif

+ 46 - 0
src/or/addr_policy_st.h

@@ -0,0 +1,46 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_ADDR_POLICY_ST_H
+#define TOR_ADDR_POLICY_ST_H
+
+#include "lib/cc/torint.h"
+#include "lib/net/address.h"
+
+/** What action type does an address policy indicate: accept or reject? */
+typedef enum {
+  ADDR_POLICY_ACCEPT=1,
+  ADDR_POLICY_REJECT=2,
+} addr_policy_action_t;
+#define addr_policy_action_bitfield_t ENUM_BF(addr_policy_action_t)
+
+/** A reference-counted address policy rule. */
+typedef struct addr_policy_t {
+  int refcnt; /**< Reference count */
+  /** What to do when the policy matches.*/
+  addr_policy_action_bitfield_t policy_type:2;
+  unsigned int is_private:1; /**< True iff this is the pseudo-address,
+                              * "private". */
+  unsigned int is_canonical:1; /**< True iff this policy is the canonical
+                                * copy (stored in a hash table to avoid
+                                * duplication of common policies) */
+  maskbits_t maskbits; /**< Accept/reject all addresses <b>a</b> such that the
+                 * first <b>maskbits</b> bits of <b>a</b> match
+                 * <b>addr</b>. */
+  /** Base address to accept or reject.
+   *
+   * Note that wildcards are treated
+   * differntly depending on address family. An AF_UNSPEC address means
+   * "All addresses, IPv4 or IPv6." An AF_INET address with maskbits==0 means
+   * "All IPv4 addresses" and an AF_INET6 address with maskbits == 0 means
+   * "All IPv6 addresses".
+  **/
+  tor_addr_t addr;
+  uint16_t prt_min; /**< Lowest port number to accept/reject. */
+  uint16_t prt_max; /**< Highest port number to accept/reject. */
+} addr_policy_t;
+
+#endif

+ 2 - 2
src/or/addressmap.c

@@ -15,13 +15,14 @@
 
 #define ADDRESSMAP_PRIVATE
 
+#include "lib/crypt_ops/crypto_rand.h"
+
 #include "or/or.h"
 #include "or/addressmap.h"
 #include "or/circuituse.h"
 #include "or/config.h"
 #include "or/connection_edge.h"
 #include "or/control.h"
-#include "lib/crypt_ops/crypto_rand.h"
 #include "or/dns.h"
 #include "or/nodelist.h"
 #include "or/routerset.h"
@@ -1153,4 +1154,3 @@ addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
      iter = strmap_iter_next(addressmap,iter);
    }
 }
-

+ 2 - 2
src/or/bridges.h

@@ -13,6 +13,7 @@
 #define TOR_BRIDGES_H
 
 struct bridge_line_t;
+struct ed25519_public_key_t;
 
 /* Opaque handle to a configured bridge */
 typedef struct bridge_info_t bridge_info_t;
@@ -38,7 +39,7 @@ int routerinfo_is_a_configured_bridge(const routerinfo_t *ri);
 int node_is_a_configured_bridge(const node_t *node);
 void learned_router_identity(const tor_addr_t *addr, uint16_t port,
                              const char *digest,
-                             const ed25519_public_key_t *ed_id);
+                             const struct ed25519_public_key_t *ed_id);
 
 void bridge_add_from_config(struct bridge_line_t *bridge_line);
 void retry_bridge_descriptor_fetch_directly(const char *digest);
@@ -77,4 +78,3 @@ STATIC void bridge_resolve_conflicts(const tor_addr_t *addr,
 #endif /* defined(TOR_BRIDGES_PRIVATE) */
 
 #endif /* !defined(TOR_BRIDGES_H) */
-

+ 2 - 1
src/or/cell_queue_st.h

@@ -7,6 +7,8 @@
 #ifndef PACKED_CELL_ST_H
 #define PACKED_CELL_ST_H
 
+#include "tor_queue.h"
+
 /** A cell as packed for writing to the network. */
 struct packed_cell_t {
   /** Next cell queued on this circuit. */
@@ -25,4 +27,3 @@ struct cell_queue_t {
 };
 
 #endif
-

+ 1 - 1
src/or/channel.c

@@ -79,6 +79,7 @@
 #include "lib/time/compat_time.h"
 #include "or/networkstatus.h"
 #include "or/rendservice.h"
+#include "common/timers.h"
 
 #include "or/cell_queue_st.h"
 
@@ -3477,4 +3478,3 @@ channel_update_bad_for_new_circs(const char *digest, int force)
     channel_rsa_id_group_set_badness(&(*iter)->channel_list, force);
   }
 }
-

+ 149 - 9
src/or/channel.h

@@ -11,8 +11,13 @@
 
 #include "or/or.h"
 #include "or/circuitmux.h"
-#include "common/timers.h"
 #include "common/handles.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+
+#include "tor_queue.h"
+
+#define tor_timer_t timeout
+struct tor_timer_t;
 
 /* Channel handler function pointer typedefs */
 typedef void (*channel_listener_fn_ptr)(channel_listener_t *, channel_t *);
@@ -30,6 +35,141 @@ typedef enum {
     CHANNEL_USED_FOR_USER_TRAFFIC,
 } channel_usage_info_t;
 
+/** Possible rules for generating circuit IDs on an OR connection. */
+typedef enum {
+  CIRC_ID_TYPE_LOWER=0, /**< Pick from 0..1<<15-1. */
+  CIRC_ID_TYPE_HIGHER=1, /**< Pick from 1<<15..1<<16-1. */
+  /** The other side of a connection is an OP: never create circuits to it,
+   * and let it use any circuit ID it wants. */
+  CIRC_ID_TYPE_NEITHER=2
+} circ_id_type_t;
+#define circ_id_type_bitfield_t ENUM_BF(circ_id_type_t)
+
+/* channel states for channel_t */
+
+typedef enum {
+  /*
+   * Closed state - channel is inactive
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_CLOSING
+   * Permitted transitions to:
+   *   - CHANNEL_STATE_OPENING
+   */
+  CHANNEL_STATE_CLOSED = 0,
+  /*
+   * Opening state - channel is trying to connect
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_CLOSED
+   * Permitted transitions to:
+   *   - CHANNEL_STATE_CLOSING
+   *   - CHANNEL_STATE_ERROR
+   *   - CHANNEL_STATE_OPEN
+   */
+  CHANNEL_STATE_OPENING,
+  /*
+   * Open state - channel is active and ready for use
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_MAINT
+   *   - CHANNEL_STATE_OPENING
+   * Permitted transitions to:
+   *   - CHANNEL_STATE_CLOSING
+   *   - CHANNEL_STATE_ERROR
+   *   - CHANNEL_STATE_MAINT
+   */
+  CHANNEL_STATE_OPEN,
+  /*
+   * Maintenance state - channel is temporarily offline for subclass specific
+   *   maintenance activities such as TLS renegotiation.
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_OPEN
+   * Permitted transitions to:
+   *   - CHANNEL_STATE_CLOSING
+   *   - CHANNEL_STATE_ERROR
+   *   - CHANNEL_STATE_OPEN
+   */
+  CHANNEL_STATE_MAINT,
+  /*
+   * Closing state - channel is shutting down
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_MAINT
+   *   - CHANNEL_STATE_OPEN
+   * Permitted transitions to:
+   *   - CHANNEL_STATE_CLOSED,
+   *   - CHANNEL_STATE_ERROR
+   */
+  CHANNEL_STATE_CLOSING,
+  /*
+   * Error state - channel has experienced a permanent error
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_CLOSING
+   *   - CHANNEL_STATE_MAINT
+   *   - CHANNEL_STATE_OPENING
+   *   - CHANNEL_STATE_OPEN
+   * Permitted transitions to:
+   *   - None
+   */
+  CHANNEL_STATE_ERROR,
+  /*
+   * Placeholder for maximum state value
+   */
+  CHANNEL_STATE_LAST
+} channel_state_t;
+
+/* channel listener states for channel_listener_t */
+
+typedef enum {
+  /*
+   * Closed state - channel listener is inactive
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_LISTENER_STATE_CLOSING
+   * Permitted transitions to:
+   *   - CHANNEL_LISTENER_STATE_LISTENING
+   */
+  CHANNEL_LISTENER_STATE_CLOSED = 0,
+  /*
+   * Listening state - channel listener is listening for incoming
+   * connections
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_LISTENER_STATE_CLOSED
+   * Permitted transitions to:
+   *   - CHANNEL_LISTENER_STATE_CLOSING
+   *   - CHANNEL_LISTENER_STATE_ERROR
+   */
+  CHANNEL_LISTENER_STATE_LISTENING,
+  /*
+   * Closing state - channel listener is shutting down
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_LISTENER_STATE_LISTENING
+   * Permitted transitions to:
+   *   - CHANNEL_LISTENER_STATE_CLOSED,
+   *   - CHANNEL_LISTENER_STATE_ERROR
+   */
+  CHANNEL_LISTENER_STATE_CLOSING,
+  /*
+   * Error state - channel listener has experienced a permanent error
+   *
+   * Permitted transitions from:
+   *   - CHANNEL_STATE_CLOSING
+   *   - CHANNEL_STATE_LISTENING
+   * Permitted transitions to:
+   *   - None
+   */
+  CHANNEL_LISTENER_STATE_ERROR,
+  /*
+   * Placeholder for maximum state value
+   */
+  CHANNEL_LISTENER_STATE_LAST
+} channel_listener_state_t;
+
 /**
  * Channel struct; see the channel_t typedef in or.h.  A channel is an
  * abstract interface for the OR-to-OR connection, similar to connection_or_t,
@@ -92,7 +232,7 @@ struct channel_s {
   monotime_coarse_t next_padding_time;
 
   /** The callback pointer for the padding callbacks */
-  tor_timer_t *padding_timer;
+  struct tor_timer_t *padding_timer;
   /** The handle to this channel (to free on canceled timers) */
   struct channel_handle_t *timer_handle;
 
@@ -251,7 +391,7 @@ struct channel_s {
    * necessarily its true identity.  Don't believe this identity unless
    * authentication has happened.
    */
-  ed25519_public_key_t ed25519_identity;
+  struct ed25519_public_key_t ed25519_identity;
 
   /**
    * Linked list of channels with the same RSA identity digest, for use with
@@ -470,8 +610,8 @@ void channel_mark_incoming(channel_t *chan);
 void channel_mark_outgoing(channel_t *chan);
 void channel_mark_remote(channel_t *chan);
 void channel_set_identity_digest(channel_t *chan,
-                                 const char *identity_digest,
-                                 const ed25519_public_key_t *ed_identity);
+                             const char *identity_digest,
+                             const struct ed25519_public_key_t *ed_identity);
 
 void channel_listener_change_state(channel_listener_t *chan_l,
                                    channel_listener_state_t to_state);
@@ -521,10 +661,10 @@ int channel_send_destroy(circid_t circ_id, channel_t *chan,
 
 channel_t * channel_connect(const tor_addr_t *addr, uint16_t port,
                             const char *rsa_id_digest,
-                            const ed25519_public_key_t *ed_id);
+                            const struct ed25519_public_key_t *ed_id);
 
 channel_t * channel_get_for_extend(const char *rsa_id_digest,
-                                   const ed25519_public_key_t *ed_id,
+                                   const struct ed25519_public_key_t *ed_id,
                                    const tor_addr_t *target_addr,
                                    const char **msg_out,
                                    int *launch_out);
@@ -537,7 +677,7 @@ int channel_is_better(channel_t *a, channel_t *b);
 
 channel_t * channel_find_by_global_id(uint64_t global_identifier);
 channel_t * channel_find_by_remote_identity(const char *rsa_id_digest,
-                                            const ed25519_public_key_t *ed_id);
+                                    const struct ed25519_public_key_t *ed_id);
 
 /** For things returned by channel_find_by_remote_digest(), walk the list.
  * The RSA key will match for all returned elements; the Ed25519 key might not.
@@ -635,6 +775,6 @@ int packed_cell_is_destroy(channel_t *chan,
 HANDLE_DECL(channel, channel_s,)
 #define channel_handle_free(h)    \
   FREE_AND_NULL(channel_handle_t, channel_handle_free_, (h))
+#undef tor_timer_t
 
 #endif /* !defined(TOR_CHANNEL_H) */
-

+ 1 - 1
src/or/channelpadding.c

@@ -22,6 +22,7 @@
 #include "or/router.h"
 #include "lib/time/compat_time.h"
 #include "or/rendservice.h"
+#include "common/timers.h"
 
 #include "or/cell_st.h"
 #include "or/or_connection_st.h"
@@ -797,4 +798,3 @@ channelpadding_decide_to_pad_channel(channel_t *chan)
     return CHANNELPADDING_PADLATER;
   }
 }
-

+ 2 - 1
src/or/channeltls.c

@@ -69,6 +69,8 @@
 #include "or/routerinfo_st.h"
 #include "or/var_cell_st.h"
 
+#include "lib/tls/tortls.h"
+
 /** How many CELL_PADDING cells have we received, ever? */
 uint64_t stats_n_padding_cells_processed = 0;
 /** How many CELL_VERSIONS cells have we received, ever? */
@@ -2454,4 +2456,3 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
 
 #undef ERR
 }
-

+ 4 - 2
src/or/channeltls.h

@@ -12,6 +12,9 @@
 #include "or/or.h"
 #include "or/channel.h"
 
+struct ed25519_public_key_t;
+struct curve25519_public_key_t;
+
 #define BASE_CHAN_TO_TLS(c) (channel_tls_from_base((c)))
 #define TLS_CHAN_TO_BASE(c) (channel_tls_to_base((c)))
 
@@ -30,7 +33,7 @@ struct channel_tls_s {
 
 channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port,
                                 const char *id_digest,
-                                const ed25519_public_key_t *ed_id);
+                                const struct ed25519_public_key_t *ed_id);
 channel_listener_t * channel_tls_get_listener(void);
 channel_listener_t * channel_tls_start_listener(void);
 channel_t * channel_tls_handle_incoming(or_connection_t *orconn);
@@ -72,4 +75,3 @@ STATIC void channel_tls_process_authenticate_cell(var_cell_t *cell,
 #endif /* defined(CHANNELTLS_PRIVATE) */
 
 #endif /* !defined(TOR_CHANNELTLS_H) */
-

+ 1 - 2
src/or/circpathbias.h

@@ -23,7 +23,6 @@ int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell);
 void pathbias_count_use_attempt(origin_circuit_t *circ);
 void pathbias_mark_use_success(origin_circuit_t *circ);
 void pathbias_mark_use_rollback(origin_circuit_t *circ);
-const char *pathbias_state_to_string(path_state_t state);
+const char *pathbias_state_to_string(enum path_state_t state);
 
 #endif /* !defined(TOR_CIRCPATHBIAS_H) */
-

+ 12 - 2
src/or/circuit_st.h

@@ -11,6 +11,17 @@
 
 #include "or/cell_queue_st.h"
 
+struct hs_token_t;
+
+/** "magic" value for an origin_circuit_t */
+#define ORIGIN_CIRCUIT_MAGIC 0x35315243u
+/** "magic" value for an or_circuit_t */
+#define OR_CIRCUIT_MAGIC 0x98ABC04Fu
+/** "magic" value for a circuit that would have been freed by circuit_free,
+ * but which we're keeping around until a cpuworker reply arrives.  See
+ * circuit_free() for more documentation. */
+#define DEAD_CIRCUIT_MAGIC 0xdeadc14c
+
 /**
  * A circuit is a path over the onion routing
  * network. Applications can connect to one end of the circuit, and can
@@ -162,11 +173,10 @@ struct circuit_t {
 
   /** If set, points to an HS token that this circuit might be carrying.
    *  Used by the HS circuitmap.  */
-  hs_token_t *hs_token;
+  struct hs_token_t *hs_token;
   /** Hashtable node: used to look up the circuit by its HS token using the HS
       circuitmap. */
   HT_ENTRY(circuit_t) hs_circuitmap_node;
 };
 
 #endif
-

+ 9 - 5
src/or/circuitbuild.h

@@ -12,6 +12,9 @@
 #ifndef TOR_CIRCUITBUILD_H
 #define TOR_CIRCUITBUILD_H
 
+struct ed25519_public_key_t;
+struct curve25519_public_key_t;
+
 int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei);
 char *circuit_list_path(origin_circuit_t *circ, int verbose);
 char *circuit_list_path_for_controller(origin_circuit_t *circ);
@@ -52,9 +55,9 @@ int circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *info);
 void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
 extend_info_t *extend_info_new(const char *nickname,
                                const char *rsa_id_digest,
-                               const ed25519_public_key_t *ed_id,
+                               const struct ed25519_public_key_t *ed_id,
                                crypto_pk_t *onion_key,
-                               const curve25519_public_key_t *ntor_key,
+                               const struct curve25519_public_key_t *ntor_key,
                                const tor_addr_t *addr, uint16_t port);
 extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
 extend_info_t *extend_info_dup(extend_info_t *info);
@@ -91,8 +94,10 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei,
                       int is_hs_v3_rp_circuit);
 
 #if defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS)
-STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags,
-                                                  const or_options_t *options);
+enum router_crn_flags_t;
+STATIC const node_t *pick_tor2web_rendezvous_node(
+                                     enum router_crn_flags_t flags,
+                                     const or_options_t *options);
 unsigned int cpath_get_n_hops(crypt_path_t **head_ptr);
 
 #endif /* defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS) */
@@ -100,4 +105,3 @@ unsigned int cpath_get_n_hops(crypt_path_t **head_ptr);
 #endif /* defined(CIRCUITBUILD_PRIVATE) */
 
 #endif /* !defined(TOR_CIRCUITBUILD_H) */
-

+ 3 - 1
src/or/circuitlist.c

@@ -67,6 +67,7 @@
 #include "or/control.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
+#include "lib/crypt_ops/crypto_dh.h"
 #include "or/directory.h"
 #include "or/entrynodes.h"
 #include "or/main.h"
@@ -86,9 +87,11 @@
 #include "or/routerlist.h"
 #include "or/routerset.h"
 #include "or/channelpadding.h"
+#include "lib/compress/compress.h"
 #include "lib/compress/compress_lzma.h"
 #include "lib/compress/compress_zlib.h"
 #include "lib/compress/compress_zstd.h"
+#include "lib/container/buffers.h"
 
 #include "ht.h"
 
@@ -2737,4 +2740,3 @@ assert_circuit_ok,(const circuit_t *c))
     tor_assert(!or_circ || !or_circ->rend_splice);
   }
 }
-

+ 141 - 1
src/or/circuitlist.h

@@ -15,6 +15,147 @@
 #include "lib/testsupport/testsupport.h"
 #include "or/hs_ident.h"
 
+/** Circuit state: I'm the origin, still haven't done all my handshakes. */
+#define CIRCUIT_STATE_BUILDING 0
+/** Circuit state: Waiting to process the onionskin. */
+#define CIRCUIT_STATE_ONIONSKIN_PENDING 1
+/** Circuit state: I'd like to deliver a create, but my n_chan is still
+ * connecting. */
+#define CIRCUIT_STATE_CHAN_WAIT 2
+/** Circuit state: the circuit is open but we don't want to actually use it
+ * until we find out if a better guard will be available.
+ */
+#define CIRCUIT_STATE_GUARD_WAIT 3
+/** Circuit state: onionskin(s) processed, ready to send/receive cells. */
+#define CIRCUIT_STATE_OPEN 4
+
+#define CIRCUIT_PURPOSE_MIN_ 1
+
+/* these circuits were initiated elsewhere */
+#define CIRCUIT_PURPOSE_OR_MIN_ 1
+/** OR-side circuit purpose: normal circuit, at OR. */
+#define CIRCUIT_PURPOSE_OR 1
+/** OR-side circuit purpose: At OR, from the service, waiting for intro from
+ * clients. */
+#define CIRCUIT_PURPOSE_INTRO_POINT 2
+/** OR-side circuit purpose: At OR, from the client, waiting for the service.
+ */
+#define CIRCUIT_PURPOSE_REND_POINT_WAITING 3
+/** OR-side circuit purpose: At OR, both circuits have this purpose. */
+#define CIRCUIT_PURPOSE_REND_ESTABLISHED 4
+#define CIRCUIT_PURPOSE_OR_MAX_ 4
+
+/* these circuits originate at this node */
+
+/* here's how circ client-side purposes work:
+ *   normal circuits are C_GENERAL.
+ *   circuits that are c_introducing are either on their way to
+ *     becoming open, or they are open and waiting for a
+ *     suitable rendcirc before they send the intro.
+ *   circuits that are c_introduce_ack_wait have sent the intro,
+ *     but haven't gotten a response yet.
+ *   circuits that are c_establish_rend are either on their way
+ *     to becoming open, or they are open and have sent the
+ *     establish_rendezvous cell but haven't received an ack.
+ *   circuits that are c_rend_ready are open and have received a
+ *     rend ack, but haven't heard from the service yet. if they have a
+ *     buildstate->pending_final_cpath then they're expecting a
+ *     cell from the service, else they're not.
+ *   circuits that are c_rend_ready_intro_acked are open, and
+ *     some intro circ has sent its intro and received an ack.
+ *   circuits that are c_rend_joined are open, have heard from
+ *     the service, and are talking to it.
+ */
+/** Client-side circuit purpose: Normal circuit, with cpath. */
+#define CIRCUIT_PURPOSE_C_GENERAL 5
+#define CIRCUIT_PURPOSE_C_HS_MIN_ 6
+/** Client-side circuit purpose: at the client, connecting to intro point. */
+#define CIRCUIT_PURPOSE_C_INTRODUCING 6
+/** Client-side circuit purpose: at the client, sent INTRODUCE1 to intro point,
+ * waiting for ACK/NAK. */
+#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7
+/** Client-side circuit purpose: at the client, introduced and acked, closing.
+ */
+#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED 8
+/** Client-side circuit purpose: at the client, waiting for ack. */
+#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 9
+/** Client-side circuit purpose: at the client, waiting for the service. */
+#define CIRCUIT_PURPOSE_C_REND_READY 10
+/** Client-side circuit purpose: at the client, waiting for the service,
+ * INTRODUCE has been acknowledged. */
+#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED 11
+/** Client-side circuit purpose: at the client, rendezvous established. */
+#define CIRCUIT_PURPOSE_C_REND_JOINED 12
+/** This circuit is used for getting hsdirs */
+#define CIRCUIT_PURPOSE_C_HSDIR_GET 13
+#define CIRCUIT_PURPOSE_C_HS_MAX_ 13
+/** This circuit is used for build time measurement only */
+#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT 14
+#define CIRCUIT_PURPOSE_C_MAX_ 14
+
+#define CIRCUIT_PURPOSE_S_HS_MIN_ 15
+/** Hidden-service-side circuit purpose: at the service, waiting for
+ * introductions. */
+#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 15
+/** Hidden-service-side circuit purpose: at the service, successfully
+ * established intro. */
+#define CIRCUIT_PURPOSE_S_INTRO 16
+/** Hidden-service-side circuit purpose: at the service, connecting to rend
+ * point. */
+#define CIRCUIT_PURPOSE_S_CONNECT_REND 17
+/** Hidden-service-side circuit purpose: at the service, rendezvous
+ * established. */
+#define CIRCUIT_PURPOSE_S_REND_JOINED 18
+/** This circuit is used for uploading hsdirs */
+#define CIRCUIT_PURPOSE_S_HSDIR_POST 19
+#define CIRCUIT_PURPOSE_S_HS_MAX_ 19
+
+/** A testing circuit; not meant to be used for actual traffic. */
+#define CIRCUIT_PURPOSE_TESTING 20
+/** A controller made this circuit and Tor should not use it. */
+#define CIRCUIT_PURPOSE_CONTROLLER 21
+/** This circuit is used for path bias probing only */
+#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING 22
+
+/** This circuit is used for vanguards/restricted paths.
+ *
+ *  This type of circuit is *only* created preemptively and never
+ *  on-demand. When an HS operation needs to take place (e.g. connect to an
+ *  intro point), these circuits are then cannibalized and repurposed to the
+ *  actual needed HS purpose. */
+#define CIRCUIT_PURPOSE_HS_VANGUARDS 23
+
+#define CIRCUIT_PURPOSE_MAX_ 23
+/** A catch-all for unrecognized purposes. Currently we don't expect
+ * to make or see any circuits with this purpose. */
+#define CIRCUIT_PURPOSE_UNKNOWN 255
+
+/** True iff the circuit purpose <b>p</b> is for a circuit that
+ * originated at this node. */
+#define CIRCUIT_PURPOSE_IS_ORIGIN(p) ((p)>CIRCUIT_PURPOSE_OR_MAX_)
+/** True iff the circuit purpose <b>p</b> is for a circuit that originated
+ * here to serve as a client.  (Hidden services don't count here.) */
+#define CIRCUIT_PURPOSE_IS_CLIENT(p)  \
+  ((p)> CIRCUIT_PURPOSE_OR_MAX_ &&    \
+   (p)<=CIRCUIT_PURPOSE_C_MAX_)
+/** True iff the circuit_t <b>c</b> is actually an origin_circuit_t. */
+#define CIRCUIT_IS_ORIGIN(c) (CIRCUIT_PURPOSE_IS_ORIGIN((c)->purpose))
+/** True iff the circuit purpose <b>p</b> is for an established rendezvous
+ * circuit. */
+#define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \
+  ((p) == CIRCUIT_PURPOSE_C_REND_JOINED ||     \
+   (p) == CIRCUIT_PURPOSE_S_REND_JOINED)
+/** True iff the circuit_t c is actually an or_circuit_t */
+#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC)
+
+/** True iff this circuit purpose should count towards the global
+ * pending rate limit (set by MaxClientCircuitsPending). We count all
+ * general purpose circuits, as well as the first step of client onion
+ * service connections (HSDir gets). */
+#define CIRCUIT_PURPOSE_COUNTS_TOWARDS_MAXPENDING(p) \
+    ((p) == CIRCUIT_PURPOSE_C_GENERAL || \
+     (p) == CIRCUIT_PURPOSE_C_HSDIR_GET)
+
 /** Convert a circuit_t* to a pointer to the enclosing or_circuit_t.  Assert
  * if the cast is impossible. */
 or_circuit_t *TO_OR_CIRCUIT(circuit_t *);
@@ -104,4 +245,3 @@ STATIC uint32_t circuit_max_queued_item_age(const circuit_t *c, uint32_t now);
 #endif /* defined(CIRCUITLIST_PRIVATE) */
 
 #endif /* !defined(TOR_CIRCUITLIST_H) */
-

+ 1 - 1
src/or/circuitmux_ewma.c

@@ -39,6 +39,7 @@
 #include "or/circuitmux_ewma.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "or/networkstatus.h"
+#include "or/or_options_st.h"
 
 /*** EWMA parameter #defines ***/
 
@@ -826,4 +827,3 @@ circuitmux_ewma_free_all(void)
 {
   ewma_ticks_initialized = 0;
 }
-

+ 2 - 0
src/or/circuitstats.c

@@ -42,9 +42,11 @@
 #include "or/circuituse.h"
 #include "lib/math/fp.h"
 #include "lib/time/tvdiff.h"
+#include "lib/encoding/confline.h"
 
 #include "or/crypt_path_st.h"
 #include "or/origin_circuit_st.h"
+#include "or/or_state_st.h"
 
 #undef log
 #include <math.h>

+ 86 - 1
src/or/circuitstats.h

@@ -21,6 +21,9 @@ int circuit_build_times_disabled(const or_options_t *options);
 int circuit_build_times_disabled_(const or_options_t *options,
                                   int ignore_consensus);
 
+/** A build_time_t is milliseconds */
+typedef uint32_t build_time_t;
+
 int circuit_build_times_enough_to_compute(const circuit_build_times_t *cbt);
 void circuit_build_times_update_state(const circuit_build_times_t *cbt,
                                       or_state_t *state);
@@ -47,6 +50,89 @@ double circuit_build_times_close_rate(const circuit_build_times_t *cbt);
 void circuit_build_times_update_last_circ(circuit_build_times_t *cbt);
 void circuit_build_times_mark_circ_as_measurement_only(origin_circuit_t *circ);
 
+/** Total size of the circuit timeout history to accumulate.
+ * 1000 is approx 2.5 days worth of continual-use circuits. */
+#define CBT_NCIRCUITS_TO_OBSERVE 1000
+
+/** Width of the histogram bins in milliseconds */
+#define CBT_BIN_WIDTH ((build_time_t)50)
+
+/** Number of modes to use in the weighted-avg computation of Xm */
+#define CBT_DEFAULT_NUM_XM_MODES 3
+#define CBT_MIN_NUM_XM_MODES 1
+#define CBT_MAX_NUM_XM_MODES 20
+
+/**
+ * CBT_BUILD_ABANDONED is our flag value to represent a force-closed
+ * circuit (Aka a 'right-censored' pareto value).
+ */
+#define CBT_BUILD_ABANDONED ((build_time_t)(INT32_MAX-1))
+#define CBT_BUILD_TIME_MAX ((build_time_t)(INT32_MAX))
+
+/** Save state every 10 circuits */
+#define CBT_SAVE_STATE_EVERY 10
+
+/* Circuit build times consensus parameters */
+
+/**
+ * How long to wait before actually closing circuits that take too long to
+ * build in terms of CDF quantile.
+ */
+#define CBT_DEFAULT_CLOSE_QUANTILE 95
+#define CBT_MIN_CLOSE_QUANTILE CBT_MIN_QUANTILE_CUTOFF
+#define CBT_MAX_CLOSE_QUANTILE CBT_MAX_QUANTILE_CUTOFF
+
+/**
+ * How many circuits count as recent when considering if the
+ * connection has gone gimpy or changed.
+ */
+#define CBT_DEFAULT_RECENT_CIRCUITS 20
+#define CBT_MIN_RECENT_CIRCUITS 3
+#define CBT_MAX_RECENT_CIRCUITS 1000
+
+/**
+ * Maximum count of timeouts that finish the first hop in the past
+ * RECENT_CIRCUITS before calculating a new timeout.
+ *
+ * This tells us whether to abandon timeout history and set
+ * the timeout back to whatever circuit_build_times_get_initial_timeout()
+ * gives us.
+ */
+#define CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT (CBT_DEFAULT_RECENT_CIRCUITS*9/10)
+#define CBT_MIN_MAX_RECENT_TIMEOUT_COUNT 3
+#define CBT_MAX_MAX_RECENT_TIMEOUT_COUNT 10000
+
+/** Minimum circuits before estimating a timeout */
+#define CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE 100
+#define CBT_MIN_MIN_CIRCUITS_TO_OBSERVE 1
+#define CBT_MAX_MIN_CIRCUITS_TO_OBSERVE 10000
+
+/** Cutoff percentile on the CDF for our timeout estimation. */
+#define CBT_DEFAULT_QUANTILE_CUTOFF 80
+#define CBT_MIN_QUANTILE_CUTOFF 10
+#define CBT_MAX_QUANTILE_CUTOFF 99
+double circuit_build_times_quantile_cutoff(void);
+
+/** How often in seconds should we build a test circuit */
+#define CBT_DEFAULT_TEST_FREQUENCY 10
+#define CBT_MIN_TEST_FREQUENCY 1
+#define CBT_MAX_TEST_FREQUENCY INT32_MAX
+
+/** Lowest allowable value for CircuitBuildTimeout in milliseconds */
+#define CBT_DEFAULT_TIMEOUT_MIN_VALUE (1500)
+#define CBT_MIN_TIMEOUT_MIN_VALUE 500
+#define CBT_MAX_TIMEOUT_MIN_VALUE INT32_MAX
+
+/** Initial circuit build timeout in milliseconds */
+#define CBT_DEFAULT_TIMEOUT_INITIAL_VALUE (60*1000)
+#define CBT_MIN_TIMEOUT_INITIAL_VALUE CBT_MIN_TIMEOUT_MIN_VALUE
+#define CBT_MAX_TIMEOUT_INITIAL_VALUE INT32_MAX
+int32_t circuit_build_times_initial_timeout(void);
+
+#if CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT < CBT_MIN_MAX_RECENT_TIMEOUT_COUNT
+#error "RECENT_CIRCUITS is set too low."
+#endif
+
 #ifdef CIRCUITSTATS_PRIVATE
 STATIC double circuit_build_times_calculate_timeout(circuit_build_times_t *cbt,
                                              double quantile);
@@ -125,4 +211,3 @@ struct circuit_build_times_s {
 #endif /* defined(CIRCUITSTATS_PRIVATE) */
 
 #endif /* !defined(TOR_CIRCUITSTATS_H) */
-

+ 14 - 0
src/or/config.c

@@ -71,6 +71,7 @@
 #include "or/circuitstats.h"
 #include "lib/compress/compress.h"
 #include "or/config.h"
+#include "lib/encoding/confline.h"
 #include "or/connection.h"
 #include "or/connection_edge.h"
 #include "or/connection_or.h"
@@ -109,6 +110,15 @@
 #ifdef _WIN32
 #include <shlobj.h>
 #endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 #include "lib/meminfo/meminfo.h"
 #include "lib/osinfo/uname.h"
@@ -146,6 +156,10 @@ static const char unix_socket_prefix[] = "unix:";
  * configuration. */
 static const char unix_q_socket_prefix[] = "unix:\"";
 
+/* limits for TCP send and recv buffer size used for constrained sockets */
+#define MIN_CONSTRAINED_TCP_BUFFER 2048
+#define MAX_CONSTRAINED_TCP_BUFFER 262144  /* 256k */
+
 /** macro to help with the bulk rename of *DownloadSchedule to
  * *DowloadInitialDelay . */
 #define DOWNLOAD_SCHEDULE(name) \

+ 15 - 5
src/or/config.h

@@ -12,6 +12,7 @@
 #ifndef TOR_CONFIG_H
 #define TOR_CONFIG_H
 
+#include "or/or_options_st.h"
 #include "lib/testsupport/testsupport.h"
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(DARWIN)
@@ -42,7 +43,16 @@ void init_protocol_warning_severity_level(void);
 int get_protocol_warning_severity_level(void);
 const char *get_version(void);
 const char *get_short_version(void);
-setopt_err_t options_trial_assign(config_line_t *list, unsigned flags,
+
+/** An error from options_trial_assign() or options_init_from_string(). */
+typedef enum setopt_err_t {
+  SETOPT_OK = 0,
+  SETOPT_ERR_MISC = -1,
+  SETOPT_ERR_PARSE = -2,
+  SETOPT_ERR_TRANSITION = -3,
+  SETOPT_ERR_SETTING = -4,
+} setopt_err_t;
+setopt_err_t options_trial_assign(struct config_line_t *list, unsigned flags,
                                   char **msg);
 
 uint32_t get_last_resolved_addr(void);
@@ -62,7 +72,7 @@ setopt_err_t options_init_from_string(const char *cf_defaults, const char *cf,
                             int command, const char *command_arg, char **msg);
 int option_is_recognized(const char *key);
 const char *option_get_canonical_name(const char *key);
-config_line_t *option_get_assignment(const or_options_t *options,
+struct config_line_t *option_get_assignment(const or_options_t *options,
                                      const char *key);
 int options_save_current(void);
 const char *get_torrc_fname(int defaults_fname);
@@ -180,8 +190,8 @@ int init_cookie_authentication(const char *fname, const char *header,
 or_options_t *options_new(void);
 
 int config_parse_commandline(int argc, char **argv, int ignore_errors,
-                             config_line_t **result,
-                             config_line_t **cmdline_result);
+                             struct config_line_t **result,
+                             struct config_line_t **cmdline_result);
 
 void config_register_addressmaps(const or_options_t *options);
 /* XXXX move to connection_edge.h */
@@ -260,7 +270,7 @@ STATIC int parse_dir_fallback_line(const char *line, int validate_only);
 STATIC int have_enough_mem_for_dircache(const or_options_t *options,
                                         size_t total_mem, char **msg);
 STATIC int parse_port_config(smartlist_t *out,
-                  const config_line_t *ports,
+                  const struct config_line_t *ports,
                   const char *portname,
                   int listener_type,
                   const char *defaultaddr,

+ 1 - 0
src/or/confparse.c

@@ -26,6 +26,7 @@
 #include "or/routerset.h"
 
 #include "lib/container/bitarray.h"
+#include "lib/encoding/confline.h"
 
 static uint64_t config_parse_memunit(const char *s, int *ok);
 static int config_parse_msec_interval(const char *s, int *ok);

+ 5 - 6
src/or/confparse.h

@@ -65,9 +65,9 @@ typedef union {
   time_t *ISOTIME;
   smartlist_t **CSV;
   int *CSV_INTERVAL;
-  config_line_t **LINELIST;
-  config_line_t **LINELIST_S;
-  config_line_t **LINELIST_V;
+  struct config_line_t **LINELIST;
+  struct config_line_t **LINELIST_S;
+  struct config_line_t **LINELIST_V;
   routerset_t **ROUTERSET;
 } confparse_dummy_values_t;
 #endif /* defined(TOR_UNIT_TESTS) */
@@ -185,7 +185,7 @@ void config_free_(const config_format_t *fmt, void *options);
     (options) = NULL;                                 \
   } while (0)
 
-config_line_t *config_get_assigned_option(const config_format_t *fmt,
+struct config_line_t *config_get_assigned_option(const config_format_t *fmt,
                                           const void *options, const char *key,
                                           int escape_val);
 int config_is_same(const config_format_t *fmt,
@@ -197,7 +197,7 @@ char *config_dump(const config_format_t *fmt, const void *default_options,
                   const void *options, int minimal,
                   int comment_defaults);
 int config_assign(const config_format_t *fmt, void *options,
-                  config_line_t *list,
+                  struct config_line_t *list,
                   unsigned flags, char **msg);
 config_var_t *config_find_option_mutable(config_format_t *fmt,
                                          const char *key);
@@ -219,4 +219,3 @@ void warn_deprecated_option(const char *what, const char *why);
 #define CFG_EQ_ROUTERSET(a,b,opt) routerset_equal((a)->opt, (b)->opt)
 
 #endif /* !defined(TOR_CONFPARSE_H) */
-

+ 10 - 0
src/or/connection.c

@@ -104,11 +104,21 @@
 #include "or/routerparse.h"
 #include "lib/sandbox/sandbox.h"
 #include "lib/net/buffers_net.h"
+#include "lib/tls/tortls.h"
+#include "common/compat_libevent.h"
+#include "lib/compress/compress.h"
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
 #ifdef HAVE_SYS_UN_H
 #include <sys/socket.h>
 #include <sys/un.h>

+ 85 - 4
src/or/connection.h

@@ -14,8 +14,72 @@
 
 listener_connection_t *TO_LISTENER_CONN(connection_t *);
 
-/* XXXX For buf_datalen in inline function */
-#include "lib/container/buffers.h"
+struct buf_t;
+
+#define CONN_TYPE_MIN_ 3
+/** Type for sockets listening for OR connections. */
+#define CONN_TYPE_OR_LISTENER 3
+/** A bidirectional TLS connection transmitting a sequence of cells.
+ * May be from an OR to an OR, or from an OP to an OR. */
+#define CONN_TYPE_OR 4
+/** A TCP connection from an onion router to a stream's destination. */
+#define CONN_TYPE_EXIT 5
+/** Type for sockets listening for SOCKS connections. */
+#define CONN_TYPE_AP_LISTENER 6
+/** A SOCKS proxy connection from the user application to the onion
+ * proxy. */
+#define CONN_TYPE_AP 7
+/** Type for sockets listening for HTTP connections to the directory server. */
+#define CONN_TYPE_DIR_LISTENER 8
+/** Type for HTTP connections to the directory server. */
+#define CONN_TYPE_DIR 9
+/* Type 10 is unused. */
+/** Type for listening for connections from user interface process. */
+#define CONN_TYPE_CONTROL_LISTENER 11
+/** Type for connections from user interface process. */
+#define CONN_TYPE_CONTROL 12
+/** Type for sockets listening for transparent connections redirected by pf or
+ * netfilter. */
+#define CONN_TYPE_AP_TRANS_LISTENER 13
+/** Type for sockets listening for transparent connections redirected by
+ * natd. */
+#define CONN_TYPE_AP_NATD_LISTENER 14
+/** Type for sockets listening for DNS requests. */
+#define CONN_TYPE_AP_DNS_LISTENER 15
+
+/** Type for connections from the Extended ORPort. */
+#define CONN_TYPE_EXT_OR 16
+/** Type for sockets listening for Extended ORPort connections. */
+#define CONN_TYPE_EXT_OR_LISTENER 17
+/** Type for sockets listening for HTTP CONNECT tunnel connections. */
+#define CONN_TYPE_AP_HTTP_CONNECT_LISTENER 18
+
+#define CONN_TYPE_MAX_ 19
+/* !!!! If _CONN_TYPE_MAX is ever over 31, we must grow the type field in
+ * connection_t. */
+
+/* Proxy client handshake states */
+/* We use a proxy but we haven't even connected to it yet. */
+#define PROXY_INFANT 1
+/* We use an HTTP proxy and we've sent the CONNECT command. */
+#define PROXY_HTTPS_WANT_CONNECT_OK 2
+/* We use a SOCKS4 proxy and we've sent the CONNECT command. */
+#define PROXY_SOCKS4_WANT_CONNECT_OK 3
+/* We use a SOCKS5 proxy and we try to negotiate without
+   any authentication . */
+#define PROXY_SOCKS5_WANT_AUTH_METHOD_NONE 4
+/* We use a SOCKS5 proxy and we try to negotiate with
+   Username/Password authentication . */
+#define PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929 5
+/* We use a SOCKS5 proxy and we just sent our credentials. */
+#define PROXY_SOCKS5_WANT_AUTH_RFC1929_OK 6
+/* We use a SOCKS5 proxy and we just sent our CONNECT command. */
+#define PROXY_SOCKS5_WANT_CONNECT_OK 7
+/* We use a proxy and we CONNECTed successfully!. */
+#define PROXY_CONNECTED 8
+
+/** State for any listener connection. */
+#define LISTENER_STATE_READY 0
 
 const char *conn_type_to_string(int type);
 const char *conn_state_to_string(int type, int state);
@@ -159,7 +223,7 @@ connection_buf_add(const char *string, size_t len, connection_t *conn)
 }
 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);
+void connection_buf_add_buf(connection_t *conn, struct buf_t *buf);
 
 size_t connection_get_inbuf_len(connection_t *conn);
 size_t connection_get_outbuf_len(connection_t *conn);
@@ -242,6 +306,24 @@ MOCK_DECL(void, clock_skew_warning,
 int connection_is_moribund(connection_t *conn);
 void connection_check_oos(int n_socks, int failed);
 
+/** Execute the statement <b>stmt</b>, which may log events concerning the
+ * connection <b>conn</b>.  To prevent infinite loops, disable log messages
+ * being sent to controllers if <b>conn</b> is a control connection.
+ *
+ * Stmt must not contain any return or goto statements.
+ */
+#define CONN_LOG_PROTECT(conn, stmt)                                    \
+  STMT_BEGIN                                                            \
+    int _log_conn_is_control;                                           \
+    tor_assert(conn);                                                   \
+    _log_conn_is_control = (conn->type == CONN_TYPE_CONTROL);           \
+    if (_log_conn_is_control)                                           \
+      disable_control_logging();                                        \
+  STMT_BEGIN stmt; STMT_END;                                            \
+    if (_log_conn_is_control)                                           \
+      enable_control_logging();                                         \
+  STMT_END
+
 #ifdef CONNECTION_PRIVATE
 STATIC void connection_free_minimal(connection_t *conn);
 
@@ -259,4 +341,3 @@ MOCK_DECL(STATIC smartlist_t *, pick_oos_victims, (int n));
 #endif /* defined(CONNECTION_PRIVATE) */
 
 #endif /* !defined(TOR_CONNECTION_H) */
-

+ 1 - 1
src/or/connection_edge.c

@@ -106,6 +106,7 @@
 #include "or/or_circuit_st.h"
 #include "or/origin_circuit_st.h"
 #include "or/socks_request_st.h"
+#include "common/compat_libevent.h"
 
 #ifdef HAVE_LINUX_TYPES_H
 #include <linux/types.h>
@@ -4221,4 +4222,3 @@ connection_edge_free_all(void)
   pending_entry_connections = NULL;
   mainloop_event_free(attach_pending_entry_connections_ev);
 }
-

+ 48 - 1
src/or/connection_edge.h

@@ -18,6 +18,54 @@ edge_connection_t *TO_EDGE_CONN(connection_t *);
 entry_connection_t *TO_ENTRY_CONN(connection_t *);
 entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *);
 
+#define EXIT_CONN_STATE_MIN_ 1
+/** State for an exit connection: waiting for response from DNS farm. */
+#define EXIT_CONN_STATE_RESOLVING 1
+/** State for an exit connection: waiting for connect() to finish. */
+#define EXIT_CONN_STATE_CONNECTING 2
+/** State for an exit connection: open and ready to transmit data. */
+#define EXIT_CONN_STATE_OPEN 3
+/** State for an exit connection: waiting to be removed. */
+#define EXIT_CONN_STATE_RESOLVEFAILED 4
+#define EXIT_CONN_STATE_MAX_ 4
+
+/* The AP state values must be disjoint from the EXIT state values. */
+#define AP_CONN_STATE_MIN_ 5
+/** State for a SOCKS connection: waiting for SOCKS request. */
+#define AP_CONN_STATE_SOCKS_WAIT 5
+/** State for a SOCKS connection: got a y.onion URL; waiting to receive
+ * rendezvous descriptor. */
+#define AP_CONN_STATE_RENDDESC_WAIT 6
+/** The controller will attach this connection to a circuit; it isn't our
+ * job to do so. */
+#define AP_CONN_STATE_CONTROLLER_WAIT 7
+/** State for a SOCKS connection: waiting for a completed circuit. */
+#define AP_CONN_STATE_CIRCUIT_WAIT 8
+/** State for a SOCKS connection: sent BEGIN, waiting for CONNECTED. */
+#define AP_CONN_STATE_CONNECT_WAIT 9
+/** State for a SOCKS connection: sent RESOLVE, waiting for RESOLVED. */
+#define AP_CONN_STATE_RESOLVE_WAIT 10
+/** State for a SOCKS connection: ready to send and receive. */
+#define AP_CONN_STATE_OPEN 11
+/** State for a transparent natd connection: waiting for original
+ * destination. */
+#define AP_CONN_STATE_NATD_WAIT 12
+/** State for an HTTP tunnel: waiting for an HTTP CONNECT command. */
+#define AP_CONN_STATE_HTTP_CONNECT_WAIT 13
+#define AP_CONN_STATE_MAX_ 13
+
+#define EXIT_PURPOSE_MIN_ 1
+/** This exit stream wants to do an ordinary connect. */
+#define EXIT_PURPOSE_CONNECT 1
+/** This exit stream wants to do a resolve (either normal or reverse). */
+#define EXIT_PURPOSE_RESOLVE 2
+#define EXIT_PURPOSE_MAX_ 2
+
+/** True iff the AP_CONN_STATE_* value <b>s</b> means that the corresponding
+ * edge connection is not attached to any circuit. */
+#define AP_CONN_STATE_IS_UNATTACHED(s) \
+  ((s) <= AP_CONN_STATE_CIRCUIT_WAIT || (s) == AP_CONN_STATE_NATD_WAIT)
+
 #define connection_mark_unattached_ap(conn, endreason)                  \
   connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__)
 
@@ -198,4 +246,3 @@ STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
 #endif /* defined(CONNECTION_EDGE_PRIVATE) */
 
 #endif /* !defined(TOR_CONNECTION_EDGE_H) */
-

+ 4 - 1
src/or/connection_or.c

@@ -66,8 +66,12 @@
 #include "or/or_connection_st.h"
 #include "or/or_handshake_certs_st.h"
 #include "or/or_handshake_state_st.h"
+#include "or/or_state_st.h"
 #include "or/routerinfo_st.h"
 #include "or/var_cell_st.h"
+#include "lib/crypt_ops/crypto_format.h"
+
+#include "lib/tls/tortls.h"
 
 static int connection_tls_finish_handshake(or_connection_t *conn);
 static int connection_or_launch_v3_or_handshake(or_connection_t *conn);
@@ -2990,4 +2994,3 @@ connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype))
 
   return 0;
 }
-

+ 43 - 13
src/or/connection_or.h

@@ -12,8 +12,38 @@
 #ifndef TOR_CONNECTION_OR_H
 #define TOR_CONNECTION_OR_H
 
+struct ed25519_public_key_t;
+struct ed25519_keypair_t;
+
 or_connection_t *TO_OR_CONN(connection_t *);
 
+#define OR_CONN_STATE_MIN_ 1
+/** State for a connection to an OR: waiting for connect() to finish. */
+#define OR_CONN_STATE_CONNECTING 1
+/** State for a connection to an OR: waiting for proxy handshake to complete */
+#define OR_CONN_STATE_PROXY_HANDSHAKING 2
+/** State for an OR connection client: SSL is handshaking, not done
+ * yet. */
+#define OR_CONN_STATE_TLS_HANDSHAKING 3
+/** State for a connection to an OR: We're doing a second SSL handshake for
+ * renegotiation purposes. (V2 handshake only.) */
+#define OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING 4
+/** State for a connection at an OR: We're waiting for the client to
+ * renegotiate (to indicate a v2 handshake) or send a versions cell (to
+ * indicate a v3 handshake) */
+#define OR_CONN_STATE_TLS_SERVER_RENEGOTIATING 5
+/** State for an OR connection: We're done with our SSL handshake, we've done
+ * renegotiation, but we haven't yet negotiated link protocol versions and
+ * sent a netinfo cell. */
+#define OR_CONN_STATE_OR_HANDSHAKING_V2 6
+/** State for an OR connection: We're done with our SSL handshake, but we
+ * haven't yet negotiated link protocol versions, done a V3 handshake, and
+ * sent a netinfo cell. */
+#define OR_CONN_STATE_OR_HANDSHAKING_V3 7
+/** State for an OR connection: Ready to send/receive cells. */
+#define OR_CONN_STATE_OPEN 8
+#define OR_CONN_STATE_MAX_ 8
+
 void connection_or_clear_identity(or_connection_t *conn);
 void connection_or_clear_identity_map(void);
 void clear_broken_connection_map(int disable);
@@ -42,7 +72,7 @@ MOCK_DECL(or_connection_t *,
           connection_or_connect,
           (const tor_addr_t *addr, uint16_t port,
            const char *id_digest,
-           const ed25519_public_key_t *ed_id,
+           const struct ed25519_public_key_t *ed_id,
            channel_tls_t *chan));
 
 void connection_or_close_normally(or_connection_t *orconn, int flush);
@@ -60,14 +90,14 @@ void connection_or_set_canonical(or_connection_t *or_conn,
 int connection_init_or_handshake_state(or_connection_t *conn,
                                        int started_here);
 void connection_or_init_conn_from_address(or_connection_t *conn,
-                                          const tor_addr_t *addr,
-                                          uint16_t port,
-                                          const char *rsa_id_digest,
-                                          const ed25519_public_key_t *ed_id,
-                                          int started_here);
+                                    const tor_addr_t *addr,
+                                    uint16_t port,
+                                    const char *rsa_id_digest,
+                                    const struct ed25519_public_key_t *ed_id,
+                                    int started_here);
 int connection_or_client_learned_peer_id(or_connection_t *conn,
                               const uint8_t *rsa_peer_id,
-                              const ed25519_public_key_t *ed_peer_id);
+                              const struct ed25519_public_key_t *ed_peer_id);
 time_t connection_or_client_used(or_connection_t *conn);
 MOCK_DECL(int, connection_or_get_num_circuits, (or_connection_t *conn));
 void or_handshake_state_free_(or_handshake_state_t *state);
@@ -94,11 +124,12 @@ int connection_or_send_auth_challenge_cell(or_connection_t *conn);
 int authchallenge_type_is_supported(uint16_t challenge_type);
 int authchallenge_type_is_better(uint16_t challenge_type_a,
                                  uint16_t challenge_type_b);
-var_cell_t *connection_or_compute_authenticate_cell_body(or_connection_t *conn,
-                                       const int authtype,
-                                       crypto_pk_t *signing_key,
-                                       const ed25519_keypair_t *ed_signing_key,
-                                       int server);
+var_cell_t *connection_or_compute_authenticate_cell_body(
+                              or_connection_t *conn,
+                              const int authtype,
+                              crypto_pk_t *signing_key,
+                              const struct ed25519_keypair_t *ed_signing_key,
+                              int server);
 MOCK_DECL(int,connection_or_send_authenticate_cell,
           (or_connection_t *conn, int type));
 
@@ -132,4 +163,3 @@ extern int certs_cell_ed25519_disabled_for_testing;
 #endif
 
 #endif /* !defined(TOR_CONNECTION_OR_H) */
-

+ 18 - 0
src/or/connection_st.h

@@ -9,6 +9,16 @@
 
 struct buf_t;
 
+/* Values for connection_t.magic: used to make sure that downcasts (casts from
+* connection_t to foo_connection_t) are safe. */
+#define BASE_CONNECTION_MAGIC 0x7C3C304Eu
+#define OR_CONNECTION_MAGIC 0x7D31FF03u
+#define EDGE_CONNECTION_MAGIC 0xF0374013u
+#define ENTRY_CONNECTION_MAGIC 0xbb4a5703
+#define DIR_CONNECTION_MAGIC 0x9988ffeeu
+#define CONTROL_CONNECTION_MAGIC 0x8abc765du
+#define LISTENER_CONNECTION_MAGIC 0x1a1ac741u
+
 /** Description of a connection to another host or process, and associated
  * data.
  *
@@ -128,4 +138,12 @@ struct connection_t {
   uint32_t n_written_conn_bw;
 };
 
+/** True iff <b>x</b> is an edge connection. */
+#define CONN_IS_EDGE(x) \
+  ((x)->type == CONN_TYPE_EXIT || (x)->type == CONN_TYPE_AP)
+
+/** True iff the purpose of <b>conn</b> means that it's a server-side
+ * directory connection. */
+#define DIR_CONN_IS_SERVER(conn) ((conn)->purpose == DIR_PURPOSE_SERVER)
+
 #endif

+ 1 - 1
src/or/conscache.c

@@ -7,6 +7,7 @@
 #include "or/conscache.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "lib/fs/storagedir.h"
+#include "lib/encoding/confline.h"
 
 #define CCE_MAGIC 0x17162253
 
@@ -624,4 +625,3 @@ consensus_cache_entry_is_mapped(consensus_cache_entry_t *ent)
   }
 }
 #endif /* defined(TOR_UNIT_TESTS) */
-

+ 4 - 5
src/or/conscache.h

@@ -27,9 +27,9 @@ void consensus_cache_delete_pending(consensus_cache_t *cache,
                                     int force);
 int consensus_cache_get_n_filenames_available(consensus_cache_t *cache);
 consensus_cache_entry_t *consensus_cache_add(consensus_cache_t *cache,
-                                             const config_line_t *labels,
-                                             const uint8_t *data,
-                                             size_t datalen);
+                                           const struct config_line_t *labels,
+                                           const uint8_t *data,
+                                           size_t datalen);
 
 consensus_cache_entry_t *consensus_cache_find_first(
                                              consensus_cache_t *cache,
@@ -46,7 +46,7 @@ void consensus_cache_filter_list(smartlist_t *lst,
 
 const char *consensus_cache_entry_get_value(const consensus_cache_entry_t *ent,
                                             const char *key);
-const config_line_t *consensus_cache_entry_get_labels(
+const struct config_line_t *consensus_cache_entry_get_labels(
                                           const consensus_cache_entry_t *ent);
 
 void consensus_cache_entry_incref(consensus_cache_entry_t *ent);
@@ -64,4 +64,3 @@ int consensus_cache_entry_is_mapped(consensus_cache_entry_t *ent);
 #endif
 
 #endif /* !defined(TOR_CONSCACHE_H) */
-

+ 3 - 1
src/or/consdiffmgr.c

@@ -21,7 +21,10 @@
 #include "or/cpuworker.h"
 #include "or/networkstatus.h"
 #include "or/routerparse.h"
+#include "common/compat_libevent.h"
 #include "common/workqueue.h"
+#include "lib/compress/compress.h"
+#include "lib/encoding/confline.h"
 
 #include "or/networkstatus_st.h"
 #include "or/networkstatus_voter_info_st.h"
@@ -1940,4 +1943,3 @@ consensus_cache_entry_get_valid_after(const consensus_cache_entry_t *ent,
   else
     return 0;
 }
-

+ 4 - 3
src/or/consdiffmgr.h

@@ -4,6 +4,8 @@
 #ifndef TOR_CONSDIFFMGR_H
 #define TOR_CONSDIFFMGR_H
 
+enum compress_method_t;
+
 /**
  * Possible outcomes from trying to look up a given consensus diff.
  */
@@ -25,7 +27,7 @@ int consdiffmgr_add_consensus(const char *consensus,
 consdiff_status_t consdiffmgr_find_consensus(
                            struct consensus_cache_entry_t **entry_out,
                            consensus_flavor_t flavor,
-                           compress_method_t method);
+                           enum compress_method_t method);
 
 consdiff_status_t consdiffmgr_find_diff_from(
                            struct consensus_cache_entry_t **entry_out,
@@ -33,7 +35,7 @@ consdiff_status_t consdiffmgr_find_diff_from(
                            int digest_type,
                            const uint8_t *digest,
                            size_t digestlen,
-                           compress_method_t method);
+                           enum compress_method_t method);
 
 int consensus_cache_entry_get_voter_id_digests(
                                   const struct consensus_cache_entry_t *ent,
@@ -71,4 +73,3 @@ STATIC int uncompress_or_copy(char **out, size_t *outlen,
 #endif /* defined(CONSDIFFMGR_PRIVATE) */
 
 #endif /* !defined(TOR_CONSDIFFMGR_H) */
-

+ 9 - 1
src/or/control.c

@@ -80,6 +80,7 @@
 #include "or/routerlist.h"
 #include "or/routerparse.h"
 #include "or/shared_random_client.h"
+#include "lib/encoding/confline.h"
 
 #include "or/cached_dir_st.h"
 #include "or/control_connection_st.h"
@@ -99,6 +100,13 @@
 #include "or/routerlist_st.h"
 #include "or/socks_request_st.h"
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
 #ifndef _WIN32
 #include <pwd.h>
 #include <sys/resource.h>
@@ -106,6 +114,7 @@
 
 #include "lib/crypt_ops/crypto_s2k.h"
 #include "common/procmon.h"
+#include "common/compat_libevent.h"
 
 /** Yield true iff <b>s</b> is the state of a control_connection_t that has
  * finished authentication and is accepting commands. */
@@ -7791,4 +7800,3 @@ control_testing_set_global_event_mask(uint64_t mask)
   global_event_mask = mask;
 }
 #endif /* defined(TOR_UNIT_TESTS) */
-

+ 89 - 2
src/or/control.h

@@ -12,8 +12,93 @@
 #ifndef TOR_CONTROL_H
 #define TOR_CONTROL_H
 
+/** Used to indicate the type of a circuit event passed to the controller.
+ * The various types are defined in control-spec.txt */
+typedef enum circuit_status_event_t {
+  CIRC_EVENT_LAUNCHED = 0,
+  CIRC_EVENT_BUILT    = 1,
+  CIRC_EVENT_EXTENDED = 2,
+  CIRC_EVENT_FAILED   = 3,
+  CIRC_EVENT_CLOSED   = 4,
+} circuit_status_event_t;
+
+/** Used to indicate the type of a CIRC_MINOR event passed to the controller.
+ * The various types are defined in control-spec.txt . */
+typedef enum circuit_status_minor_event_t {
+  CIRC_MINOR_EVENT_PURPOSE_CHANGED,
+  CIRC_MINOR_EVENT_CANNIBALIZED,
+} circuit_status_minor_event_t;
+
+/** Used to indicate the type of a stream event passed to the controller.
+ * The various types are defined in control-spec.txt */
+typedef enum stream_status_event_t {
+  STREAM_EVENT_SENT_CONNECT = 0,
+  STREAM_EVENT_SENT_RESOLVE = 1,
+  STREAM_EVENT_SUCCEEDED    = 2,
+  STREAM_EVENT_FAILED       = 3,
+  STREAM_EVENT_CLOSED       = 4,
+  STREAM_EVENT_NEW          = 5,
+  STREAM_EVENT_NEW_RESOLVE  = 6,
+  STREAM_EVENT_FAILED_RETRIABLE = 7,
+  STREAM_EVENT_REMAP        = 8
+} stream_status_event_t;
+
+/** Used to indicate the type of an OR connection event passed to the
+ * controller.  The various types are defined in control-spec.txt */
+typedef enum or_conn_status_event_t {
+  OR_CONN_EVENT_LAUNCHED     = 0,
+  OR_CONN_EVENT_CONNECTED    = 1,
+  OR_CONN_EVENT_FAILED       = 2,
+  OR_CONN_EVENT_CLOSED       = 3,
+  OR_CONN_EVENT_NEW          = 4,
+} or_conn_status_event_t;
+
+/** Used to indicate the type of a buildtime event */
+typedef enum buildtimeout_set_event_t {
+  BUILDTIMEOUT_SET_EVENT_COMPUTED  = 0,
+  BUILDTIMEOUT_SET_EVENT_RESET     = 1,
+  BUILDTIMEOUT_SET_EVENT_SUSPENDED = 2,
+  BUILDTIMEOUT_SET_EVENT_DISCARD = 3,
+  BUILDTIMEOUT_SET_EVENT_RESUME = 4
+} buildtimeout_set_event_t;
+
+/** Enum describing various stages of bootstrapping, for use with controller
+ * bootstrap status events. The values range from 0 to 100. */
+typedef enum {
+  BOOTSTRAP_STATUS_UNDEF=-1,
+  BOOTSTRAP_STATUS_STARTING=0,
+  BOOTSTRAP_STATUS_CONN_DIR=5,
+  BOOTSTRAP_STATUS_HANDSHAKE=-2,
+  BOOTSTRAP_STATUS_HANDSHAKE_DIR=10,
+  BOOTSTRAP_STATUS_ONEHOP_CREATE=15,
+  BOOTSTRAP_STATUS_REQUESTING_STATUS=20,
+  BOOTSTRAP_STATUS_LOADING_STATUS=25,
+  BOOTSTRAP_STATUS_LOADING_KEYS=40,
+  BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS=45,
+  BOOTSTRAP_STATUS_LOADING_DESCRIPTORS=50,
+  BOOTSTRAP_STATUS_CONN_OR=80,
+  BOOTSTRAP_STATUS_HANDSHAKE_OR=85,
+  BOOTSTRAP_STATUS_CIRCUIT_CREATE=90,
+  BOOTSTRAP_STATUS_DONE=100
+} bootstrap_status_t;
+
 control_connection_t *TO_CONTROL_CONN(connection_t *);
 
+#define CONTROL_CONN_STATE_MIN_ 1
+/** State for a control connection: Authenticated and accepting v1 commands. */
+#define CONTROL_CONN_STATE_OPEN 1
+/** State for a control connection: Waiting for authentication; speaking
+ * protocol v1. */
+#define CONTROL_CONN_STATE_NEEDAUTH 2
+#define CONTROL_CONN_STATE_MAX_ 2
+
+/** Reason for remapping an AP connection's address: we have a cached
+ * answer. */
+#define REMAP_STREAM_SOURCE_CACHE 1
+/** Reason for remapping an AP connection's address: the exit node told us an
+ * answer. */
+#define REMAP_STREAM_SOURCE_EXIT 2
+
 void control_initialize_event_queue(void);
 
 void control_update_global_event_mask(void);
@@ -99,7 +184,8 @@ int control_event_signal(uintptr_t signal);
 
 int init_control_cookie_authentication(int enabled);
 char *get_controller_cookie_file_name(void);
-smartlist_t *decode_hashed_passwords(config_line_t *passwords);
+struct config_line_t;
+smartlist_t *decode_hashed_passwords(struct config_line_t *passwords);
 void disable_control_logging(void);
 void enable_control_logging(void);
 
@@ -162,6 +248,8 @@ void control_event_hs_descriptor_content(const char *onion_address,
 void control_free_all(void);
 
 #ifdef CONTROL_PRIVATE
+#include "lib/crypt_ops/crypto_ed25519.h"
+
 /* Recognized asynchronous event types.  It's okay to expand this list
  * because it is used both as a list of v0 event types, and as indices
  * into the bitfield to determine which controllers want which events.
@@ -325,4 +413,3 @@ STATIC int getinfo_helper_current_time(
 #endif /* defined(CONTROL_PRIVATE) */
 
 #endif /* !defined(TOR_CONTROL_H) */
-

+ 16 - 2
src/or/crypt_path_st.h

@@ -8,6 +8,21 @@
 #define CRYPT_PATH_ST_H
 
 #include "or/relay_crypto_st.h"
+struct crypto_dh_t;
+
+#define CRYPT_PATH_MAGIC 0x70127012u
+
+struct fast_handshake_state_t;
+struct ntor_handshake_state_t;
+struct crypto_dh_t;
+struct onion_handshake_state_t {
+  uint16_t tag;
+  union {
+    struct fast_handshake_state_t *fast;
+    struct crypto_dh_t *tap;
+    struct ntor_handshake_state_t *ntor;
+  } u;
+};
 
 /** Holds accounting information for a single step in the layered encryption
  * performed by a circuit.  Used only at the client edge of a circuit. */
@@ -23,7 +38,7 @@ struct crypt_path_t {
   onion_handshake_state_t handshake_state;
   /** Diffie-hellman handshake state for performing an introduction
    * operations */
-  crypto_dh_t *rend_dh_handshake_state;
+  struct crypto_dh_t *rend_dh_handshake_state;
 
   /** Negotiated key material shared with the OR at this step. */
   char rend_circ_nonce[DIGEST_LEN];/* KH in tor-spec.txt */
@@ -53,4 +68,3 @@ struct crypt_path_t {
 };
 
 #endif
-

+ 6 - 1
src/or/desc_store_st.h

@@ -7,6 +7,12 @@
 #ifndef DESC_STORE_ST_H
 #define DESC_STORE_ST_H
 
+/** Allowable types of desc_store_t. */
+typedef enum store_type_t {
+  ROUTER_STORE = 0,
+  EXTRAINFO_STORE = 1
+} store_type_t;
+
 /** A 'store' is a set of descriptors saved on disk, with accompanying
  * journal, mmaped as needed, rebuilt as needed. */
 struct desc_store_t {
@@ -31,4 +37,3 @@ struct desc_store_t {
 };
 
 #endif
-

+ 3 - 2
src/or/dir_connection_st.h

@@ -9,6 +9,8 @@
 
 #include "or/connection_st.h"
 
+struct tor_compress_state_t;
+
 /** Subtype of connection_t for an "directory connection" -- that is, an HTTP
  * connection to retrieve or serve directory material. */
 struct dir_connection_t {
@@ -31,7 +33,7 @@ struct dir_connection_t {
    * 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;
+  struct tor_compress_state_t *compress_state;
 
   /** What rendezvous service are we querying for? */
   rend_data_t *rend_data;
@@ -63,4 +65,3 @@ struct dir_connection_t {
 };
 
 #endif
-

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

@@ -44,6 +44,8 @@
 #include "or/vote_timing_st.h"
 
 #include "lib/container/order.h"
+#include "lib/encoding/confline.h"
+#include "lib/crypt_ops/crypto_format.h"
 
 /**
  * \file dirvote.c

+ 3 - 1
src/or/dirauth/shared_random_state.c

@@ -21,6 +21,9 @@
 #include "or/shared_random_client.h"
 #include "or/dirauth/shared_random_state.h"
 #include "or/voting_schedule.h"
+#include "lib/encoding/confline.h"
+
+#include "or/or_state_st.h"
 
 /* Default filename of the shared random state on disk. */
 static const char default_fname[] = "sr-state";
@@ -1321,4 +1324,3 @@ get_sr_state(void)
 }
 
 #endif /* defined(TOR_UNIT_TESTS) */
-

+ 3 - 4
src/or/dirauth/shared_random_state.h

@@ -85,11 +85,11 @@ typedef struct sr_disk_state_t {
   /* State valid until? */
   time_t ValidUntil;
   /* All commits seen that are valid. */
-  config_line_t *Commit;
+  struct config_line_t *Commit;
   /* Previous and current shared random value. */
-  config_line_t *SharedRandValues;
+  struct config_line_t *SharedRandValues;
   /* Extra Lines for configuration we might not know. */
-  config_line_t *ExtraLines;
+  struct config_line_t *ExtraLines;
 } sr_disk_state_t;
 
 /* API */
@@ -144,4 +144,3 @@ STATIC sr_state_t *get_sr_state(void);
 #endif /* defined(TOR_UNIT_TESTS) */
 
 #endif /* !defined(TOR_SHARED_RANDOM_STATE_H) */
-

+ 12 - 1
src/or/directory.c

@@ -17,6 +17,7 @@
 #include "or/consdiff.h"
 #include "or/consdiffmgr.h"
 #include "or/control.h"
+#include "lib/compress/compress.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/directory.h"
@@ -42,6 +43,8 @@
 #include "or/routerlist.h"
 #include "or/routerparse.h"
 #include "or/routerset.h"
+#include "lib/encoding/confline.h"
+#include "lib/crypt_ops/crypto_format.h"
 
 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
 #if !defined(OpenBSD)
@@ -141,6 +144,15 @@ static void connection_dir_close_consensus_fetches(
 
 /********* START VARIABLES **********/
 
+/** Maximum size, in bytes, for resized buffers. */
+#define MAX_BUF_SIZE ((1<<24)-1) /* 16MB-1 */
+/** Maximum size, in bytes, for any directory object that we've downloaded. */
+#define MAX_DIR_DL_SIZE MAX_BUF_SIZE
+
+/** Maximum size, in bytes, for any directory object that we're accepting
+ * as an upload. */
+#define MAX_DIR_UL_SIZE MAX_BUF_SIZE
+
 /** How far in the future do we allow a directory server to tell us it is
  * before deciding that one of us has the wrong time? */
 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
@@ -5952,4 +5964,3 @@ dir_split_resource_into_spoolable(const char *resource,
   smartlist_free(fingerprints);
   return r;
 }
-

+ 82 - 6
src/or/directory.h

@@ -13,8 +13,82 @@
 #define TOR_DIRECTORY_H
 
 #include "or/hs_ident.h"
+enum compress_method_t;
 
 dir_connection_t *TO_DIR_CONN(connection_t *c);
+
+#define DIR_CONN_STATE_MIN_ 1
+/** State for connection to directory server: waiting for connect(). */
+#define DIR_CONN_STATE_CONNECTING 1
+/** State for connection to directory server: sending HTTP request. */
+#define DIR_CONN_STATE_CLIENT_SENDING 2
+/** State for connection to directory server: reading HTTP response. */
+#define DIR_CONN_STATE_CLIENT_READING 3
+/** State for connection to directory server: happy and finished. */
+#define DIR_CONN_STATE_CLIENT_FINISHED 4
+/** State for connection at directory server: waiting for HTTP request. */
+#define DIR_CONN_STATE_SERVER_COMMAND_WAIT 5
+/** State for connection at directory server: sending HTTP response. */
+#define DIR_CONN_STATE_SERVER_WRITING 6
+#define DIR_CONN_STATE_MAX_ 6
+
+#define DIR_PURPOSE_MIN_ 4
+/** A connection to a directory server: set after a v2 rendezvous
+ * descriptor is downloaded. */
+#define DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 4
+/** A connection to a directory server: download one or more server
+ * descriptors. */
+#define DIR_PURPOSE_FETCH_SERVERDESC 6
+/** A connection to a directory server: download one or more extra-info
+ * documents. */
+#define DIR_PURPOSE_FETCH_EXTRAINFO 7
+/** A connection to a directory server: upload a server descriptor. */
+#define DIR_PURPOSE_UPLOAD_DIR 8
+/** A connection to a directory server: upload a v3 networkstatus vote. */
+#define DIR_PURPOSE_UPLOAD_VOTE 10
+/** A connection to a directory server: upload a v3 consensus signature */
+#define DIR_PURPOSE_UPLOAD_SIGNATURES 11
+/** A connection to a directory server: download one or more v3 networkstatus
+ * votes. */
+#define DIR_PURPOSE_FETCH_STATUS_VOTE 12
+/** A connection to a directory server: download a v3 detached signatures
+ * object for a consensus. */
+#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES 13
+/** A connection to a directory server: download a v3 networkstatus
+ * consensus. */
+#define DIR_PURPOSE_FETCH_CONSENSUS 14
+/** A connection to a directory server: download one or more directory
+ * authority certificates. */
+#define DIR_PURPOSE_FETCH_CERTIFICATE 15
+
+/** Purpose for connection at a directory server. */
+#define DIR_PURPOSE_SERVER 16
+/** A connection to a hidden service directory server: upload a v2 rendezvous
+ * descriptor. */
+#define DIR_PURPOSE_UPLOAD_RENDDESC_V2 17
+/** A connection to a hidden service directory server: download a v2 rendezvous
+ * descriptor. */
+#define DIR_PURPOSE_FETCH_RENDDESC_V2 18
+/** A connection to a directory server: download a microdescriptor. */
+#define DIR_PURPOSE_FETCH_MICRODESC 19
+/** A connection to a hidden service directory: upload a v3 descriptor. */
+#define DIR_PURPOSE_UPLOAD_HSDESC 20
+/** A connection to a hidden service directory: fetch a v3 descriptor. */
+#define DIR_PURPOSE_FETCH_HSDESC 21
+/** A connection to a directory server: set after a hidden service descriptor
+ * is downloaded. */
+#define DIR_PURPOSE_HAS_FETCHED_HSDESC 22
+#define DIR_PURPOSE_MAX_ 22
+
+/** True iff <b>p</b> is a purpose corresponding to uploading
+ * data to a directory server. */
+#define DIR_PURPOSE_IS_UPLOAD(p)                \
+  ((p)==DIR_PURPOSE_UPLOAD_DIR ||               \
+   (p)==DIR_PURPOSE_UPLOAD_VOTE ||              \
+   (p)==DIR_PURPOSE_UPLOAD_SIGNATURES ||        \
+   (p)==DIR_PURPOSE_UPLOAD_RENDDESC_V2 ||       \
+   (p)==DIR_PURPOSE_UPLOAD_HSDESC)
+
 int directories_have_accepted_server_descriptor(void);
 void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
                                   dirinfo_type_t type, const char *payload,
@@ -90,7 +164,7 @@ void directory_request_add_header(directory_request_t *req,
 MOCK_DECL(void, directory_initiate_request, (directory_request_t *request));
 
 int parse_http_response(const char *headers, int *code, time_t *date,
-                        compress_method_t *compression, char **response);
+                        enum compress_method_t *compression, char **response);
 int parse_http_command(const char *headers,
                        char **command_out, char **url_out);
 char *http_get_header(const char *headers, const char *which);
@@ -189,7 +263,7 @@ struct directory_request_t {
   /** Hidden-service-specific information v2. */
   const rend_data_t *rend_query;
   /** Extra headers to append to the request */
-  config_line_t *additional_headers;
+  struct config_line_t *additional_headers;
   /** Hidden-service-specific information for v3+. */
   const hs_ident_dir_conn_t *hs_ident;
   /** Used internally to directory.c: gets informed when the attempt to
@@ -203,8 +277,10 @@ STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn,
                                        const struct get_handler_args_t *args);
 STATIC int directory_handle_command(dir_connection_t *conn);
 STATIC char *accept_encoding_header(void);
-STATIC int allowed_anonymous_connection_compression_method(compress_method_t);
-STATIC void warn_disallowed_anonymous_compression_method(compress_method_t);
+STATIC int allowed_anonymous_connection_compression_method(
+                                               enum compress_method_t);
+STATIC void warn_disallowed_anonymous_compression_method(
+                                               enum compress_method_t);
 
 STATIC int handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
                                           const response_handler_args_t *args);
@@ -239,7 +315,8 @@ STATIC int handle_post_hs_descriptor(const char *url, const char *body);
 STATIC char* authdir_type_to_string(dirinfo_type_t auth);
 STATIC const char * dir_conn_purpose_to_string(int purpose);
 STATIC int should_use_directory_guards(const or_options_t *options);
-STATIC compression_level_t choose_compression_level(ssize_t n_bytes);
+enum compression_level_t;
+STATIC enum compression_level_t choose_compression_level(ssize_t n_bytes);
 STATIC int find_dl_min_delay(const download_status_t *dls,
                              const or_options_t *options);
 
@@ -268,4 +345,3 @@ STATIC unsigned parse_accept_encoding_header(const char *h);
 #endif /* defined(TOR_UNIT_TESTS) || defined(DIRECTORY_PRIVATE) */
 
 #endif /* !defined(TOR_DIRECTORY_H) */
-

+ 3 - 0
src/or/dirserv.c

@@ -46,7 +46,10 @@
 #include "or/tor_version_st.h"
 #include "or/vote_routerstatus_st.h"
 
+#include "lib/compress/compress.h"
 #include "lib/container/order.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/encoding/confline.h"
 
 /**
  * \file dirserv.c

+ 18 - 2
src/or/dirserv.h

@@ -12,8 +12,25 @@
 #ifndef TOR_DIRSERV_H
 #define TOR_DIRSERV_H
 
+struct ed25519_public_key_t;
+
 #include "lib/testsupport/testsupport.h"
 
+/** An enum to describe what format we're generating a routerstatus line in.
+ */
+typedef enum {
+  /** For use in a v2 opinion */
+  NS_V2,
+  /** For use in a consensus networkstatus document (ns flavor) */
+  NS_V3_CONSENSUS,
+  /** For use in a vote networkstatus document */
+  NS_V3_VOTE,
+  /** For passing to the controlport in response to a GETINFO request */
+  NS_CONTROL_PORT,
+  /** For use in a consensus networkstatus document (microdesc flavor) */
+  NS_V3_CONSENSUS_MICRODESC
+} routerstatus_format_type_t;
+
 /** What fraction (1 over this number) of the relay ID space do we
  * (as a directory authority) launch connections to at each reachability
  * test? */
@@ -138,7 +155,7 @@ int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
 void dirserv_orconn_tls_done(const tor_addr_t *addr,
                              uint16_t or_port,
                              const char *digest_rcvd,
-                             const ed25519_public_key_t *ed_id_rcvd);
+                             const struct ed25519_public_key_t *ed_id_rcvd);
 int dirserv_should_launch_reachability_test(const routerinfo_t *ri,
                                             const routerinfo_t *ri_old);
 void dirserv_single_reachability_test(time_t now, routerinfo_t *router);
@@ -220,4 +237,3 @@ void dirserv_spool_sort(dir_connection_t *conn);
 void dir_conn_clear_spool(dir_connection_t *conn);
 
 #endif /* !defined(TOR_DIRSERV_H) */
-

+ 5 - 1
src/or/dns.c

@@ -64,10 +64,15 @@
 #include "or/router.h"
 #include "ht.h"
 #include "lib/sandbox/sandbox.h"
+#include "common/compat_libevent.h"
 
 #include "or/edge_connection_st.h"
 #include "or/or_circuit_st.h"
 
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
 #include <event2/event.h>
 #include <event2/dns.h>
 
@@ -2136,4 +2141,3 @@ dns_insert_cache_entry(cached_resolve_t *new_entry)
 {
   HT_INSERT(cache_map, &cache_root, new_entry);
 }
-

+ 1 - 1
src/or/dnsserv.c

@@ -34,6 +34,7 @@
 #include "or/entry_connection_st.h"
 #include "or/listener_connection_st.h"
 #include "or/socks_request_st.h"
+#include "common/compat_libevent.h"
 
 #include <event2/dns.h>
 #include <event2/dns_compat.h>
@@ -412,4 +413,3 @@ dnsserv_close_listener(connection_t *conn)
     listener_conn->dns_server_port = NULL;
   }
 }
-

+ 1 - 1
src/or/dos.c

@@ -11,6 +11,7 @@
 #include "or/or.h"
 #include "or/channel.h"
 #include "or/config.h"
+#include "or/connection.h"
 #include "or/connection_or.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "or/geoip.h"
@@ -798,4 +799,3 @@ dos_init(void)
   /* To initialize, we only need to get the parameters. */
   set_dos_parameters(NULL);
 }
-

+ 2 - 0
src/or/entrynodes.c

@@ -139,9 +139,11 @@
 #include "or/transports.h"
 #include "or/statefile.h"
 #include "lib/math/fp.h"
+#include "lib/encoding/confline.h"
 
 #include "or/node_st.h"
 #include "or/origin_circuit_st.h"
+#include "or/or_state_st.h"
 
 #include "lib/crypt_ops/digestset.h"
 

+ 2 - 1
src/or/entrynodes.h

@@ -64,6 +64,8 @@ typedef struct guard_pathbias_t {
 } guard_pathbias_t;
 
 #if defined(ENTRYNODES_PRIVATE)
+#include "lib/crypt_ops/crypto_ed25519.h"
+
 /**
  * @name values for entry_guard_t.is_reachable.
  *
@@ -635,4 +637,3 @@ guard_get_guardfraction_bandwidth(guardfraction_bandwidth_t *guardfraction_bw,
                                   uint32_t guardfraction_percentage);
 
 #endif /* !defined(TOR_ENTRYNODES_H) */
-

+ 19 - 1
src/or/ext_orport.h

@@ -7,6 +7,25 @@
 #ifndef EXT_ORPORT_H
 #define EXT_ORPORT_H
 
+/** States of the Extended ORPort protocol. Be careful before changing
+ *  the numbers: they matter. */
+#define EXT_OR_CONN_STATE_MIN_ 1
+/** Extended ORPort authentication is waiting for the authentication
+ *  type selected by the client. */
+#define EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE 1
+/** Extended ORPort authentication is waiting for the client nonce. */
+#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE 2
+/** Extended ORPort authentication is waiting for the client hash. */
+#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH 3
+#define EXT_OR_CONN_STATE_AUTH_MAX 3
+/** Authentication finished and the Extended ORPort is now accepting
+ *  traffic. */
+#define EXT_OR_CONN_STATE_OPEN 4
+/** Extended ORPort is flushing its last messages and preparing to
+ *  start accepting OR connections. */
+#define EXT_OR_CONN_STATE_FLUSHING 5
+#define EXT_OR_CONN_STATE_MAX_ 5
+
 int connection_ext_or_start_auth(or_connection_t *or_conn);
 
 ext_or_cmd_t *ext_or_cmd_new(uint16_t len);
@@ -43,4 +62,3 @@ extern int ext_or_auth_cookie_is_set;
 #endif /* defined(EXT_ORPORT_PRIVATE) */
 
 #endif /* !defined(EXT_ORPORT_H) */
-

+ 3 - 1
src/or/extend_info_st.h

@@ -7,6 +7,9 @@
 #ifndef EXTEND_INFO_ST_H
 #define EXTEND_INFO_ST_H
 
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+
 /** Information on router used when extending a circuit. We don't need a
  * full routerinfo_t to extend: we only need addr:port:keyid to build an OR
  * connection, and onion_key to create the onionskin. Note that for onehop
@@ -25,4 +28,3 @@ struct extend_info_t {
 };
 
 #endif
-

+ 58 - 1
src/or/geoip.h

@@ -15,6 +15,64 @@
 #include "lib/testsupport/testsupport.h"
 #include "or/dos.h"
 
+/** Indicates an action that we might be noting geoip statistics on.
+ * Note that if we're noticing CONNECT, we're a bridge, and if we're noticing
+ * the others, we're not.
+ */
+typedef enum {
+  /** We've noticed a connection as a bridge relay or entry guard. */
+  GEOIP_CLIENT_CONNECT = 0,
+  /** We've served a networkstatus consensus as a directory server. */
+  GEOIP_CLIENT_NETWORKSTATUS = 1,
+} geoip_client_action_t;
+/** Indicates either a positive reply or a reason for rejectng a network
+ * status request that will be included in geoip statistics. */
+typedef enum {
+  /** Request is answered successfully. */
+  GEOIP_SUCCESS = 0,
+  /** V3 network status is not signed by a sufficient number of requested
+   * authorities. */
+  GEOIP_REJECT_NOT_ENOUGH_SIGS = 1,
+  /** Requested network status object is unavailable. */
+  GEOIP_REJECT_UNAVAILABLE = 2,
+  /** Requested network status not found. */
+  GEOIP_REJECT_NOT_FOUND = 3,
+  /** Network status has not been modified since If-Modified-Since time. */
+  GEOIP_REJECT_NOT_MODIFIED = 4,
+  /** Directory is busy. */
+  GEOIP_REJECT_BUSY = 5,
+} geoip_ns_response_t;
+#define GEOIP_NS_RESPONSE_NUM 6
+
+/** Directory requests that we are measuring can be either direct or
+ * tunneled. */
+typedef enum {
+  DIRREQ_DIRECT = 0,
+  DIRREQ_TUNNELED = 1,
+} dirreq_type_t;
+
+/** Possible states for either direct or tunneled directory requests that
+ * are relevant for determining network status download times. */
+typedef enum {
+  /** Found that the client requests a network status; applies to both
+   * direct and tunneled requests; initial state of a request that we are
+   * measuring. */
+  DIRREQ_IS_FOR_NETWORK_STATUS = 0,
+  /** Finished writing a network status to the directory connection;
+   * applies to both direct and tunneled requests; completes a direct
+   * request. */
+  DIRREQ_FLUSHING_DIR_CONN_FINISHED = 1,
+  /** END cell sent to circuit that initiated a tunneled request. */
+  DIRREQ_END_CELL_SENT = 2,
+  /** Flushed last cell from queue of the circuit that initiated a
+    * tunneled request to the outbuf of the OR connection. */
+  DIRREQ_CIRC_QUEUE_FLUSHED = 3,
+  /** Flushed last byte from buffer of the channel belonging to the
+    * circuit that initiated a tunneled request; completes a tunneled
+    * request. */
+  DIRREQ_CHANNEL_BUFFER_FLUSHED = 4
+} dirreq_state_t;
+
 #ifdef GEOIP_PRIVATE
 STATIC int geoip_parse_entry(const char *line, sa_family_t family);
 STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr);
@@ -97,4 +155,3 @@ char *geoip_get_bridge_stats_controller(time_t);
 char *format_client_stats_heartbeat(time_t now);
 
 #endif /* !defined(TOR_GEOIP_H) */
-

+ 6 - 1
src/or/hibernate.c

@@ -41,8 +41,14 @@ hibernating, phase 2:
 #include "or/main.h"
 #include "or/router.h"
 #include "or/statefile.h"
+#include "common/compat_libevent.h"
 
 #include "or/or_connection_st.h"
+#include "or/or_state_st.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 /** Are we currently awake, asleep, running out of bandwidth, or shutting
  * down? */
@@ -1227,4 +1233,3 @@ hibernate_set_state_for_testing_(hibernate_state_t newstate)
   hibernate_state = newstate;
 }
 #endif /* defined(TOR_UNIT_TESTS) */
-

+ 1 - 1
src/or/hs_cache.c

@@ -11,6 +11,7 @@
 
 #include "or/or.h"
 #include "or/config.h"
+#include "lib/crypt_ops/crypto_format.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/hs_ident.h"
 #include "or/hs_common.h"
@@ -976,4 +977,3 @@ hs_cache_free_all(void)
                     cache_client_intro_state_free_void);
   hs_cache_client_intro_state = NULL;
 }
-

+ 13 - 11
src/or/hs_cache.h

@@ -11,12 +11,13 @@
 
 #include <stdint.h>
 
-#include "lib/crypt_ops/crypto_ed25519.h"
 #include "or/hs_common.h"
 #include "or/hs_descriptor.h"
 #include "or/rendcommon.h"
 #include "or/torcert.h"
 
+struct ed25519_public_key_t;
+
 /* This is the maximum time an introduction point state object can stay in the
  * client cache in seconds (2 mins or 120 seconds). */
 #define HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE (2 * 60)
@@ -79,30 +80,32 @@ int hs_cache_lookup_as_dir(uint32_t version, const char *query,
                            const char **desc_out);
 
 const hs_descriptor_t *
-hs_cache_lookup_as_client(const ed25519_public_key_t *key);
+hs_cache_lookup_as_client(const struct ed25519_public_key_t *key);
 const char *
-hs_cache_lookup_encoded_as_client(const ed25519_public_key_t *key);
+hs_cache_lookup_encoded_as_client(const struct ed25519_public_key_t *key);
 int hs_cache_store_as_client(const char *desc_str,
-                             const ed25519_public_key_t *identity_pk);
+                             const struct ed25519_public_key_t *identity_pk);
 void hs_cache_clean_as_client(time_t now);
 void hs_cache_purge_as_client(void);
 
 /* Client failure cache. */
-void hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk,
-                                      const ed25519_public_key_t *auth_key,
-                                      rend_intro_point_failure_t failure);
+void hs_cache_client_intro_state_note(
+                              const struct ed25519_public_key_t *service_pk,
+                              const struct ed25519_public_key_t *auth_key,
+                              rend_intro_point_failure_t failure);
 const hs_cache_intro_state_t *hs_cache_client_intro_state_find(
-                                       const ed25519_public_key_t *service_pk,
-                                       const ed25519_public_key_t *auth_key);
+                              const struct ed25519_public_key_t *service_pk,
+                              const struct ed25519_public_key_t *auth_key);
 void hs_cache_client_intro_state_clean(time_t now);
 void hs_cache_client_intro_state_purge(void);
 
 #ifdef HS_CACHE_PRIVATE
+#include "lib/crypt_ops/crypto_ed25519.h"
 
 /** Represents a locally cached HS descriptor on a hidden service client. */
 typedef struct hs_cache_client_descriptor_t {
   /* This object is indexed using the service identity public key */
-  ed25519_public_key_t key;
+  struct ed25519_public_key_t key;
 
   /* When will this entry expire? We expire cached client descriptors in the
    * start of the next time period, since that's when clients need to start
@@ -125,4 +128,3 @@ lookup_v3_desc_as_client(const uint8_t *key);
 #endif /* defined(HS_CACHE_PRIVATE) */
 
 #endif /* !defined(TOR_HS_CACHE_H) */
-

+ 7 - 5
src/or/hs_circuit.c

@@ -13,6 +13,7 @@
 #include "or/circuitlist.h"
 #include "or/circuituse.h"
 #include "or/config.h"
+#include "lib/crypt_ops/crypto_dh.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/nodelist.h"
@@ -23,6 +24,7 @@
 #include "or/router.h"
 
 #include "or/hs_cell.h"
+#include "or/hs_circuitmap.h"
 #include "or/hs_ident.h"
 #include "or/hs_ntor.h"
 #include "or/hs_service.h"
@@ -102,7 +104,8 @@ create_rend_cpath(const uint8_t *ntor_key_seed, size_t seed_len,
 /* We are a v2 legacy HS client: Create and return a crypt path for the hidden
  * service on the other side of the rendezvous circuit <b>circ</b>. Initialize
  * the crypt path crypto using the body of the RENDEZVOUS1 cell at
- * <b>rend_cell_body</b> (which must be at least DH_KEY_LEN+DIGEST_LEN bytes).
+ * <b>rend_cell_body</b> (which must be at least DH1024_KEY_LEN+DIGEST_LEN
+ * bytes).
  */
 static crypt_path_t *
 create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
@@ -110,7 +113,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
   crypt_path_t *hop = NULL;
   char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN];
 
-  /* first DH_KEY_LEN bytes are g^y from the service. Finish the dh
+  /* first DH1024_KEY_LEN bytes are g^y from the service. Finish the dh
    * handshake...*/
   tor_assert(circ->build_state);
   tor_assert(circ->build_state->pending_final_cpath);
@@ -118,7 +121,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
 
   tor_assert(hop->rend_dh_handshake_state);
   if (crypto_dh_compute_secret(LOG_PROTOCOL_WARN, hop->rend_dh_handshake_state,
-                               (char*)rend_cell_body, DH_KEY_LEN,
+                               (char*)rend_cell_body, DH1024_KEY_LEN,
                                keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
     log_warn(LD_GENERAL, "Couldn't complete DH handshake.");
     goto err;
@@ -130,7 +133,7 @@ create_rend_cpath_legacy(origin_circuit_t *circ, const uint8_t *rend_cell_body)
     goto err;
 
   /* Check whether the digest is right... */
-  if (tor_memneq(keys, rend_cell_body+DH_KEY_LEN, DIGEST_LEN)) {
+  if (tor_memneq(keys, rend_cell_body+DH1024_KEY_LEN, DIGEST_LEN)) {
     log_warn(LD_PROTOCOL, "Incorrect digest of key material.");
     goto err;
   }
@@ -1244,4 +1247,3 @@ hs_circ_cleanup(circuit_t *circ)
     hs_circuitmap_remove_circuit(circ);
   }
 }
-

+ 0 - 1
src/or/hs_circuitmap.c

@@ -583,4 +583,3 @@ hs_circuitmap_free_all(void)
     tor_free(the_hs_circuitmap);
   }
 }
-

+ 2 - 3
src/or/hs_circuitmap.h

@@ -11,7 +11,7 @@
 
 typedef HT_HEAD(hs_circuitmap_ht, circuit_t) hs_circuitmap_ht;
 
-typedef struct hs_token_s hs_token_t;
+typedef struct hs_token_t hs_token_t;
 struct or_circuit_t;
 struct origin_circuit_t;
 
@@ -90,7 +90,7 @@ typedef enum {
 
 /** Represents a token used in the HS protocol. Each such token maps to a
  *  specific introduction or rendezvous circuit. */
-struct hs_token_s {
+struct hs_token_t {
   /* Type of HS token. */
   hs_token_type_t type;
 
@@ -110,4 +110,3 @@ hs_circuitmap_ht *get_hs_circuitmap(void);
 #endif /* TOR_UNIT_TESTS */
 
 #endif /* !defined(TOR_HS_CIRCUITMAP_H) */
-

+ 2 - 1
src/or/hs_client.c

@@ -16,12 +16,14 @@
 #include "or/config.h"
 #include "or/connection.h"
 #include "or/connection_edge.h"
+#include "lib/crypt_ops/crypto_format.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/directory.h"
 #include "or/hs_cache.h"
 #include "or/hs_cell.h"
 #include "or/hs_circuit.h"
+#include "or/hs_circuitmap.h"
 #include "or/hs_client.h"
 #include "or/hs_control.h"
 #include "or/hs_descriptor.h"
@@ -1619,4 +1621,3 @@ hs_client_dir_info_changed(void)
    * AP_CONN_STATE_RENDDESC_WAIT state in order to fetch the descriptor. */
   retry_all_socks_conn_waiting_for_desc();
 }
-

+ 0 - 1
src/or/hs_common.c

@@ -1823,4 +1823,3 @@ hs_inc_rdv_stream_counter(origin_circuit_t *circ)
     tor_assert_nonfatal_unreached();
   }
 }
-

+ 19 - 15
src/or/hs_common.h

@@ -10,6 +10,11 @@
 #define TOR_HS_COMMON_H
 
 #include "or/or.h"
+#include "lib/defs/x25519_sizes.h"
+
+struct curve25519_public_key_t;
+struct ed25519_public_key_t;
+struct ed25519_keypair_t;
 
 /* Trunnel */
 #include "trunnel/ed25519_cert.h"
@@ -122,7 +127,7 @@
  * bigger than the 84 bytes needed for version 3 so we need to pad up to that
  * length so it is indistinguishable between versions. */
 #define HS_LEGACY_RENDEZVOUS_CELL_SIZE \
-  (REND_COOKIE_LEN + DH_KEY_LEN + DIGEST_LEN)
+  (REND_COOKIE_LEN + DH1024_KEY_LEN + DIGEST_LEN)
 
 /* Type of authentication key used by an introduction point. */
 typedef enum {
@@ -167,20 +172,20 @@ int hs_check_service_private_dir(const char *username, const char *path,
 int hs_get_service_max_rend_failures(void);
 
 char *hs_path_from_filename(const char *directory, const char *filename);
-void hs_build_address(const ed25519_public_key_t *key, uint8_t version,
+void hs_build_address(const struct ed25519_public_key_t *key, uint8_t version,
                       char *addr_out);
 int hs_address_is_valid(const char *address);
-int hs_parse_address(const char *address, ed25519_public_key_t *key_out,
+int hs_parse_address(const char *address, struct ed25519_public_key_t *key_out,
                      uint8_t *checksum_out, uint8_t *version_out);
 
-void hs_build_blinded_pubkey(const ed25519_public_key_t *pubkey,
+void hs_build_blinded_pubkey(const struct ed25519_public_key_t *pubkey,
                              const uint8_t *secret, size_t secret_len,
                              uint64_t time_period_num,
-                             ed25519_public_key_t *pubkey_out);
-void hs_build_blinded_keypair(const ed25519_keypair_t *kp,
+                             struct ed25519_public_key_t *pubkey_out);
+void hs_build_blinded_keypair(const struct ed25519_keypair_t *kp,
                               const uint8_t *secret, size_t secret_len,
                               uint64_t time_period_num,
-                              ed25519_keypair_t *kp_out);
+                              struct ed25519_keypair_t *kp_out);
 int hs_service_requires_uptime_circ(const smartlist_t *ports);
 
 void rend_data_free_(rend_data_t *data);
@@ -203,8 +208,8 @@ const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data,
 
 routerstatus_t *pick_hsdir(const char *desc_id, const char *desc_id_base32);
 
-void hs_get_subcredential(const ed25519_public_key_t *identity_pk,
-                          const ed25519_public_key_t *blinded_pk,
+void hs_get_subcredential(const struct ed25519_public_key_t *identity_pk,
+                          const struct ed25519_public_key_t *blinded_pk,
                           uint8_t *subcred_out);
 
 uint64_t hs_get_previous_time_period_num(time_t now);
@@ -222,18 +227,18 @@ uint8_t *hs_get_current_srv(uint64_t time_period_num,
 uint8_t *hs_get_previous_srv(uint64_t time_period_num,
                              const networkstatus_t *ns);
 
-void hs_build_hsdir_index(const ed25519_public_key_t *identity_pk,
+void hs_build_hsdir_index(const struct ed25519_public_key_t *identity_pk,
                           const uint8_t *srv, uint64_t period_num,
                           uint8_t *hsdir_index_out);
 void hs_build_hs_index(uint64_t replica,
-                       const ed25519_public_key_t *blinded_pk,
+                       const struct ed25519_public_key_t *blinded_pk,
                        uint64_t period_num, uint8_t *hs_index_out);
 
 int32_t hs_get_hsdir_n_replicas(void);
 int32_t hs_get_hsdir_spread_fetch(void);
 int32_t hs_get_hsdir_spread_store(void);
 
-void hs_get_responsible_hsdirs(const ed25519_public_key_t *blinded_pk,
+void hs_get_responsible_hsdirs(const struct ed25519_public_key_t *blinded_pk,
                               uint64_t time_period_num,
                               int use_second_hsdir_index,
                               int for_fetching, smartlist_t *responsible_dirs);
@@ -254,8 +259,8 @@ void hs_inc_rdv_stream_counter(origin_circuit_t *circ);
 void hs_dec_rdv_stream_counter(origin_circuit_t *circ);
 
 extend_info_t *hs_get_extend_info_from_lspecs(const smartlist_t *lspecs,
-                                  const curve25519_public_key_t *onion_key,
-                                  int direct_conn);
+                          const struct curve25519_public_key_t *onion_key,
+                          int direct_conn);
 
 #ifdef HS_COMMON_PRIVATE
 
@@ -281,4 +286,3 @@ STATIC uint8_t *get_second_cached_disaster_srv(void);
 #endif /* defined(HS_COMMON_PRIVATE) */
 
 #endif /* !defined(TOR_HS_COMMON_H) */
-

+ 2 - 1
src/or/hs_config.c

@@ -29,6 +29,8 @@
 #include "or/hs_config.h"
 #include "or/hs_service.h"
 #include "or/rendservice.h"
+#include "lib/encoding/confline.h"
+#include "or/or_options_st.h"
 
 /* Using the given list of services, stage them into our global state. Every
  * service version are handled. This function can remove entries in the given
@@ -587,4 +589,3 @@ hs_config_service_all(const or_options_t *options, int validate_only)
   /* Tor main should call the free all function on error. */
   return ret;
 }
-

+ 1 - 1
src/or/hs_control.c

@@ -8,6 +8,7 @@
 
 #include "or/or.h"
 #include "or/control.h"
+#include "lib/crypt_ops/crypto_format.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/hs_common.h"
 #include "or/hs_control.h"
@@ -258,4 +259,3 @@ hs_control_hspost_command(const char *body, const char *onion_address,
   smartlist_free(hsdirs);
   return ret;
 }
-

+ 2 - 1
src/or/hs_descriptor.c

@@ -66,6 +66,8 @@
 #include "or/hs_cache.h"
 #include "or/hs_config.h"
 #include "or/torcert.h" /* tor_cert_encode_ed22519() */
+#include "lib/memarea/memarea.h"
+#include "lib/crypt_ops/crypto_format.h"
 
 #include "or/extend_info_st.h"
 
@@ -2607,4 +2609,3 @@ hs_desc_lspec_to_trunnel(const hs_desc_link_specifier_t *spec)
 
   return ls;
 }
-

+ 0 - 4
src/or/hs_descriptor.h

@@ -12,9 +12,6 @@
 #include <stdint.h>
 
 #include "or/or.h"
-#include "lib/net/address.h"
-#include "lib/crypt_ops/crypto.h"
-#include "lib/crypt_ops/crypto_ed25519.h"
 #include "trunnel/ed25519_cert.h" /* needed for trunnel */
 #include "or/torcert.h"
 
@@ -281,4 +278,3 @@ MOCK_DECL(STATIC size_t, decrypt_desc_layer,(const hs_descriptor_t *desc,
 #endif /* defined(HS_DESCRIPTOR_PRIVATE) */
 
 #endif /* !defined(TOR_HS_DESCRIPTOR_H) */
-

+ 1 - 1
src/or/hs_intropoint.c

@@ -15,6 +15,7 @@
 #include "or/relay.h"
 #include "or/rendmid.h"
 #include "or/rephist.h"
+#include "lib/crypt_ops/crypto_format.h"
 
 /* Trunnel */
 #include "trunnel/ed25519_cert.h"
@@ -611,4 +612,3 @@ hs_intropoint_clear(hs_intropoint_t *ip)
   smartlist_free(ip->link_specifiers);
   memset(ip, 0, sizeof(hs_intropoint_t));
 }
-

+ 2 - 1
src/or/hs_ntor.c

@@ -26,6 +26,8 @@
 
 #include "or/or.h"
 #include "lib/crypt_ops/crypto_util.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
 #include "or/hs_ntor.h"
 
 /* String constants used by the ntor HS protocol */
@@ -616,4 +618,3 @@ hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed, size_t seed_len,
 
   return 0;
 }
-

+ 23 - 21
src/or/hs_ntor.h

@@ -5,6 +5,9 @@
 #define TOR_HS_NTOR_H
 
 #include "or/or.h"
+struct ed25519_public_key_t;
+struct curve25519_public_key_t;
+struct curve25519_keypair_t;
 
 /* Output length of KDF for key expansion */
 #define HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN \
@@ -28,32 +31,32 @@ typedef struct {
 } hs_ntor_rend_cell_keys_t;
 
 int hs_ntor_client_get_introduce1_keys(
-                      const ed25519_public_key_t *intro_auth_pubkey,
-                      const curve25519_public_key_t *intro_enc_pubkey,
-                      const curve25519_keypair_t *client_ephemeral_enc_keypair,
-                      const uint8_t *subcredential,
-                      hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out);
+              const struct ed25519_public_key_t *intro_auth_pubkey,
+              const struct curve25519_public_key_t *intro_enc_pubkey,
+              const struct curve25519_keypair_t *client_ephemeral_enc_keypair,
+              const uint8_t *subcredential,
+              hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out);
 
 int hs_ntor_client_get_rendezvous1_keys(
-                  const ed25519_public_key_t *intro_auth_pubkey,
-                  const curve25519_keypair_t *client_ephemeral_enc_keypair,
-                  const curve25519_public_key_t *intro_enc_pubkey,
-                  const curve25519_public_key_t *service_ephemeral_rend_pubkey,
-                  hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out);
+          const struct ed25519_public_key_t *intro_auth_pubkey,
+          const struct curve25519_keypair_t *client_ephemeral_enc_keypair,
+          const struct curve25519_public_key_t *intro_enc_pubkey,
+          const struct curve25519_public_key_t *service_ephemeral_rend_pubkey,
+          hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out);
 
 int hs_ntor_service_get_introduce1_keys(
-                  const ed25519_public_key_t *intro_auth_pubkey,
-                  const curve25519_keypair_t *intro_enc_keypair,
-                  const curve25519_public_key_t *client_ephemeral_enc_pubkey,
-                  const uint8_t *subcredential,
-                  hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out);
+            const struct ed25519_public_key_t *intro_auth_pubkey,
+            const struct curve25519_keypair_t *intro_enc_keypair,
+            const struct curve25519_public_key_t *client_ephemeral_enc_pubkey,
+            const uint8_t *subcredential,
+            hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out);
 
 int hs_ntor_service_get_rendezvous1_keys(
-                  const ed25519_public_key_t *intro_auth_pubkey,
-                  const curve25519_keypair_t *intro_enc_keypair,
-                  const curve25519_keypair_t *service_ephemeral_rend_keypair,
-                  const curve25519_public_key_t *client_ephemeral_enc_pubkey,
-                  hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out);
+            const struct ed25519_public_key_t *intro_auth_pubkey,
+            const struct curve25519_keypair_t *intro_enc_keypair,
+            const struct curve25519_keypair_t *service_ephemeral_rend_keypair,
+            const struct curve25519_public_key_t *client_ephemeral_enc_pubkey,
+            hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys_out);
 
 int hs_ntor_circuit_key_expansion(const uint8_t *ntor_key_seed,
                                   size_t seed_len,
@@ -64,4 +67,3 @@ int hs_ntor_client_rendezvous2_mac_is_good(
                         const uint8_t *rcvd_mac);
 
 #endif /* !defined(TOR_HS_NTOR_H) */
-

+ 11 - 1
src/or/hs_service.c

@@ -45,13 +45,24 @@
 #include "or/networkstatus_st.h"
 #include "or/node_st.h"
 #include "or/origin_circuit_st.h"
+#include "or/or_state_st.h"
 #include "or/routerstatus_st.h"
 
+#include "lib/encoding/confline.h"
+#include "lib/crypt_ops/crypto_format.h"
+
 /* Trunnel */
 #include "trunnel/ed25519_cert.h"
 #include "trunnel/hs/cell_common.h"
 #include "trunnel/hs/cell_establish_intro.h"
 
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 /* Helper macro. Iterate over every service in the global map. The var is the
  * name of the service pointer. */
 #define FOR_EACH_SERVICE_BEGIN(var)                          \
@@ -3631,4 +3642,3 @@ get_first_service(void)
 }
 
 #endif /* defined(TOR_UNIT_TESTS) */
-

+ 4 - 1
src/or/include.am

@@ -75,7 +75,7 @@ LIBTOR_APP_A_SOURCES = \
 	src/or/onion_fast.c				\
 	src/or/onion_tap.c				\
 	src/or/transports.c				\
-	src/or/parsecommon.c			\
+	src/or/parsecommon.c				\
 	src/or/periodic.c				\
 	src/or/protover.c				\
 	src/or/protover_rust.c				\
@@ -180,6 +180,7 @@ endif
 
 ORHEADERS = \
 	src/or/addressmap.h				\
+	src/or/addr_policy_st.h				\
 	src/or/authority_cert_st.h			\
 	src/or/auth_dirs.inc				\
 	src/or/bridges.h				\
@@ -274,6 +275,8 @@ ORHEADERS = \
 	src/or/or_connection_st.h			\
 	src/or/or_handshake_certs_st.h			\
 	src/or/or_handshake_state_st.h			\
+	src/or/or_options_st.h				\
+	src/or/or_state_st.h				\
 	src/or/origin_circuit_st.h			\
 	src/or/transports.h				\
 	src/or/parsecommon.h				\

+ 9 - 0
src/or/main.c

@@ -116,6 +116,10 @@
 #include "lib/sandbox/sandbox.h"
 #include "lib/fs/lockfile.h"
 #include "lib/net/buffers_net.h"
+#include "lib/tls/tortls.h"
+#include "common/compat_libevent.h"
+#include "lib/encoding/confline.h"
+#include "common/timers.h"
 
 #include <event2/event.h>
 
@@ -127,10 +131,15 @@
 #include "or/entry_connection_st.h"
 #include "or/networkstatus_st.h"
 #include "or/or_connection_st.h"
+#include "or/or_state_st.h"
 #include "or/port_cfg_st.h"
 #include "or/routerinfo_st.h"
 #include "or/socks_request_st.h"
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 #ifdef HAVE_SYSTEMD
 #   if defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__)
 /* Systemd's use of gcc's __INCLUDE_LEVEL__ extension macro appears to confuse

+ 4 - 3
src/or/main.h

@@ -96,10 +96,12 @@ uint64_t get_main_loop_idle_count(void);
 void periodic_events_on_new_options(const or_options_t *options);
 void reschedule_per_second_timer(void);
 
+struct token_bucket_rw_t;
+
 extern time_t time_of_process_start;
 extern int quiet_level;
-extern token_bucket_rw_t global_bucket;
-extern token_bucket_rw_t global_relayed_bucket;
+extern struct token_bucket_rw_t global_bucket;
+extern struct token_bucket_rw_t global_relayed_bucket;
 
 #ifdef MAIN_PRIVATE
 STATIC void init_connection_lists(void);
@@ -118,4 +120,3 @@ extern periodic_event_item_t periodic_events[];
 #endif /* defined(MAIN_PRIVATE) */
 
 #endif /* !defined(TOR_MAIN_H) */
-

+ 7 - 0
src/or/microdesc.c

@@ -30,6 +30,13 @@
 #include "or/node_st.h"
 #include "or/routerstatus_st.h"
 
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
 /** A data structure to hold a bunch of cached microdescriptors.  There are
  * two active files in the cache: a "cache file" that we mmap, and a "journal
  * file" that we append to.  Periodically, we rebuild the cache file to hold

+ 8 - 5
src/or/microdesc_st.h

@@ -7,6 +7,10 @@
 #ifndef MICRODESC_ST_H
 #define MICRODESC_ST_H
 
+struct curve25519_public_key_t;
+struct ed25519_public_key_t;
+struct short_policy_t;
+
 /** A microdescriptor is the smallest amount of information needed to build a
  * circuit through a router.  They are generated by the directory authorities,
  * using information from the uploaded routerinfo documents.  They are not
@@ -52,9 +56,9 @@ struct microdesc_t {
   /** As routerinfo_t.onion_pkey */
   crypto_pk_t *onion_pkey;
   /** As routerinfo_t.onion_curve25519_pkey */
-  curve25519_public_key_t *onion_curve25519_pkey;
+  struct curve25519_public_key_t *onion_curve25519_pkey;
   /** Ed25519 identity key, if included. */
-  ed25519_public_key_t *ed25519_identity_pkey;
+  struct ed25519_public_key_t *ed25519_identity_pkey;
   /** As routerinfo_t.ipv6_addr */
   tor_addr_t ipv6_addr;
   /** As routerinfo_t.ipv6_orport */
@@ -62,10 +66,9 @@ struct microdesc_t {
   /** As routerinfo_t.family */
   smartlist_t *family;
   /** IPv4 exit policy summary */
-  short_policy_t *exit_policy;
+  struct short_policy_t *exit_policy;
   /** IPv6 exit policy summary */
-  short_policy_t *ipv6_exit_policy;
+  struct short_policy_t *ipv6_exit_policy;
 };
 
 #endif
-

+ 5 - 1
src/or/networkstatus.c

@@ -45,6 +45,7 @@
 #include "or/circuitstats.h"
 #include "or/config.h"
 #include "or/connection.h"
+#include "or/connection_edge.h"
 #include "or/connection_or.h"
 #include "or/consdiffmgr.h"
 #include "or/control.h"
@@ -87,6 +88,10 @@
 #include "or/vote_microdesc_hash_st.h"
 #include "or/vote_routerstatus_st.h"
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 /** Most recently received and validated v3 "ns"-flavored consensus network
  * status. */
 STATIC networkstatus_t *current_ns_consensus = NULL;
@@ -2719,4 +2724,3 @@ networkstatus_free_all(void)
     tor_free(waiting->body);
   }
 }
-

+ 7 - 1
src/or/networkstatus_st.h

@@ -9,6 +9,13 @@
 
 #include "or/networkstatus_sr_info_st.h"
 
+/** Enumerates the possible seriousness values of a networkstatus document. */
+typedef enum networkstatus_type_t {
+  NS_TYPE_VOTE,
+  NS_TYPE_CONSENSUS,
+  NS_TYPE_OPINION,
+} networkstatus_type_t;
+
 /** A common structure to hold a v3 network status vote, or a v3 network
  * status consensus. */
 struct networkstatus_t {
@@ -92,4 +99,3 @@ struct networkstatus_t {
 };
 
 #endif
-

+ 1 - 1
src/or/node_st.h

@@ -8,6 +8,7 @@
 #define NODE_ST_H
 
 #include "or/hsdir_index_st.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
 
 /** A node_t represents a Tor router.
  *
@@ -99,4 +100,3 @@ struct node_t {
 };
 
 #endif
-

+ 9 - 6
src/or/nodelist.h

@@ -12,15 +12,19 @@
 #ifndef TOR_NODELIST_H
 #define TOR_NODELIST_H
 
+struct ed25519_public_key_t;
+struct curve25519_public_key_t;
+
 #define node_assert_ok(n) STMT_BEGIN {                          \
     tor_assert((n)->ri || (n)->rs);                             \
   } STMT_END
 
 MOCK_DECL(node_t *, node_get_mutable_by_id,(const char *identity_digest));
 MOCK_DECL(const node_t *, node_get_by_id, (const char *identity_digest));
-node_t *node_get_mutable_by_ed25519_id(const ed25519_public_key_t *ed_id);
+node_t *node_get_mutable_by_ed25519_id(
+                            const struct ed25519_public_key_t *ed_id);
 MOCK_DECL(const node_t *, node_get_by_ed25519_id,
-          (const ed25519_public_key_t *ed_id));
+          (const struct ed25519_public_key_t *ed_id));
 
 #define NNF_NO_WARN_UNNAMED (1u<<0)
 
@@ -65,9 +69,9 @@ uint32_t node_get_prim_addr_ipv4h(const node_t *node);
 void node_get_address_string(const node_t *node, char *cp, size_t len);
 long node_get_declared_uptime(const node_t *node);
 const smartlist_t *node_get_declared_family(const node_t *node);
-const ed25519_public_key_t *node_get_ed25519_id(const node_t *node);
+const struct ed25519_public_key_t *node_get_ed25519_id(const node_t *node);
 int node_ed25519_id_matches(const node_t *node,
-                            const ed25519_public_key_t *id);
+                            const struct ed25519_public_key_t *id);
 int node_supports_ed25519_link_authentication(const node_t *node,
                                               int compatible_with_us);
 int node_supports_v3_hsdir(const node_t *node);
@@ -89,7 +93,7 @@ void node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out);
 void node_get_pref_dirport(const node_t *node, tor_addr_port_t *ap_out);
 void node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out);
 int node_has_curve25519_onion_key(const node_t *node);
-const curve25519_public_key_t *node_get_curve25519_onion_key(
+const struct curve25519_public_key_t *node_get_curve25519_onion_key(
                                   const node_t *node);
 
 MOCK_DECL(smartlist_t *, nodelist_get_list, (void));
@@ -162,4 +166,3 @@ node_set_hsdir_index(node_t *node, const networkstatus_t *ns);
 MOCK_DECL(int, get_estimated_address_per_node, (void));
 
 #endif /* !defined(TOR_NODELIST_H) */
-

+ 1 - 0
src/or/ntmain.c

@@ -25,6 +25,7 @@
 #include "or/ntmain.h"
 #include "lib/log/win32err.h"
 #include "lib/fs/winlib.h"
+#include "common/compat_libevent.h"
 
 #include <windows.h>
 #define GENSRV_SERVICENAME  "tor"

+ 3 - 3
src/or/onion.c

@@ -68,6 +68,7 @@
 #include "or/config.h"
 #include "or/cpuworker.h"
 #include "lib/crypt_ops/crypto_util.h"
+#include "lib/crypt_ops/crypto_dh.h"
 #include "or/networkstatus.h"
 #include "or/onion.h"
 #include "or/onion_fast.h"
@@ -558,7 +559,7 @@ onion_skin_server_handshake(int type,
                                         (char*)keys_out, keys_out_len)<0)
       return -1;
     r = TAP_ONIONSKIN_REPLY_LEN;
-    memcpy(rend_nonce_out, reply_out+DH_KEY_LEN, DIGEST_LEN);
+    memcpy(rend_nonce_out, reply_out+DH1024_KEY_LEN, DIGEST_LEN);
     break;
   case ONION_HANDSHAKE_TYPE_FAST:
     if (onionskin_len != CREATE_FAST_LEN)
@@ -635,7 +636,7 @@ onion_skin_client_handshake(int type,
                                         msg_out) < 0)
       return -1;
 
-    memcpy(rend_authenticator_out, reply+DH_KEY_LEN, DIGEST_LEN);
+    memcpy(rend_authenticator_out, reply+DH1024_KEY_LEN, DIGEST_LEN);
 
     return 0;
   case ONION_HANDSHAKE_TYPE_FAST:
@@ -1343,4 +1344,3 @@ extended_cell_format(uint8_t *command_out, uint16_t *len_out,
 
   return 0;
 }
-

+ 7 - 4
src/or/onion.h

@@ -13,6 +13,10 @@
 #define TOR_ONION_H
 
 struct create_cell_t;
+struct curve25519_keypair_t;
+struct curve25519_public_key_t;
+#include "lib/crypt_ops/crypto_ed25519.h"
+
 int onion_pending_add(or_circuit_t *circ, struct create_cell_t *onionskin);
 or_circuit_t *onion_next_task(struct create_cell_t **onionskin_out);
 int onion_num_pending(uint16_t handshake_type);
@@ -23,8 +27,8 @@ typedef struct server_onion_keys_t {
   uint8_t my_identity[DIGEST_LEN];
   crypto_pk_t *onion_key;
   crypto_pk_t *last_onion_key;
-  di_digest256_map_t *curve25519_key_map;
-  curve25519_keypair_t *junk_keypair;
+  struct di_digest256_map_t *curve25519_key_map;
+  struct curve25519_keypair_t *junk_keypair;
 } server_onion_keys_t;
 
 #define MAX_ONIONSKIN_CHALLENGE_LEN 255
@@ -88,7 +92,7 @@ typedef struct extend_cell_t {
   /** Identity fingerprint of the node we're conecting to.*/
   uint8_t node_id[DIGEST_LEN];
   /** Ed25519 public identity key. Zero if not set. */
-  ed25519_public_key_t ed_pubkey;
+  struct ed25519_public_key_t ed_pubkey;
   /** The "create cell" embedded in this extend cell. Note that unlike the
    * create cells we generate ourself, this once can have a handshake type we
    * don't recognize. */
@@ -122,4 +126,3 @@ int extended_cell_format(uint8_t *command_out, uint16_t *len_out,
                          uint8_t *payload_out, const extended_cell_t *cell_in);
 
 #endif /* !defined(TOR_ONION_H) */
-

+ 1 - 1
src/or/onion_fast.c

@@ -29,6 +29,7 @@
 
 #include "or/or.h"
 #include "or/onion_fast.h"
+#include "lib/crypt_ops/crypto_hkdf.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
 
@@ -141,4 +142,3 @@ fast_client_handshake(const fast_handshake_state_t *handshake_state,
   tor_free(out);
   return r;
 }
-

+ 1 - 1
src/or/onion_ntor.c

@@ -27,6 +27,7 @@
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/onion_ntor.h"
 #include "lib/log/torlog.h"
+#include "lib/ctime/di_ops.h"
 #include "common/util.h"
 
 /** Free storage held in an ntor handshake state. */
@@ -335,4 +336,3 @@ onion_skin_ntor_client_handshake(
 
   return bad ? -1 : 0;
 }
-

+ 12 - 10
src/or/onion_ntor.h

@@ -5,8 +5,10 @@
 #define TOR_ONION_NTOR_H
 
 #include "lib/cc/torint.h"
-#include "lib/crypt_ops/crypto_curve25519.h"
-#include "lib/ctime/di_ops.h"
+
+struct di_digest256_map_t;
+struct curve25519_public_key_t;
+struct curve25519_keypair_t;
 
 /** State to be maintained by a client between sending an ntor onionskin
  * and receiving a reply. */
@@ -22,17 +24,17 @@ void ntor_handshake_state_free_(ntor_handshake_state_t *state);
   FREE_AND_NULL(ntor_handshake_state_t, ntor_handshake_state_free_, (state))
 
 int onion_skin_ntor_create(const uint8_t *router_id,
-                           const curve25519_public_key_t *router_key,
+                           const struct curve25519_public_key_t *router_key,
                            ntor_handshake_state_t **handshake_state_out,
                            uint8_t *onion_skin_out);
 
 int onion_skin_ntor_server_handshake(const uint8_t *onion_skin,
-                                 const di_digest256_map_t *private_keys,
-                                 const curve25519_keypair_t *junk_keypair,
-                                 const uint8_t *my_node_id,
-                                 uint8_t *handshake_reply_out,
-                                 uint8_t *key_out,
-                                 size_t key_out_len);
+                           const struct di_digest256_map_t *private_keys,
+                           const struct curve25519_keypair_t *junk_keypair,
+                           const uint8_t *my_node_id,
+                           uint8_t *handshake_reply_out,
+                           uint8_t *key_out,
+                           size_t key_out_len);
 
 int onion_skin_ntor_client_handshake(
                              const ntor_handshake_state_t *handshake_state,
@@ -42,6 +44,7 @@ int onion_skin_ntor_client_handshake(
                              const char **msg_out);
 
 #ifdef ONION_NTOR_PRIVATE
+#include "lib/crypt_ops/crypto_curve25519.h"
 
 /** Storage held by a client while waiting for an ntor reply from a server. */
 struct ntor_handshake_state_t {
@@ -60,4 +63,3 @@ struct ntor_handshake_state_t {
 #endif /* defined(ONION_NTOR_PRIVATE) */
 
 #endif /* !defined(TOR_ONION_NTOR_H) */
-

+ 10 - 10
src/or/onion_tap.c

@@ -29,6 +29,7 @@
 
 #include "or/or.h"
 #include "or/config.h"
+#include "lib/crypt_ops/crypto_dh.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/crypt_ops/crypto_util.h"
 #include "or/onion_tap.h"
@@ -53,7 +54,7 @@ onion_skin_TAP_create(crypto_pk_t *dest_router_key,
                   crypto_dh_t **handshake_state_out,
                   char *onion_skin_out) /* TAP_ONIONSKIN_CHALLENGE_LEN bytes */
 {
-  char challenge[DH_KEY_LEN];
+  char challenge[DH1024_KEY_LEN];
   crypto_dh_t *dh = NULL;
   int dhbytes, pkbytes;
 
@@ -77,7 +78,7 @@ onion_skin_TAP_create(crypto_pk_t *dest_router_key,
   /* set meeting point, meeting cookie, etc here. Leave zero for now. */
   if (crypto_pk_obsolete_public_hybrid_encrypt(dest_router_key, onion_skin_out,
                                       TAP_ONIONSKIN_CHALLENGE_LEN,
-                                      challenge, DH_KEY_LEN,
+                                      challenge, DH1024_KEY_LEN,
                                       PK_PKCS1_OAEP_PADDING, 1)<0)
     goto err;
 
@@ -136,7 +137,7 @@ onion_skin_TAP_server_handshake(
     log_info(LD_PROTOCOL,
              "Couldn't decrypt onionskin: client may be using old onion key");
     goto err;
-  } else if (len != DH_KEY_LEN) {
+  } else if (len != DH1024_KEY_LEN) {
     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
            "Unexpected onionskin length after decryption: %ld",
            (long)len);
@@ -152,7 +153,7 @@ onion_skin_TAP_server_handshake(
     goto err;
     /* LCOV_EXCL_STOP */
   }
-  if (crypto_dh_get_public(dh, handshake_reply_out, DH_KEY_LEN)) {
+  if (crypto_dh_get_public(dh, handshake_reply_out, DH1024_KEY_LEN)) {
     /* LCOV_EXCL_START
      * This can only fail if the length of the key we just allocated is too
      * big. That should be impossible. */
@@ -164,7 +165,7 @@ onion_skin_TAP_server_handshake(
   key_material_len = DIGEST_LEN+key_out_len;
   key_material = tor_malloc(key_material_len);
   len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh, challenge,
-                                 DH_KEY_LEN, key_material,
+                                 DH1024_KEY_LEN, key_material,
                                  key_material_len);
   if (len < 0) {
     log_info(LD_GENERAL, "crypto_dh_compute_secret failed.");
@@ -172,7 +173,7 @@ onion_skin_TAP_server_handshake(
   }
 
   /* send back H(K|0) as proof that we learned K. */
-  memcpy(handshake_reply_out+DH_KEY_LEN, key_material, DIGEST_LEN);
+  memcpy(handshake_reply_out+DH1024_KEY_LEN, key_material, DIGEST_LEN);
 
   /* use the rest of the key material for our shared keys, digests, etc */
   memcpy(key_out, key_material+DIGEST_LEN, key_out_len);
@@ -212,12 +213,12 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
   ssize_t len;
   char *key_material=NULL;
   size_t key_material_len;
-  tor_assert(crypto_dh_get_bytes(handshake_state) == DH_KEY_LEN);
+  tor_assert(crypto_dh_get_bytes(handshake_state) == DH1024_KEY_LEN);
 
   key_material_len = DIGEST_LEN + key_out_len;
   key_material = tor_malloc(key_material_len);
   len = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, handshake_state,
-                                 handshake_reply, DH_KEY_LEN, key_material,
+                                 handshake_reply, DH1024_KEY_LEN, key_material,
                                  key_material_len);
   if (len < 0) {
     if (msg_out)
@@ -225,7 +226,7 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
     goto err;
   }
 
-  if (tor_memneq(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) {
+  if (tor_memneq(key_material, handshake_reply+DH1024_KEY_LEN, DIGEST_LEN)) {
     /* H(K) does *not* match. Something fishy. */
     if (msg_out)
       *msg_out = "Digest DOES NOT MATCH on onion handshake. Bug or attack.";
@@ -243,4 +244,3 @@ onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
   tor_free(key_material);
   return -1;
 }
-

+ 10 - 8
src/or/onion_tap.h

@@ -14,25 +14,27 @@
 
 #define TAP_ONIONSKIN_CHALLENGE_LEN (PKCS1_OAEP_PADDING_OVERHEAD+\
                                  CIPHER_KEY_LEN+\
-                                 DH_KEY_LEN)
-#define TAP_ONIONSKIN_REPLY_LEN (DH_KEY_LEN+DIGEST_LEN)
+                                 DH1024_KEY_LEN)
+#define TAP_ONIONSKIN_REPLY_LEN (DH1024_KEY_LEN+DIGEST_LEN)
 
-int onion_skin_TAP_create(crypto_pk_t *router_key,
-                      crypto_dh_t **handshake_state_out,
+struct crypto_dh_t;
+struct crypto_pk_t;
+
+int onion_skin_TAP_create(struct crypto_pk_t *router_key,
+                      struct crypto_dh_t **handshake_state_out,
                       char *onion_skin_out);
 
 int onion_skin_TAP_server_handshake(const char *onion_skin,
-                                crypto_pk_t *private_key,
-                                crypto_pk_t *prev_private_key,
+                                struct crypto_pk_t *private_key,
+                                struct crypto_pk_t *prev_private_key,
                                 char *handshake_reply_out,
                                 char *key_out,
                                 size_t key_out_len);
 
-int onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state,
+int onion_skin_TAP_client_handshake(struct crypto_dh_t *handshake_state,
                                 const char *handshake_reply,
                                 char *key_out,
                                 size_t key_out_len,
                                 const char **msg_out);
 
 #endif /* !defined(TOR_ONION_TAP_H) */
-

File diff suppressed because it is too large
+ 17 - 1906
src/or/or.h


+ 4 - 2
src/or/or_connection_st.h

@@ -8,6 +8,9 @@
 #define OR_CONNECTION_ST_H
 
 #include "or/connection_st.h"
+#include "common/token_bucket.h"
+
+struct tor_tls_t;
 
 /** Subtype of connection_t for an "OR connection" -- that is, one that speaks
  * cells over TLS. */
@@ -33,7 +36,7 @@ struct or_connection_t {
 
   char *nickname; /**< Nickname of OR on other side (if any). */
 
-  tor_tls_t *tls; /**< TLS connection state. */
+  struct tor_tls_t *tls; /**< TLS connection state. */
   int tls_error; /**< Last tor_tls error code. */
   /** When we last used this conn for any client traffic. If not
    * recent, we can rate limit it further. */
@@ -87,4 +90,3 @@ struct or_connection_t {
 };
 
 #endif
-

+ 5 - 4
src/or/or_handshake_certs_st.h

@@ -7,6 +7,8 @@
 #ifndef OR_HANDSHAKE_CERTS_ST
 #define OR_HANDSHAKE_CERTS_ST
 
+struct tor_x509_cert_t;
+
 /** Structure to hold all the certificates we've received on an OR connection
  */
 struct or_handshake_certs_t {
@@ -14,13 +16,13 @@ struct or_handshake_certs_t {
   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;
+  struct tor_x509_cert_t *auth_cert;
   /** The cert for the 'link' RSA key that was used to negotiate the TLS
    *  connection.  Signed with the RSA identity key. */
-  tor_x509_cert_t *link_cert;
+  struct tor_x509_cert_t *link_cert;
   /** A self-signed identity certificate: the RSA identity key signed
    * with itself.  */
-  tor_x509_cert_t *id_cert;
+  struct tor_x509_cert_t *id_cert;
   /** The Ed25519 signing key, signed with the Ed25519 identity key. */
   struct tor_cert_st *ed_id_sign;
   /** A digest of the X509 link certificate for the TLS connection, signed
@@ -36,4 +38,3 @@ struct or_handshake_certs_t {
 };
 
 #endif
-

+ 1077 - 0
src/or/or_options_st.h

@@ -0,0 +1,1077 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_OR_OPTIONS_ST_H
+#define TOR_OR_OPTIONS_ST_H
+
+#include "lib/cc/torint.h"
+#include "lib/net/address.h"
+
+struct smartlist_t;
+struct config_line_t;
+
+/** Enumeration of outbound address configuration types:
+ * Exit-only, OR-only, or both */
+typedef enum {OUTBOUND_ADDR_EXIT, OUTBOUND_ADDR_OR,
+              OUTBOUND_ADDR_EXIT_AND_OR,
+              OUTBOUND_ADDR_MAX} outbound_addr_t;
+
+/** Configuration options for a Tor process. */
+struct or_options_t {
+  uint32_t magic_;
+
+  /** What should the tor process actually do? */
+  enum {
+    CMD_RUN_TOR=0, CMD_LIST_FINGERPRINT, CMD_HASH_PASSWORD,
+    CMD_VERIFY_CONFIG, CMD_RUN_UNITTESTS, CMD_DUMP_CONFIG,
+    CMD_KEYGEN,
+    CMD_KEY_EXPIRATION,
+  } command;
+  char *command_arg; /**< Argument for command-line option. */
+
+  struct config_line_t *Logs; /**< New-style list of configuration lines
+                        * for logs */
+  int LogTimeGranularity; /**< Log resolution in milliseconds. */
+
+  int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which
+                          * each log message occurs? */
+  int TruncateLogFile; /**< Boolean: Should we truncate the log file
+                            before we start writing? */
+  char *SyslogIdentityTag; /**< Identity tag to add for syslog logging. */
+  char *AndroidIdentityTag; /**< Identity tag to add for Android logging. */
+
+  char *DebugLogFile; /**< Where to send verbose log messages. */
+  char *DataDirectory_option; /**< Where to store long-term data, as
+                               * configured by the user. */
+  char *DataDirectory; /**< Where to store long-term data, as modified. */
+  int DataDirectoryGroupReadable; /**< Boolean: Is the DataDirectory g+r? */
+
+  char *KeyDirectory_option; /**< Where to store keys, as
+                               * configured by the user. */
+  char *KeyDirectory; /**< Where to store keys data, as modified. */
+  int KeyDirectoryGroupReadable; /**< Boolean: Is the KeyDirectory g+r? */
+
+  char *CacheDirectory_option; /**< Where to store cached data, as
+                               * configured by the user. */
+  char *CacheDirectory; /**< Where to store cached data, as modified. */
+  int CacheDirectoryGroupReadable; /**< Boolean: Is the CacheDirectory g+r? */
+
+  char *Nickname; /**< OR only: nickname of this onion router. */
+  char *Address; /**< OR only: configured address for this onion router. */
+  char *PidFile; /**< Where to store PID of Tor process. */
+
+  routerset_t *ExitNodes; /**< Structure containing nicknames, digests,
+                           * country codes and IP address patterns of ORs to
+                           * consider as exits. */
+  routerset_t *EntryNodes;/**< Structure containing nicknames, digests,
+                           * country codes and IP address patterns of ORs to
+                           * consider as entry points. */
+  int StrictNodes; /**< Boolean: When none of our EntryNodes or ExitNodes
+                    * are up, or we need to access a node in ExcludeNodes,
+                    * do we just fail instead? */
+  routerset_t *ExcludeNodes;/**< Structure containing nicknames, digests,
+                             * country codes and IP address patterns of ORs
+                             * not to use in circuits. But see StrictNodes
+                             * above. */
+  routerset_t *ExcludeExitNodes;/**< Structure containing nicknames, digests,
+                                 * country codes and IP address patterns of
+                                 * ORs not to consider as exits. */
+
+  /** Union of ExcludeNodes and ExcludeExitNodes */
+  routerset_t *ExcludeExitNodesUnion_;
+
+  int DisableAllSwap; /**< Boolean: Attempt to call mlockall() on our
+                       * process for all current and future memory. */
+
+  struct config_line_t *ExitPolicy; /**< Lists of exit policy components. */
+  int ExitPolicyRejectPrivate; /**< Should we not exit to reserved private
+                                * addresses, and our own published addresses?
+                                */
+  int ExitPolicyRejectLocalInterfaces; /**< Should we not exit to local
+                                        * interface addresses?
+                                        * Includes OutboundBindAddresses and
+                                        * configured ports. */
+  int ReducedExitPolicy; /**<Should we use the Reduced Exit Policy? */
+  struct config_line_t *SocksPolicy; /**< Lists of socks policy components */
+  struct config_line_t *DirPolicy; /**< Lists of dir policy components */
+  /** Local address to bind outbound sockets */
+  struct config_line_t *OutboundBindAddress;
+  /** Local address to bind outbound relay sockets */
+  struct config_line_t *OutboundBindAddressOR;
+  /** Local address to bind outbound exit sockets */
+  struct config_line_t *OutboundBindAddressExit;
+  /** Addresses derived from the various OutboundBindAddress lines.
+   * [][0] is IPv4, [][1] is IPv6
+   */
+  tor_addr_t OutboundBindAddresses[OUTBOUND_ADDR_MAX][2];
+  /** Directory server only: which versions of
+   * Tor should we tell users to run? */
+  struct config_line_t *RecommendedVersions;
+  struct config_line_t *RecommendedClientVersions;
+  struct config_line_t *RecommendedServerVersions;
+  struct config_line_t *RecommendedPackages;
+  /** Whether dirservers allow router descriptors with private IPs. */
+  int DirAllowPrivateAddresses;
+  /** Whether routers accept EXTEND cells to routers with private IPs. */
+  int ExtendAllowPrivateAddresses;
+  char *User; /**< Name of user to run Tor as. */
+   /** Ports to listen on for OR connections. */
+  struct config_line_t *ORPort_lines;
+  /** Ports to listen on for extended OR connections. */
+  struct config_line_t *ExtORPort_lines;
+  /** Ports to listen on for SOCKS connections. */
+  struct config_line_t *SocksPort_lines;
+  /** Ports to listen on for transparent pf/netfilter connections. */
+  struct config_line_t *TransPort_lines;
+  char *TransProxyType; /**< What kind of transparent proxy
+                         * implementation are we using? */
+  /** Parsed value of TransProxyType. */
+  enum {
+    TPT_DEFAULT,
+    TPT_PF_DIVERT,
+    TPT_IPFW,
+    TPT_TPROXY,
+  } TransProxyType_parsed;
+  /** Ports to listen on for transparent natd connections. */
+  struct config_line_t *NATDPort_lines;
+  /** Ports to listen on for HTTP Tunnel connections. */
+  struct config_line_t *HTTPTunnelPort_lines;
+  struct config_line_t *ControlPort_lines; /**< Ports to listen on for control
+                               * connections. */
+  /** List of Unix Domain Sockets to listen on for control connections. */
+  struct config_line_t *ControlSocket;
+
+  int ControlSocketsGroupWritable; /**< Boolean: Are control sockets g+rw? */
+  int UnixSocksGroupWritable; /**< Boolean: Are SOCKS Unix sockets g+rw? */
+  /** Ports to listen on for directory connections. */
+  struct config_line_t *DirPort_lines;
+  /** Ports to listen on for DNS requests. */
+  struct config_line_t *DNSPort_lines;
+
+  /* MaxMemInQueues value as input by the user. We clean this up to be
+   * MaxMemInQueues. */
+  uint64_t MaxMemInQueues_raw;
+  uint64_t MaxMemInQueues;/**< If we have more memory than this allocated
+                            * for queues and buffers, run the OOM handler */
+  /** Above this value, consider ourselves low on RAM. */
+  uint64_t MaxMemInQueues_low_threshold;
+
+  /** @name port booleans
+   *
+   * Derived booleans: For server ports and ControlPort, true iff there is a
+   * non-listener port on an AF_INET or AF_INET6 address of the given type
+   * configured in one of the _lines options above.
+   * For client ports, also true if there is a unix socket configured.
+   * If you are checking for client ports, you may want to use:
+   *   SocksPort_set || TransPort_set || NATDPort_set || DNSPort_set ||
+   *   HTTPTunnelPort_set
+   * rather than SocksPort_set.
+   *
+   * @{
+   */
+  unsigned int ORPort_set : 1;
+  unsigned int SocksPort_set : 1;
+  unsigned int TransPort_set : 1;
+  unsigned int NATDPort_set : 1;
+  unsigned int ControlPort_set : 1;
+  unsigned int DirPort_set : 1;
+  unsigned int DNSPort_set : 1;
+  unsigned int ExtORPort_set : 1;
+  unsigned int HTTPTunnelPort_set : 1;
+  /**@}*/
+
+  int AssumeReachable; /**< Whether to publish our descriptor regardless. */
+  int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */
+  int V3AuthoritativeDir; /**< Boolean: is this an authoritative directory
+                           * for version 3 directories? */
+  int VersioningAuthoritativeDir; /**< Boolean: is this an authoritative
+                                   * directory that's willing to recommend
+                                   * versions? */
+  int BridgeAuthoritativeDir; /**< Boolean: is this an authoritative directory
+                               * that aggregates bridge descriptors? */
+
+  /** If set on a bridge relay, it will include this value on a new
+   * "bridge-distribution-request" line in its bridge descriptor. */
+  char *BridgeDistribution;
+
+  /** If set on a bridge authority, it will answer requests on its dirport
+   * for bridge statuses -- but only if the requests use this password. */
+  char *BridgePassword;
+  /** If BridgePassword is set, this is a SHA256 digest of the basic http
+   * authenticator for it. Used so we can do a time-independent comparison. */
+  char *BridgePassword_AuthDigest_;
+
+  int UseBridges; /**< Boolean: should we start all circuits with a bridge? */
+  struct config_line_t *Bridges; /**< List of bootstrap bridge addresses. */
+
+  struct config_line_t *ClientTransportPlugin; /**< List of client
+                                           transport plugins. */
+
+  struct config_line_t *ServerTransportPlugin; /**< List of client
+                                           transport plugins. */
+
+  /** List of TCP/IP addresses that transports should listen at. */
+  struct config_line_t *ServerTransportListenAddr;
+
+  /** List of options that must be passed to pluggable transports. */
+  struct config_line_t *ServerTransportOptions;
+
+  int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
+                    * this explicit so we can change how we behave in the
+                    * future. */
+
+  /** Boolean: if we know the bridge's digest, should we get new
+   * descriptors from the bridge authorities or from the bridge itself? */
+  int UpdateBridgesFromAuthority;
+
+  int AvoidDiskWrites; /**< Boolean: should we never cache things to disk?
+                        * Not used yet. */
+  int ClientOnly; /**< Boolean: should we never evolve into a server role? */
+
+  int ReducedConnectionPadding; /**< Boolean: Should we try to keep connections
+                                  open shorter and pad them less against
+                                  connection-level traffic analysis? */
+  /** Autobool: if auto, then connection padding will be negotiated by client
+   * and server. If 0, it will be fully disabled. If 1, the client will still
+   * pad to the server regardless of server support. */
+  int ConnectionPadding;
+
+  /** To what authority types do we publish our descriptor? Choices are
+   * "v1", "v2", "v3", "bridge", or "". */
+  struct smartlist_t *PublishServerDescriptor;
+  /** A bitfield of authority types, derived from PublishServerDescriptor. */
+  dirinfo_type_t PublishServerDescriptor_;
+  /** Boolean: do we publish hidden service descriptors to the HS auths? */
+  int PublishHidServDescriptors;
+  int FetchServerDescriptors; /**< Do we fetch server descriptors as normal? */
+  int FetchHidServDescriptors; /**< and hidden service descriptors? */
+
+  int MinUptimeHidServDirectoryV2; /**< As directory authority, accept hidden
+                                    * service directories after what time? */
+
+  int FetchUselessDescriptors; /**< Do we fetch non-running descriptors too? */
+  int AllDirActionsPrivate; /**< Should every directory action be sent
+                             * through a Tor circuit? */
+
+  /** Run in 'tor2web mode'? (I.e. only make client connections to hidden
+   * services, and use a single hop for all hidden-service-related
+   * circuits.) */
+  int Tor2webMode;
+
+  /** A routerset that should be used when picking RPs for HS circuits. */
+  routerset_t *Tor2webRendezvousPoints;
+
+  /** A routerset that should be used when picking middle nodes for HS
+   *  circuits. */
+  routerset_t *HSLayer2Nodes;
+
+  /** A routerset that should be used when picking third-hop nodes for HS
+   *  circuits. */
+  routerset_t *HSLayer3Nodes;
+
+  /** Onion Services in HiddenServiceSingleHopMode make one-hop (direct)
+   * circuits between the onion service server, and the introduction and
+   * rendezvous points. (Onion service descriptors are still posted using
+   * 3-hop paths, to avoid onion service directories blocking the service.)
+   * This option makes every hidden service instance hosted by
+   * this tor instance a Single Onion Service.
+   * HiddenServiceSingleHopMode requires HiddenServiceNonAnonymousMode to be
+   * set to 1.
+   * Use rend_service_allow_non_anonymous_connection() or
+   * rend_service_reveal_startup_time() instead of using this option directly.
+   */
+  int HiddenServiceSingleHopMode;
+  /* Makes hidden service clients and servers non-anonymous on this tor
+   * instance. Allows the non-anonymous HiddenServiceSingleHopMode. Enables
+   * non-anonymous behaviour in the hidden service protocol.
+   * Use rend_service_non_anonymous_mode_enabled() instead of using this option
+   * directly.
+   */
+  int HiddenServiceNonAnonymousMode;
+
+  int ConnLimit; /**< Demanded minimum number of simultaneous connections. */
+  int ConnLimit_; /**< Maximum allowed number of simultaneous connections. */
+  int ConnLimit_high_thresh; /**< start trying to lower socket usage if we
+                              *   have this many. */
+  int ConnLimit_low_thresh; /**< try to get down to here after socket
+                             *   exhaustion. */
+  int RunAsDaemon; /**< If true, run in the background. (Unix only) */
+  int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */
+  struct smartlist_t *FirewallPorts; /**< Which ports our firewall allows
+                               * (strings). */
+   /** IP:ports our firewall allows. */
+  struct config_line_t *ReachableAddresses;
+  struct config_line_t *ReachableORAddresses; /**< IP:ports for OR conns. */
+  struct config_line_t *ReachableDirAddresses; /**< IP:ports for Dir conns. */
+
+  int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */
+  uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */
+
+  /** Whether we should drop exit streams from Tors that we don't know are
+   * relays.  One of "0" (never refuse), "1" (always refuse), or "-1" (do
+   * what the consensus says, defaulting to 'refuse' if the consensus says
+   * nothing). */
+  int RefuseUnknownExits;
+
+  /** Application ports that require all nodes in circ to have sufficient
+   * uptime. */
+  struct smartlist_t *LongLivedPorts;
+  /** Application ports that are likely to be unencrypted and
+   * unauthenticated; we reject requests for them to prevent the
+   * user from screwing up and leaking plaintext secrets to an
+   * observer somewhere on the Internet. */
+  struct smartlist_t *RejectPlaintextPorts;
+  /** Related to RejectPlaintextPorts above, except this config option
+   * controls whether we warn (in the log and via a controller status
+   * event) every time a risky connection is attempted. */
+  struct smartlist_t *WarnPlaintextPorts;
+  /** Should we try to reuse the same exit node for a given host */
+  struct smartlist_t *TrackHostExits;
+  int TrackHostExitsExpire; /**< Number of seconds until we expire an
+                             * addressmap */
+  struct config_line_t *AddressMap; /**< List of address map directives. */
+  int AutomapHostsOnResolve; /**< If true, when we get a resolve request for a
+                              * hostname ending with one of the suffixes in
+                              * <b>AutomapHostsSuffixes</b>, map it to a
+                              * virtual address. */
+  /** List of suffixes for <b>AutomapHostsOnResolve</b>.  The special value
+   * "." means "match everything." */
+  struct smartlist_t *AutomapHostsSuffixes;
+  int RendPostPeriod; /**< How often do we post each rendezvous service
+                       * descriptor? Remember to publish them independently. */
+  int KeepalivePeriod; /**< How often do we send padding cells to keep
+                        * connections alive? */
+  int SocksTimeout; /**< How long do we let a socks connection wait
+                     * unattached before we fail it? */
+  int LearnCircuitBuildTimeout; /**< If non-zero, we attempt to learn a value
+                                 * for CircuitBuildTimeout based on timeout
+                                 * history. Use circuit_build_times_disabled()
+                                 * rather than checking this value directly. */
+  int CircuitBuildTimeout; /**< Cull non-open circuits that were born at
+                            * least this many seconds ago. Used until
+                            * adaptive algorithm learns a new value. */
+  int CircuitsAvailableTimeout; /**< Try to have an open circuit for at
+                                     least this long after last activity */
+  int CircuitStreamTimeout; /**< If non-zero, detach streams from circuits
+                             * and try a new circuit if the stream has been
+                             * waiting for this many seconds. If zero, use
+                             * our default internal timeout schedule. */
+  int MaxOnionQueueDelay; /*< DOCDOC */
+  int NewCircuitPeriod; /**< How long do we use a circuit before building
+                         * a new one? */
+  int MaxCircuitDirtiness; /**< Never use circs that were first used more than
+                                this interval ago. */
+  uint64_t BandwidthRate; /**< How much bandwidth, on average, are we willing
+                           * to use in a second? */
+  uint64_t BandwidthBurst; /**< How much bandwidth, at maximum, are we willing
+                            * to use in a second? */
+  uint64_t MaxAdvertisedBandwidth; /**< How much bandwidth are we willing to
+                                    * tell other nodes we have? */
+  uint64_t RelayBandwidthRate; /**< How much bandwidth, on average, are we
+                                 * willing to use for all relayed conns? */
+  uint64_t RelayBandwidthBurst; /**< How much bandwidth, at maximum, will we
+                                 * use in a second for all relayed conns? */
+  uint64_t PerConnBWRate; /**< Long-term bw on a single TLS conn, if set. */
+  uint64_t PerConnBWBurst; /**< Allowed burst on a single TLS conn, if set. */
+  int NumCPUs; /**< How many CPUs should we try to use? */
+  struct config_line_t *RendConfigLines; /**< List of configuration lines
+                                          * for rendezvous services. */
+  struct config_line_t *HidServAuth; /**< List of configuration lines for
+                               * client-side authorizations for hidden
+                               * services */
+  char *ContactInfo; /**< Contact info to be published in the directory. */
+
+  int HeartbeatPeriod; /**< Log heartbeat messages after this many seconds
+                        * have passed. */
+  int MainloopStats; /**< Log main loop statistics as part of the
+                      * heartbeat messages. */
+
+  char *HTTPProxy; /**< hostname[:port] to use as http proxy, if any. */
+  tor_addr_t HTTPProxyAddr; /**< Parsed IPv4 addr for http proxy, if any. */
+  uint16_t HTTPProxyPort; /**< Parsed port for http proxy, if any. */
+  char *HTTPProxyAuthenticator; /**< username:password string, if any. */
+
+  char *HTTPSProxy; /**< hostname[:port] to use as https proxy, if any. */
+  tor_addr_t HTTPSProxyAddr; /**< Parsed addr for https proxy, if any. */
+  uint16_t HTTPSProxyPort; /**< Parsed port for https proxy, if any. */
+  char *HTTPSProxyAuthenticator; /**< username:password string, if any. */
+
+  char *Socks4Proxy; /**< hostname:port to use as a SOCKS4 proxy, if any. */
+  tor_addr_t Socks4ProxyAddr; /**< Derived from Socks4Proxy. */
+  uint16_t Socks4ProxyPort; /**< Derived from Socks4Proxy. */
+
+  char *Socks5Proxy; /**< hostname:port to use as a SOCKS5 proxy, if any. */
+  tor_addr_t Socks5ProxyAddr; /**< Derived from Sock5Proxy. */
+  uint16_t Socks5ProxyPort; /**< Derived from Socks5Proxy. */
+  char *Socks5ProxyUsername; /**< Username for SOCKS5 authentication, if any */
+  char *Socks5ProxyPassword; /**< Password for SOCKS5 authentication, if any */
+
+  /** List of configuration lines for replacement directory authorities.
+   * If you just want to replace one class of authority at a time,
+   * use the "Alternate*Authority" options below instead. */
+  struct config_line_t *DirAuthorities;
+
+  /** List of fallback directory servers */
+  struct config_line_t *FallbackDir;
+  /** Whether to use the default hard-coded FallbackDirs */
+  int UseDefaultFallbackDirs;
+
+  /** Weight to apply to all directory authority rates if considering them
+   * along with fallbackdirs */
+  double DirAuthorityFallbackRate;
+
+  /** If set, use these main (currently v3) directory authorities and
+   * not the default ones. */
+  struct config_line_t *AlternateDirAuthority;
+
+  /** If set, use these bridge authorities and not the default one. */
+  struct config_line_t *AlternateBridgeAuthority;
+
+  struct config_line_t *MyFamily_lines; /**< Declared family for this OR. */
+  struct config_line_t *MyFamily; /**< Declared family for this OR,
+                                     normalized */
+  struct config_line_t *NodeFamilies; /**< List of config lines for
+                                * node families */
+  /** List of parsed NodeFamilies values. */
+  struct smartlist_t *NodeFamilySets;
+  struct config_line_t *AuthDirBadExit; /**< Address policy for descriptors to
+                                  * mark as bad exits. */
+  struct config_line_t *AuthDirReject; /**< Address policy for descriptors to
+                                 * reject. */
+  struct config_line_t *AuthDirInvalid; /**< Address policy for descriptors to
+                                  * never mark as valid. */
+  /** @name AuthDir...CC
+   *
+   * Lists of country codes to mark as BadExit, or Invalid, or to
+   * reject entirely.
+   *
+   * @{
+   */
+  struct smartlist_t *AuthDirBadExitCCs;
+  struct smartlist_t *AuthDirInvalidCCs;
+  struct smartlist_t *AuthDirRejectCCs;
+  /**@}*/
+
+  int AuthDirListBadExits; /**< True iff we should list bad exits,
+                            * and vote for all other exits as good. */
+  int AuthDirMaxServersPerAddr; /**< Do not permit more than this
+                                 * number of servers per IP address. */
+  int AuthDirHasIPv6Connectivity; /**< Boolean: are we on IPv6?  */
+  int AuthDirPinKeys; /**< Boolean: Do we enforce key-pinning? */
+
+  /** If non-zero, always vote the Fast flag for any relay advertising
+   * this amount of capacity or more. */
+  uint64_t AuthDirFastGuarantee;
+
+  /** If non-zero, this advertised capacity or more is always sufficient
+   * to satisfy the bandwidth requirement for the Guard flag. */
+  uint64_t AuthDirGuardBWGuarantee;
+
+  char *AccountingStart; /**< How long is the accounting interval, and when
+                          * does it start? */
+  uint64_t AccountingMax; /**< How many bytes do we allow per accounting
+                           * interval before hibernation?  0 for "never
+                           * hibernate." */
+  /** How do we determine when our AccountingMax has been reached?
+   * "max" for when in or out reaches AccountingMax
+   * "sum" for when in plus out reaches AccountingMax
+   * "in"  for when in reaches AccountingMax
+   * "out" for when out reaches AccountingMax */
+  char *AccountingRule_option;
+  enum { ACCT_MAX, ACCT_SUM, ACCT_IN, ACCT_OUT } AccountingRule;
+
+  /** Base64-encoded hash of accepted passwords for the control system. */
+  struct config_line_t *HashedControlPassword;
+  /** As HashedControlPassword, but not saved. */
+  struct config_line_t *HashedControlSessionPassword;
+
+  int CookieAuthentication; /**< Boolean: do we enable cookie-based auth for
+                             * the control system? */
+  char *CookieAuthFile; /**< Filesystem location of a ControlPort
+                         *   authentication cookie. */
+  char *ExtORPortCookieAuthFile; /**< Filesystem location of Extended
+                                 *   ORPort authentication cookie. */
+  int CookieAuthFileGroupReadable; /**< Boolean: Is the CookieAuthFile g+r? */
+  int ExtORPortCookieAuthFileGroupReadable; /**< Boolean: Is the
+                                             * ExtORPortCookieAuthFile g+r? */
+  int LeaveStreamsUnattached; /**< Boolean: Does Tor attach new streams to
+                          * circuits itself (0), or does it expect a controller
+                          * to cope? (1) */
+  int DisablePredictedCircuits; /**< Boolean: does Tor preemptively
+                                 * make circuits in the background (0),
+                                 * or not (1)? */
+
+  /** Process specifier for a controller that ‘owns’ this Tor
+   * instance.  Tor will terminate if its owning controller does. */
+  char *OwningControllerProcess;
+  /** FD specifier for a controller that owns this Tor instance. */
+  int OwningControllerFD;
+
+  int ShutdownWaitLength; /**< When we get a SIGINT and we're a server, how
+                           * long do we wait before exiting? */
+  char *SafeLogging; /**< Contains "relay", "1", "0" (meaning no scrubbing). */
+
+  /* Derived from SafeLogging */
+  enum {
+    SAFELOG_SCRUB_ALL, SAFELOG_SCRUB_RELAY, SAFELOG_SCRUB_NONE
+  } SafeLogging_;
+
+  int Sandbox; /**< Boolean: should sandboxing be enabled? */
+  int SafeSocks; /**< Boolean: should we outright refuse application
+                  * connections that use socks4 or socks5-with-local-dns? */
+  int ProtocolWarnings; /**< Boolean: when other parties screw up the Tor
+                         * protocol, is it a warn or an info in our logs? */
+  int TestSocks; /**< Boolean: when we get a socks connection, do we loudly
+                  * log whether it was DNS-leaking or not? */
+  int HardwareAccel; /**< Boolean: Should we enable OpenSSL hardware
+                      * acceleration where available? */
+  /** Token Bucket Refill resolution in milliseconds. */
+  int TokenBucketRefillInterval;
+  char *AccelName; /**< Optional hardware acceleration engine name. */
+  char *AccelDir; /**< Optional hardware acceleration engine search dir. */
+
+  /** Boolean: Do we try to enter from a smallish number
+   * of fixed nodes? */
+  int UseEntryGuards_option;
+  /** Internal variable to remember whether we're actually acting on
+   * UseEntryGuards_option -- when we're a non-anonymous Tor2web client or
+   * Single Onion Service, it is always false, otherwise we use the value of
+   * UseEntryGuards_option. */
+  int UseEntryGuards;
+
+  int NumEntryGuards; /**< How many entry guards do we try to establish? */
+
+  /** If 1, we use any guardfraction information we see in the
+   * consensus.  If 0, we don't.  If -1, let the consensus parameter
+   * decide. */
+  int UseGuardFraction;
+
+  int NumDirectoryGuards; /**< How many dir guards do we try to establish?
+                           * If 0, use value from NumEntryGuards. */
+  int NumPrimaryGuards; /**< How many primary guards do we want? */
+
+  int RephistTrackTime; /**< How many seconds do we keep rephist info? */
+  /** Should we always fetch our dir info on the mirror schedule (which
+   * means directly from the authorities) no matter our other config? */
+  int FetchDirInfoEarly;
+
+  /** Should we fetch our dir info at the start of the consensus period? */
+  int FetchDirInfoExtraEarly;
+
+  int DirCache; /**< Cache all directory documents and accept requests via
+                 * tunnelled dir conns from clients. If 1, enabled (default);
+                 * If 0, disabled. */
+
+  char *VirtualAddrNetworkIPv4; /**< Address and mask to hand out for virtual
+                                 * MAPADDRESS requests for IPv4 addresses */
+  char *VirtualAddrNetworkIPv6; /**< Address and mask to hand out for virtual
+                                 * MAPADDRESS requests for IPv6 addresses */
+  int ServerDNSSearchDomains; /**< Boolean: If set, we don't force exit
+                      * addresses to be FQDNs, but rather search for them in
+                      * the local domains. */
+  int ServerDNSDetectHijacking; /**< Boolean: If true, check for DNS failure
+                                 * hijacking. */
+  int ServerDNSRandomizeCase; /**< Boolean: Use the 0x20-hack to prevent
+                               * DNS poisoning attacks. */
+  char *ServerDNSResolvConfFile; /**< If provided, we configure our internal
+                     * resolver from the file here rather than from
+                     * /etc/resolv.conf (Unix) or the registry (Windows). */
+  char *DirPortFrontPage; /**< This is a full path to a file with an html
+                    disclaimer. This allows a server administrator to show
+                    that they're running Tor and anyone visiting their server
+                    will know this without any specialized knowledge. */
+  int DisableDebuggerAttachment; /**< Currently Linux only specific attempt to
+                                      disable ptrace; needs BSD testing. */
+  /** Boolean: if set, we start even if our resolv.conf file is missing
+   * or broken. */
+  int ServerDNSAllowBrokenConfig;
+  /** Boolean: if set, then even connections to private addresses will get
+   * rate-limited. */
+  int CountPrivateBandwidth;
+  /** A list of addresses that definitely should be resolvable. Used for
+   * testing our DNS server. */
+  struct smartlist_t *ServerDNSTestAddresses;
+  int EnforceDistinctSubnets; /**< If true, don't allow multiple routers in the
+                               * same network zone in the same circuit. */
+  int AllowNonRFC953Hostnames; /**< If true, we allow connections to hostnames
+                                * with weird characters. */
+  /** If true, we try resolving hostnames with weird characters. */
+  int ServerDNSAllowNonRFC953Hostnames;
+
+  /** If true, we try to download extra-info documents (and we serve them,
+   * if we are a cache).  For authorities, this is always true. */
+  int DownloadExtraInfo;
+
+  /** If true, we're configured to collect statistics on clients
+   * requesting network statuses from us as directory. */
+  int DirReqStatistics_option;
+  /** Internal variable to remember whether we're actually acting on
+   * DirReqStatistics_option -- yes if it's set and we're a server, else no. */
+  int DirReqStatistics;
+
+  /** If true, the user wants us to collect statistics on port usage. */
+  int ExitPortStatistics;
+
+  /** If true, the user wants us to collect connection statistics. */
+  int ConnDirectionStatistics;
+
+  /** If true, the user wants us to collect cell statistics. */
+  int CellStatistics;
+
+  /** If true, the user wants us to collect padding statistics. */
+  int PaddingStatistics;
+
+  /** If true, the user wants us to collect statistics as entry node. */
+  int EntryStatistics;
+
+  /** If true, the user wants us to collect statistics as hidden service
+   * directory, introduction point, or rendezvous point. */
+  int HiddenServiceStatistics_option;
+  /** Internal variable to remember whether we're actually acting on
+   * HiddenServiceStatistics_option -- yes if it's set and we're a server,
+   * else no. */
+  int HiddenServiceStatistics;
+
+  /** If true, include statistics file contents in extra-info documents. */
+  int ExtraInfoStatistics;
+
+  /** If true, do not believe anybody who tells us that a domain resolves
+   * to an internal address, or that an internal address has a PTR mapping.
+   * Helps avoid some cross-site attacks. */
+  int ClientDNSRejectInternalAddresses;
+
+  /** If true, do not accept any requests to connect to internal addresses
+   * over randomly chosen exits. */
+  int ClientRejectInternalAddresses;
+
+  /** If true, clients may connect over IPv4. If false, they will avoid
+   * connecting over IPv4. We enforce this for OR and Dir connections. */
+  int ClientUseIPv4;
+  /** If true, clients may connect over IPv6. If false, they will avoid
+   * connecting over IPv4. We enforce this for OR and Dir connections.
+   * Use fascist_firewall_use_ipv6() instead of accessing this value
+   * directly. */
+  int ClientUseIPv6;
+  /** If true, prefer an IPv6 OR port over an IPv4 one for entry node
+   * connections. If auto, bridge clients prefer IPv6, and other clients
+   * prefer IPv4. Use node_ipv6_or_preferred() instead of accessing this value
+   * directly. */
+  int ClientPreferIPv6ORPort;
+  /** If true, prefer an IPv6 directory port over an IPv4 one for direct
+   * directory connections. If auto, bridge clients prefer IPv6, and other
+   * clients prefer IPv4. Use fascist_firewall_prefer_ipv6_dirport() instead of
+   * accessing this value directly.  */
+  int ClientPreferIPv6DirPort;
+
+  /** The length of time that we think a consensus should be fresh. */
+  int V3AuthVotingInterval;
+  /** The length of time we think it will take to distribute votes. */
+  int V3AuthVoteDelay;
+  /** The length of time we think it will take to distribute signatures. */
+  int V3AuthDistDelay;
+  /** The number of intervals we think a consensus should be valid. */
+  int V3AuthNIntervalsValid;
+
+  /** Should advertise and sign consensuses with a legacy key, for key
+   * migration purposes? */
+  int V3AuthUseLegacyKey;
+
+  /** Location of bandwidth measurement file */
+  char *V3BandwidthsFile;
+
+  /** Location of guardfraction file */
+  char *GuardfractionFile;
+
+  /** Authority only: key=value pairs that we add to our networkstatus
+   * consensus vote on the 'params' line. */
+  char *ConsensusParams;
+
+  /** Authority only: minimum number of measured bandwidths we must see
+   * before we only believe measured bandwidths to assign flags. */
+  int MinMeasuredBWsForAuthToIgnoreAdvertised;
+
+  /** The length of time that we think an initial consensus should be fresh.
+   * Only altered on testing networks. */
+  int TestingV3AuthInitialVotingInterval;
+
+  /** The length of time we think it will take to distribute initial votes.
+   * Only altered on testing networks. */
+  int TestingV3AuthInitialVoteDelay;
+
+  /** The length of time we think it will take to distribute initial
+   * signatures.  Only altered on testing networks.*/
+  int TestingV3AuthInitialDistDelay;
+
+  /** Offset in seconds added to the starting time for consensus
+      voting. Only altered on testing networks. */
+  int TestingV3AuthVotingStartOffset;
+
+  /** If an authority has been around for less than this amount of time, it
+   * does not believe its reachability information is accurate.  Only
+   * altered on testing networks. */
+  int TestingAuthDirTimeToLearnReachability;
+
+  /** Clients don't download any descriptor this recent, since it will
+   * probably not have propagated to enough caches.  Only altered on testing
+   * networks. */
+  int TestingEstimatedDescriptorPropagationTime;
+
+  /** Schedule for when servers should download things in general.  Only
+   * altered on testing networks. */
+  int TestingServerDownloadInitialDelay;
+
+  /** Schedule for when clients should download things in general.  Only
+   * altered on testing networks. */
+  int TestingClientDownloadInitialDelay;
+
+  /** Schedule for when servers should download consensuses.  Only altered
+   * on testing networks. */
+  int TestingServerConsensusDownloadInitialDelay;
+
+  /** Schedule for when clients should download consensuses.  Only altered
+   * on testing networks. */
+  int TestingClientConsensusDownloadInitialDelay;
+
+  /** Schedule for when clients should download consensuses from authorities
+   * if they are bootstrapping (that is, they don't have a usable, reasonably
+   * live consensus).  Only used by clients fetching from a list of fallback
+   * directory mirrors.
+   *
+   * This schedule is incremented by (potentially concurrent) connection
+   * attempts, unlike other schedules, which are incremented by connection
+   * failures.  Only altered on testing networks. */
+  int ClientBootstrapConsensusAuthorityDownloadInitialDelay;
+
+  /** Schedule for when clients should download consensuses from fallback
+   * directory mirrors if they are bootstrapping (that is, they don't have a
+   * usable, reasonably live consensus). Only used by clients fetching from a
+   * list of fallback directory mirrors.
+   *
+   * This schedule is incremented by (potentially concurrent) connection
+   * attempts, unlike other schedules, which are incremented by connection
+   * failures.  Only altered on testing networks. */
+  int ClientBootstrapConsensusFallbackDownloadInitialDelay;
+
+  /** Schedule for when clients should download consensuses from authorities
+   * if they are bootstrapping (that is, they don't have a usable, reasonably
+   * live consensus).  Only used by clients which don't have or won't fetch
+   * from a list of fallback directory mirrors.
+   *
+   * This schedule is incremented by (potentially concurrent) connection
+   * attempts, unlike other schedules, which are incremented by connection
+   * failures.  Only altered on testing networks. */
+  int ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay;
+
+  /** Schedule for when clients should download bridge descriptors.  Only
+   * altered on testing networks. */
+  int TestingBridgeDownloadInitialDelay;
+
+  /** Schedule for when clients should download bridge descriptors when they
+   * have no running bridges.  Only altered on testing networks. */
+  int TestingBridgeBootstrapDownloadInitialDelay;
+
+  /** When directory clients have only a few descriptors to request, they
+   * batch them until they have more, or until this amount of time has
+   * passed.  Only altered on testing networks. */
+  int TestingClientMaxIntervalWithoutRequest;
+
+  /** How long do we let a directory connection stall before expiring
+   * it?  Only altered on testing networks. */
+  int TestingDirConnectionMaxStall;
+
+  /** How many simultaneous in-progress connections will we make when trying
+   * to fetch a consensus before we wait for one to complete, timeout, or
+   * error out?  Only altered on testing networks. */
+  int ClientBootstrapConsensusMaxInProgressTries;
+
+  /** If true, we take part in a testing network. Change the defaults of a
+   * couple of other configuration options and allow to change the values
+   * of certain configuration options. */
+  int TestingTorNetwork;
+
+  /** Minimum value for the Exit flag threshold on testing networks. */
+  uint64_t TestingMinExitFlagThreshold;
+
+  /** Minimum value for the Fast flag threshold on testing networks. */
+  uint64_t TestingMinFastFlagThreshold;
+
+  /** Relays in a testing network which should be voted Exit
+   * regardless of exit policy. */
+  routerset_t *TestingDirAuthVoteExit;
+  int TestingDirAuthVoteExitIsStrict;
+
+  /** Relays in a testing network which should be voted Guard
+   * regardless of uptime and bandwidth. */
+  routerset_t *TestingDirAuthVoteGuard;
+  int TestingDirAuthVoteGuardIsStrict;
+
+  /** Relays in a testing network which should be voted HSDir
+   * regardless of uptime and DirPort. */
+  routerset_t *TestingDirAuthVoteHSDir;
+  int TestingDirAuthVoteHSDirIsStrict;
+
+  /** Enable CONN_BW events.  Only altered on testing networks. */
+  int TestingEnableConnBwEvent;
+
+  /** Enable CELL_STATS events.  Only altered on testing networks. */
+  int TestingEnableCellStatsEvent;
+
+  /** If true, and we have GeoIP data, and we're a bridge, keep a per-country
+   * count of how many client addresses have contacted us so that we can help
+   * the bridge authority guess which countries have blocked access to us. */
+  int BridgeRecordUsageByCountry;
+
+  /** Optionally, IPv4 and IPv6 GeoIP data. */
+  char *GeoIPFile;
+  char *GeoIPv6File;
+
+  /** Autobool: if auto, then any attempt to Exclude{Exit,}Nodes a particular
+   * country code will exclude all nodes in ?? and A1.  If true, all nodes in
+   * ?? and A1 are excluded. Has no effect if we don't know any GeoIP data. */
+  int GeoIPExcludeUnknown;
+
+  /** If true, SIGHUP should reload the torrc.  Sometimes controllers want
+   * to make this false. */
+  int ReloadTorrcOnSIGHUP;
+
+  /* The main parameter for picking circuits within a connection.
+   *
+   * If this value is positive, when picking a cell to relay on a connection,
+   * we always relay from the circuit whose weighted cell count is lowest.
+   * Cells are weighted exponentially such that if one cell is sent
+   * 'CircuitPriorityHalflife' seconds before another, it counts for half as
+   * much.
+   *
+   * If this value is zero, we're disabling the cell-EWMA algorithm.
+   *
+   * If this value is negative, we're using the default approach
+   * according to either Tor or a parameter set in the consensus.
+   */
+  double CircuitPriorityHalflife;
+
+  /** Set to true if the TestingTorNetwork configuration option is set.
+   * This is used so that options_validate() has a chance to realize that
+   * the defaults have changed. */
+  int UsingTestNetworkDefaults_;
+
+  /** If 1, we try to use microdescriptors to build circuits.  If 0, we don't.
+   * If -1, Tor decides. */
+  int UseMicrodescriptors;
+
+  /** File where we should write the ControlPort. */
+  char *ControlPortWriteToFile;
+  /** Should that file be group-readable? */
+  int ControlPortFileGroupReadable;
+
+#define MAX_MAX_CLIENT_CIRCUITS_PENDING 1024
+  /** Maximum number of non-open general-purpose origin circuits to allow at
+   * once. */
+  int MaxClientCircuitsPending;
+
+  /** If 1, we always send optimistic data when it's supported.  If 0, we
+   * never use it.  If -1, we do what the consensus says. */
+  int OptimisticData;
+
+  /** If 1, we accept and launch no external network connections, except on
+   * control ports. */
+  int DisableNetwork;
+
+  /**
+   * Parameters for path-bias detection.
+   * @{
+   * These options override the default behavior of Tor's (**currently
+   * experimental**) path bias detection algorithm. To try to find broken or
+   * misbehaving guard nodes, Tor looks for nodes where more than a certain
+   * fraction of circuits through that guard fail to get built.
+   *
+   * The PathBiasCircThreshold option controls how many circuits we need to
+   * build through a guard before we make these checks.  The
+   * PathBiasNoticeRate, PathBiasWarnRate and PathBiasExtremeRate options
+   * control what fraction of circuits must succeed through a guard so we
+   * won't write log messages.  If less than PathBiasExtremeRate circuits
+   * succeed *and* PathBiasDropGuards is set to 1, we disable use of that
+   * guard.
+   *
+   * When we have seen more than PathBiasScaleThreshold circuits through a
+   * guard, we scale our observations by 0.5 (governed by the consensus) so
+   * that new observations don't get swamped by old ones.
+   *
+   * By default, or if a negative value is provided for one of these options,
+   * Tor uses reasonable defaults from the networkstatus consensus document.
+   * If no defaults are available there, these options default to 150, .70,
+   * .50, .30, 0, and 300 respectively.
+   */
+  int PathBiasCircThreshold;
+  double PathBiasNoticeRate;
+  double PathBiasWarnRate;
+  double PathBiasExtremeRate;
+  int PathBiasDropGuards;
+  int PathBiasScaleThreshold;
+  /** @} */
+
+  /**
+   * Parameters for path-bias use detection
+   * @{
+   * Similar to the above options, these options override the default behavior
+   * of Tor's (**currently experimental**) path use bias detection algorithm.
+   *
+   * Where as the path bias parameters govern thresholds for successfully
+   * building circuits, these four path use bias parameters govern thresholds
+   * only for circuit usage. Circuits which receive no stream usage are not
+   * counted by this detection algorithm. A used circuit is considered
+   * successful if it is capable of carrying streams or otherwise receiving
+   * well-formed responses to RELAY cells.
+   *
+   * By default, or if a negative value is provided for one of these options,
+   * Tor uses reasonable defaults from the networkstatus consensus document.
+   * If no defaults are available there, these options default to 20, .80,
+   * .60, and 100, respectively.
+   */
+  int PathBiasUseThreshold;
+  double PathBiasNoticeUseRate;
+  double PathBiasExtremeUseRate;
+  int PathBiasScaleUseThreshold;
+  /** @} */
+
+  int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
+
+  /** Fraction: */
+  double PathsNeededToBuildCircuits;
+
+  /** What expiry time shall we place on our SSL certs? "0" means we
+   * should guess a suitable value. */
+  int SSLKeyLifetime;
+
+  /** How long (seconds) do we keep a guard before picking a new one? */
+  int GuardLifetime;
+
+  /** Is this an exit node?  This is a tristate, where "1" means "yes, and use
+   * the default exit policy if none is given" and "0" means "no; exit policy
+   * is 'reject *'" and "auto" (-1) means "same as 1, but warn the user."
+   *
+   * XXXX Eventually, the default will be 0. */
+  int ExitRelay;
+
+  /** For how long (seconds) do we declare our signing keys to be valid? */
+  int SigningKeyLifetime;
+  /** For how long (seconds) do we declare our link keys to be valid? */
+  int TestingLinkCertLifetime;
+  /** For how long (seconds) do we declare our auth keys to be valid? */
+  int TestingAuthKeyLifetime;
+
+  /** How long before signing keys expire will we try to make a new one? */
+  int TestingSigningKeySlop;
+  /** How long before link keys expire will we try to make a new one? */
+  int TestingLinkKeySlop;
+  /** How long before auth keys expire will we try to make a new one? */
+  int TestingAuthKeySlop;
+
+  /** Force use of offline master key features: never generate a master
+   * ed25519 identity key except from tor --keygen */
+  int OfflineMasterKey;
+
+  enum {
+    FORCE_PASSPHRASE_AUTO=0,
+    FORCE_PASSPHRASE_ON,
+    FORCE_PASSPHRASE_OFF
+  } keygen_force_passphrase;
+  int use_keygen_passphrase_fd;
+  int keygen_passphrase_fd;
+  int change_key_passphrase;
+  char *master_key_fname;
+
+  /** Autobool: Do we try to retain capabilities if we can? */
+  int KeepBindCapabilities;
+
+  /** Maximum total size of unparseable descriptors to log during the
+   * lifetime of this Tor process.
+   */
+  uint64_t MaxUnparseableDescSizeToLog;
+
+  /** Bool (default: 1): Switch for the shared random protocol. Only
+   * relevant to a directory authority. If off, the authority won't
+   * participate in the protocol. If on (default), a flag is added to the
+   * vote indicating participation. */
+  int AuthDirSharedRandomness;
+
+  /** If 1, we skip all OOS checks. */
+  int DisableOOSCheck;
+
+  /** Autobool: Should we include Ed25519 identities in extend2 cells?
+   * If -1, we should do whatever the consensus parameter says. */
+  int ExtendByEd25519ID;
+
+  /** Bool (default: 1): When testing routerinfos as a directory authority,
+   * do we enforce Ed25519 identity match? */
+  /* NOTE: remove this option someday. */
+  int AuthDirTestEd25519LinkKeys;
+
+  /** Bool (default: 0): Tells if a %include was used on torrc */
+  int IncludeUsed;
+
+  /** The seconds after expiration which we as a relay should keep old
+   * consensuses around so that we can generate diffs from them.  If 0,
+   * use the default. */
+  int MaxConsensusAgeForDiffs;
+
+  /** Bool (default: 0). Tells Tor to never try to exec another program.
+   */
+  int NoExec;
+
+  /** Have the KIST scheduler run every X milliseconds. If less than zero, do
+   * not use the KIST scheduler but use the old vanilla scheduler instead. If
+   * zero, do what the consensus says and fall back to using KIST as if this is
+   * set to "10 msec" if the consensus doesn't say anything. */
+  int KISTSchedRunInterval;
+
+  /** A multiplier for the KIST per-socket limit calculation. */
+  double KISTSockBufSizeFactor;
+
+  /** The list of scheduler type string ordered by priority that is first one
+   * has to be tried first. Default: KIST,KISTLite,Vanilla */
+  struct smartlist_t *Schedulers;
+  /* An ordered list of scheduler_types mapped from Schedulers. */
+  struct smartlist_t *SchedulerTypes_;
+
+  /** List of files that were opened by %include in torrc and torrc-defaults */
+  struct smartlist_t *FilesOpenedByIncludes;
+
+  /** If true, Tor shouldn't install any posix signal handlers, since it is
+   * running embedded inside another process.
+   */
+  int DisableSignalHandlers;
+
+  /** Autobool: Is the circuit creation DoS mitigation subsystem enabled? */
+  int DoSCircuitCreationEnabled;
+  /** Minimum concurrent connection needed from one single address before any
+   * defense is used. */
+  int DoSCircuitCreationMinConnections;
+  /** Circuit rate used to refill the token bucket. */
+  int DoSCircuitCreationRate;
+  /** Maximum allowed burst of circuits. Reaching that value, the address is
+   * detected as malicious and a defense might be used. */
+  int DoSCircuitCreationBurst;
+  /** When an address is marked as malicous, what defense should be used
+   * against it. See the dos_cc_defense_type_t enum. */
+  int DoSCircuitCreationDefenseType;
+  /** For how much time (in seconds) the defense is applicable for a malicious
+   * address. A random time delta is added to the defense time of an address
+   * which will be between 1 second and half of this value. */
+  int DoSCircuitCreationDefenseTimePeriod;
+
+  /** Autobool: Is the DoS connection mitigation subsystem enabled? */
+  int DoSConnectionEnabled;
+  /** Maximum concurrent connection allowed per address. */
+  int DoSConnectionMaxConcurrentCount;
+  /** When an address is reaches the maximum count, what defense should be
+   * used against it. See the dos_conn_defense_type_t enum. */
+  int DoSConnectionDefenseType;
+
+  /** Autobool: Do we refuse single hop client rendezvous? */
+  int DoSRefuseSingleHopClientRendezvous;
+};
+
+#endif

+ 86 - 0
src/or/or_state_st.h

@@ -0,0 +1,86 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_OR_STATE_ST_H
+#define TOR_OR_STATE_ST_H
+
+#include "lib/cc/torint.h"
+struct smartlist_t;
+
+/** Persistent state for an onion router, as saved to disk. */
+struct or_state_t {
+  uint32_t magic_;
+  /** The time at which we next plan to write the state to the disk.  Equal to
+   * TIME_MAX if there are no savable changes, 0 if there are changes that
+   * should be saved right away. */
+  time_t next_write;
+
+  /** When was the state last written to disk? */
+  time_t LastWritten;
+
+  /** Fields for accounting bandwidth use. */
+  time_t AccountingIntervalStart;
+  uint64_t AccountingBytesReadInInterval;
+  uint64_t AccountingBytesWrittenInInterval;
+  int AccountingSecondsActive;
+  int AccountingSecondsToReachSoftLimit;
+  time_t AccountingSoftLimitHitAt;
+  uint64_t AccountingBytesAtSoftLimit;
+  uint64_t AccountingExpectedUsage;
+
+  /** A list of Entry Guard-related configuration lines. (pre-prop271) */
+  struct config_line_t *EntryGuards;
+
+  /** A list of guard-related configuration lines. (post-prop271) */
+  struct config_line_t *Guard;
+
+  struct config_line_t *TransportProxies;
+
+  /** Cached revision counters for active hidden services on this host */
+  struct config_line_t *HidServRevCounter;
+
+  /** These fields hold information on the history of bandwidth usage for
+   * servers.  The "Ends" fields hold the time when we last updated the
+   * bandwidth usage. The "Interval" fields hold the granularity, in seconds,
+   * of the entries of Values.  The "Values" lists hold decimal string
+   * representations of the number of bytes read or written in each
+   * interval. The "Maxima" list holds decimal strings describing the highest
+   * rate achieved during the interval.
+   */
+  time_t      BWHistoryReadEnds;
+  int         BWHistoryReadInterval;
+  struct smartlist_t *BWHistoryReadValues;
+  struct smartlist_t *BWHistoryReadMaxima;
+  time_t      BWHistoryWriteEnds;
+  int         BWHistoryWriteInterval;
+  struct smartlist_t *BWHistoryWriteValues;
+  struct smartlist_t *BWHistoryWriteMaxima;
+  time_t      BWHistoryDirReadEnds;
+  int         BWHistoryDirReadInterval;
+  struct smartlist_t *BWHistoryDirReadValues;
+  struct smartlist_t *BWHistoryDirReadMaxima;
+  time_t      BWHistoryDirWriteEnds;
+  int         BWHistoryDirWriteInterval;
+  struct smartlist_t *BWHistoryDirWriteValues;
+  struct smartlist_t *BWHistoryDirWriteMaxima;
+
+  /** Build time histogram */
+  struct config_line_t * BuildtimeHistogram;
+  int TotalBuildTimes;
+  int CircuitBuildAbandonedCount;
+
+  /** What version of Tor wrote this state file? */
+  char *TorVersion;
+
+  /** Holds any unrecognized values we found in the state file, in the order
+   * in which we found them. */
+  struct config_line_t *ExtraLines;
+
+  /** When did we last rotate our onion key?  "0" for 'no idea'. */
+  time_t LastRotatedOnionKey;
+};
+
+#endif

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