snowflake_client

package
v2.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 18, 2023 License: BSD-3-Clause Imports: 31 Imported by: 1

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

View Source
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
)
View Source
const (
	LogTimeInterval = 5 * time.Second
)

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

func NewPeers(tongue Tongue) (*Peers, error)

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

func (p *Peers) Count() int

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

type RendezvousMethod interface {
	Exchange([]byte) ([]byte, error)
}

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

type SnowflakeConn struct {
	*smux.Stream
	// contains filtered or unexported fields
}

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

func (t *Transport) Dial() (net.Conn, error)

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|

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL