client multiplexing using a webRTCConn channel (#31)

This commit is contained in:
Serene Han 2016-03-22 18:03:25 -07:00 committed by Arlo Breault
parent 2515ddb1fa
commit a8ea5e586e
2 changed files with 30 additions and 16 deletions

View file

@ -20,20 +20,20 @@ import (
var ptInfo pt.ClientInfo var ptInfo pt.ClientInfo
const (
ReconnectTimeout = 5
SnowflakeCapacity = 1
)
var brokerURL string var brokerURL string
var frontDomain string var frontDomain string
var iceServers IceServerList 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 // When a connection handler starts, +1 is written to this channel; when it
// ends, -1 is written. // ends, -1 is written.
var handlerChan = make(chan int) var handlerChan = make(chan int)
const (
ReconnectTimeout = 5
SnowflakeCapacity = 1
)
func copyLoop(a, b net.Conn) { func copyLoop(a, b net.Conn) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(2) wg.Add(2)
@ -58,14 +58,22 @@ type SnowflakeChannel interface {
// Maintain |WebRTCSlots| number of open connections to // Maintain |WebRTCSlots| number of open connections to
// transfer to SOCKS when needed. TODO: complete // transfer to SOCKS when needed. TODO: complete
func SnowflakeConnectLoop() { func SnowflakeConnectLoop() {
for len(snowflakes) < SnowflakeCapacity { for {
s, err := dialWebRTC() if len(snowflakeChan) >= SnowflakeCapacity {
if err != nil { log.Println("At Capacity: ", len(snowflakeChan), "snowflake. Re-checking in 10s")
snowflakes = append(snowflakes, s) <-time.After(time.Second * 10)
continue continue
} }
log.Println("WebRTC Error: ", err) s, err := dialWebRTC()
<-time.After(time.Second * ReconnectTimeout) if nil == s || nil != err {
log.Println("WebRTC Error: ", err, " retrying...")
<-time.After(time.Second * ReconnectTimeout)
continue
}
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 handlerChan <- -1
}() }()
remote, err := dialWebRTC() remote, ok := <-snowflakeChan
if err != nil || remote == nil { if remote == nil || !ok {
conn.Reject() conn.Reject()
return err return errors.New("handler: Received invalid Snowflake")
} }
defer remote.Close() defer remote.Close()
defer conn.Close() defer conn.Close()
// TODO: Fix this global
webrtcRemote = remote 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 { if err != nil {
return err return err
} }
@ -201,6 +211,8 @@ func main() {
go readSignalingMessages(signalFile) go readSignalingMessages(signalFile)
} }
go SnowflakeConnectLoop()
ptInfo, err = pt.ClientSetup(nil) ptInfo, err = pt.ClientSetup(nil)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View file

@ -24,6 +24,7 @@ type webRTCConn struct {
writePipe *io.PipeWriter writePipe *io.PipeWriter
buffer bytes.Buffer buffer bytes.Buffer
reset chan struct{} reset chan struct{}
active bool
*BytesInfo *BytesInfo
} }
@ -86,6 +87,7 @@ func NewWebRTCConnection(config *webrtc.Configuration,
// creation & local description setting, which happens asynchronously. // creation & local description setting, which happens asynchronously.
connection.errorChannel = make(chan error, 1) connection.errorChannel = make(chan error, 1)
connection.reset = make(chan struct{}, 1) connection.reset = make(chan struct{}, 1)
connection.active = false
// Log every few seconds. // Log every few seconds.
connection.BytesInfo = &BytesInfo{ connection.BytesInfo = &BytesInfo{