[tor-commits] [snowflake/master] Move snowflake ConnectLoop inside SOCKS Handler

cohosh at torproject.org cohosh at torproject.org
Thu Aug 27 20:45:15 UTC 2020


commit 1364d7d45bbec9de605a266a84ea60cdfa6676db
Author: Cecylia Bocovich <cohosh at torproject.org>
Date:   Tue Aug 11 13:22:16 2020 -0400

    Move snowflake ConnectLoop inside SOCKS Handler
    
    Bug #21314: maintains a separate snowflake connect loop per SOCKS
    connection. This way, if Tor decides to stop using Snowflake, Snowflake
    will stop using the client's network.
---
 client/lib/lib_test.go  |  6 +++---
 client/lib/snowflake.go | 34 +++++++++++++++++++++++++++++++++-
 client/snowflake.go     | 38 +++++---------------------------------
 3 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/client/lib/lib_test.go b/client/lib/lib_test.go
index ebcf284..a93943f 100644
--- a/client/lib/lib_test.go
+++ b/client/lib/lib_test.go
@@ -157,11 +157,11 @@ func TestSnowflakeClient(t *testing.T) {
 
 		SkipConvey("Handler Grants correctly", func() {
 			socks := &FakeSocksConn{}
-			snowflakes := &FakePeers{}
+			broker := &BrokerChannel{Host: "test"}
+			d := NewWebRTCDialer(broker, nil)
 
 			So(socks.rejected, ShouldEqual, false)
-			snowflakes.toRelease = nil
-			Handler(socks, snowflakes)
+			Handler(socks, d)
 			So(socks.rejected, ShouldEqual, true)
 		})
 	})
diff --git a/client/lib/snowflake.go b/client/lib/snowflake.go
index b355c3e..d08a7bc 100644
--- a/client/lib/snowflake.go
+++ b/client/lib/snowflake.go
@@ -142,7 +142,17 @@ var sessionManager = sessionManager_{}
 
 // Given an accepted SOCKS connection, establish a WebRTC connection to the
 // remote peer and exchange traffic.
-func Handler(socks net.Conn, snowflakes SnowflakeCollector) error {
+func Handler(socks net.Conn, tongue Tongue) error {
+	// Prepare to collect remote WebRTC peers.
+	snowflakes := NewPeers(1)
+	snowflakes.Tongue = tongue
+
+	// Use a real logger to periodically output how much traffic is happening.
+	snowflakes.BytesLogger = NewBytesSyncLogger()
+
+	log.Printf("---- Handler: begin collecting snowflakes ---")
+	go connectLoop(snowflakes)
+
 	// Return the global smux.Session.
 	sess, err := sessionManager.Get(snowflakes)
 	if err != nil {
@@ -160,9 +170,31 @@ func Handler(socks net.Conn, snowflakes SnowflakeCollector) error {
 	log.Printf("---- Handler: begin stream %v ---", stream.ID())
 	copyLoop(socks, stream)
 	log.Printf("---- Handler: closed stream %v ---", stream.ID())
+	snowflakes.End()
+	log.Printf("---- Handler: end collecting snowflakes ---")
 	return nil
 }
 
+// Maintain |SnowflakeCapacity| number of available WebRTC connections, to
+// transfer to the Tor SOCKS handler when needed.
+func connectLoop(snowflakes SnowflakeCollector) {
+	for {
+		// Check if ending is necessary.
+		_, err := snowflakes.Collect()
+		if err != nil {
+			log.Printf("WebRTC: %v  Retrying in %v...",
+				err, ReconnectTimeout)
+		}
+		select {
+		case <-time.After(ReconnectTimeout):
+			continue
+		case <-snowflakes.Melted():
+			log.Println("ConnectLoop: stopped.")
+			return
+		}
+	}
+}
+
 // Exchanges bytes between two ReadWriters.
 // (In this case, between a SOCKS connection and smux stream.)
 func copyLoop(socks, stream io.ReadWriter) {
diff --git a/client/snowflake.go b/client/snowflake.go
index 55bc48e..a7f5208 100644
--- a/client/snowflake.go
+++ b/client/snowflake.go
@@ -26,28 +26,8 @@ const (
 	DefaultSnowflakeCapacity = 1
 )
 
-// Maintain |SnowflakeCapacity| number of available WebRTC connections, to
-// transfer to the Tor SOCKS handler when needed.
-func ConnectLoop(snowflakes sf.SnowflakeCollector) {
-	for {
-		// Check if ending is necessary.
-		_, err := snowflakes.Collect()
-		if err != nil {
-			log.Printf("WebRTC: %v  Retrying in %v...",
-				err, sf.ReconnectTimeout)
-		}
-		select {
-		case <-time.After(sf.ReconnectTimeout):
-			continue
-		case <-snowflakes.Melted():
-			log.Println("ConnectLoop: stopped.")
-			return
-		}
-	}
-}
-
 // Accept local SOCKS connections and pass them to the handler.
-func socksAcceptLoop(ln *pt.SocksListener, snowflakes sf.SnowflakeCollector) {
+func socksAcceptLoop(ln *pt.SocksListener, tongue sf.Tongue) {
 	defer ln.Close()
 	for {
 		conn, err := ln.AcceptSocks()
@@ -68,7 +48,7 @@ func socksAcceptLoop(ln *pt.SocksListener, snowflakes sf.SnowflakeCollector) {
 				return
 			}
 
-			err = sf.Handler(conn, snowflakes)
+			err = sf.Handler(conn, tongue)
 			if err != nil {
 				log.Printf("handler error: %s", err)
 				return
@@ -158,9 +138,6 @@ func main() {
 		log.Printf("url: %v", strings.Join(server.URLs, " "))
 	}
 
-	// Prepare to collect remote WebRTC peers.
-	snowflakes := sf.NewPeers(*max)
-
 	// Use potentially domain-fronting broker to rendezvous.
 	broker, err := sf.NewBrokerChannel(
 		*brokerURL, *frontDomain, sf.CreateBrokerTransport(),
@@ -170,12 +147,8 @@ func main() {
 	}
 	go updateNATType(iceServers, broker)
 
-	snowflakes.Tongue = sf.NewWebRTCDialer(broker, iceServers)
-
-	// Use a real logger to periodically output how much traffic is happening.
-	snowflakes.BytesLogger = sf.NewBytesSyncLogger()
-
-	go ConnectLoop(snowflakes)
+	// Create a new WebRTCDialer to use as the |Tongue| to catch snowflakes
+	dialer := sf.NewWebRTCDialer(broker, iceServers)
 
 	// Begin goptlib client process.
 	ptInfo, err := pt.ClientSetup(nil)
@@ -197,7 +170,7 @@ func main() {
 				break
 			}
 			log.Printf("Started SOCKS listener at %v.", ln.Addr())
-			go socksAcceptLoop(ln, snowflakes)
+			go socksAcceptLoop(ln, dialer)
 			pt.Cmethod(methodName, ln.Version(), ln.Addr())
 			listeners = append(listeners, ln)
 		default:
@@ -228,7 +201,6 @@ func main() {
 	for _, ln := range listeners {
 		ln.Close()
 	}
-	snowflakes.End()
 	log.Println("snowflake is done.")
 }
 





More information about the tor-commits mailing list