* circ_max_cell_queue_size_out limit before being marked. */
static uint32_t dos_num_circ_max_outq;
+/*
+ * Stream denial of service mitigation.
+ *
+ * Namespace used for this mitigation framework is "dos_stream_".
+ */
+
+/* Is the connection DoS mitigation enabled? */
+static unsigned int dos_stream_enabled = 0;
+
+/* Consensus parameters. They can be changed when a new consensus arrives.
+ * They are initialized with the hardcoded default values. */
+static dos_stream_defense_type_t dos_stream_defense_type;
+static uint32_t dos_stream_rate = DOS_STREAM_RATE_DEFAULT;
+static uint32_t dos_stream_burst = DOS_STREAM_BURST_DEFAULT;
+
+/* Keep some stats for the heartbeat so we can report out. */
+static uint64_t stream_num_rejected;
+
/*
* General interface of the denial of service mitigation subsystem.
*/
INT32_MAX);
}
+/* Return true iff the stream creation mitigation is enabled. We look at the
+ * consensus for this else a default value is returned. */
+MOCK_IMPL(STATIC unsigned int,
+get_param_stream_enabled, (const networkstatus_t *ns))
+{
+ if (dos_get_options()->DoSStreamCreationEnabled != -1) {
+ return dos_get_options()->DoSStreamCreationEnabled;
+ }
+
+ return !!networkstatus_get_param(ns, "DoSStreamCreationEnabled",
+ DOS_STREAM_ENABLED_DEFAULT, 0, 1);
+}
+
+/* Return the parameter for the time rate that is how many stream per circuit
+ * over this time span. */
+static uint32_t
+get_param_stream_rate(const networkstatus_t *ns)
+{
+ /* This is in seconds. */
+ if (dos_get_options()->DoSStreamCreationRate) {
+ return dos_get_options()->DoSStreamCreationRate;
+ }
+ return networkstatus_get_param(ns, "DoSStreamCreationRate",
+ DOS_STREAM_RATE_DEFAULT,
+ 1, INT32_MAX);
+}
+
+/* Return the parameter for the maximum circuit count for the circuit time
+ * rate. */
+static uint32_t
+get_param_stream_burst(const networkstatus_t *ns)
+{
+ if (dos_get_options()->DoSStreamCreationBurst) {
+ return dos_get_options()->DoSStreamCreationBurst;
+ }
+ return networkstatus_get_param(ns, "DoSStreamCreationBurst",
+ DOS_STREAM_BURST_DEFAULT,
+ 1, INT32_MAX);
+}
+
+/* Return the consensus parameter of the circuit creation defense type. */
+static uint32_t
+get_param_stream_defense_type(const networkstatus_t *ns)
+{
+ if (dos_get_options()->DoSStreamCreationDefenseType) {
+ return dos_get_options()->DoSStreamCreationDefenseType;
+ }
+ return networkstatus_get_param(ns, "DoSStreamCreationDefenseType",
+ DOS_STREAM_DEFENSE_TYPE_DEFAULT,
+ DOS_STREAM_DEFENSE_NONE, DOS_STREAM_DEFENSE_MAX);
+}
+
/* Set circuit creation parameters located in the consensus or their default
* if none are present. Called at initialization or when the consensus
* changes. */
/* Circuit. */
dos_num_circ_max_outq = get_param_dos_num_circ_max_outq(ns);
+
+ /* Stream. */
+ dos_stream_enabled = get_param_stream_enabled(ns);
+ dos_stream_defense_type = get_param_stream_rate(ns);
+ dos_stream_rate = get_param_stream_burst(ns);
+ dos_stream_burst = get_param_stream_defense_type(ns);
}
/* Free everything for the circuit creation DoS mitigation subsystem. */
"[DoSRefuseSingleHopClientRendezvous disabled]");
}
+ if (dos_stream_enabled) {
+ smartlist_add_asprintf(elems,
+ "%" PRIu64 " stream rejected",
+ stream_num_rejected);
+ } else {
+ smartlist_add_asprintf(elems, "[DoSStreamCreationEnabled disabled]");
+ }
+
/* HS DoS stats. */
smartlist_add_asprintf(elems,
"%" PRIu64 " INTRODUCE2 rejected",
dos_conn_defense_type_t dos_conn_addr_get_defense_type(const tor_addr_t *addr);
+/*
+ * Stream creation DoS mitigation subsystem interface.
+ */
+
+/* DoSStreamCreationEnabled default. Disabled by deault. */
+#define DOS_STREAM_ENABLED_DEFAULT 0
+/* DoSStreamCreationDefenseType maps to the dos_stream_defense_type_t enum */
+#define DOS_STREAM_DEFENSE_TYPE_DEFAULT DOS_STREAM_DEFENSE_REFUSE_STREAM
+/* DosStreamCreationRate is 100 per seconds. */
+#define DOS_STREAM_RATE_DEFAULT 100
+/* DosStreamCreationBurst default. */
+#define DOS_STREAM_BURST_DEFAULT 300
+
+/* Type of defense that we can use for the stream creation DoS mitigation. */
+typedef enum dos_stream_defense_type_t {
+ /* No defense used. */
+ DOS_STREAM_DEFENSE_NONE = 1,
+ /* Reject the stream */
+ DOS_STREAM_DEFENSE_REFUSE_STREAM = 2,
+ /* Close the circuit */
+ DOS_STREAM_DEFENSE_CLOSE_CIRCUIT = 3,
+
+ /* Maimum value that can be used. Useful for the boundaries of the
+ * consensus parameter. */
+ DOS_STREAM_DEFENSE_MAX = 3,
+} dos_stream_defense_type_t;
+
#ifdef DOS_PRIVATE
STATIC uint32_t get_param_conn_max_concurrent_count(
(const networkstatus_t *ns));
MOCK_DECL(STATIC unsigned int, get_param_conn_enabled,
(const networkstatus_t *ns));
+MOCK_DECL(STATIC unsigned int, get_param_stream_enabled,
+ (const networkstatus_t *ns));
#endif /* defined(DOS_PRIVATE) */
/** Allowed rate of client connection allowed per address. */
CONF_VAR(DoSConnectionConnectRate, POSINT, 0, "0")
+/** Autobool: Is the stream creation DoS mitigation subsystem enabled? */
+CONF_VAR(DoSStreamCreationEnabled, AUTOBOOL, 0, "auto")
+
+/** Stream rate used to refill the token bucket. */
+CONF_VAR(DoSStreamCreationRate, POSINT, 0, "0")
+
+/** Maximum allowed burst of stream. */
+CONF_VAR(DoSStreamCreationBurst, POSINT, 0, "0")
+
+/** When an circuit is detected as malicious, what defense should be used
+ * against it. See the dos_stream_defense_type_t enum. */
+CONF_VAR(DoSStreamCreationDefenseType, INT, 0, "0")
+
/** For how much time (in seconds) the connection connect rate 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