Commit ea2e052a authored by Serene H's avatar Serene H
Browse files

defer snowflake.Reset to fix handler recovery when localhost SOCKS occassionally fails first

parent 0ae71952
...@@ -184,11 +184,11 @@ func TestSnowflakeClient(t *testing.T) { ...@@ -184,11 +184,11 @@ func TestSnowflakeClient(t *testing.T) {
}) })
Convey("WebRTC Connection", func() { Convey("WebRTC Connection", func() {
c := NewWebRTCConnection(nil, nil) c := NewWebRTCPeer(nil, nil)
So(c.buffer.Bytes(), ShouldEqual, nil) So(c.buffer.Bytes(), ShouldEqual, nil)
Convey("Can construct a WebRTCConn", func() { Convey("Can construct a WebRTCConn", func() {
s := NewWebRTCConnection(nil, nil) s := NewWebRTCPeer(nil, nil)
So(s, ShouldNotBeNil) So(s, ShouldNotBeNil)
So(s.offerChannel, ShouldNotBeNil) So(s.offerChannel, ShouldNotBeNil)
So(s.answerChannel, ShouldNotBeNil) So(s.answerChannel, ShouldNotBeNil)
......
...@@ -138,7 +138,7 @@ func (w WebRTCDialer) Catch() (Snowflake, error) { ...@@ -138,7 +138,7 @@ func (w WebRTCDialer) Catch() (Snowflake, error) {
} }
// TODO: [#3] Fetch ICE server information from Broker. // TODO: [#3] Fetch ICE server information from Broker.
// TODO: [#18] Consider TURN servers here too. // TODO: [#18] Consider TURN servers here too.
connection := NewWebRTCConnection(w.webrtcConfig, w.BrokerChannel) connection := NewWebRTCPeer(w.webrtcConfig, w.BrokerChannel)
err := connection.Connect() err := connection.Connect()
return connection, err return connection, err
} }
...@@ -177,12 +177,12 @@ func NewCopyPasteDialer(iceServers IceServerList) *CopyPasteDialer { ...@@ -177,12 +177,12 @@ func NewCopyPasteDialer(iceServers IceServerList) *CopyPasteDialer {
return dialer return dialer
} }
// Initialize a WebRTC connection via manual copy-paste. // Initialize a WebRTC Peer via manual copy-paste.
func (d *CopyPasteDialer) Catch() (Snowflake, error) { func (d *CopyPasteDialer) Catch() (Snowflake, error) {
if nil == d.signal { if nil == d.signal {
return nil, errors.New("Cannot copy-paste dial without signal pipe.") return nil, errors.New("Cannot copy-paste dial without signal pipe.")
} }
connection := NewWebRTCConnection(d.webrtcConfig, nil) connection := NewWebRTCPeer(d.webrtcConfig, nil)
// Must keep track of pending new connection until copy-paste completes. // Must keep track of pending new connection until copy-paste completes.
d.current = connection d.current = connection
// Outputs SDP offer to log, expecting user to copy-paste to the remote Peer. // Outputs SDP offer to log, expecting user to copy-paste to the remote Peer.
......
...@@ -81,6 +81,7 @@ func handler(socks SocksConnector, snowflakes SnowflakeCollector) error { ...@@ -81,6 +81,7 @@ func handler(socks SocksConnector, snowflakes SnowflakeCollector) error {
return errors.New("handler: Received invalid Snowflake") return errors.New("handler: Received invalid Snowflake")
} }
defer socks.Close() defer socks.Close()
defer snowflake.Reset()
log.Println("---- Handler: snowflake assigned ----") log.Println("---- Handler: snowflake assigned ----")
err := socks.Grant(&net.TCPAddr{IP: net.IPv4zero, Port: 0}) err := socks.Grant(&net.TCPAddr{IP: net.IPv4zero, Port: 0})
if err != nil { if err != nil {
...@@ -88,13 +89,13 @@ func handler(socks SocksConnector, snowflakes SnowflakeCollector) error { ...@@ -88,13 +89,13 @@ func handler(socks SocksConnector, snowflakes SnowflakeCollector) error {
} }
go func() { go func() {
// When WebRTC resets, close the SOCKS connection, which ends // When WebRTC resets, close the SOCKS connection too.
// the copyLoop below and induces new handler.
snowflake.WaitForReset() snowflake.WaitForReset()
socks.Close() socks.Close()
}() }()
// Begin exchanging data. // Begin exchanging data. Either WebRTC or localhost SOCKS will close first.
// In eithercase, this closes the handler and induces a new handler.
copyLoop(socks, snowflake) copyLoop(socks, snowflake)
log.Println("---- Handler: closed ---") log.Println("---- Handler: closed ---")
return nil return nil
......
...@@ -5,6 +5,6 @@ ClientTransportPlugin snowflake exec ./client \ ...@@ -5,6 +5,6 @@ ClientTransportPlugin snowflake exec ./client \
-url https://snowflake-reg.appspot.com/ \ -url https://snowflake-reg.appspot.com/ \
-front www.google.com \ -front www.google.com \
-ice stun:stun.l.google.com:19302 \ -ice stun:stun.l.google.com:19302 \
-max 3 -max 1
Bridge snowflake 0.0.3.0:1 Bridge snowflake 0.0.3.0:1
...@@ -58,12 +58,14 @@ func (c *WebRTCPeer) Write(b []byte) (int, error) { ...@@ -58,12 +58,14 @@ func (c *WebRTCPeer) Write(b []byte) (int, error) {
// As part of |Snowflake| // As part of |Snowflake|
func (c *WebRTCPeer) Close() error { func (c *WebRTCPeer) Close() error {
var err error = nil if c.closed { // Skip if already closed.
return nil
}
log.Printf("WebRTC: Closing") log.Printf("WebRTC: Closing")
c.cleanup() c.cleanup()
// Mark for deletion. // Mark for deletion.
c.closed = true c.closed = true
return err return nil
} }
// As part of |Resetter| // As part of |Resetter|
...@@ -79,7 +81,7 @@ func (c *WebRTCPeer) Reset() { ...@@ -79,7 +81,7 @@ func (c *WebRTCPeer) Reset() {
func (c *WebRTCPeer) WaitForReset() { <-c.reset } func (c *WebRTCPeer) WaitForReset() { <-c.reset }
// Construct a WebRTC PeerConnection. // Construct a WebRTC PeerConnection.
func NewWebRTCConnection(config *webrtc.Configuration, func NewWebRTCPeer(config *webrtc.Configuration,
broker *BrokerChannel) *WebRTCPeer { broker *BrokerChannel) *WebRTCPeer {
connection := new(WebRTCPeer) connection := new(WebRTCPeer)
connection.id = "snowflake-" + uniuri.New() connection.id = "snowflake-" + uniuri.New()
...@@ -298,8 +300,8 @@ func (c *WebRTCPeer) cleanup() { ...@@ -298,8 +300,8 @@ func (c *WebRTCPeer) cleanup() {
if nil != c.transport { if nil != c.transport {
log.Printf("WebRTC: closing DataChannel") log.Printf("WebRTC: closing DataChannel")
dataChannel := c.transport dataChannel := c.transport
// Setting dc to nil *before* Close indicates to OnClose that it // Setting transport to nil *before* dc Close indicates to OnClose that
// was locally triggered. // this was locally triggered.
c.transport = nil c.transport = nil
dataChannel.Close() dataChannel.Close()
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment