[tor-commits] [snowflake/master] client multiplexing using a webRTCConn channel (#31)

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


commit a8ea5e586ebf535994d029d1f78c6dd5cfa2b1e4
Author: Serene Han <keroserene+git at gmail.com>
Date:   Tue Mar 22 18:03:25 2016 -0700

    client multiplexing using a webRTCConn channel (#31)
---
 client/snowflake.go | 42 +++++++++++++++++++++++++++---------------
 client/webrtc.go    |  2 ++
 2 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/client/snowflake.go b/client/snowflake.go
index ac593a4..101d26f 100644
--- a/client/snowflake.go
+++ b/client/snowflake.go
@@ -20,20 +20,20 @@ import (
 
 var ptInfo pt.ClientInfo
 
+const (
+	ReconnectTimeout  = 5
+	SnowflakeCapacity = 1
+)
+
 var brokerURL string
 var frontDomain string
 var iceServers IceServerList
-var snowflakes []*webRTCConn
+var snowflakeChan = make(chan *webRTCConn, 1)
 
 // When a connection handler starts, +1 is written to this channel; when it
 // ends, -1 is written.
 var handlerChan = make(chan int)
 
-const (
-	ReconnectTimeout = 5
-	SnowflakeCapacity = 1
-)
-
 func copyLoop(a, b net.Conn) {
 	var wg sync.WaitGroup
 	wg.Add(2)
@@ -58,14 +58,22 @@ type SnowflakeChannel interface {
 // Maintain |WebRTCSlots| number of open connections to
 // transfer to SOCKS when needed. TODO: complete
 func SnowflakeConnectLoop() {
-	for len(snowflakes) < SnowflakeCapacity {
+	for {
+		if len(snowflakeChan) >= SnowflakeCapacity {
+			log.Println("At Capacity: ", len(snowflakeChan), "snowflake. Re-checking in 10s")
+			<-time.After(time.Second * 10)
+			continue
+		}
 		s, err := dialWebRTC()
-		if err != nil {
-			snowflakes = append(snowflakes, s)
+		if nil == s || nil != err {
+			log.Println("WebRTC Error: ", err, " retrying...")
+			<-time.After(time.Second * ReconnectTimeout)
 			continue
 		}
-		log.Println("WebRTC Error: ", err)
-		<-time.After(time.Second * ReconnectTimeout)
+
+		log.Println("Created a snowflake.")
+		// TODO: Better handling of multiplex snowflakes.
+		snowflakeChan <- s
 	}
 }
 
@@ -99,16 +107,18 @@ func handler(conn *pt.SocksConn) error {
 		handlerChan <- -1
 	}()
 
-	remote, err := dialWebRTC()
-	if err != nil || remote == nil {
+	remote, ok := <-snowflakeChan
+	if remote == nil || !ok {
 		conn.Reject()
-		return err
+		return errors.New("handler: Received invalid Snowflake")
 	}
 	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})
+	err := conn.Grant(&net.TCPAddr{IP: net.IPv4zero, Port: 0})
 	if err != nil {
 		return err
 	}
@@ -201,6 +211,8 @@ func main() {
 		go readSignalingMessages(signalFile)
 	}
 
+	go SnowflakeConnectLoop()
+
 	ptInfo, err = pt.ClientSetup(nil)
 	if err != nil {
 		log.Fatal(err)
diff --git a/client/webrtc.go b/client/webrtc.go
index 55f39e0..022a855 100644
--- a/client/webrtc.go
+++ b/client/webrtc.go
@@ -24,6 +24,7 @@ type webRTCConn struct {
 	writePipe     *io.PipeWriter
 	buffer        bytes.Buffer
 	reset         chan struct{}
+	active        bool
 	*BytesInfo
 }
 
@@ -86,6 +87,7 @@ 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{





More information about the tor-commits mailing list