225 Commits
Author SHA1 Message Date
Benjamin Erhart f1b9b97a26 Updated dependencies. 2026-05-05 15:05:11 +02:00
Benjamin Erhart bf6f46a082 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	dnstt-client/lib/dns.go
#	dnstt-server/main.go
2026-05-05 14:15:52 +02:00
David Fifield 0c5c52a57d Update CHANGELOG to v1.20260501.0. 2026-05-01 01:13:58 +00:00
David Fifield 4d61987592 Remove the Temporary() check from ReadFrom calls.
net.Error.Temporary is deprecated since go1.18:
https://github.com/golang/go/issues/45729
https://go.dev/doc/go1.18#netpkgnet

We don't set a deadline on these reads, so we don't expect errors ever
to be Timeout(). Maybe we can get away with simply terminating the
program on any error.
2026-05-01 00:46:24 +00:00
David Fifield b79c436671 Log temporary errors from AcceptKCP and AcceptStream. 2026-05-01 00:46:24 +00:00
David Fifield a7d8773259 Don't let a WriteTo error terminate sendLoop, except net.ErrClosed.
This error check was meant to terminate sendLoop and cause it to return
with the error from WriteTo. (Except for the special case where the
error is a net.Error that is also Temporary(), in which case we merely
logged the error and continued running sendLoop.)

Errors from WriteTo (whether Temporary() or not) were rare. I managed to
get one line this after several days' uptime on a server with heavy use:
	sendLoop: write udp [::]:5300->X.X.X.X:YYYYY: sendto: operation not permitted
The above dnstt-server error was accompanied by a Linux kernel log
message:
	nf_conntrack: nf_conntrack: table full, dropping packet
What happened is the conntrack table filled and failed to track the
state of some UDP exchanges. A UDP 4-tuple lost the RELATED state and
and outbound packet was blocked by the local firewall ("operation not
permitted").

This may not be the only way a non-Temporary() WriteTo error could
happen. But in any case, when one did happen, it would cause sendLoop to
return and the server to stop processing traffic. (Before
37129955de, this was especially bad,
because the return of sendLoop would not terminate the program: it would
keep running and receiving queries, but never send any responses. Now,
at least, the program terminates, so the failure is immediately
detectable.)

Now we simply log errors from WriteTo, as if they were always temporary.
The only exception is net.ErrClosed, which causes sendLoop to terminate
as before.

Background on the net.Error Temporary() pattern:

* "Use net.Error to distinguish temporary Accept errors."
  https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib/-/commit/3030f080eecf72b0e896236fca5fabd245c00bdb
* "Don't report errors that are not caused by Accept in AcceptSocks."
  https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib/-/commit/50b39b746c6ff34bf31977b658848d876ee84fbf
* https://go.dev/blog/error-handling-and-go#the-error-type

net.Error.Temporary was deprecated in go1.18:
* "net: deprecate Temporary error status"
  https://github.com/golang/go/issues/45729
* https://go.dev/doc/go1.18#netpkgnet
See also:
* "net/http: server.Serve() uses deprecated net.Error.Temporary()"
  https://github.com/golang/go/issues/66208
* "proposal: net: add ErrRetryableAcceptError"
  https://github.com/golang/go/issues/66252

For now, though, even though I'm removing the Temporary() check on
WriteTo errors, I'm keeping it for KCP AcceptKCP and AcceptStream. It
may still be the right thing for an accept loop; cf.
https://groups.google.com/g/golang-nuts/c/-JcZzOkyqYI/m/wp_5G8LmAwAJ:
	While the whole suite of Temporary errors isn't really coherent,
	the issue is that a small subset of Temporary is still useful
	for Accept loops and it doesn't have a non-deprecated
	replacement. As a case in point, I presume that http.Server is
	going to keep using Temporary indefinitely.
2026-05-01 00:46:24 +00:00
David Fifield a3210833f1 Reorganize README. 2026-04-21 01:06:38 +00:00
David Fifield 0b5b9b10f0 Use port 8000 in Dante example to match the others. 2026-04-21 01:06:16 +00:00
David Fifield 65880742b9 Add Dante configuration example. 2026-04-21 01:00:13 +00:00
David Fifield a786303c10 Let termination of acceptSessions end the program as well. 2026-04-21 00:27:36 +00:00
David Fifield 37129955de Let the program end if sendLoop happens to end before recvLoop.
Without sendLoop, the program can no longer make progress. Treat
sendLoop and recvLoop as peer goroutines, instead of having recvLoop on
the main class stack and sendLoop as a goroutine.
2026-04-21 00:26:36 +00:00
David Fifield 2d7ce00f5b Stop and drain the timer before Reset in sendLoop.
Before go1.23, calling Stop, and draining the channel if the timer did
not already fire, is necessary before calling Reset:
https://pkg.go.dev/time@go1.22.12#Timer.Reset

This changed in go1.23: now Reset automatically effectively drains the
channel, and calling Stop is no longer necessary.
https://pkg.go.dev/time@go1.23.9#Timer.Reset

However, the changes in go1.23 only take effect if go.mod specifies
1.23 or later. We currently specify 1.21.
https://go.dev/doc/go1.23#timer-changes

For compatibility, do the Stop/drain procedure before calling Reset. We
were already doing this for pollTimer in DNSPacketConn) sendLoop in
dnstt-client.

This change may not have any observable effect. The duration we Reset
the timer to was 0, so if there had been a stale value in the channel
because of a failure to drain it, the effect would be the same as
waiting 0 seconds. We were already calling Stop when finished with the
timer, so it would have been garbage-collectable even before go1.23.
2026-04-17 16:50:58 +00:00
Benjamin Erhart 4d6751daa3 Fixed problem, where threads were blocked endlessly after shutdown. v1.20260311.0 2026-03-11 15:45:18 +01:00
Benjamin Erhart 0bb20c1113 Fixed warning. 2026-03-11 15:45:18 +01:00
Benjamin Erhart 743dad1f5c Replaced panic with log and return. 2026-03-11 15:45:18 +01:00
Benjamin Erhart 110764f0a9 Issue #2: Updated README to direct confused users to the original project. 2026-02-09 13:50:12 +01:00
Benjamin Erhart 0d2e84c7d4 Merge remote-tracking branch 'upstream/master' 2026-02-03 15:19:57 +01:00
David Fifield e5e873bd64 The effective MTU is independent of DOMAIN. 2026-01-25 06:54:56 +00:00
David Fifield 9ccfc3730e Fix a use of .Nm in dnstt-server man page. 2026-01-25 06:26:02 +00:00
Benjamin Erhart e111260cbc Switched to the latest version of goptlib. Made AcceptLoop publicly accessible for easier reuse. 2026-01-21 14:44:09 +01:00
Benjamin Erhart d734764a6b Updated all dependencies. 2026-01-21 13:06:15 +01:00
Benjamin Erhart eed4f410df Merge remote-tracking branch 'upstream/master' 2026-01-21 12:57:33 +01:00
David Fifield 82fb0a6790 Add CC0 COPYING file. v1.20241021.0 2024-10-21 05:39:01 +00:00
David Fifield 01100d2288 CHANGELOG for v1.20240513.0. v1.20240513.0 2024-05-13 19:46:00 +00:00
David Fifield 9391b29dfd Update kcp-go and smux. 2024-05-13 19:46:00 +00:00
David Fifield 644489c181 Update default uTLS fingerprint distribution.
Chrome fingerprints appear to be usable now, as long as they are not the
oldest ones.. (Compare to the commit log message of
98bdffa1706dfc041d1e99b86c47f29d72ad3a0c.) Also add the "random"
fingerprint.

            -doh dns.google   -dot dns.google   -doh 1.1.1.1   -dot 1.1.1.1
none        ok                ok                ok             ok
random      ok                ok                ok             ok
Firefox_55  ok                ok                ok             ok
Firefox_56  ok                ok                ok             ok
Firefox_63  ok                ok                ok             ok
Firefox_65  ok                ok                ok             ok
Firefox_99  ok                ok                ok             ok
Firefox_102 ok                ok                ok             ok
Firefox_105 ok                ok                ok             ok
Firefox_120 ok                ok                ok             ok
Chrome_58   ERROR             ERROR             ok             ok
Chrome_62   ERROR             ERROR             ok             ok
Chrome_70   ERROR             ERROR             ok             ok
Chrome_72   ok                ok                ok             ok
Chrome_83   ok                ok                ok             ok
Chrome_87   ok                ok                ok             ok
Chrome_96   ok                ok                ok             ok
Chrome_100  ok                ok                ok             ok
Chrome_102  ok                ok                ok             ok
Chrome_120  ok                ok                ok             ok
iOS_11_1    ok                ok                ok             ok
iOS_12_1    ok                ok                ok             ok
iOS_13      ok                ok                ok             ok
iOS_14      ok                ok                ok             ok

