Commit Graph
43 Commits
Author SHA1 Message Date
David Fifield fec00a2a78 -utls option and random TLS fingerprint selection. 2022-01-02 19:16:00 -07:00
David Fifield 70c78e24d7 TLS camouflage using uTLS and a hardcoded Client Hello ID.
net/http Transport.DialTLSContext requires go1.14.
https://go.dev/doc/go1.14#net/http
2022-01-02 19:14:35 -07:00
David Fifield e4dc2883ef Use errors.Is to compare against ErrClosedPipe.
I was still getting "io: read/write on closed pipe" errors in the logs,
even after comparing errors against io.ErrClosedPipe to skip logging
them. It turns out that kcp-go wraps many of its errors in another type.
The actual type of the errors was *errors.withStack, where errors is
https://github.com/pkg/errors. We can use the go1.13 errors interface
(https://blog.golang.org/go1.13-errors) to get at the value inside.
2021-08-03 21:00:45 -06:00
David Fifield 1f73f6f5b6 Ignore ErrClosedPipe in "copy stream←upstream" as well.
Saw this happen on the server during the 2021-08-02 performance tests.
Doing on the client, too, for uniformity.
2021-08-03 20:58:20 -06:00
David Fifield de15c5a512 Performance tuning: MaxStreamBuffer, SetWindowSize, QueueSize.
This enlarges a few buffers and windows, with the goal of improving
download performance. kcp's SetWindowSize controls the number of
unacknowledged packets that are allowed. smux's MaxStreamBuffer is
another kind of "receive window" that is advertised to the peer of how
much we are willing to receive at once. The default MaxStreamBuffer is
64 KB, but kcptun overrides the default to 2 MB. turbotunnel's QueueSize
is the size of internal buffers in QueuePacketConn and RemoteMap;
empirically I found that the server would sometimes fill its outgoing
buffer if SetWindowSize and QueueSize were equal, so I set QueueSize to
be twice SetWindowSize.

https://lists.torproject.org/pipermail/anti-censorship-team/2021-July/000178.html
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/merge_requests/48

The changes have a large effect on a direct -udp connection without a
recursive resolver—which, however, is a discouraged configuration.
Through a recursive resolver, the improvements are more modest. If I
really crank up the buffer sizes, I can get surprisingly fast downloads
over a direct -udp connection (over 1 MB/s), but a connection through a
resolver doesn't keep getting faster and may even get slower. I want to
avoid a bufferbloat situation with oversized buffers, too. I manually
explored a small neighborhood of parameter values and picked some
settings that looked reasonable.

The tables below show the test results. The test is downloading 10 MiB
between two servers with 100 ms RTT between them. Server:
	dnstt-server -udp :53 -privkey-file server.key t.example.com 127.0.0.1:9321
	ncat -l -k -v 9321 --send-only --sh-exec 'dd bs=1M count=10 if=/dev/urandom'
Client:
	dnstt-client -pubkey-file server.pub t.example.com 127.0.0.1:7000
	ncat --recv-only 127.0.0.1 7000 | pv -t -r -a -b -i 0.2 > /dev/null
I did the download under every treatment twice and recorded the download
rate in KiB/s. "Server drops" comes from hacking some log messages to
turbotunnel.QueuePacketConn to track how often the "Drop the incoming
packet" (QueueIncoming method) and "Drop the outgoing packet" (WriteTo)
cases happen.

resolver	method	QueueSize	MaxStreamBuffer	SetWindowSize	KiB/s	KiB/s
--------	------	---------	---------------	-------------	-----	-----
direct		udp	64		64*1024		(32, 32)	 169	 173	(status before this commit)
dns.google	udp	64		64*1024		(32, 32)	  63.8	  64.3	(status before this commit)
dns.google	doh	64		64*1024		(32, 32)	 125	 122	(status before this commit)

resolver	method	QueueSize	MaxStreamBuffer	SetWindowSize	KiB/s	KiB/s
--------	------	---------	---------------	-------------	-----	-----
direct		udp	64		1*1024*1024	(32, 32)	 172	 174
dns.google	udp	64		1*1024*1024	(32, 32)	  57.3	  58.4	server drops
dns.google	doh	64		1*1024*1024	(32, 32)	 128	 128

resolver	method	QueueSize	MaxStreamBuffer	SetWindowSize	KiB/s	KiB/s
--------	------	---------	---------------	-------------	-----	-----
direct		udp	64		1*1024*1024	(64, 64)	 322	 305
dns.google	udp	64		1*1024*1024	(64, 64)	  72.5	  70.9	server drops
dns.google	doh	64		1*1024*1024	(64, 64)	 136	 139	server drops

resolver	method	QueueSize	MaxStreamBuffer	SetWindowSize	KiB/s	KiB/s
--------	------	---------	---------------	-------------	-----	-----
direct		udp	128		1*1024*1024	(64, 64)	 321	 325	(this commit)
dns.google	udp	128		1*1024*1024	(64, 64)	  82.5	  78.5	(this commit)
dns.google	doh	128		1*1024*1024	(64, 64)	 129	 131	(this commit)

resolver	method	QueueSize	MaxStreamBuffer	SetWindowSize	KiB/s	KiB/s
--------	------	---------	---------------	-------------	-----	-----
direct		udp	2048		4*1024*1024	(1024, 1024)	1240	1060	server drops
dns.google	udp	2048		4*1024*1024	(1024, 1024)	  73.5	 81.4
dns.google	doh	2048		4*1024*1024	(1024, 1024)	 115	 129
2021-08-02 15:25:19 -06:00
David Fifield c7613b89e1 Reduce smux idle timeout from 10 minutes to 2 minutes. 2021-08-01 22:32:57 -06:00
David Fifield 064c53e3d1 Be uniform about not ending log calls with "\n". 2021-04-20 15:14:10 -06:00
David Fifield 7b033a38ca Reflow comment. 2021-04-20 12:57:47 -06:00
David Fifield 3254c1c81e Open the client's local listener first. 2020-04-29 23:56:36 -06:00
David Fifield 05444dcb22 smux Stream.Write may also return EOF. 2020-04-25 21:27:14 -06:00
David Fifield 241225df1d Add -mtu option to server. 2020-04-25 20:54:09 -06:00
David Fifield 9ee6bf8abf Use wg.Add(2) instead of 2 × wg.Add(1). 2020-04-23 15:51:53 -06:00
David Fifield d14deab12b Documentation and light refactoring. 2020-04-19 17:16:27 -06:00
David Fifield 813a8564e8 Move some helper functions into dns.go. 2020-04-19 11:29:50 -06:00
David Fifield e9a98c3aef Avoid logging EOF and ErrClosedPipe errors.
smux Stream.WriteTo may return io.EOF, which breaks the contract of
io.Copy that says it should not return io.EOF. smux.Stream doesn't have
a unidirectional shutdown, so we always end up slamming it shut in both
directions and leave the other direction with a broken pipe.
2020-04-19 02:13:48 -06:00
David Fifield e7098959e2 Move global base32Encoding into dns.go. 2020-04-18 23:39:35 -06:00
David Fifield 41c146355a Do MTU check first. 2020-04-18 19:05:23 -06:00
David Fifield 0a630f91c5 Log stream begin/end in server, log conv in client. 2020-04-18 19:05:23 -06:00
David Fifield 7ed79218eb Insert more padding when polling. 2020-04-18 18:46:54 -06:00
David Fifield b1bf9164a7 -privkey-file and -pubkey-file options. 2020-04-18 17:56:45 -06:00
David Fifield 505db3ec23 Server -privkey option and client -pubkey option. 2020-04-18 17:35:32 -06:00
David Fifield b98eb2c75e Move dummyAddr to turbotunnel.DummyAddr. 2020-04-18 16:02:14 -06:00
David Fifield 5350ea1e68 Increase initPollDelay to 500 ms. 2020-04-18 16:02:14 -06:00
David Fifield 06144f76ae -dot mode. 2020-04-18 16:02:11 -06:00
David Fifield be9c3f1ac7 Refactor PacketConn handling. 2020-04-18 14:34:10 -06:00
David Fifield 7f3e9e4571 Overlay a noise layer atop KCP. 2020-04-18 14:34:10 -06:00
David Fifield 3f98c62207 Log when there's an error opening a stream. 2020-04-18 14:34:10 -06:00
David Fifield a6c891c5ae -doh mode. 2020-04-18 14:33:39 -06:00
David Fifield aefe4f9971 Factor out a pattern for different kinds of remote address. 2020-04-18 14:33:39 -06:00
David Fifield 45c44e1c33 Factor out udp.go. 2020-04-18 14:33:39 -06:00
David Fifield 2cf79b1763 Log stream begin/end. 2020-04-18 14:33:39 -06:00
David Fifield 700291d6a1 MTU to log, not stdout. 2020-04-18 14:33:39 -06:00
David Fifield ea824f3658 Check for error from SetMtu. 2020-04-18 14:33:39 -06:00
David Fifield 584dc3950d Advertise EDNS(0) in client. 2020-04-18 14:33:39 -06:00
David Fifield 410dafa29c Packetization server→client direction. 2020-04-18 14:29:30 -06:00
David Fifield ffcea8b633 Logging in client. 2020-04-18 14:29:30 -06:00
David Fifield 0ebbe21789 Don't explicitly send 0-length packets. 2020-04-18 14:29:30 -06:00
David Fifield 933f17de78 Packetization and padding in the client→server direction. 2020-04-18 14:29:29 -06:00
David Fifield bf609a4cf8 Set MTU based on domain length. 2020-04-18 14:29:13 -06:00
David Fifield f47fa9781b Increasing poll interval. 2020-04-18 14:28:55 -06:00
David Fifield 1a630ef92f Automatic polling. 2020-04-18 14:28:55 -06:00
David Fifield 3b48d1aee1 Send full 8-byte ClientID
Sending just 4 bytes and relying on the convid for the remaining bytes
doesn't work for empty polling requests. Could probably just eliminate
the convid and make it a static constant before feeding to KCP.
2020-04-18 14:28:55 -06:00
David Fifield 9f72a8a87d client 2020-04-18 14:28:53 -06:00