diff options
author | Oto Šťáva <oto.stava@nic.cz> | 2023-08-01 16:36:53 +0200 |
---|---|---|
committer | Vladimír Čunát <vladimir.cunat@nic.cz> | 2023-08-22 13:38:27 +0200 |
commit | 7aec8ebdf1428afcb7f5bc62764149ffeaf3d3fe (patch) | |
tree | 95183cf8c0654c6c4fafcd1299d4b661471d00f8 /daemon/worker.c | |
parent | Merge !1444: manager: datamodel: fix /cache/ttl-max default (diff) | |
download | knot-resolver-7aec8ebdf1428afcb7f5bc62764149ffeaf3d3fe.tar.xz knot-resolver-7aec8ebdf1428afcb7f5bc62764149ffeaf3d3fe.zip |
daemon: more avoidance of excessive TCP reconnections
Previously this penalization was only triggered if the remote server
closed TCP. Now it's extended to us closing it when the server
(only) sends back some nonsense. At least for the cases which I could
see immediately.
That's just three trivial one-line additions; the rest is refactoring.
Adapted to 6.0 from commit 6468ab22 by Oto Šťáva <oto.stava@nic.cz>
Co-Authored-By: Vladimír Čunat <vladimir.cunat@nic.cz>
Diffstat (limited to '')
-rw-r--r-- | daemon/worker.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/daemon/worker.c b/daemon/worker.c index 8d0a6b28..2d293ba9 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -41,6 +41,8 @@ #define MAX_PIPELINED 100 #endif +#define MAX_DGRAM_LEN UINT16_MAX + #define VERBOSE_MSG(qry, ...) kr_log_q(qry, WORKER, __VA_ARGS__) /** Client request state. */ @@ -1757,6 +1759,12 @@ static enum protolayer_iter_cb_result pl_dns_dgram_unwrap( int ret = kr_ok(); for (int i = 0; i < ctx->payload.iovec.cnt; i++) { const struct iovec *iov = &ctx->payload.iovec.iov[i]; + if (iov->iov_len > MAX_DGRAM_LEN) { + session2_penalize(session); + ret = kr_error(EFBIG); + break; + } + knot_pkt_t *pkt = produce_packet( iov->iov_base, iov->iov_len); if (!pkt) { @@ -1772,6 +1780,10 @@ static enum protolayer_iter_cb_result pl_dns_dgram_unwrap( mp_flush(the_worker->pkt_pool.ctx); return protolayer_break(ctx, ret); } else if (ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER) { + if (ctx->payload.buffer.len > MAX_DGRAM_LEN) { + session2_penalize(session); + return protolayer_break(ctx, kr_error(EFBIG)); + } knot_pkt_t *pkt = produce_packet( ctx->payload.buffer.buf, ctx->payload.buffer.len); @@ -1782,9 +1794,15 @@ static enum protolayer_iter_cb_result pl_dns_dgram_unwrap( mp_flush(the_worker->pkt_pool.ctx); return protolayer_break(ctx, ret); } else if (ctx->payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) { + const size_t msg_len = wire_buf_data_length(ctx->payload.wire_buf); + if (msg_len > MAX_DGRAM_LEN) { + session2_penalize(session); + return protolayer_break(ctx, kr_error(EFBIG)); + } + knot_pkt_t *pkt = produce_packet( wire_buf_data(ctx->payload.wire_buf), - wire_buf_data_length(ctx->payload.wire_buf)); + msg_len); if (!pkt) return protolayer_break(ctx, KNOT_EMALF); @@ -2079,10 +2097,12 @@ static knot_pkt_t *stream_produce_packet(struct session2 *session, uint16_t msg_len = knot_wire_read_u16(wire_buf_data(wb)); if (msg_len == 0) { *out_err = true; + session2_penalize(session); return NULL; } if (msg_len >= wb->size) { *out_err = true; + session2_penalize(session); return NULL; } if (wire_buf_data_length(wb) < msg_len + sizeof(uint16_t)) { |