Documentation ¶
Overview ¶
Package snowflake_client implements functionality necessary for a client to establish a connection to a server using Snowflake.
Included in the package is a Transport type that implements the Pluggable Transports v2.1 Go API specification. To use Snowflake, you must first create a client from a configuration:
config := snowflake_client.ClientConfig{ BrokerURL: "https://snowflake-broker.example.com", FrontDomain: "https://friendlyfrontdomain.net", // ... } transport, err := snowflake_client.NewSnowflakeClient(config) if err != nil { // handle error }
The Dial function connects to a Snowflake server:
conn, err := transport.Dial() if err != nil { // handle error } defer conn.Close()
Index ¶
Constants ¶
const ( // ReconnectTimeout is the time a Snowflake client will wait before collecting // more snowflakes. ReconnectTimeout = 10 * time.Second // SnowflakeTimeout is the time a Snowflake client will wait before determining that // a remote snowflake has been disconnected. If no new messages are sent or received // in this time period, the client will terminate the connection with the remote // peer and collect a new snowflake. SnowflakeTimeout = 20 * time.Second // DataChannelTimeout is how long the client will wait for the OnOpen callback // on a newly created DataChannel. DataChannelTimeout = 10 * time.Second // WindowSize is the number of packets in the send and receive window of a KCP connection. WindowSize = 65535 // StreamSize controls the maximum amount of in flight data between a client and server. StreamSize = 1048576 //1MB )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BrokerChannel ¶
type BrokerChannel struct { Rendezvous RendezvousMethod BridgeFingerprint string // contains filtered or unexported fields }
BrokerChannel uses a RendezvousMethod to communicate with the Snowflake broker. The BrokerChannel is responsible for encoding and decoding SDP offers and answers; RendezvousMethod is responsible for the exchange of encoded information.
func (*BrokerChannel) Negotiate ¶
func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) ( *webrtc.SessionDescription, error)
Negotiate uses a RendezvousMethod to send the client's WebRTC SDP offer and receive a snowflake proxy WebRTC SDP answer in return.
func (*BrokerChannel) SetNATType ¶
func (bc *BrokerChannel) SetNATType(NATType string)
SetNATType sets the NAT type of the client so we can send it to the WebRTC broker.
type ClientConfig ¶
type ClientConfig struct { // BrokerURL is the full URL of the Snowflake broker that the client will connect to. BrokerURL string // AmpCacheURL is the full URL of a valid AMP cache. A nonzero value indicates // that AMP cache will be used as the rendezvous method with the broker. AmpCacheURL string // FrontDomain is a the full URL of an optional front domain that can be used with either // the AMP cache or HTTP domain fronting rendezvous method. FrontDomain string // ICEAddresses are a slice of ICE server URLs that will be used for NAT traversal and // the creation of the client's WebRTC SDP offer. ICEAddresses []string // KeepLocalAddresses is an optional setting that will prevent the removal of local or // invalid addresses from the client's SDP offer. This is useful for local deployments // and testing. KeepLocalAddresses bool // Max is the maximum number of snowflake proxy peers that the client should attempt to // connect to. Defaults to 1. Max int // UTLSClientID is the type of user application that snowflake should imitate. // If an empty value is provided, it will use Go's default TLS implementation UTLSClientID string // UTLSRemoveSNI is the flag to control whether SNI should be removed from Client Hello // when uTLS is used. UTLSRemoveSNI bool // BridgeFingerprint is the fingerprint of the bridge that the client will eventually // connect to, as specified in the Bridge line of the torrc. BridgeFingerprint string }
ClientConfig defines how the SnowflakeClient will connect to the broker and Snowflake proxies.
type Peers ¶
type Peers struct { Tongue // contains filtered or unexported fields }
Peers is a container that keeps track of multiple WebRTC remote peers. Implements |SnowflakeCollector|.
Maintaining a set of pre-connected Peers with fresh but inactive datachannels allows allows rapid recovery when the current WebRTC Peer disconnects.
Note: For now, only one remote can be active at any given moment. This is a property of Tor circuits & its current multiplexing constraints, but could be updated if that changes. (Also, this constraint does not necessarily apply to the more generic PT version of Snowflake)
func NewPeers ¶
NewPeers constructs a fresh container of remote peers.
func (*Peers) Collect ¶
func (p *Peers) Collect() (*WebRTCPeer, error)
Collect connects to and adds a new remote peer as part of |SnowflakeCollector| interface.
func (*Peers) Count ¶
Count returns the total available Snowflakes (including the active ones) The count only reduces when connections themselves close, rather than when they are popped.
func (*Peers) End ¶
func (p *Peers) End()
End closes all active connections to Peers contained here, and stops the collection of future Peers.
func (*Peers) Melted ¶
func (p *Peers) Melted() <-chan struct{}
Melted returns a channel that will close when peers stop being collected. Melted is a necessary part of |SnowflakeCollector| interface.
func (*Peers) Pop ¶
func (p *Peers) Pop() *WebRTCPeer
Pop blocks until an available, valid snowflake appears. Pop will return nil after End has been called.
type RendezvousMethod ¶
RendezvousMethod represents a way of communicating with the broker: sending an encoded client poll request (SDP offer) and receiving an encoded client poll response (SDP answer) in return. RendezvousMethod is used by BrokerChannel, which is in charge of encoding and decoding, and all other tasks that are independent of the rendezvous method.
type SnowflakeCollector ¶
type SnowflakeCollector interface { // Collect adds a snowflake to the collection. // The implementation of Collect should decide how to connect to and maintain // the connection to the WebRTCPeer. Collect() (*WebRTCPeer, error) // Pop removes and returns the most available snowflake from the collection. Pop() *WebRTCPeer // Melted returns a channel that will signal when the collector has stopped. Melted() <-chan struct{} }
SnowflakeCollector is an interface for managing a client's collection of snowflakes.
type SnowflakeConn ¶
SnowflakeConn is a reliable connection to a snowflake server that implements net.Conn.
func (*SnowflakeConn) Close ¶
func (conn *SnowflakeConn) Close() error
Close closes the connection.
The collection of snowflake proxies for this connection is stopped.
type Tongue ¶
type Tongue interface { // Catch makes a connection to a new snowflake. Catch() (*WebRTCPeer, error) // GetMax returns the maximum number of snowflakes a client can have. GetMax() int }
Tongue is an interface for catching Snowflakes. (aka the remote dialer)
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport is a structure with methods that conform to the Go PT v2.1 API https://github.com/Pluggable-Transports/Pluggable-Transports-spec/blob/master/releases/PTSpecV2.1/Pluggable%20Transport%20Specification%20v2.1%20-%20Go%20Transport%20API.pdf
func NewSnowflakeClient ¶
func NewSnowflakeClient(config ClientConfig) (*Transport, error)
NewSnowflakeClient creates a new Snowflake transport client that can spawn multiple Snowflake connections.
brokerURL and frontDomain are the urls for the broker host and domain fronting host iceAddresses are the STUN/TURN urls needed for WebRTC negotiation keepLocalAddresses is a flag to enable sending local network addresses (for testing purposes) max is the maximum number of snowflakes the client should gather for each SOCKS connection
func (*Transport) AddSnowflakeEventListener ¶ added in v2.1.0
func (t *Transport) AddSnowflakeEventListener(receiver event.SnowflakeEventReceiver)
func (*Transport) Dial ¶
Dial creates a new Snowflake connection. Dial starts the collection of snowflakes and returns a SnowflakeConn that is a wrapper around a smux.Stream that will reliably deliver data to a Snowflake server through one or more snowflake proxies.
func (*Transport) RemoveSnowflakeEventListener ¶ added in v2.1.0
func (t *Transport) RemoveSnowflakeEventListener(receiver event.SnowflakeEventReceiver)
func (*Transport) SetRendezvousMethod ¶
func (t *Transport) SetRendezvousMethod(r RendezvousMethod)
SetRendezvousMethod sets the rendezvous method to the Snowflake broker.
type WebRTCDialer ¶
type WebRTCDialer struct { *BrokerChannel // contains filtered or unexported fields }
WebRTCDialer implements the |Tongue| interface to catch snowflakes, using BrokerChannel.
func NewWebRTCDialer ¶
func NewWebRTCDialer(broker *BrokerChannel, iceServers []webrtc.ICEServer, max int) *WebRTCDialer
func NewWebRTCDialerWithEvents ¶ added in v2.1.0
func NewWebRTCDialerWithEvents(broker *BrokerChannel, iceServers []webrtc.ICEServer, max int, eventLogger event.SnowflakeEventReceiver) *WebRTCDialer
NewWebRTCDialerWithEvents constructs a new WebRTCDialer.
func (WebRTCDialer) Catch ¶
func (w WebRTCDialer) Catch() (*WebRTCPeer, error)
Catch initializes a WebRTC Connection by signaling through the BrokerChannel.
func (WebRTCDialer) GetMax ¶
func (w WebRTCDialer) GetMax() int
GetMax returns the maximum number of snowflakes to collect.
type WebRTCPeer ¶
type WebRTCPeer struct {
// contains filtered or unexported fields
}
WebRTCPeer represents a WebRTC connection to a remote snowflake proxy.
Each WebRTCPeer only ever has one DataChannel that is used as the peer's transport.
func NewWebRTCPeer ¶
func NewWebRTCPeer(config *webrtc.Configuration, broker *BrokerChannel) (*WebRTCPeer, error)
func NewWebRTCPeerWithEvents ¶ added in v2.1.0
func NewWebRTCPeerWithEvents(config *webrtc.Configuration, broker *BrokerChannel, eventsLogger event.SnowflakeEventReceiver) (*WebRTCPeer, error)
NewWebRTCPeerWithEvents constructs a WebRTC PeerConnection to a snowflake proxy.
The creation of the peer handles the signaling to the Snowflake broker, including the exchange of SDP information, the creation of a PeerConnection, and the establishment of a DataChannel to the Snowflake proxy.
func (*WebRTCPeer) Close ¶
func (c *WebRTCPeer) Close() error
Close closes the connection the snowflake proxy.
func (*WebRTCPeer) Closed ¶
func (c *WebRTCPeer) Closed() bool
Closed returns a boolean indicated whether the peer is closed.
func (*WebRTCPeer) Read ¶
func (c *WebRTCPeer) Read(b []byte) (int, error)
Read bytes from local SOCKS. As part of |io.ReadWriter|
func (*WebRTCPeer) Write ¶
func (c *WebRTCPeer) Write(b []byte) (int, error)
Writes bytes out to remote WebRTC. As part of |io.ReadWriter|