Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sleep upon conn objection OOM #153

Merged
merged 1 commit into from
Apr 20, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion src/core/data/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#define SERVER_MODULE_NAME "core::server"

#define SLEEP_CONN_USEC 10000 /* sleep for 10ms on out-of-stream-object error */

static bool server_init = false;
static server_metrics_st *server_metrics = NULL;

Expand Down Expand Up @@ -71,10 +73,45 @@ _tcp_accept(struct buf_sock *ss)

s = buf_sock_borrow();
if (s == NULL) {
/*
* TODO: what's the best way to respond to DDoS?
*
* If the DDoS is intentional, the best response is probably to do as
* little work as possible, and hope OS can handle/shed the load.
*
* If DDoS is caused by synchronized client connect attempts with
* a reasonable backoff policy, we probably can close the connections
* right away to trigger the client-side policy.
*
* If the client-side policy is for timeout only but not for other
* errors, we probably want to wait (sleep()), so the client-side
* backoff can be triggered.
*
* If the client-side logic does not have any backoff, we are pretty
* much in the same situation as an intentional DDoS.
*/
/*
* Aside from properly handle the connections, another issue is what
* server should do with its CPU time. There are three options:
* - keep handling incoming events (mostly rejecting connections)
* - sleep for a while and then wake up, hoping things change by then
* - stop handling incoming events until a connection is freed
*
* Delayed response saves CPU resources and generally makes more sense
* for the server, knowing that client probably will retry and succeed
* eventually. However at this point it is not clear to me whether it's
* better to do a timed sleep or a conditional sleep.
* Timed sleep is easy to implement but a little inflexible; conditional
* sleep is the smartest option but requires cross-thread communication.
*
* Twemcache enables/disables event on the listening port dinamically,
* but the handling is not really thread-safe.
*/
log_error("establish connection failed: cannot allocate buf_sock, "
"reject connection request");
ss->hdl->reject(sc); /* server rejects connection by closing it */
return true;
usleep(SLEEP_CONN_USEC);
return false;
}

if (!ss->hdl->accept(sc, s->ch)) {
Expand Down