fix: harden DoT listener against slowloris and stale handshakes

- Add 10s timeout on TLS handshake — prevents clients from holding a
  semaphore permit without completing the handshake
- Add IDLE_TIMEOUT on payload read_exact — prevents slowloris after
  sending a valid length prefix then trickling bytes
- Extract accept_loop() shared between start_dot and tests — eliminates
  duplicated accept logic that could drift
- Add 5s timeout on TCP reads in recursive test mock server

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Razvan Dimescu
2026-04-06 23:10:45 +03:00
parent aa8923b2c6
commit cb54ab3dfc
2 changed files with 42 additions and 43 deletions

View File

@@ -870,14 +870,25 @@ mod tests {
};
let handler = handler.clone();
tokio::spawn(async move {
let timeout = std::time::Duration::from_secs(5);
// Read length-prefixed DNS query
let mut len_buf = [0u8; 2];
if stream.read_exact(&mut len_buf).await.is_err() {
if tokio::time::timeout(timeout, stream.read_exact(&mut len_buf))
.await
.ok()
.and_then(|r| r.ok())
.is_none()
{
return;
}
let len = u16::from_be_bytes(len_buf) as usize;
let mut data = vec![0u8; len];
if stream.read_exact(&mut data).await.is_err() {
if tokio::time::timeout(timeout, stream.read_exact(&mut data))
.await
.ok()
.and_then(|r| r.ok())
.is_none()
{
return;
}