This is the script used to collect data for the above table:

TCPDUMP="tcpdump"
FPS="
none random Firefox_55 Firefox_56 Firefox_63 Firefox_65
Firefox_99 Firefox_102 Firefox_105 Firefox_120 Chrome_58
Chrome_62 Chrome_70 Chrome_72 Chrome_83 Chrome_87 Chrome_96 Chrome_100
Chrome_102 Chrome_120 iOS_11_1 iOS_12_1 iOS_13 iOS_14
"
sudo -v; \
for HOST in dns.google 1.1.1.1; do
	for UTLS in $FPS; do
		ID="doh-utls-$HOST-$UTLS";
		echo
		echo "$ID"
		sudo $TCPDUMP -n -U -w "$ID.pcap" &
		sleep 1;
		timeout 2 ./dnstt-client -doh https://"$HOST"/dns-query -utls "$UTLS" -pubkey-file "$PUBKEY" "$DOMAIN" 127.0.0.1:7000;
		sudo kill $!;
		tshark -n -V -Y ssl.handshake.ciphersuites -r "$ID.pcap" | sed -n -e '/^Transport Layer Security/,/^$/p' > "$ID.txt";
		ID="dot-utls-$HOST-$UTLS";
		echo
		echo "$ID"
		sudo $TCPDUMP -n -U -w "$ID.pcap" &
		sleep 1;
		timeout 2 ./dnstt-client -dot "$HOST":853 -utls "$UTLS" -pubkey-file "$PUBKEY" "$DOMAIN" 127.0.0.1:7000;
		sudo kill $!;
		tshark -n -V -Y ssl.handshake.ciphersuites -r "$ID.pcap" | sed -n -e '/^Transport Layer Security/,/^$/p' > "$ID.txt";
	done;
done
2024-05-13 19:32:08 +00:00
David Fifield 4d3d776470 Allow -utls random for HelloRandomizedALPN. 2024-05-13 19:16:42 +00:00
David Fifield 45f9079b53 Activate new Firefox, Chrome, and iOS uTLS fingerprints. 2024-05-13 19:16:29 +00:00
David Fifield 6adedaa823 Upgrade utls to v1.6.6.
Remove the SNI workaround that is fixed in v1.6.6.

https://github.com/refraction-networking/utls/issues/96

I find that the workaround for
https://github.com/refraction-networking/utls/issues/75
is still necessary; otherwise the local side thinks it's speaking
HTTP/1.1 while the remote is speaking HTTP/2:

