mirror of
https://github.com/tladesignz/dnstt.git
synced 2026-10-06 05:48:06 +03:00
In my testing locally, specifying -dot with a non-responsive TCP port would time out after about 30 seconds anyway: $ time ./dnstt-client -dot tns.example.com:8000 -pubkey-file server.pub t.example.com 127.0.0.1:7000 dial tcp 45.79.134.119:8000: connect: connection timed out real 0m31.398s user 0m0.006s sys 0m0.003s Which is in line with the documentation for net.Dialer: https://golang.org/pkg/net/#Dialer With or without a timeout, the operating system may impose its own earlier timeout. For instance, TCP timeouts are often around 3 minutes. But may as well be explicit. This commit has the side effect of changing the error message from "connection timed out" to "i/o timeout". $ time ./dnstt-client -dot tns.example.com:8000 -pubkey-file server.pub t.example.com 127.0.0.1:7000 dial tcp 45.79.134.119:8000: i/o timeout real 0m30.007s user 0m0.003s sys 0m0.007s I tried setting the dialTimeout to 40 seconds, and in that case the system timeout take precedence after ≈31 seconds, with the "connection timed out" error as before. This is issue UCB-02-007 from the 2021 security audit of Turbo Tunnel by Cure53. The audit report additionally recommends calling SetReadDeadline before each read operation. I have chosen not to do that. It is intended that the TLS connection should be able to remain idle if there is nothing to send. As DNS is a query–response protocol, one might expect a response (and within a certain amount of time) only after sending a query; sendLoop could refresh the ReadDeadline for recvLoop every time it sends a query. But a malicious DoT server could keep a useless connection alive anyway by sending Slowloris-style short responses within each deadline, and an external adversary could capable of delaying responses could deny service indefinitely or simply block the server. In any case, the smux KeepAliveTimeout serves as a check that prevents stalled connections from remaining indefinitely.