commit 22ace32a713558b6c22fc15eed08d781bf503f60
Author: Serene Han <keroserene+git(a)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()