Commit graph

867 commits

Author SHA1 Message Date
Cecylia Bocovich
6baa3c4d5f Add synchronization to prevent post-melt collects
This fixes a race condition in which snowflakes.End() is called while
snowflakes.Collect() is in progress resulting in a write to a closed
channel. We now wait for all in-progress collections to finish and add
an extra check before proceeding with a collection.
2020-10-15 14:47:51 -04:00
Cecylia Bocovich
d7aa9b8356 Extract remote address from ICE candidates
Parse the received ICE candidates as well as the Connection Data
field for a non-local IP address to pass to the bridge. This fixes
bug #33157.
2020-10-05 17:02:57 -04:00
Peter Gerber
8467c01e9e Consider more IPs to be local 2020-09-21 15:55:14 +00:00
Cecylia Bocovich
2d43dd26b1 Merge branch 'issue/21314' 2020-08-27 16:45:05 -04:00
Cecylia Bocovich
cc55481faf Set max number of snowflakes in the Tongue 2020-08-27 16:44:07 -04:00
Cecylia Bocovich
1364d7d45b Move snowflake ConnectLoop inside SOCKS Handler
Bug #21314: maintains a separate snowflake connect loop per SOCKS
connection. This way, if Tor decides to stop using Snowflake, Snowflake
will stop using the client's network.
2020-08-27 16:43:55 -04:00
Cecylia Bocovich
3c3317503e Update broker stats to include info on NAT types
As we now partition proxies by NAT type, our stats are more useful if they
capture how many proxies of each type we have, and information on
whether we have enough proxies of the right NAT type for our clients.
This change adds proxy counts by NAT type and binned counts of denied clients by NAT type.
2020-08-24 09:39:17 -04:00
Cecylia Bocovich
d5ae7562ac Add response header timeouts to broker transports
The client and proxy use the net/http default transport to make round
trip connecitons to the broker. These by default don't time out and can
wait indefinitely for the broker to respond if the broker hangs and
doesn't terminate the connection.
2020-07-30 17:54:28 -04:00
Cecylia Bocovich
82031289a3 Refactor subsetting of ice servers into main
This moves the subsetting of ice servers out of the parseIceServers
function and into main.
2020-07-24 14:08:09 -04:00
Cecylia Bocovich
92520f681d Choose a random subset from given STUN servers
Only chooses a subset as long as we have over 2 STUN servers to choose
from.
2020-07-23 11:30:36 -04:00
Cecylia Bocovich
eaac9f5b6b Use go modules to build android library
This commit removes the symlinks and turns go modules back on to run
gomobile bind locally on the project.
2020-07-14 09:16:23 -04:00
Cecylia Bocovich
c1fa4efe4b Refactor android script to be in android job 2020-07-14 09:16:23 -04:00
Hans-Christoph Steiner
d44fc23815 update .gitlab-ci.yml 2020-07-14 09:16:23 -04:00
Cecylia Bocovich
8c875f0ba7 Use STUN server compatable with RFC 5780 in proxy 2020-07-09 09:55:41 -04:00
Cecylia Bocovich
818226acf2 Testing Gitlab sync. 2020-07-06 15:42:41 -04:00
Cecylia Bocovich
046dab865f Have broker pass client NAT type to proxy
This will allow browser-based proxies that are unable to determine their
NAT type to conservatively label themselves as restricted NATs if they
fail to work with clients that have restricted NATs.
2020-07-06 13:16:03 -04:00
Cecylia Bocovich
0052c0e10c Add a new heap at the broker for restricted flakes
Now when proxies poll, they provide their NAT type to the broker. This
introduces a new snowflake heap of just restricted snowflakes that the
broker can pull from if the client has a known, unrestricted NAT. All
other clients will pull from a heap of snowflakes with unrestricted or
unknown NAT topologies.
2020-07-06 13:16:03 -04:00
Cecylia Bocovich
f6cf9a453b Implement NAT discover for go standalone proxies 2020-07-06 13:16:03 -04:00
Cecylia Bocovich
bf924445e3 Implement NAT discovery (RFC 5780) at the client
Snowflake clients will now attempt NAT discovery using the provided STUN
servers and report their NAT type to the Snowflake broker for matching.
The three possibilities for NAT types are:
- unknown (the client was unable to determine their NAT type),
- restricted (the client has a restrictive NAT and can only be paired
with unrestricted NATs)
- unrestricted (the client can be paired with any other NAT).
2020-07-06 13:16:03 -04:00
Cecylia Bocovich
1448c3885f Update documentation to include broker spec
Add broker messaging specification with endpoints for clients and
proxies.
2020-06-19 10:05:35 -04:00
Cecylia Bocovich
bbf11a97e4 Reduce SnowflakeTimeout to 20 seconds
The underlying smux layer sends a keep-alive ping every 10 seconds. This
modification will allow for one dropped/delayed ping before discarding
the snowflake
2020-05-07 09:42:09 -04:00
David Fifield
7043a055f9 Reduce DataChannelTimeout from 30s to 10s.
https://bugs.torproject.org/34042
2020-05-04 19:43:48 -06:00
David Fifield
c8293a5de3 Format the establishDataChannel error log message like other log messages.
It was sticking out in the context of other log messages.

2020/04/30 22:39:10 WebRTC: DataChannel created.
2020/04/30 22:39:20 establishDataChannel: timeout waiting for DataChannel.OnOpen
2020/04/30 22:39:20 WebRTC: closing PeerConnection
2020/04/30 22:39:20 WebRTC: Closing
2020/04/30 22:39:20 WebRTC: WebRTC: Could not establish DataChannel  Retrying in 10s...
2020-05-01 10:30:04 -06:00
David Fifield
72cfb96ede Restore check for nil writePipe in WebRTCPeer.Close.
I removed this check in 047d3214bf because
NewWebRTCPeer always initializes writePipe, and it is never reset to
nil. However tests used &WebRTCPeer{} which bypasses NewWebRTCPeer and
leaves writePipe set to nil.

https://bugs.torproject.org/34049#comment:3
https://bugs.torproject.org/34050
2020-04-28 11:47:34 -06:00
Cecylia Bocovich
5e8f9ac538 Update proxy tests to check serialization errors 2020-04-28 13:01:32 -04:00
Cecylia Bocovich
1d2df3cd71 Update calls to session description utils in proxy 2020-04-28 12:55:58 -04:00
David Fifield
047d3214bf Wait for data channel OnOpen before returning from NewWebRTCPeer.
Now callers cannot call Write without there being a DataChannel to write
to. This lets us remove the internal buffer and checks for transport ==
nil.

Don't set internal fields like writePipe, transport, and pc to nil when
closing; just close them and let them return errors if further calls are
made on them.

There's now a constant DataChannelTimeout that's separate from
SnowflakeTimeout (the latter is what checkForStaleness uses). Now we can
set DataChannel timeout to a lower value, to quickly dispose of
unconnectable proxies, while still keeping the threshold for detecting
the failure of a once-working proxy at 30 seconds.

https://bugs.torproject.org/33897
2020-04-27 18:48:00 -06:00
David Fifield
e8c41650ae Move establishDataChannel to after exchangeSDP. 2020-04-27 18:48:00 -06:00
David Fifield
85277274fd Make exchangeSDP into a standalone function. 2020-04-27 18:48:00 -06:00
David Fifield
8295c87fbe Make preparePeerConnection a standalone function. 2020-04-27 18:48:00 -06:00
David Fifield
81d14ad33a Make WebRTCPeer.preparePeerConnection block.
Formerly, preparePeerConnection set up a callback that sent into a
channel, and exchangeSDP waited until it could receive from the channel.
We can move the channel entirely into preparePeerConnection (having it
not return until the callback has been called) and that way remove some
shared state.
2020-04-27 18:48:00 -06:00
David Fifield
5787d5b8b0 Simplify WebRTCPeer.exchangeSDP.
No need to run sendOfferToBroker in a goroutine.
2020-04-27 18:48:00 -06:00
David Fifield
8caa737700 Remove SnowflakeDataChannel interface.
Use *webrtc.DataChannel directly.
2020-04-27 18:48:00 -06:00
David Fifield
32207d6f06 Eliminate separate WebRTCPeer.Connect method.
Do it as a side effect of NewWebRTCPeer.

