diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/redirector.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/redirector.c b/src/redirector.c index be3802f..b4d7a78 100644 --- a/src/redirector.c +++ b/src/redirector.c @@ -4,6 +4,7 @@ #include <string.h> #include <signal.h> #include <pthread.h> +#include <time.h> #include <assert.h> #include "redirector.h" @@ -21,6 +22,8 @@ typedef struct client_thread { typedef struct server_event { redirector_ctx **rdr_ctx; const size_t siz; + size_t last_accept_count; + time_t last_accept_stamp; } server_event; typedef struct client_event { @@ -222,11 +225,12 @@ fwd_state_string(const forward_state c_state, const client_thread *args, static int redirector_mainloop(event_ctx **ev_ctx, redirector_ctx *rdr_ctx[], size_t siz) { int rc; - server_event ev_srv = { rdr_ctx, siz }; + server_event ev_srv = { rdr_ctx, siz, 0, 0 }; set_procname("[potd] redirector"); assert( set_child_sighandler() == 0 ); + ev_srv.last_accept_stamp = time(NULL); rc = event_loop(*ev_ctx, redirector_accept_client, &ev_srv); event_free(ev_ctx); @@ -236,7 +240,9 @@ static int redirector_mainloop(event_ctx **ev_ctx, redirector_ctx *rdr_ctx[], si static int redirector_accept_client(event_ctx *ev_ctx, int fd, void *user_data) { size_t i; + double d; int s; + time_t t; server_event *ev_srv = (server_event *) user_data; client_thread *args; redirector_ctx *rdr_ctx; @@ -258,6 +264,21 @@ static int redirector_accept_client(event_ctx *ev_ctx, int fd, void *user_data) goto error; } + ev_srv->last_accept_count++; + t = time(NULL); + d = difftime(t, ev_srv->last_accept_stamp); + if (d == 0.0f) + d = 1.0f; + if (d > 5.0f) { + ev_srv->last_accept_stamp = t; + ev_srv->last_accept_count = 0; + } + if (ev_srv->last_accept_count / (size_t)d > 3) { + W2("DoS protection: Got %zu accepts/s", + ev_srv->last_accept_count / (size_t)d); + goto error; + } + args->rdr_ctx = rdr_ctx; s = socket_addrtostr_in(&args->client_sock, args->host_buf, args->service_buf); |