mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Fix datarace for WebRTCPeer.lastReceive
The race condition occurs because concurrent goroutines are intermixing reads and writes of `WebRTCPeer.lastReceive`. Spotted when integrating Snowflake inside OONI in https://github.com/ooni/probe-cli/pull/373.
This commit is contained in:
parent
e84bc81e31
commit
ed2d5df87d
1 changed files with 12 additions and 3 deletions
|
@ -21,8 +21,10 @@ type WebRTCPeer struct {
|
||||||
pc *webrtc.PeerConnection
|
pc *webrtc.PeerConnection
|
||||||
transport *webrtc.DataChannel
|
transport *webrtc.DataChannel
|
||||||
|
|
||||||
recvPipe *io.PipeReader
|
recvPipe *io.PipeReader
|
||||||
writePipe *io.PipeWriter
|
writePipe *io.PipeWriter
|
||||||
|
|
||||||
|
mu sync.Mutex // protects the following:
|
||||||
lastReceive time.Time
|
lastReceive time.Time
|
||||||
|
|
||||||
open chan struct{} // Channel to notify when datachannel opens
|
open chan struct{} // Channel to notify when datachannel opens
|
||||||
|
@ -89,12 +91,17 @@ func (c *WebRTCPeer) Close() error {
|
||||||
// Should also update the DataChannel in underlying go-webrtc's to make Closes
|
// Should also update the DataChannel in underlying go-webrtc's to make Closes
|
||||||
// more immediate / responsive.
|
// more immediate / responsive.
|
||||||
func (c *WebRTCPeer) checkForStaleness() {
|
func (c *WebRTCPeer) checkForStaleness() {
|
||||||
|
c.mu.Lock()
|
||||||
c.lastReceive = time.Now()
|
c.lastReceive = time.Now()
|
||||||
|
c.mu.Unlock()
|
||||||
for {
|
for {
|
||||||
if c.closed {
|
if c.closed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if time.Since(c.lastReceive) > SnowflakeTimeout {
|
c.mu.Lock()
|
||||||
|
lastReceive := c.lastReceive
|
||||||
|
c.mu.Unlock()
|
||||||
|
if time.Since(lastReceive) > SnowflakeTimeout {
|
||||||
log.Printf("WebRTC: No messages received for %v -- closing stale connection.",
|
log.Printf("WebRTC: No messages received for %v -- closing stale connection.",
|
||||||
SnowflakeTimeout)
|
SnowflakeTimeout)
|
||||||
c.Close()
|
c.Close()
|
||||||
|
@ -173,7 +180,9 @@ func (c *WebRTCPeer) preparePeerConnection(config *webrtc.Configuration) error {
|
||||||
log.Printf("c.writePipe.CloseWithError returned error: %v", inerr)
|
log.Printf("c.writePipe.CloseWithError returned error: %v", inerr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c.mu.Lock()
|
||||||
c.lastReceive = time.Now()
|
c.lastReceive = time.Now()
|
||||||
|
c.mu.Unlock()
|
||||||
})
|
})
|
||||||
c.transport = dc
|
c.transport = dc
|
||||||
c.open = make(chan struct{})
|
c.open = make(chan struct{})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue