From 06a9d580c37d80c680c3dda2ff8f3c53f487c735 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 20 Nov 2018 16:07:44 +0100 Subject: [PATCH] Simplify rate limiting of incoming connections. We now really allow max_connection_burst connections per second, rather than only allowing one second per connection on average, but allowing a burst of max_connection_burst connections to go through. --- src/net_socket.c | 62 +++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/src/net_socket.c b/src/net_socket.c index f98023bd..6d1d8fb3 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -636,6 +636,22 @@ void setup_outgoing_connection(meshlink_handle_t *mesh, outgoing_t *outgoing) { do_outgoing_connection(mesh, outgoing); } +/// Delayed close of a filedescriptor. +static void tarpit(int fd) { + static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + static int next_pit = 0; + + if(pits[next_pit] != -1) { + closesocket(pits[next_pit]); + } + + pits[next_pit++] = fd; + + if(next_pit >= (int)(sizeof pits / sizeof pits[0])) { + next_pit = 0; + } +} + /* accept a new tcp connect and create a new connection @@ -663,57 +679,23 @@ void handle_new_meta_connection(event_loop_t *loop, void *data, int flags) { sockaddrunmap(&sa); - // Check if we get many connections from the same host - - static sockaddr_t prev_sa; - static int tarpit = -1; - - if(tarpit >= 0) { - closesocket(tarpit); - tarpit = -1; - } - - if(!sockaddrcmp_noport(&sa, &prev_sa)) { - static int samehost_burst; - static int samehost_burst_time; - - if(mesh->loop.now.tv_sec - samehost_burst_time > samehost_burst) { - samehost_burst = 0; - } else { - samehost_burst -= mesh->loop.now.tv_sec - samehost_burst_time; - } - - samehost_burst_time = mesh->loop.now.tv_sec; - samehost_burst++; - - if(samehost_burst > max_connection_burst) { - tarpit = fd; - return; - } - } - - memcpy(&prev_sa, &sa, sizeof(sa)); - - // Check if we get many connections from different hosts + /* Rate limit incoming connections to max_connection_burst/second. */ static int connection_burst; static int connection_burst_time; - if(mesh->loop.now.tv_sec - connection_burst_time > connection_burst) { + if(mesh->loop.now.tv_sec != connection_burst_time) { + connection_burst_time = mesh->loop.now.tv_sec; connection_burst = 0; - } else { - connection_burst -= mesh->loop.now.tv_sec - connection_burst_time; } - connection_burst_time = mesh->loop.now.tv_sec; - connection_burst++; - if(connection_burst >= max_connection_burst) { - connection_burst = max_connection_burst; - tarpit = fd; + tarpit(fd); return; } + connection_burst++; + // Accept the new connection c = new_connection(); -- 2.39.2