mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
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>
This commit is contained in:
parent
1bfc91a029
commit
acf7ea77d8
@ -1600,6 +1600,14 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
|||||||
return 0;
|
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 = connection_new(new_type, conn->socket_family);
|
||||||
newconn->s = news;
|
newconn->s = news;
|
||||||
|
34
src/or/dos.c
34
src/or/dos.c
@ -53,6 +53,9 @@ static unsigned int dos_conn_enabled = 0;
|
|||||||
static uint32_t dos_conn_max_concurrent_count;
|
static uint32_t dos_conn_max_concurrent_count;
|
||||||
static dos_conn_defense_type_t dos_conn_defense_type;
|
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.
|
* 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. */
|
/* 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 */
|
/* General API */
|
||||||
|
|
||||||
/* Called when a new client connection has been established on the given
|
/* Called when a new client connection has been established on the given
|
||||||
|
@ -107,6 +107,8 @@ typedef enum dos_conn_defense_type_t {
|
|||||||
DOS_CONN_DEFENSE_MAX = 2,
|
DOS_CONN_DEFENSE_MAX = 2,
|
||||||
} dos_conn_defense_type_t;
|
} dos_conn_defense_type_t;
|
||||||
|
|
||||||
|
dos_conn_defense_type_t dos_conn_addr_get_defense_type(const tor_addr_t *addr);
|
||||||
|
|
||||||
#ifdef DOS_PRIVATE
|
#ifdef DOS_PRIVATE
|
||||||
|
|
||||||
STATIC uint32_t get_param_conn_max_concurrent_count(
|
STATIC uint32_t get_param_conn_max_concurrent_count(
|
||||||
|
Loading…
Reference in New Issue
Block a user