mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 11:11:30 -04:00
Start refactoring out a client and library
This commit is contained in:
parent
7662ccb00c
commit
cce7ee64a7
8 changed files with 120 additions and 105 deletions
69
client/lib/snowflake.go
Normal file
69
client/lib/snowflake.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
ReconnectTimeout = 10
|
||||
SnowflakeTimeout = 30
|
||||
)
|
||||
|
||||
// When a connection handler starts, +1 is written to this channel; when it
|
||||
// ends, -1 is written.
|
||||
var HandlerChan = make(chan int)
|
||||
|
||||
// Given an accepted SOCKS connection, establish a WebRTC connection to the
|
||||
// remote peer and exchange traffic.
|
||||
func Handler(socks SocksConnector, snowflakes SnowflakeCollector) error {
|
||||
HandlerChan <- 1
|
||||
defer func() {
|
||||
HandlerChan <- -1
|
||||
}()
|
||||
// Obtain an available WebRTC remote. May block.
|
||||
snowflake := snowflakes.Pop()
|
||||
if nil == snowflake {
|
||||
socks.Reject()
|
||||
return errors.New("handler: Received invalid Snowflake")
|
||||
}
|
||||
defer socks.Close()
|
||||
defer snowflake.Close()
|
||||
log.Println("---- Handler: snowflake assigned ----")
|
||||
err := socks.Grant(&net.TCPAddr{IP: net.IPv4zero, Port: 0})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
// When WebRTC resets, close the SOCKS connection too.
|
||||
snowflake.WaitForReset()
|
||||
socks.Close()
|
||||
}()
|
||||
|
||||
// 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)
|
||||
log.Println("---- Handler: closed ---")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Exchanges bytes between two ReadWriters.
|
||||
// (In this case, between a SOCKS and WebRTC connection.)
|
||||
func copyLoop(a, b io.ReadWriter) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
io.Copy(b, a)
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
io.Copy(a, b)
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
log.Println("copy loop ended")
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue