Commit graph

447 commits

Author SHA1 Message Date
Shelikhoo
80262c9e4f set protocol query for connection with server unconditionally 2025-01-21 20:55:26 +04:00
Shelikhoo
2606075bdf add debug protocol output 2025-01-21 20:55:25 +04:00
Shelikhoo
93d303b47b Add testing environment helpers 2025-01-21 20:55:25 +04:00
Shelikhoo
457c4fbf15 Add UDP Like transport mode to snowflake 2025-01-21 20:55:25 +04:00
WofWca
e038b68d79 refactor(proxy): simplify tokens.ret() on error 2025-01-04 19:31:44 +04:00
WofWca
85a93c5303 docs: clarify -ports-range is for port forwarding 2024-12-13 17:06:13 +04:00
WofWca
92521b6679 improvement: warn if ports-range is too narrow
...and improve the docstring for the parameter.
2024-12-13 17:06:11 +04:00
WofWca
cb32d008ca docs: improve ephemeral-ports-range description
Clarify that the default range is wide.
2024-12-13 16:09:22 +04:00
Cecylia Bocovich
6ecd5bf6d7
Remove log when offer is nil
After !414, we started returning a nil offer from pollOffer if the proxy
was not matched with a client. It's not longer an indication of failure,
so we should remove the "bad offer from broker" log message.
2024-12-03 15:05:44 -05:00
Cecylia Bocovich
5b479fdb13
Log EventOnCurrentNATTypeDetermined for proxy 2024-12-03 15:05:44 -05:00
WofWca
ae5bd52821
improvement: use SetIPFilter for local addrs
Closes https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40271.
Supersedes https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/merge_requests/417.

This simplifies the code and (probably) removes the need for
`StripLocalAddresses`, although makes us more dependent on Pion.

Signed-off-by: Cecylia Bocovich <cohosh@torproject.org>
2024-11-28 10:56:40 -05:00
Cecylia Bocovich
43799819a1
Suppress logs of proxy events by default 2024-11-28 10:42:54 -05:00
WofWca
c5d680342b
refactor: separate function for connectToRelay
This should make the code easier to glance over,
to understand that relay connection is performed from inside
the datachannel handler.
2024-11-21 14:55:28 +00:00
Shelikhoo
239357509f
update snowflake to use pion webrtc v4 2024-11-13 14:58:53 +00:00
Renovate Bot
290be512e3 chore(deps): update module github.com/pion/webrtc/v3 to v4 2024-11-11 18:45:36 +00:00
Cecylia Bocovich
aaf8826560
Add proxy event for when client has connected
This enables the usage of callbacks that will be called when a client
has opened a data channel connection to the proxy.
2024-11-06 10:31:33 -05:00
Waldemar Zimpel
028ff82683 Optionally enable local time for logging
Introduces the option `-log-local-time` which switches to local time
for logging instead of using UTC. Also if this option is applied, a message
is being output to the log on startup about the usage of local time
to draw attention, so the user/operator can take care of anonymity in case
the logs are going to be shared.
2024-10-28 16:23:44 +01:00
Neel Chauhan
f4305180b9
Remove the pollInterval loop from SignalingServer.pollOffer in the standalone proxy
Closes #40210.
2024-10-22 14:50:43 -04:00
Neel Chauhan
8792771cdc
broker and proxy must not reject client offers with no ICE candidates
Fixes #40371. Partially reverts !141.
2024-10-17 15:46:02 -04:00
Neel Chauhan
9ff205dd7f
Probetest/proxy: Set multiple comma-separated default STUN URLs
This adds the BlackBerry STUN server alongside Google's. Closes #40392.
2024-10-17 15:15:02 -04:00
WofWca
d346639eda
improvement(proxy): improve NAT check logging 2024-09-26 18:15:04 +01:00
WofWca
9b04728809
docs: improve proxy CLI param descriptions
Since the proxy component is the most dedicated for public use,
more comprehensive docs are good.
2024-09-25 16:50:18 +01:00
David Fifield
de61d7bb8d Document relayURL return in SignalingServer.pollOffer.
The second return value was added in
863a8296e8.
2024-09-21 18:28:17 +00:00
WofWca
0f0f118827 improvement(proxy): don't panic on invalid relayURL
Though prior to this change the panic could only happen
if the default relayURL set by the proxy is invalid,
since `datachannelHandler` is only called after a succesful
`checkIsRelayURLAcceptable()`, which ensures that it _is_ valid.
But in the case of invalid default relay URL, a warning is printed
already.
2024-09-21 18:20:31 +00:00
David Fifield
f752d2ab0c Spell out EphemeralMinPort and EphemeralMaxPort in comment.
For searching purposes.
2024-09-21 14:30:59 +00:00
WofWca
daff4d8913 refactor(proxy): add comment about packet size 2024-09-19 19:14:04 +00:00
WofWca
51edbbfd26
fix(proxy): maybe memory leak on failed NAT check
Maybe related: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40243
2024-09-09 15:26:58 +01:00
WofWca
f44aa279fe
refactor(proxy): improve NAT check logging
4ed5da7f2f introduced `OnError` but it did not print
failed periodic NAT type check errors - the error was simply
ignored.
2024-09-09 15:26:55 +01:00
WofWca
7f9fea5797
fix(proxy): send answer even if ICE gathering is not complete
Otherwise the connection is guaranteed to fail, even though
we actually might have gathered enough to make a successful
connection.

Closes https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40230

This is the standalone proxy counterpart of https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake-webext/-/merge_requests/55
2024-09-09 11:58:28 +01:00
WofWca
2bbd4d0643
refactor(proxy): better RelayURL description
It's the case that it's simply "default" after
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/merge_requests/87
Now the broker specifies the relay URL (see `ProxyPollResponse`).
2024-09-05 13:04:42 +01:00
WofWca
94c6089cdd
hardening(proxy): don't proxy private IP addresses
...by default.

This is useful when `RelayDomainNamePattern` is lax (e.g. just "$")
(which is not the case by default, so this is simply
a hardening measure).
2024-09-02 14:59:26 +01:00
WofWca
399bda5257
refactor(proxy): tidy up isRelayURLAcceptable
Add clearer error messages
2024-09-02 14:59:26 +01:00
WofWca
0f2bdffba0
hardening(proxy): only accept ws & wss relays 2024-09-02 14:59:26 +01:00
WofWca
14f4c82ff7
test(proxy): add tests for relayURL check 2024-09-02 14:59:23 +01:00
WofWca
f4db64612c
feat: expose pollInterval in CLI
Closes https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40373
2024-08-22 09:31:37 -04:00
obble
a6d4570c23
Fix log message in CopyLoop 2024-08-21 16:06:41 +01:00
obble
1d6a2580c6 Improving Snowflake Proxy Performance by Adjusting Copy Buffer Size
TL;DR: The current implementation uses a 32K buffer size for a total of 64K of
buffers/connection, but each read/write is less than 2K according to my measurements.

# Background

The Snwoflake proxy uses as particularly hot function `copyLoop`
(proxy/lib/snowflake.go) to proxy data from a Tor relay to a connected client.
This is currently done using the `io.Copy` function to write all incoming data
both ways.

Looking at the `io.Copy` implementation, it internally uses `io.CopyBuffer`,
which in turn defaults to a buffer of size 32K for copying data (I checked and
the current implementation uses 32K every time).

Since `snowflake-proxy` is intended to be run in a very distributed manner, on
as many machines as possible, minimizing the CPU and memory footprint of each
proxied connection would be ideal, as well as maximising throughput for
clients.

# Hypothesis

There might exist a buffer size `X` that is more suitable for usage in `copyLoop` than 32K.

# Testing

## Using tcpdump

Assuming you use `-ephemeral-ports-range 50000:51000` for `snowflake-proxy`,
you can capture the UDP packets being proxied using

```sh
sudo tcpdump  -i <interface> udp portrange 50000-51000
```

which will provide a `length` value for each packet captured. One good start
value for `X` could then be slighly larger than the largest captured packet,
assuming one packet is copied at a time.

Experimentally I found this value to be 1265 bytes, which would make `X = 2K` a
possible starting point.

## Printing actual read

The following snippe was added in `proxy/lib/snowflake.go`:

```go
// Taken straight from standardlib io.copyBuffer
func copyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) {
	// If the reader has a WriteTo method, use it to do the copy.
	// Avoids an allocation and a copy.
	if wt, ok := src.(io.WriterTo); ok {
		return wt.WriteTo(dst)
	}
	// Similarly, if the writer has a ReadFrom method, use it to do the copy.
	if rt, ok := dst.(io.ReaderFrom); ok {
		return rt.ReadFrom(src)
	}
	if buf == nil {
		size := 32 * 1024
		if l, ok := src.(*io.LimitedReader); ok && int64(size) > l.N {
			if l.N < 1 {
				size = 1
			} else {
				size = int(l.N)
			}
		}
		buf = make([]byte, size)
	}
	for {
		nr, er := src.Read(buf)
		if nr > 0 {
			log.Printf("Read %d", nr) // THIS IS THE ONLY DIFFERENCE FROM io.CopyBuffer
			nw, ew := dst.Write(buf[0:nr])
			if nw < 0 || nr < nw {
				nw = 0
				if ew == nil {
					ew = errors.New("invalid write result")
				}
			}
			written += int64(nw)
			if ew != nil {
				err = ew
				break
			}
			if nr != nw {
				err = io.ErrShortWrite
				break
			}
		}
		if er != nil {
			if er != io.EOF {
				err = er
			}
			break
		}
	}
	return written, err
}
```

and `copyLoop` was amended to use this instead of `io.Copy`.

The `Read: BYTES` was saved to a file using this command

```sh
./proxy -verbose -ephemeral-ports-range 50000:50010 2>&1 >/dev/null  | awk '/Read: / { print $4 }' | tee read_sizes.txt
```

I got the result:

min: 8
max: 1402
median: 1402
average: 910.305

Suggested buffer size: 2K
Current buffer size: 32768 (32K, experimentally verified)

## Using a Snowflake Proxy in Tor browser and use Wireshark

I also used Wireshark, and concluded that all packets sent was < 2K.

# Conclusion

As per the commit I suggest changing the buffer size to 2K. Some things I have not been able to answer:

1. Does this make a big impact on performance?
1. Are there any unforseen consequences? What happens if a packet is > 2K (I
	 think the Go standard libary just splits the packet, but someone please confirm).
2024-08-21 15:02:15 +00:00
David Fifield
ee5f815f60 Cosmetic changes from dev-snowflake-udp-rebase-extradata.
https://gitlab.torproject.org/shelikhoo/snowflake/-/tree/dev-snowflake-udp-rebase-extradata
commit 59b76dc68d2ee0383c2acd91cb0f44edc46af939
2024-08-01 22:12:56 +00:00
itchyonion
4ed5da7f2f
Simplify proxy NAT checking logic 2024-05-28 12:30:44 -07:00
meskio
a9df5dd71a
Use ptutil for safelog and prometheus rounded metrics
* Related: #40354
2024-05-09 16:24:33 +02:00
meskio
01588d99db
Merge remote-tracking branches 'gitlab/mr/289' and 'gitlab/mr/293' 2024-04-04 12:27:14 +02:00
Sky
cec3c2df21 Update README.md to include all available CLI options 2024-04-04 08:21:56 +00:00
Sky
d439f89536 Allow to set listen address for metrics service via cl flags 2024-04-04 06:28:33 +00:00
am3o
acce1f1fd9
refactor: change deprecated "io/ioutil" package to recommended "io" package 2024-02-17 12:47:22 +01:00
David Fifield
d0529141ac Cosmetic fixes taken from !219.
shelikhoo/dev-udp-performance-rebased branch
https://gitlab.torproject.org/shelikhoo/snowflake/-/commits/9dce28cfc2093490473432ffecd9abaab7ebdbdb
2024-01-16 18:43:58 +00:00
Cecylia Bocovich
3939554058
Add proxy commandline option for probe server URL 2024-01-10 11:05:56 -05:00
Cecylia Bocovich
9f330caa08
Suppress logs of EventOnProxyConnectionOver 2023-12-21 10:39:48 -05:00
n8fr8
36a8eb487f
Add Ignore Android Restriction Workaround for Proxy 2023-12-18 12:58:48 +00:00
David Fifield
234d9cb11c Link a section in the pion/webrtc@3.0.0 release notes. 2023-11-21 01:27:09 +00:00
Cecylia Bocovich
b3b0d3b5dd
Document that prometheus transfer metrics are in KB 2023-11-20 10:40:34 -05:00