This is an automated email from the git hooks/post-receive script.
dcf pushed a commit to branch turbotunnel in repository pluggable-transports/meek.
commit 80b6d3b101108086375fda872c0f7c19d4c0c158 Author: David Fifield david@bamsoftware.com AuthorDate: Thu Oct 27 17:58:47 2022 -0600
Factor turbotunnel into a common package. --- {meek-server => common/turbotunnel}/client_map.go | 2 +- common/turbotunnel/clientid.go | 28 +++++++++++++ common/turbotunnel/consts.go | 14 +++++++ .../turbotunnel/queuepacketconn.go | 47 +++------------------- meek-client/turbotunnel.go | 27 ++----------- meek-server/meek-server.go | 7 ++-- 6 files changed, 56 insertions(+), 69 deletions(-)
diff --git a/meek-server/client_map.go b/common/turbotunnel/client_map.go similarity index 99% rename from meek-server/client_map.go rename to common/turbotunnel/client_map.go index 6f2f69a..733480a 100644 --- a/meek-server/client_map.go +++ b/common/turbotunnel/client_map.go @@ -1,4 +1,4 @@ -package main +package turbotunnel
import ( "container/heap" diff --git a/common/turbotunnel/clientid.go b/common/turbotunnel/clientid.go new file mode 100644 index 0000000..17257e1 --- /dev/null +++ b/common/turbotunnel/clientid.go @@ -0,0 +1,28 @@ +package turbotunnel + +import ( + "crypto/rand" + "encoding/hex" +) + +// ClientID is an abstract identifier that binds together all the communications +// belonging to a single client session, even though those communications may +// arrive from multiple IP addresses or over multiple lower-level connections. +// It plays the same role that an (IP address, port number) tuple plays in a +// net.UDPConn: it's the return address pertaining to a long-lived abstract +// client session. The client attaches its ClientID to each of its +// communications, enabling the server to disambiguate requests among its many +// clients. ClientID implements the net.Addr interface. +type ClientID [8]byte + +func NewClientID() ClientID { + var id ClientID + _, err := rand.Read(id[:]) + if err != nil { + panic(err) + } + return id +} + +func (id ClientID) Network() string { return "clientid" } +func (id ClientID) String() string { return hex.EncodeToString(id[:]) } diff --git a/common/turbotunnel/consts.go b/common/turbotunnel/consts.go new file mode 100644 index 0000000..0d280af --- /dev/null +++ b/common/turbotunnel/consts.go @@ -0,0 +1,14 @@ +// The code in this package provides a compatibility layer between an underlying +// packet-based connection and our polling-based domain-fronted HTTP carrier. +// The main interface is QueuePacketConn, which stores packets in buffered +// channels instead of sending/receiving them on some concrete network +// interface. Callers can inspect these channels. +package turbotunnel + +import "errors" + +// The size of receive and send queues. +const queueSize = 256 + +var errClosedPacketConn = errors.New("operation on closed connection") +var errNotImplemented = errors.New("not implemented") diff --git a/meek-server/turbotunnel.go b/common/turbotunnel/queuepacketconn.go similarity index 73% rename from meek-server/turbotunnel.go rename to common/turbotunnel/queuepacketconn.go index d10b795..acb04c1 100644 --- a/meek-server/turbotunnel.go +++ b/common/turbotunnel/queuepacketconn.go @@ -1,44 +1,12 @@ -// The code in this file provides a compatibility layer between an underlying -// packet-based connection and our polling-based domain-fronted HTTP carrier. -// The main interface is QueuePacketConn, which stores packets in buffered -// channels instead of sending/receiving them on some concrete network -// interface. Callers can inspect these channels. - -package main +package turbotunnel
import ( - "crypto/rand" - "encoding/hex" - "errors" "net" "sync" "sync/atomic" "time" )
-// The size of receive and send queues. -const queueSize = 256 - -// ClientID plays the role in QueuePacketConn that an (IP address, port) tuple -// plays in a net.UDPConn. It is a persistent identifier that binds together all -// the HTTP transactions that occur as part of a session. The ClientID is sent -// along with all HTTP requests, and the server uses the ClientID to -// disambiguate requests among its many clients. ClientID implements the -// net.Addr interface. -type ClientID [8]byte - -func newClientID() ClientID { - var id ClientID - _, err := rand.Read(id[:]) - if err != nil { - panic(err) - } - return id -} - -func (id ClientID) Network() string { return "clientid" } -func (id ClientID) String() string { return hex.EncodeToString(id[:]) } - // taggedPacket is a combination of a []byte and a net.Addr, encapsulating the // return type of PacketConn.ReadFrom. type taggedPacket struct { @@ -48,9 +16,9 @@ type taggedPacket struct {
// QueuePacketConn implements net.PacketConn by storing queues of packets. There // is one incoming queue (where packets are additionally tagged by the source -// address of the client that sent them). There are many outgoing queues, one -// for each client address that has been recently seen. The QueueIncoming method -// inserts a packet into the incoming queue, to eventually be returned by +// address of the peer that sent them). There are many outgoing queues, one for +// each remote peer address that has been recently seen. The QueueIncoming +// method inserts a packet into the incoming queue, to eventually be returned by // ReadFrom. WriteTo inserts a packet into an address-specific outgoing queue, // which can later by accessed through the OutgoingQueue method. type QueuePacketConn struct { @@ -63,8 +31,8 @@ type QueuePacketConn struct { err atomic.Value }
-// NewQueuePacketConn makes a new QueuePacketConn, set to track recent clients -// for at least a duration of timeout. +// NewQueuePacketConn makes a new QueuePacketConn, set to track recent peers for +// at least a duration of timeout. func NewQueuePacketConn(localAddr net.Addr, timeout time.Duration) *QueuePacketConn { return &QueuePacketConn{ clients: NewClientMap(timeout), @@ -100,9 +68,6 @@ func (c *QueuePacketConn) OutgoingQueue(addr net.Addr) <-chan []byte { return c.clients.SendQueue(addr) }
-var errClosedPacketConn = errors.New("operation on closed connection") -var errNotImplemented = errors.New("not implemented") - // ReadFrom returns a packet and address previously stored by QueueIncoming. func (c *QueuePacketConn) ReadFrom(p []byte) (int, net.Addr, error) { select { diff --git a/meek-client/turbotunnel.go b/meek-client/turbotunnel.go index 535c05c..d4274e2 100644 --- a/meek-client/turbotunnel.go +++ b/meek-client/turbotunnel.go @@ -10,8 +10,6 @@ package main
import ( "bytes" - "crypto/rand" - "encoding/hex" "errors" "io" "net" @@ -20,6 +18,7 @@ import ( "time"
"git.torproject.org/pluggable-transports/meek.git/common/encapsulation" + "git.torproject.org/pluggable-transports/meek.git/common/turbotunnel" )
const ( @@ -47,26 +46,6 @@ const ( pollDelayMultiplier = 2.0 )
-// ClientID plays the role in PollingPacketConn that an (IP address, port) tuple -// plays in a net.UDPConn. It is a persistent identifier that binds together all -// the HTTP transactions that occur as part of a session. The ClientID is sent -// along with all HTTP requests, and the server uses the ClientID to -// disambiguate requests among its many clients. ClientID implements the -// net.Addr interface. -type ClientID [8]byte - -func newClientID() ClientID { - var id ClientID - _, err := rand.Read(id[:]) - if err != nil { - panic(err) - } - return id -} - -func (id ClientID) Network() string { return "clientid" } -func (id ClientID) String() string { return hex.EncodeToString(id[:]) } - // Poller is an abstract interface over an operation that writes a stream of // bytes and reads a stream of bytes in return, like an HTTP request. type Poller interface { @@ -84,7 +63,7 @@ type Poller interface { // HTTP response body). The Poller can apply HTTP request customizations such as // domain fronting. type PollingPacketConn struct { - clientID ClientID + clientID turbotunnel.ClientID remoteAddr net.Addr poller Poller recvQueue chan []byte @@ -105,7 +84,7 @@ type PollingPacketConn struct { // effective remote address. func NewPollingPacketConn(remoteAddr net.Addr, poller Poller) *PollingPacketConn { c := &PollingPacketConn{ - clientID: newClientID(), + clientID: turbotunnel.NewClientID(), remoteAddr: remoteAddr, poller: poller, recvQueue: make(chan []byte, queueSize), diff --git a/meek-server/meek-server.go b/meek-server/meek-server.go index a8efad2..f971ab8 100644 --- a/meek-server/meek-server.go +++ b/meek-server/meek-server.go @@ -40,6 +40,7 @@ import (
"git.torproject.org/pluggable-transports/goptlib.git" "git.torproject.org/pluggable-transports/meek.git/common/encapsulation" + "git.torproject.org/pluggable-transports/meek.git/common/turbotunnel" "github.com/xtaci/kcp-go/v5" "github.com/xtaci/smux" "golang.org/x/crypto/acme/autocert" @@ -80,11 +81,11 @@ func httpInternalServerError(w http.ResponseWriter) { // listener, so there is just one global state. State also serves as the http // Handler. type State struct { - conn *QueuePacketConn + conn *turbotunnel.QueuePacketConn }
func NewState(localAddr net.Addr) (*State, error) { - pconn := NewQueuePacketConn(localAddr, smuxIdleTimeout) + pconn := turbotunnel.NewQueuePacketConn(localAddr, smuxIdleTimeout)
ln, err := kcp.ServeConn(nil, 0, 0, pconn) if err != nil { @@ -147,7 +148,7 @@ func (state *State) Post(w http.ResponseWriter, req *http.Request) { defer req.Body.Close() body := http.MaxBytesReader(w, req.Body, maxPayloadLength+1)
- var clientID ClientID + var clientID turbotunnel.ClientID _, err := io.ReadFull(body, clientID[:]) if err != nil { // The request body didn't even contain enough bytes for the