commit bd71e0a0c8ccf684c40201f08c456596eac60887 Merge: c67adddac 2bcd264a2 Author: Nick Mathewson nickm@torproject.org Date: Fri Feb 16 09:54:13 2018 -0500
Merge branch 'maint-0.3.1' into maint-0.3.2
changes/bug24952 | 5 + changes/bug25223 | 4 + changes/ticket24902 | 13 + changes/ticket25122 | 4 + changes/ticket25202 | 4 + doc/tor.1.txt | 95 ++++++ src/common/address.c | 27 +- src/common/address.h | 2 + src/common/address_set.c | 129 +++++++ src/common/address_set.h | 35 ++ src/common/include.am | 2 + src/common/log.c | 2 +- src/common/torlog.h | 4 +- src/or/channel.c | 9 +- src/or/channel.h | 3 +- src/or/channeltls.c | 2 +- src/or/command.c | 13 + src/or/config.c | 25 ++ src/or/connection.c | 16 + src/or/dos.c | 794 ++++++++++++++++++++++++++++++++++++++++++++ src/or/dos.h | 140 ++++++++ src/or/geoip.c | 205 ++++++++++-- src/or/geoip.h | 29 ++ src/or/include.am | 2 + src/or/main.c | 2 + src/or/networkstatus.c | 2 + src/or/nodelist.c | 77 +++++ src/or/nodelist.h | 3 + src/or/or.h | 33 ++ src/or/relay.c | 14 +- src/or/rendmid.c | 12 + src/or/status.c | 2 + src/test/include.am | 2 + src/test/test.c | 20 ++ src/test/test.h | 2 + src/test/test_address_set.c | 174 ++++++++++ src/test/test_dos.c | 497 +++++++++++++++++++++++++++ 37 files changed, 2361 insertions(+), 43 deletions(-)
diff --cc src/common/address.c index dbe129be5,e6b437e9d..c683e90aa --- a/src/common/address.c +++ b/src/common/address.c @@@ -1193,11 -1194,11 +1196,11 @@@ tor_addr_hash(const tor_addr_t *addr case AF_INET: return siphash24g(&addr->addr.in_addr.s_addr, 4); case AF_UNSPEC: - return 0x4e4d5342; + return siphash24g(unspec_hash_input, sizeof(unspec_hash_input)); case AF_INET6: return siphash24g(&addr->addr.in6_addr.s6_addr, 16); - default: /* LCOV_EXCL_START */ + default: tor_fragile_assert(); return 0; /* LCOV_EXCL_STOP */ diff --cc src/common/include.am index cd5eea340,d12895b10..715ec0264 --- a/src/common/include.am +++ b/src/common/include.am @@@ -80,8 -80,8 +80,9 @@@ src_common_libor_ctime_testing_a_CFLAG
LIBOR_A_SRC = \ src/common/address.c \ + src/common/address_set.c \ src/common/backtrace.c \ + src/common/buffers.c \ src/common/compat.c \ src/common/compat_threads.c \ src/common/compat_time.c \ @@@ -148,9 -147,8 +149,10 @@@ src_common_libor_event_testing_a_CFLAG
COMMONHEADERS = \ src/common/address.h \ + src/common/address_set.h \ src/common/backtrace.h \ + src/common/buffers.h \ + src/common/buffers_tls.h \ src/common/aes.h \ src/common/ciphers.inc \ src/common/compat.h \ diff --cc src/or/connection.c index d2cf4fb41,fc0646b88..ed8de05d7 --- a/src/or/connection.c +++ b/src/or/connection.c @@@ -704,7 -696,14 +705,14 @@@ connection_free,(connection_t *conn) connection_ap_warn_and_unmark_if_pending_circ(TO_ENTRY_CONN(conn), "connection_free"); } -#endif +#endif /* 1 */ + + /* Notify the circuit creation DoS mitigation subsystem that an OR client + * connection has been closed. And only do that if we track it. */ + if (conn->type == CONN_TYPE_OR) { + dos_close_client_conn(TO_OR_CONN(conn)); + } + connection_unregister_events(conn); connection_free_(conn); } diff --cc src/or/geoip.h index acf61b97a,773525ccf..753bdbf82 --- a/src/or/geoip.h +++ b/src/or/geoip.h @@@ -19,7 -20,30 +20,30 @@@ STATIC int geoip_parse_entry(const cha STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr); STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr); STATIC void clear_geoip_db(void); -#endif +#endif /* defined(GEOIP_PRIVATE) */ + + /** Entry in a map from IP address to the last time we've seen an incoming + * connection from that IP address. Used by bridges only to track which + * countries have them blocked, or the DoS mitigation subsystem if enabled. */ + typedef struct clientmap_entry_t { + HT_ENTRY(clientmap_entry_t) node; + tor_addr_t addr; + /* Name of pluggable transport used by this client. NULL if no + pluggable transport was used. */ + char *transport_name; + + /** Time when we last saw this IP address, in MINUTES since the epoch. + * + * (This will run out of space around 4011 CE. If Tor is still in use around + * 4000 CE, please remember to add more bits to last_seen_in_minutes.) */ + unsigned int last_seen_in_minutes:30; + unsigned int action:2; + + /* This object is used to keep some statistics per client address for the + * DoS mitigation subsystem. */ + dos_client_stats_t dos_stats; + } clientmap_entry_t; + int should_record_bridge_info(const or_options_t *options); int geoip_load_file(sa_family_t family, const char *filename); MOCK_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr)); diff --cc src/or/include.am index 7216aba9a,5d5ff5c41..abf62c2e8 --- a/src/or/include.am +++ b/src/or/include.am @@@ -47,8 -48,13 +47,9 @@@ LIBTOR_A_SOURCES = src/or/dirvote.c \ src/or/dns.c \ src/or/dnsserv.c \ + src/or/dos.c \ src/or/fp_pair.c \ src/or/geoip.c \ - src/or/hs_intropoint.c \ - src/or/hs_circuitmap.c \ - src/or/hs_ntor.c \ - src/or/hs_service.c \ src/or/entrynodes.c \ src/or/ext_orport.c \ src/or/hibernate.c \ diff --cc src/or/main.c index c340e4128,197dfd430..036ef1efd --- a/src/or/main.c +++ b/src/or/main.c @@@ -3268,7 -3242,7 +3269,8 @@@ tor_free_all(int postfork protover_free_all(); bridges_free_all(); consdiffmgr_free_all(); + hs_free_all(); + dos_free_all(); if (!postfork) { config_free_all(); or_state_free_all(); diff --cc src/or/networkstatus.c index 9d9a2b8ad,e59069e84..dd82f6681 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@@ -1564,22 -1604,15 +1565,23 @@@ notify_control_networkstatus_changed(co smartlist_free(changed); }
-/* Called when the consensus has changed from old_c to new_c. */ +/* Called before the consensus changes from old_c to new_c. */ static void -notify_networkstatus_changed(const networkstatus_t *old_c, - const networkstatus_t *new_c) +notify_before_networkstatus_changes(const networkstatus_t *old_c, + const networkstatus_t *new_c) { notify_control_networkstatus_changed(old_c, new_c); + dos_consensus_has_changed(new_c); }
+/* Called after a new consensus has been put in the global state. It is safe + * to use the consensus getters in this function. */ +static void +notify_after_networkstatus_changes(void) +{ + scheduler_notify_networkstatus_changed(); +} + /** Copy all the ancillary information (like router download status and so on) * from <b>old_c</b> to <b>new_c</b>. */ static void diff --cc src/or/nodelist.c index f2e979be8,c754ebdb6..9a477ecf4 --- a/src/or/nodelist.c +++ b/src/or/nodelist.c @@@ -38,10 -38,9 +38,11 @@@ * used for authorities and fallback directories.) */
+#define NODELIST_PRIVATE + #include "or.h" #include "address.h" + #include "address_set.h" #include "config.h" #include "control.h" #include "dirserv.h" @@@ -95,14 -92,9 +97,16 @@@ typedef struct nodelist_t smartlist_t *nodes; /* Hash table to map from node ID digest to node. */ HT_HEAD(nodelist_map, node_t) nodes_by_id; - + /* Hash table to map from node Ed25519 ID to node. + * + * Whenever a node's routerinfo or microdescriptor is about to change, + * you should remove it from this map with node_remove_from_ed25519_map(). + * Whenever a node's routerinfo or microdescriptor has just chaned, + * you should add it to this map with node_add_to_ed25519_map(). + */ + HT_HEAD(nodelist_ed_map, node_t) nodes_by_ed_id; + /* Set of addresses that belong to nodes we believe in. */ + address_set_t *node_addrs; } nodelist_t;
static inline unsigned int @@@ -442,14 -264,8 +490,16 @@@ nodelist_set_routerinfo(routerinfo_t *r dirserv_set_node_flags_from_authoritative_status(node, status); }
+ /* Setting the HSDir index requires the ed25519 identity key which can + * only be found either in the ri or md. This is why this is called here. + * Only nodes supporting HSDir=2 protocol version needs this index. */ + if (node->rs && node->rs->supports_v3_hsdir) { + node_set_hsdir_index(node, + networkstatus_get_latest_consensus()); + } + + node_add_to_address_set(node); + return node; }
@@@ -476,21 -292,14 +526,23 @@@ nodelist_add_microdesc(microdesc_t *md return NULL; node = node_get_mutable_by_id(rs->identity_digest); if (node) { + node_remove_from_ed25519_map(node); if (node->md) node->md->held_by_nodes--; + node->md = md; md->held_by_nodes++; + /* Setting the HSDir index requires the ed25519 identity key which can + * only be found either in the ri or md. This is why this is called here. + * Only nodes supporting HSDir=2 protocol version needs this index. */ + if (rs->supports_v3_hsdir) { + node_set_hsdir_index(node, ns); + } + node_add_to_ed25519_map(node); }
+ node_add_to_address_set(node); + return node; }
diff --cc src/or/nodelist.h index 754990ac8,9cd66f60a..8a0c79f86 --- a/src/or/nodelist.h +++ b/src/or/nodelist.h @@@ -142,16 -132,7 +143,18 @@@ void router_dir_info_changed(void) const char *get_dir_info_status_string(void); int count_loading_descriptors_progress(void);
+#ifdef NODELIST_PRIVATE + +#ifdef TOR_UNIT_TESTS + +STATIC void +node_set_hsdir_index(node_t *node, const networkstatus_t *ns); + +#endif /* defined(TOR_UNIT_TESTS) */ + +#endif /* defined(NODELIST_PRIVATE) */ + + MOCK_DECL(int, get_estimated_address_per_node, (void)); + -#endif +#endif /* !defined(TOR_NODELIST_H) */
diff --cc src/or/or.h index 03e20b80d,9e7833386..5128fd219 --- a/src/or/or.h +++ b/src/or/or.h @@@ -4624,28 -4583,36 +4628,57 @@@ typedef struct * use the default. */ int MaxConsensusAgeForDiffs;
+ /** Bool (default: 0). Tells Tor to never try to exec another program. + */ + int NoExec; + + /** Have the KIST scheduler run every X milliseconds. If less than zero, do + * not use the KIST scheduler but use the old vanilla scheduler instead. If + * zero, do what the consensus says and fall back to using KIST as if this is + * set to "10 msec" if the consensus doesn't say anything. */ + int KISTSchedRunInterval; + + /** A multiplier for the KIST per-socket limit calculation. */ + double KISTSockBufSizeFactor; + + /** The list of scheduler type string ordered by priority that is first one + * has to be tried first. Default: KIST,KISTLite,Vanilla */ + smartlist_t *Schedulers; + /* An ordered list of scheduler_types mapped from Schedulers. */ + smartlist_t *SchedulerTypes_; ++ + /** Autobool: Is the circuit creation DoS mitigation subsystem enabled? */ + int DoSCircuitCreationEnabled; + /** Minimum concurrent connection needed from one single address before any + * defense is used. */ + int DoSCircuitCreationMinConnections; + /** Circuit rate used to refill the token bucket. */ + int DoSCircuitCreationRate; + /** Maximum allowed burst of circuits. Reaching that value, the address is + * detected as malicious and a defense might be used. */ + int DoSCircuitCreationBurst; + /** When an address is marked as malicous, what defense should be used + * against it. See the dos_cc_defense_type_t enum. */ + int DoSCircuitCreationDefenseType; + /** For how much time (in seconds) the defense is applicable for a malicious + * address. A random time delta is added to the defense time of an address + * which will be between 1 second and half of this value. */ + int DoSCircuitCreationDefenseTimePeriod; + + /** Autobool: Is the DoS connection mitigation subsystem enabled? */ + int DoSConnectionEnabled; + /** Maximum concurrent connection allowed per address. */ + int DoSConnectionMaxConcurrentCount; + /** When an address is reaches the maximum count, what defense should be + * used against it. See the dos_conn_defense_type_t enum. */ + int DoSConnectionDefenseType; + + /** Autobool: Do we refuse single hop client rendezvous? */ + int DoSRefuseSingleHopClientRendezvous; } or_options_t;
+#define LOG_PROTOCOL_WARN (get_protocol_warning_severity_level()) + /** Persistent state for an onion router, as saved to disk. */ typedef struct { uint32_t magic_;
tor-commits@lists.torproject.org