mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Add synchronization to prevent post-melt collects
This fixes a race condition in which snowflakes.End() is called while snowflakes.Collect() is in progress resulting in a write to a closed channel. We now wait for all in-progress collections to finish and add an extra check before proceeding with a collection.
This commit is contained in:
parent
d7aa9b8356
commit
6baa3c4d5f
2 changed files with 13 additions and 3 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Container which keeps track of multiple WebRTC remote peers.
|
||||
|
@ -25,7 +26,10 @@ type Peers struct {
|
|||
snowflakeChan chan *WebRTCPeer
|
||||
activePeers *list.List
|
||||
|
||||
melt chan struct{}
|
||||
melt chan struct{}
|
||||
melted bool
|
||||
|
||||
collection sync.WaitGroup
|
||||
}
|
||||
|
||||
// Construct a fresh container of remote peers.
|
||||
|
@ -45,6 +49,11 @@ func NewPeers(tongue Tongue) (*Peers, error) {
|
|||
// As part of |SnowflakeCollector| interface.
|
||||
func (p *Peers) Collect() (*WebRTCPeer, error) {
|
||||
// Engage the Snowflake Catching interface, which must be available.
|
||||
p.collection.Add(1)
|
||||
defer p.collection.Done()
|
||||
if p.melted {
|
||||
return nil, fmt.Errorf("Snowflakes have melted")
|
||||
}
|
||||
if nil == p.Tongue {
|
||||
return nil, errors.New("missing Tongue to catch Snowflakes with")
|
||||
}
|
||||
|
@ -110,8 +119,10 @@ func (p *Peers) purgeClosedPeers() {
|
|||
|
||||
// Close all Peers contained here.
|
||||
func (p *Peers) End() {
|
||||
close(p.snowflakeChan)
|
||||
close(p.melt)
|
||||
p.melted = true
|
||||
p.collection.Wait()
|
||||
close(p.snowflakeChan)
|
||||
cnt := p.Count()
|
||||
for e := p.activePeers.Front(); e != nil; {
|
||||
next := e.Next()
|
||||
|
|
|
@ -181,7 +181,6 @@ func Handler(socks net.Conn, tongue Tongue) error {
|
|||
// transfer to the Tor SOCKS handler when needed.
|
||||
func connectLoop(snowflakes SnowflakeCollector) {
|
||||
for {
|
||||
// Check if ending is necessary.
|
||||
_, err := snowflakes.Collect()
|
||||
if err != nil {
|
||||
log.Printf("WebRTC: %v Retrying in %v...",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue