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 */
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 \
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 \
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);
}
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));
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 \
protover_free_all();
bridges_free_all();
consdiffmgr_free_all();
+ hs_free_all();
+ dos_free_all();
if (!postfork) {
config_free_all();
or_state_free_all();
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
* 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"
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
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;
}
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;
}
const char *get_dir_info_status_string(void);
int count_loading_descriptors_progress(void);
-#endif
+#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 /* !defined(TOR_NODELIST_H) */
* 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_;