[tor-commits] [snowflake/master] replace webrtcRemote with webrtcRemotes map & indexing, client multiplexing remotes confirmed working (#31)

arlo at torproject.org arlo at torproject.org
Sun Mar 27 16:09:19 UTC 2016


commit 22ace32a713558b6c22fc15eed08d781bf503f60
Author: Serene Han <keroserene+git at gmail.com>
Date:   Wed Mar 23 19:40:26 2016 -0700

    replace webrtcRemote with webrtcRemotes map & indexing, client multiplexing remotes confirmed working (#31)
---
 client/snowflake.go | 31 ++++++++++++-------------------
 client/webrtc.go    | 14 ++++++++------
 2 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/client/snowflake.go b/client/snowflake.go
index 101d26f..a9f17cc 100644
--- a/client/snowflake.go
+++ b/client/snowflake.go
@@ -22,7 +22,7 @@ var ptInfo pt.ClientInfo
 
 const (
 	ReconnectTimeout  = 5
-	SnowflakeCapacity = 1
+	SnowflakeCapacity = 3
 )
 
 var brokerURL string
@@ -55,12 +55,13 @@ type SnowflakeChannel interface {
 	Close() error
 }
 
-// Maintain |WebRTCSlots| number of open connections to
-// transfer to SOCKS when needed. TODO: complete
+// Maintain |SnowflakeCapacity| number of available WebRTC connections, to
+// transfer to the Tor SOCKS handler when needed.
 func SnowflakeConnectLoop() {
 	for {
-		if len(snowflakeChan) >= SnowflakeCapacity {
-			log.Println("At Capacity: ", len(snowflakeChan), "snowflake. Re-checking in 10s")
+		numRemotes := len(snowflakeChan)
+		if numRemotes >= SnowflakeCapacity {
+			log.Println("At Capacity: ", numRemotes, "snowflake. Re-checking in 10s")
 			<-time.After(time.Second * 10)
 			continue
 		}
@@ -70,9 +71,6 @@ func SnowflakeConnectLoop() {
 			<-time.After(time.Second * ReconnectTimeout)
 			continue
 		}
-
-		log.Println("Created a snowflake.")
-		// TODO: Better handling of multiplex snowflakes.
 		snowflakeChan <- s
 	}
 }
@@ -93,11 +91,9 @@ func dialWebRTC() (*webRTCConn, error) {
 
 func endWebRTC() {
 	log.Printf("WebRTC: interruped")
-	if nil == webrtcRemote {
-		return
+	for _, r := range webrtcRemotes {
+		r.Close()
 	}
-	webrtcRemote.Close()
-	webrtcRemote = nil
 }
 
 // Establish a WebRTC channel for SOCKS connections.
@@ -106,7 +102,7 @@ func handler(conn *pt.SocksConn) error {
 	defer func() {
 		handlerChan <- -1
 	}()
-
+	// Wait for an available WebRTC remote...
 	remote, ok := <-snowflakeChan
 	if remote == nil || !ok {
 		conn.Reject()
@@ -114,8 +110,6 @@ func handler(conn *pt.SocksConn) error {
 	}
 	defer remote.Close()
 	defer conn.Close()
-	// TODO: Fix this global
-	webrtcRemote = remote
 	log.Println("handler: Snowflake assigned.")
 
 	err := conn.Grant(&net.TCPAddr{IP: net.IPv4zero, Port: 0})
@@ -123,8 +117,6 @@ func handler(conn *pt.SocksConn) error {
 		return err
 	}
 
-	// TODO: Make SOCKS acceptance more independent from WebRTC so they can
-	// be more easily interchanged.
 	go copyLoop(conn, remote)
 	// When WebRTC resets, close the SOCKS connection, which induces new handler.
 	<-remote.reset
@@ -164,10 +156,10 @@ func readSignalingMessages(f *os.File) {
 			log.Printf("ignoring invalid signal message %+q", msg)
 			continue
 		}
-		webrtcRemote.answerChannel <- sdp
+		webrtcRemotes[0].answerChannel <- sdp
 	}
 	log.Printf("close answerChannel")
-	close(webrtcRemote.answerChannel)
+	close(webrtcRemotes[0].answerChannel)
 	if err := s.Err(); err != nil {
 		log.Printf("signal FIFO: %s", err)
 	}
@@ -211,6 +203,7 @@ func main() {
 		go readSignalingMessages(signalFile)
 	}
 
+	webrtcRemotes = make(map[int]*webRTCConn)
 	go SnowflakeConnectLoop()
 
 	ptInfo, err = pt.ClientSetup(nil)
diff --git a/client/webrtc.go b/client/webrtc.go
index 022a855..2b907ad 100644
--- a/client/webrtc.go
+++ b/client/webrtc.go
@@ -24,11 +24,12 @@ type webRTCConn struct {
 	writePipe     *io.PipeWriter
 	buffer        bytes.Buffer
 	reset         chan struct{}
-	active        bool
+	index         int
 	*BytesInfo
 }
 
-var webrtcRemote *webRTCConn
+var webrtcRemotes map[int]*webRTCConn
+var remoteIndex int = 0
 
 func (c *webRTCConn) Read(b []byte) (int, error) {
 	return c.recvPipe.Read(b)
@@ -53,6 +54,7 @@ func (c *webRTCConn) Close() error {
 	close(c.offerChannel)
 	close(c.answerChannel)
 	close(c.errorChannel)
+	delete(webrtcRemotes, c.index)
 	return err
 }
 
@@ -87,7 +89,6 @@ func NewWebRTCConnection(config *webrtc.Configuration,
 	// creation & local description setting, which happens asynchronously.
 	connection.errorChannel = make(chan error, 1)
 	connection.reset = make(chan struct{}, 1)
-	connection.active = false
 
 	// Log every few seconds.
 	connection.BytesInfo = &BytesInfo{
@@ -98,13 +99,14 @@ func NewWebRTCConnection(config *webrtc.Configuration,
 
 	// Pipes remain the same even when DataChannel gets switched.
 	connection.recvPipe, connection.writePipe = io.Pipe()
-
+	connection.index = remoteIndex
+	webrtcRemotes[connection.index] = connection
+	remoteIndex++
 	return connection
 }
 
-// TODO: Multiplex.
 func (c *webRTCConn) Connect() error {
-	log.Println("Establishing WebRTC connection...")
+	log.Printf("Establishing WebRTC connection #%d...", c.index)
 	// TODO: When go-webrtc is more stable, it's possible that a new
 	// PeerConnection won't need to be re-prepared each time.
 	err := c.preparePeerConnection()





More information about the tor-commits mailing list