Remove WebRTCPeer tests as they currently require invasively modifying
internal fields at different stages of construction.
2020-04-27 18:47:59 -06:00
David Fifield
b48fb781ee Have util.{Serialize,Deserialize}SessionDescription return an error
https://bugs.torproject.org/33897#comment:4
2020-04-27 18:46:56 -06:00
David Fifield
76732155e7 Remove Snowflake interface, use *WebRTCPeer directly.
The other interfaces in client/lib/interfaces.go exist for the purpose
of running tests, but not Snowflake. Existing code would not have worked
with other types anyway, because it does unchecked .(*WebRTCPeer)
conversions.
2020-04-27 17:51:21 -06:00
David Fifield
d9b076c32e Don't do a separate check for a short write.
A short write will result in a non-nil error. It's an io.PipeWriter
anyway, which blocks until all the data has been read or the read end is
closed, in which case it returns io.ErrClosedPipe if not some other
error.
2020-04-27 17:49:38 -06:00
David Fifield
51bb49fa6f Move pc.CreateOffer/pc.SetLocalDescription out of a goroutine.
This allows us to remove the internal errorChannel.
2020-04-27 17:47:14 -06:00
David Fifield
3520f4e8b9 Simplify Peers.Pop. 2020-04-24 15:45:15 -06:00
David Fifield
17c0d0ff82 Remove unused Resetter interface.
WaitForReset is not used since 70126177fb.
2020-04-24 13:31:04 -06:00
David Fifield
6c2e3adc41 Disable trickle ICE.
https://bugs.torproject.org/33984

OnICEGatheringStateChange is no longer called when candidate gathering
is complete. SetLocalDescription kicks off the gathering process.

https://bugs.torproject.org/28942#comment:28
https://bugs.torproject.org/33157#comment:2
2020-04-24 10:38:27 -06:00
David Fifield
73173cb698 Simplify BytesSyncLogger. 2020-04-23 21:38:44 -06:00
David Fifield
2853fc9362 Make BytesSyncLogger's implementation details internal.
Provide NewBytesSyncLogger that returns an opaque data structure.
Automatically start up the logging loop goroutine in NewBytesSyncLogger.
2020-04-23 21:38:44 -06:00
David Fifield
9a4e3e7bd9 Remove unused BytesSyncLogger.IsLogging. 2020-04-23 21:38:44 -06:00
David Fifield
d376d7036b Make WebRTCPeer and Peers not inherit the methods of BytesLogger.
You would have been able to do, for example,
snowflake.(*WebRTCPeer).AddInbound(...).
2020-04-23 21:38:44 -06:00
David Fifield
65ecb798ca Update a comment (no signal pipe anymore). 2020-04-23 20:36:55 -06:00
David Fifield
2f52217d2f Restore go 1.13 to go.mod, lost in the turbotunnel merge. 2020-04-23 17:08:49 -06:00
David Fifield
2022496d3b Use a global RedialPacketConn and smux.Session.
This allows multiple SOCKS connections to share the available proxies,
and in particular prevents a SOCKS connection from being starved of a
proxy when the maximum proxy capacity is less then the number of the
number of SOCKS connections.

This is option 4 from https://bugs.torproject.org/33519.
2020-04-23 16:03:03 -06:00
David Fifield
0790954020 USERADDR support for turbotunnel sessions.
The difficulty here is that the whole point of turbotunnel sessions is
that they are not necessarily tied to a single WebSocket connection, nor
even a single client IP address. We use a heuristic: whenever a
WebSocket connection starts that has a new ClientID, we store a mapping
from that ClientID to the IP address attached to the WebSocket
connection in a lookup table. Later, when enough packets have arrived to
establish a turbotunnel session, we recover the ClientID associated with
the session (which kcp-go has stored in the RemoteAddr field), and look
it up in the table to get an IP address. We introduce a new data type,
clientIDMap, to store the clientID-to-IP mapping during the short time
between when a WebSocket connection starts and handleSession receives a
fully fledged KCP session.
2020-04-23 16:03:02 -06:00
David Fifield
70126177fb Turbo Tunnel client and server.
The client opts into turbotunnel mode by sending a magic token at the
beginning of each WebSocket connection (before sending even the
ClientID). The token is just a random byte string I generated. The
server peeks at the token and, if it matches, uses turbotunnel mode.
Otherwise, it unreads the token and continues in the old
one-session-per-WebSocket mode.
2020-04-23 16:02:56 -06:00