Commit 8ea37cc3 authored by Grigorii Demidov's avatar Grigorii Demidov Committed by Petr Špaček

daemon/worker: robustness against the slow-lorris attack

parent f7821d60
......@@ -826,14 +826,12 @@ static int qr_task_on_send(struct qr_task *task, uv_handle_t *handle, int status
if (session->waiting.len > 0) {
struct qr_task *t = session->waiting.at[0];
int ret = qr_task_send(t, handle, &session->peer.ip, t->pktbuf);
uv_timer_t *timer = &session->timeout;
uv_timer_stop(timer);
if (ret == kr_ok()) {
uv_timer_t *timer = &session->timeout;
uv_timer_stop(timer);
session->timeout.data = session;
timer_start(session, on_tcp_watchdog_timeout, MAX_TCP_INACTIVITY, 0);
} else {
uv_timer_t *timer = &session->timeout;
uv_timer_stop(timer);
while (session->waiting.len > 0) {
struct qr_task *t = session->waiting.at[0];
if (session->outgoing) {
......@@ -1081,6 +1079,7 @@ static int session_next_waiting_send(struct session *session)
struct qr_task *task = session->waiting.at[0];
ret = qr_task_send(task, session->handle, &peer->ip, task->pktbuf);
}
uv_timer_stop(&session->timeout);
session->timeout.data = session;
timer_start(session, on_tcp_watchdog_timeout, MAX_TCP_INACTIVITY, 0);
return ret;
......@@ -1693,8 +1692,9 @@ static int qr_task_step(struct qr_task *task,
session_close(session);
return qr_task_finalize(task, KR_STATE_FAIL);
}
uv_timer_stop(&session->timeout);
ret = timer_start(session, on_tcp_watchdog_timeout,
KR_CONN_RTT_MAX, 0);
MAX_TCP_INACTIVITY, 0);
if (ret < 0) {
session_del_waiting(session, task);
session_del_tasks(session, task);
......@@ -2097,11 +2097,6 @@ int worker_process_tcp(struct worker_ctx *worker, uv_stream_t *handle,
return kr_ok();
}
if (session->outgoing) {
uv_timer_stop(&session->timeout);
timer_start(session, on_tcp_watchdog_timeout, MAX_TCP_INACTIVITY, 0);
}
if (session->bytes_to_skip) {
assert(session->buffering == NULL);
ssize_t min_len = MIN(session->bytes_to_skip, len);
......@@ -2285,27 +2280,33 @@ int worker_process_tcp(struct worker_ctx *worker, uv_stream_t *handle,
/* Message was assembled, clear temporary. */
session->buffering = NULL;
session->msg_hdr_idx = 0;
if (session->outgoing) {
session_del_tasks(session, task);
}
/* Parse the packet and start resolving complete query */
int ret = parse_packet(pkt_buf);
if (ret == 0 && !session->outgoing) {
/* Start only new queries,
* not subrequests that are already pending */
ret = request_start(task->ctx, pkt_buf);
assert(ret == 0);
if (ret == 0) {
ret = qr_task_register(task, session);
}
if (ret == 0) {
submitted += 1;
}
if (task->leading) {
assert(false);
}
}
if (ret == 0) {
if (session->outgoing) {
session_del_tasks(session, task);
/* To prevent slow lorris attack restart watchdog only after
* the whole message was successfully assembled and parsed */
uv_timer_stop(&session->timeout);
if (session->tasks.len > 0) {
timer_start(session, on_tcp_watchdog_timeout,
MAX_TCP_INACTIVITY, 0);
}
} else {
/* Start only new queries,
* not subrequests that are already pending */
ret = request_start(task->ctx, pkt_buf);
assert(ret == 0);
if (ret == 0) {
ret = qr_task_register(task, session);
}
if (ret == 0) {
submitted += 1;
}
if (task->leading) {
assert(false);
}
}
const struct sockaddr *addr = session->outgoing ? &session->peer.ip : NULL;
/* since there can be next dns message, we must to proceed
* even if qr_task_step() returns error */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment