Commit graph

853 commits

Author SHA1 Message Date
Cecylia Bocovich
a39d6693e1 Call conn.Reject() if SOCKS arguments are invalid 2021-08-19 21:31:51 -04:00
Cecylia Bocovich
97175a91a5 Modify torrc example to pass client args in bridge line 2021-08-19 21:20:34 -04:00
Cecylia Bocovich
e762f58a31 Parse SOCKS arguments and prefer over command line options
Parsing the Snowflake client options from SOCKS allow us to specify
snowflake client settings in the bridge lines.
2021-08-19 21:20:34 -04:00
Cecylia Bocovich
4acc08cc60 Use a config struct for snowflake client options 2021-08-19 21:20:34 -04:00
Cecylia Bocovich
e6715cb4ee Increase smux and QueuePacketConn buffer sizes
This should increase the maximum amount of inflight data and hopefully
the performance of Snowflake, especially for clients geographically
distant from proxies and the server.
2021-08-10 15:38:11 -04:00
David Fifield
b203a75c41 Document -ampcache in snowflake-client man page. 2021-08-05 16:13:24 -06:00
David Fifield
f2dc41d778 Document /amp/client in broker-spec.txt. 2021-08-05 16:13:24 -06:00
David Fifield
521eb4d4d6 Add info about rendezvous methods to client README. 2021-08-05 16:13:24 -06:00
David Fifield
e833119bef Broker /amp/client route (AMP cache client registration). 2021-08-05 16:13:24 -06:00
David Fifield
5adb994028 Implement ampCacheRendezvous. 2021-08-05 16:13:24 -06:00
David Fifield
c13810192d Skeleton of ampCacheRendezvous.
Currently the same as httpRendezvous, but activated using the -ampcache
command-line option.
2021-08-05 16:13:24 -06:00
David Fifield
c9e0dd287f amp package.
This package contains a CacheURL function that modifies a URL to be
accessed through an AMP cache, and the "AMP armor" data encoding scheme
for encoding data into the AMP subset of HTML.
2021-08-05 16:13:24 -06:00
David Fifield
0f34a7778f Factor out httpRendezvous separate from BrokerChannel.
Makes BrokerChannel abstract over a rendezvousMethod. BrokerChannel
itself is responsible for keepLocalAddresses and the NAT type state, as
well as encoding and decoding client poll messages. rendezvousMethod is
only responsible for delivery of encoded messages.
2021-08-05 16:13:24 -06:00
David Fifield
55f4814dfb Change the representation of domain fronting in HTTP rendezvous.
Formerly, BrokerChannel represented the broker URL and possible domain
fronting as
	bc.url  *url.URL
        bc.Host string
That is, bc.url is the URL of the server which we contact directly, and
bc.Host is the Host header to use in the request. With no domain
fronting, bc.url points directly at the broker itself, and bc.Host is
blank. With domain fronting, we do the following reshuffling:
	if front != "" {
		bc.Host = bc.url.Host
		bc.url.Host = front
	}
That is, we alter bc.url to reflect that the server to which we send
requests directly is the CDN, not the broker, and store the broker's own
URL in the HTTP Host header.

The above representation was always confusing to me, because in my
mental model, we are always conceptually communicating with the broker;
but we may optionally be using a CDN proxy in the middle. The new
representation is
	bc.url   *url.URL
        bc.front string
bc.url is the URL of the broker itself, and never changes. bc.front is
the optional CDN front domain, and likewise never changes after
initialization. When domain fronting is in use, we do the swap in the
http.Request struct, not in BrokerChannel itself:
	if bc.front != "" {
		request.Host = request.URL.Host
		request.URL.Host = bc.front
	}

Compare to the representation in meek-client:

https://gitweb.torproject.org/pluggable-transports/meek.git/tree/meek-client/meek-client.go?h=v0.35.0#n94
	var options struct {
		URL       string
		Front     string
	}
https://gitweb.torproject.org/pluggable-transports/meek.git/tree/meek-client/meek-client.go?h=v0.35.0#n308
	if ok { // if front is set
		info.Host = info.URL.Host
		info.URL.Host = front
	}
