Commit graph

1016 commits

Author SHA1 Message Date
Simone Basso
ed2d5df87d Fix datarace for WebRTCPeer.lastReceive
The race condition occurs because concurrent goroutines are
intermixing reads and writes of `WebRTCPeer.lastReceive`.

Spotted when integrating Snowflake inside OONI in
https://github.com/ooni/probe-cli/pull/373.
2021-06-24 11:16:24 -04:00
Cecylia Bocovich
e84bc81e31 Bump version of kcp and smux libraries 2021-06-23 19:41:03 -04:00
Cecylia Bocovich
6634f2bec9 Store net.Addr in clientIDAddrMap
This fixes a stats collection bug where we were converting client
addresses between a string and net.Addr using the clientAddr function
multiple times, resulting in an empty string for all addresses.
2021-06-19 11:16:38 -04:00
Simone Basso
aefabe683f fix(client/snowflake.go): prevent wg.Add race condition
In VSCode, the staticcheck tool emits this warning:

> should call wg.Add(1) before starting the goroutine to
> avoid a race (SA2000)go-staticcheck

To avoid this warning, just move wg.Add outside.
2021-06-14 10:10:02 +02:00
Cecylia Bocovich
8e0b5bd20a Add changelog and release v1.0.0 2021-06-07 10:24:19 -04:00
meskio
c5ca41f138
Add man pages for proxy and client commands
To be used by the debian package (#19409)
2021-06-02 16:47:50 +02:00
Cecylia Bocovich
270eb21803 Encode client-broker messages as json in HTTP body
Send the client poll request and response in a json-encoded format in
the HTTP request body rather than sending the data in HTTP headers. This
will pave the way for using domain-fronting alternatives for the
Snowflake rendezvous.
2021-06-02 09:52:42 -04:00
David Fifield
ae7cc478fd Release resources in client Transport.Dial on error.
Make a stack of cleanup functions to run (as with defer), but clear the
stack before returning if no error occurs.

Uselessly pushing the stream.Close() cleanup just before clearing the
stack is an intentional safeguard, for in case additional operations are
added before the return in the future.

Fixes #40042.
2021-05-24 15:28:13 -06:00
David Fifield
01a96c7d95 Fix error handling around transport.Dial.
The code checked for and displayed an error, but would then go on to
call copyLoop on the nil Conn returned from transport.Dial. Add a return
in that case, and put the cleanup operations in defer. Also remove an
obsolete comment about an empty address. Obsolete because:
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/merge_requests/31#note_2733279
2021-05-24 14:40:50 -06:00
David Fifield
ef4d0a1da5
Stop timers before expiration
If we don't stop them explicitly, the timers will not get garbage collected
until they timeout:
https://medium.com/@oboturov/golang-time-after-is-not-garbage-collected-4cbc94740082

Related to #40039
2021-05-21 10:09:00 +02:00
Arlo Breault
7ef49272fa Remove sync.Once from around logMetrics
Follow up to 160ae2d

Analysis by @dcf,

> I don't think the sync.Once around logMetrics is necessary anymore.
Its original purpose was to inhibit logging on later file handles of
metrics.log, if there were more than one opened. See 171c55a9 and #29734
(comment 2593039) "Making a singleton *Metrics variable causes problems
with how Convey does tests. It shouldn't be called more than once, but
for now I'm using sync.Once on the logging at least so it's explicit."
Commit ba4fe1a7 changed it so that metrics.log is opened in main, used
to create a *log.Logger, and that same instance of *log.Logger is passed
to both NewMetrics and NewBrokerContext. It's safe to share the same
*log.Logger across multiple BrokerContext.
2021-05-20 15:39:30 -04:00
Arlo Breault
160ae2dd71 Make promMetrics not a global
Doesn't seem like it needs to exist outside of the metrics struct.

Also, the call to logMetrics is moved to the constructor.  A metrics
instance is only created when a BrokerContext is created, which only
happens at startup.  The sync of only doing that once is left for
documentation purposes, since it doesn't hurt, but also seems redundant.
2021-05-18 20:07:43 -04:00
Cecylia Bocovich
0054cb2dec Update .gitlab-ci.yml after refactor of client 2021-05-12 10:50:06 -04:00
Cecylia Bocovich
7c9005bed3 Ensure turbotunnel read and write loop terminate
Introduce a waitgroup and done channel to ensure that both the read and
write gorouting for turbotunnel connections terminate when the
connection is closed.
2021-05-12 09:32:07 -04:00
Cecylia Bocovich
11f0846264 Implement server as a v2.1 PT Go API 2021-05-12 09:08:41 -04:00
Cecylia Bocovich
e87b9175dd Implement snowflake client lib as PTv2.1 Go API
This implements a pluggable transports v2.1 compatible Go API in the
Snowflake client library, and refactors how the main Snowflake program
calls it. The Go API implements the two required client side functions:
a constructor that returns a Transport, and a Dial function for the
Transport that returns a net.Conn. See the PT specification for more
information:
https://github.com/Pluggable-Transports/Pluggable-Transports-spec/blob/master/releases/PTSpecV2.1/Pluggable%20Transport%20Specification%20v2.1%20-%20Go%20Transport%20API.pdf
2021-05-12 09:08:41 -04:00
Cecylia Bocovich
af6e2c30e1 Replace default with custom prometheus registry
The default prometheus registry exports data that may be useful for
side-channel attacks. This removes all of the default metrics and makes
sure we are only reporting snowflake metrics from the broker.
2021-04-26 14:18:50 -04:00
Cecylia Bocovich
2a310682b5 Add new gauge to show currently available proxies 2021-04-26 14:18:50 -04:00
Cecylia Bocovich
92bd900bc5 Implement binned counts for polling metrics 2021-04-26 14:07:55 -04:00
Cecylia Bocovich
83ef0b6f6d Export snowflake broker metrics for prometheus
This change adds a prometheus exporter for our existing snowflake broker
metrics. Current values for the metrics can be fetched by sending a GET
request to /prometheus.
2021-04-22 10:39:35 -04:00
Cecylia Bocovich
eff73c3016 Switch front domain and host to fastly 2021-04-01 11:56:52 -04:00
Cecylia Bocovich
196c230ac7 Update Go version for .gitlab-ci.yml 2021-03-25 16:07:48 -04:00
Cecylia Bocovich
087a037f82 Update webrtc library to v3.0.15
This fixes a vulnerability in the library: CVE-2021-28681
2021-03-18 23:08:05 -04:00
Cecylia Bocovich
c0b6e082f2 Don't log errors from callng close on OR conns
Snowflake copies data between the OR connection and the KCP stream,
meaning that in most cases the copy loops will only terminate once the
OR connection times out. In this case the OR connection is already
closed and so calls to CloseRead and CloseWrite will generate errors.
2021-03-18 22:05:40 -04:00
Cecylia Bocovich
720d2b8eb7 Don't log io.ErrClosedPipe in server
These errors are triggered in three places when the OR connection times
out. They don't tell us anything useful and are filling up our logs.
2021-03-18 22:05:40 -04:00
David Fifield
850d2f0683 Update required Go version to 1.13 in README. 2021-03-05 23:26:35 -07:00
Cecylia Bocovich
7187f1009e Log a throughput summary for each connection
This will increase transparency for people running standalone proxies
and help us debug any potential issues with proxies behaving unreliably.
2021-02-02 11:21:16 -05:00
Cecylia Bocovich
bae0bacbfd Classify proxies with unknown NATs as restricted 2021-01-25 14:05:24 -05:00
Cecylia Bocovich
1b29ad7de1 Bump version of pion/sdp
Update our dependency on pion/sdp from v2 to v3, to match pion/webrtc
v3. This requires some changes in how we parse out addresses from ice
candidates. This will ease tor browser builds of snowflake since we are
now only relying on one version of pion/sdp instead of two different
ones.
2021-01-25 10:28:17 -05:00
Cecylia Bocovich
83c01565ef Update webrtc library to v3.0.0
This update required two main changes to how we use the library. First,
we had to make sure we created the datachannel on the offering peer side
before creating the offer. Second, we had to make sure we wait for the
gathering of all candidates to complete since trickle-ice is enabled by
default. See the release notes for more details:
https://github.com/pion/webrtc/wiki/Release-WebRTC@v3.0.0.
2021-01-12 10:37:26 -05:00
Cecylia Bocovich
f908576c60 Increase the KCP maximum window size 2020-12-17 09:54:18 -05:00
Cecylia Bocovich
8ec8a7cb63 Pass lock to socksAcceptLoop by reference
This fixes a bug where we were passing the lock by value to
socksAcceptLoop.
2020-12-16 10:52:19 -05:00
Cecylia Bocovich
3e8947bfc9 Avoid double delay in client from ReconnectTimeout
Run the snowflake collection ReconnectTimeout timer in parallel to the
negotiation with the broker. This way, if the broker takes a long time
to respond the client doesn't have to wait the full timeout to respond.
2020-12-05 15:51:42 -05:00
Cecylia Bocovich
effc667544 Wait until all goroutines finish before shutdown 2020-12-05 15:50:16 -05:00
Cecylia Bocovich
b9cc54b3b7 Send shutdown signal to shutdown open connections
Normally all dangling goroutines are terminated when the main function
exits. However, for projects that use a patched version of snowflake as
a library, these goroutines continued running as long as the main function
had not yet terminated. This commit has all open SOCKS connections close
after receiving a shutdown signal.
2020-12-05 15:50:16 -05:00
Cecylia Bocovich
114df695ce Create new smux session for each SOCKS connection
Each SOCKS connection has its own set of snowflakes and broker poll
loop. Since the session manager was tied to a single set of snowflakes,
this resulted in a bug where RedialPacketConn would sometimes try to
pull snowflakes from a previously melted pool. The fix is to maintain
separate smux sessions for each SOCKS connection, tied to its own
snowflake pool.
2020-12-04 11:17:13 -05:00
Philipp Winter
5efcde5187
Sort snowflake-ips stats by country count.
We currently don't sort the snowflake-ips metrics:

    snowflake-ips CA=1,DE=1,AR=1,NL=1,FR=1,GB=2,US=4,CH=1

To facilitate eyeballing our metrics, this patch sorts snowflake-ips by
value.  If the value is identical, we sort by string, i.e.:

    snowflake-ips US=4,GB=2,AR=1,CA=1,CH=1,DE=1,FR=1,NL=1

This patch fixes tpo/anti-censorship/pluggable-transports/snowflake#40011
2020-11-27 11:20:40 -08:00
Cecylia Bocovich
665d76c5b0 Remove for loop around broker.Negotiate
Instead of continuously polling the broker until the client receives a
snowflake, fail back to the Connect() loop and try again to collect more
peers after ReconnectTimeout.
2020-11-23 12:10:59 -05:00
Cecylia Bocovich
ece43cbfcf Note that isRestrictedFiltering is no longer used 2020-11-20 01:15:16 -05:00
Cecylia Bocovich
00f8f85f41 Use remote probe to determine proxy NAT type
Rather than having standalone proxies determine their NAT type by
conducting the NAT behaviour checks in RFC 5780, use the remote probe
service instead.
2020-11-20 01:13:18 -05:00
Cecylia Bocovich
cf2eb5e6c0 Add a stub sid to probetest answer
This will prevent calls to DecodeAnswerRequest from returning an error
even though the sid is not needed for the probetest.
2020-11-18 15:57:51 -05:00
Cecylia Bocovich
0bed9c48b7 Redefine only symmetric NATs as restricted 2020-11-18 15:40:32 -05:00
Cecylia Bocovich
61beb9d996 Revert accidentally merged code
Some temporary testing code for the proxy got accidentally merged into
the latest changes. This commit undoes that mistake.
2020-11-05 19:28:20 -05:00
Cecylia Bocovich
4663599382 Make probetest wait for a datachannel to open 2020-11-05 16:48:00 -05:00
Cecylia Bocovich
b5ce259858 Fixed a bug that forced datachannel timeout
The probetest answer response was not being sent until the select call
received a datachannel timeout causing all attempted connections to
fail.
2020-11-05 16:46:48 -05:00
Cecylia Bocovich
a4f10d9d6e Add Dockerfile and README for deploying probetest
The easiest way to set up the probe server behind a symmetric NAT is to
deploy it as a Docker container and alter the iptables rules for the
Docker network subnet that the container runs in.
2020-10-29 11:03:51 -04:00
Cecylia Bocovich
f368c87109 Add a remote service to test NAT compatability
Add a remote probetest service that will allow proxies to test their
compatability with symmetric NATs.
2020-10-29 11:03:51 -04:00
Cecylia Bocovich
7a0428e3b1 Refactor proxy to reuse signaling code
Simplify proxy interactions with the broker signaling server and prepare
for the introduction of an additional signaling server.
2020-10-29 11:03:51 -04:00
David Fifield
912bcae24e Don't log io.ErrClosedPipe in proxy.
We expect one of these at the end of just about every proxy session, as
the Conns in both directions are closed as soon as the copy loop
finishes in one direction.

Closes #40016.
2020-10-22 23:01:45 -06:00
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