aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2018-01-25 16:28:54 -0500
committerDavid Goulet <dgoulet@torproject.org>2018-01-30 09:18:15 -0500
commitacf7ea77d8d76830924a14145afbcf3c95a06b0e (patch)
tree83fa38059defe75af1dbcb905370c0b79ed25082 /src
parent1bfc91a029839f36e04c8204d1bccaa04a5c2afd (diff)
downloadtor-acf7ea77d8d76830924a14145afbcf3c95a06b0e.tar.gz
tor-acf7ea77d8d76830924a14145afbcf3c95a06b0e.zip
dos: Add the connection DoS mitigation subsystem
Defend against an address that has reached the concurrent connection count threshold. Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src')
-rw-r--r--src/or/connection.c8
-rw-r--r--src/or/dos.c34
-rw-r--r--src/or/dos.h2
3 files changed, 44 insertions, 0 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 15f489c6b4..791fd95c27 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1600,6 +1600,14 @@ connection_handle_listener_read(connection_t *conn, int new_type)
return 0;
}
}
+ if (new_type == CONN_TYPE_OR) {
+ /* Assess with the connection DoS mitigation subsystem if this address
+ * can open a new connection. */
+ if (dos_conn_addr_get_defense_type(&addr) == DOS_CONN_DEFENSE_CLOSE) {
+ tor_close_socket(news);
+ return 0;
+ }
+ }
newconn = connection_new(new_type, conn->socket_family);
newconn->s = news;
diff --git a/src/or/dos.c b/src/or/dos.c
index 8c00a2f310..7e3a2ab7f9 100644
--- a/src/or/dos.c
+++ b/src/or/dos.c
@@ -53,6 +53,9 @@ static unsigned int dos_conn_enabled = 0;
static uint32_t dos_conn_max_concurrent_count;
static dos_conn_defense_type_t dos_conn_defense_type;
+/* Keep some stats for the heartbeat so we can report out. */
+static uint64_t conn_num_addr_rejected;
+
/*
* General interface of the denial of service mitigation subsystem.
*/
@@ -488,6 +491,37 @@ dos_cc_get_defense_type(channel_t *chan)
/* Concurrent connection detection public API. */
+/* Return true iff the given address is permitted to open another connection.
+ * A defense value is returned for the caller to take appropriate actions. */
+dos_conn_defense_type_t
+dos_conn_addr_get_defense_type(const tor_addr_t *addr)
+{
+ clientmap_entry_t *entry;
+
+ tor_assert(addr);
+
+ /* Skip everything if not enabled. */
+ if (!dos_conn_enabled) {
+ goto end;
+ }
+
+ /* We are only interested in client connection from the geoip cache. */
+ entry = geoip_lookup_client(addr, NULL, GEOIP_CLIENT_CONNECT);
+ if (entry == NULL) {
+ goto end;
+ }
+
+ /* Need to be above the maximum concurrent connection count to trigger a
+ * defense. */
+ if (entry->dos_stats.concurrent_count > dos_conn_max_concurrent_count) {
+ conn_num_addr_rejected++;
+ return dos_conn_defense_type;
+ }
+
+ end:
+ return DOS_CONN_DEFENSE_NONE;
+}
+
/* General API */
/* Called when a new client connection has been established on the given
diff --git a/src/or/dos.h b/src/or/dos.h
index fa86295cf6..cc7749836f 100644
--- a/src/or/dos.h
+++ b/src/or/dos.h
@@ -107,6 +107,8 @@ typedef enum dos_conn_defense_type_t {
DOS_CONN_DEFENSE_MAX = 2,
} dos_conn_defense_type_t;
+dos_conn_defense_type_t dos_conn_addr_get_defense_type(const tor_addr_t *addr);
+
#ifdef DOS_PRIVATE
STATIC uint32_t get_param_conn_max_concurrent_count(