Browse Source

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>
David Goulet 6 years ago
parent
commit
acf7ea77d8
3 changed files with 44 additions and 0 deletions
  1. 8 0
      src/or/connection.c
  2. 34 0
      src/or/dos.c
  3. 2 0
      src/or/dos.h

+ 8 - 0
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;

+ 34 - 0
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

+ 2 - 0
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(