2021-08-05 16:13:24 -06:00
David Fifield
191510c416 Use a URL with a Host component in BrokerChannel tests.
The tests were using a broker URL of "test.broker" (i.e., a schema-less,
host-less, relative path), and running assertions on the value of
b.url.Path. This is strange, especially in tests regarding domain
fronting, where we care about b.url.Host, not b.url.Path. This commit
changes the broker URL to "http://test.broker" and changes tests to
check b.url.Host. I also added an additional assertion for an empty
b.Host in the non-domain-fronted case.
2021-08-05 16:13:24 -06:00
meskio
e3d376ca43
Wait pollInterval between proxy offers
Closes: #40055
2021-07-21 16:38:29 +02:00
meskio
099f4127ea
Refactor the poll offer to use a ticker
Simplify the code to use a ticker. Using a pattern to allow a first run
of the loop before hitting the ticker:
https://github.com/golang/go/issues/17601#issuecomment-311955879
2021-07-21 16:38:27 +02:00
Cecylia Bocovich
b4e964c682 Added some Snowflake library documentation 2021-07-19 10:16:26 -04:00
Cecylia Bocovich
c1b0fdd8cf Cleaned up and reorganized READMEs 2021-07-19 10:16:26 -04:00
David Fifield
2d7cd3f2b7 Use the readLimit constant in a test.
Instead of copying the value.
2021-07-18 16:25:09 -06:00
David Fifield
d9a83e26b5 Remove unused FakePeers.
Unused since 1364d7d45b.
2021-07-18 13:11:29 -06:00
Cecylia Bocovich
4f7833b384 Version bump to v1.1.0 2021-07-13 17:50:44 -04:00
Arlo Breault
2c2f93c022 Remove and restore some comments, after review 2021-07-08 15:35:04 -04:00
Arlo Breault
dfb68d7cfc Fix race is broker test reported by go test -race 2021-07-08 15:32:25 -04:00
Arlo Breault
c3c84fdb48 Use variables for string matching
The legacy code does case matching on these exact strings so it's better
to ensure they're constant.
2021-07-08 12:47:23 -04:00
Arlo Breault
87ad06a5e2 Get rid of legacy version
Move the logic for the legacy version into the http handlers and use a
shim when doing ipc.
2021-07-08 12:32:37 -04:00
Arlo Breault
0ced1cc324 Move http handlers to a separate file 2021-07-08 12:32:37 -04:00
Arlo Breault
015958fbe6 Intermediary refactor teasing apart http / ipc
Introduces an IPC struct and moves the logic out of the http handlers
and into methods on that.
2021-07-08 12:32:35 -04:00
meskio
ced539f234
Refactor webRTCConn to its own file 2021-07-07 19:36:24 +02:00
meskio
7a1857c42f
Make the proxy to report the number of clients to the broker
So the assignment of proxies is based on the load. The number of clients
is ronded down to 8. Existing proxies that doesn't report the number
of clients will be distributed equaly to new proxies until they get 8
clients, that is okish as the existing proxies do have a maximum
capacity of 10.

Fixes #40048
2021-07-07 19:36:20 +02:00
Cecylia Bocovich
74bdb85b30 Update example torrc file for client
Remove the -max 3 option because we only use one snowflake. Add
SocksPort auto because many testers have a tor process already bound to
port 9050.
2021-06-24 13:46:11 -04:00
Cecylia Bocovich
53a2365696 Fix leak in server acceptLoop
Refactor out a separate handleStream function and ensure that all
connections are closed and the references are out of scope.
2021-06-24 13:32:55 -04:00
Cecylia Bocovich
10b6075eaa Refactor checkForStaleness to take time.Duration 2021-06-24 11:20:44 -04:00
Cecylia Bocovich
e3351cb08a Fix data race for Peers.collection
We used a WaitGroup to prevent a call to Peers.End from melting
snowflakes while a new one is being collected. However, calls to
WaitGroup.Add are in a race with WaitGroup.Wait. To fix this, we use a
Mutex instead.
2021-06-24 11:16:24 -04:00
Cecylia Bocovich
95cbe36565 Add unit tests to check for webrtc peer data races 2021-06-24 11:16:24 -04:00
Cecylia Bocovich
bb7ff6180b Fix datarace for Peers.melted
Using the boolean value was unnecessary since we already have a channel
we can check for closure.
2021-06-24 11:16:24 -04:00
Cecylia Bocovich
ddcdfc4f09 Fix datarace for WebRTCPeer.closed
The race condition occurs because concurrent goroutines are intermixing
reads and writes of `WebRTCPeer.closed`.

Spotted when integrating Snowflake inside OONI in
https://github.com/ooni/probe-cli/pull/373.
2021-06-24 11:16:24 -04:00
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