2024/05/13 17:15:49 sendLoop: Post "https://1.1.1.1/dns-query": net/http: HTTP/1.x transport connection broken: malformed HTTP response "\x00\x00\x12\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00d\x00\x04\x00\x01\x00\x00\x00\x05\x00\xff\xff\xff\x00\x00\x04\b\x00\x00\x00\x00\x00\x7f\xff\x00\x00\x00\x00\b\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
2024-05-13 19:14:47 +00:00
David Fifield 4a55755e72 Comment on -utls none in man page. 2024-05-13 19:14:47 +00:00
David Fifield ad8951f685 fmt with go1.19 conventions.
https://go.dev/doc/go1.19#go-doc
2023-12-21 15:10:11 +00:00
David Fifield 81b502c735 Remove extra newline in README. 2022-10-06 23:25:23 -06:00
David Fifield 31b5b1db4b RFC 9250 for DoQ. 2022-09-01 08:57:54 -04:00
David Fifield 8616ecd1f3 Add reference for DoH3 in Android. 2022-07-20 15:02:33 -04:00
Benjamin Erhart c9c02b827b Moved DoH/DoT/UDP configuration from command line to PT-compatible SOCKS CONNECT configuration. 2022-07-15 15:39:19 +02:00
Benjamin Erhart 057566a0b2 Server: First attempt at making server PT1 compatible. 2022-06-10 17:23:35 +02:00
Benjamin Erhart a55be91df9 Server: Fixed IDE warnings. 2022-06-10 16:29:31 +02:00
Benjamin Erhart b2a094e820 Added Stop function. 2022-06-10 15:42:52 +02:00
Benjamin Erhart 66b792b5d0 Moved more out of main package, to allow use in library without any patches. 2022-06-10 15:31:35 +02:00
Benjamin Erhart df4186f635 Suggestion from dcf: Let domain and pubkey be configurable via each SOCKS5 connection instead of for all connections via command line. 2022-06-10 13:41:36 +02:00
Benjamin Erhart f67f357a1e Moved most files of the client into a subdirectory, to reduce need for patching for use in IPtProxy. 2022-06-10 13:41:36 +02:00
Benjamin Erhart f7aff04bef Suggestion from dcf: PTs should not require a local address argument, but instead always listen on localhost on a random port. 2022-06-10 13:41:25 +02:00
Benjamin Erhart 04132afdb5 Improved PT 1 spec compatibility: Don't just say you talk SOCKS5 - actually do it! 2022-06-09 16:27:22 +02:00
Benjamin Erhart ef22747193 First attempt at adding PT 1.0 compatibility. 2022-06-03 13:55:51 +02:00
David Fifield 04f04590c6 Add RFC reference for RCODE=BADVERS. 2022-02-13 09:52:48 -07:00
David Fifield 14a29048e4 CHANGELOG for v1.20220208.0. v1.20220208.0 2022-02-08 15:48:16 -07:00
David Fifield 70670d4a77 Fix up the BNF for weighted lists. 2022-01-06 12:18:12 -07:00
David Fifield 4a0bab019b Add -utls to dnstt-client man page. 2022-01-06 12:17:28 -07:00
David Fifield 98bdffa170 Remove Chrome fingerprints from the default uTLS distribution.
In testing with uTLS v1.0.0, go1.15.15, -doh and -dot, and dns.google
and 1.1.1.1, there is no Chrome fingerprint that works on all of them. I
did not investigate what exactly is going wrong. The error message
generally is "remote error: tls: unexpected message".

		-doh dns.google	-dot dns.google	-doh 1.1.1.1	-dot 1.1.1.1
Firefox_55	ok		ok		ok		ok
Firefox_56	ok		ok		ok		ok
Firefox_63	ok		ok		ok		ok
Firefox_65	ok		ok		ok		ok
Chrome_58	ERROR		ERROR		ok		ok
Chrome_62	ERROR		ERROR		ok		ok
Chrome_70	ERROR		ERROR		ERROR		ok
Chrome_72	ok		ok		ERROR		ok
Chrome_83	ok		ok		ERROR		ok
iOS_11_1	ok		ok		ok		ok
iOS_12_1	ok		ok		ok		ok

This is a script I used for testing fingerprints:

FPS="none Firefox_55 Firefox_56 Firefox_63 Firefox_65 Chrome_58 Chrome_62 Chrome_70 Chrome_72 Chrome_83 iOS_11_1 iOS_12_1"
sudo -v; \
for HOST in dns.google 1.1.1.1; do \
	for UTLS in $FPS; do \
		ID="doh-utls-$HOST-$UTLS"; \
		sudo tcpdump -n -U -w "$ID.pcap" & \
		timeout 2 ./dnstt-client -doh https://"$HOST"/dns-query -utls "$UTLS" -pubkey-file "$PUBKEY" "$DOMAIN" 127.0.0.1:7000; \
		sudo kill $!; \
		tshark -n -V -Y ssl.handshake.ciphersuites -r "$ID.pcap" | sed -n -e '/^Transport Layer Security/,/^$/p' > "$ID.txt"; \
		ID="dot-utls-$HOST-$UTLS"; \
		sudo tcpdump -n -U -w "$ID.pcap" & \
		timeout 2 ./dnstt-client -dot "$HOST":853 -utls "$UTLS" -pubkey-file "$PUBKEY" "$DOMAIN" 127.0.0.1:7000; \
		sudo kill $!; \
		tshark -n -V -Y ssl.handshake.ciphersuites -r "$ID.pcap" | sed -n -e '/^Transport Layer Security/,/^$/p' > "$ID.txt"; \
	done; \
done
2022-01-02 19:50:33 -07:00
David Fifield d365a09d86 Permit "-utls none" to disable uTLS. 2022-01-02 19:50:33 -07:00