Commit a8ea5e58 authored by Serene Han's avatar Serene Han Committed by Arlo Breault
Browse files

client multiplexing using a webRTCConn channel (#31)

parent 2515ddb1
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -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 {
		s, err := dialWebRTC()
		if err != nil {
			snowflakes = append(snowflakes, s)
	for {
		if len(snowflakeChan) >= SnowflakeCapacity {
			log.Println("At Capacity: ", len(snowflakeChan), "snowflake. Re-checking in 10s")
			<-time.After(time.Second * 10)
			continue
		}
		log.Println("WebRTC Error: ", err)
		s, err := dialWebRTC()
		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
	}()

	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)
+2 −0
Original line number Diff line number Diff line
@@ -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{