diff --git a/client/lib/rendezvous.go b/client/lib/rendezvous.go index d58e729..cf67e09 100644 --- a/client/lib/rendezvous.go +++ b/client/lib/rendezvous.go @@ -26,21 +26,20 @@ const ( readLimit = 100000 //Maximum number of bytes to be read from an HTTP response ) -// rendezvousMethod represents a way of communicating with the broker: sending +// 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 +// 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 rendezvousMethod interface { +type RendezvousMethod interface { Exchange([]byte) ([]byte, error) } -// BrokerChannel contains a rendezvousMethod, as well as data that is not -// specific to any rendezvousMethod. BrokerChannel has the responsibility of -// encoding and decoding SDP offers and answers; rendezvousMethod is responsible -// for the exchange of encoded information. +// 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. type BrokerChannel struct { - rendezvous rendezvousMethod + Rendezvous RendezvousMethod keepLocalAddresses bool natType string lock sync.Mutex @@ -68,7 +67,7 @@ func NewBrokerChannel(broker, ampCache, front string, keepLocalAddresses bool) ( log.Println("Domain fronting using:", front) } - var rendezvous rendezvousMethod + var rendezvous RendezvousMethod var err error if ampCache != "" { rendezvous, err = newAMPCacheRendezvous(broker, ampCache, front, createBrokerTransport()) @@ -80,7 +79,7 @@ func NewBrokerChannel(broker, ampCache, front string, keepLocalAddresses bool) ( } return &BrokerChannel{ - rendezvous: rendezvous, + Rendezvous: rendezvous, keepLocalAddresses: keepLocalAddresses, natType: nat.NATUnknown, }, nil @@ -118,8 +117,8 @@ func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) ( return nil, err } - // Do the exchange using our rendezvousMethod. - encResp, err := bc.rendezvous.Exchange(encReq) + // Do the exchange using our RendezvousMethod. + encResp, err := bc.Rendezvous.Exchange(encReq) if err != nil { return nil, err } diff --git a/client/lib/rendezvous_ampcache.go b/client/lib/rendezvous_ampcache.go index 4856893..2f1fb9f 100644 --- a/client/lib/rendezvous_ampcache.go +++ b/client/lib/rendezvous_ampcache.go @@ -11,7 +11,7 @@ import ( "git.torproject.org/pluggable-transports/snowflake.git/common/amp" ) -// ampCacheRendezvous is a rendezvousMethod that communicates with the +// ampCacheRendezvous is a RendezvousMethod that communicates with the // .../amp/client route of the broker, optionally over an AMP cache proxy, and // with optional domain fronting. type ampCacheRendezvous struct { diff --git a/client/lib/rendezvous_http.go b/client/lib/rendezvous_http.go index 01219cb..e020077 100644 --- a/client/lib/rendezvous_http.go +++ b/client/lib/rendezvous_http.go @@ -10,7 +10,7 @@ import ( "net/url" ) -// httpRendezvous is a rendezvousMethod that communicates with the .../client +// httpRendezvous is a RendezvousMethod that communicates with the .../client // route of the broker over HTTP or HTTPS, with optional domain fronting. type httpRendezvous struct { brokerURL *url.URL diff --git a/client/lib/snowflake.go b/client/lib/snowflake.go index fb7fab9..e0591a7 100644 --- a/client/lib/snowflake.go +++ b/client/lib/snowflake.go @@ -132,6 +132,10 @@ func (t *Transport) Dial() (net.Conn, error) { return &SnowflakeConn{Stream: stream, sess: sess, pconn: pconn, snowflakes: snowflakes}, nil } +func (t *Transport) SetRendezvousMethod(r RendezvousMethod) { + t.dialer.Rendezvous = r +} + type SnowflakeConn struct { *smux.Stream sess *smux.Session diff --git a/doc/using-the-snowflake-library.md b/doc/using-the-snowflake-library.md index 9308cdc..4dc47fc 100644 --- a/doc/using-the-snowflake-library.md +++ b/doc/using-the-snowflake-library.md @@ -38,6 +38,60 @@ func main() { } ``` +#### Using your own rendezvous method + +You can define and use your own rendezvous method to communicate with a Snowflake broker by implementing the `RendezvousMethod` interface. + +```Golang + +package main + +import ( + "log" + + sf "git.torproject.org/pluggable-transports/snowflake.git/client/lib" +) + +type StubMethod struct { +} + +func (m *StubMethod) Exchange(pollReq []byte) ([]byte, error) { + var brokerResponse []byte + var err error + + //Implement the logic you need to communicate with the Snowflake broker here + + return brokerResponse, err +} + +func main() { + config := sf.ClientConfig{ + ICEAddresses: []string{ + "stun:stun.voip.blackberry.com:3478", + "stun:stun.stunprotocol.org:3478"}, + } + transport, err := sf.NewSnowflakeClient(config) + if err != nil { + log.Fatal("Failed to start snowflake transport: ", err) + } + + // custom rendezvous methods can be set with `SetRendezvousMethod` + rendezvous := &StubMethod{} + transport.SetRendezvousMethod(rendezvous) + + // transport implements the ClientFactory interface and returns a net.Conn + conn, err := transport.Dial() + if err != nil { + log.Printf("dial error: %s", err) + return + } + defer conn.Close() + + // ... + +} +``` + ### Server library The Snowflake server library contains functions for running a Snowflake server.