[tor-commits] [snowflake/main] Add package functions to define and set the rendezvous method

cohosh at torproject.org cohosh at torproject.org
Mon Oct 4 14:18:49 UTC 2021


commit 99887cd05d830896d2b2cda9809e4ff1a2836c93
Author: Cecylia Bocovich <cohosh at torproject.org>
Date:   Thu Sep 9 12:54:31 2021 -0400

    Add package functions to define and set the rendezvous method
    
    Add exported functions to the snowflake client library to allow calling
    programs to define and set their own custom broker rendezvous methods.
---
 client/lib/rendezvous.go           | 23 ++++++++--------
 client/lib/rendezvous_ampcache.go  |  2 +-
 client/lib/rendezvous_http.go      |  2 +-
 client/lib/snowflake.go            |  4 +++
 doc/using-the-snowflake-library.md | 54 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 71 insertions(+), 14 deletions(-)

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.





More information about the tor-commits mailing list