mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Add connection expire time for uTLS pendingConn
This commit is contained in:
parent
8d5998b744
commit
3132f68012
1 changed files with 43 additions and 4 deletions
|
@ -7,6 +7,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
utls "github.com/refraction-networking/utls"
|
utls "github.com/refraction-networking/utls"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
|
@ -19,7 +20,7 @@ func NewUTLSHTTPRoundTripper(clientHelloID utls.ClientHelloID, uTlsConfig *utls.
|
||||||
config: uTlsConfig,
|
config: uTlsConfig,
|
||||||
connectWithH1: map[string]bool{},
|
connectWithH1: map[string]bool{},
|
||||||
backdropTransport: backdropTransport,
|
backdropTransport: backdropTransport,
|
||||||
pendingConn: map[pendingConnKey]net.Conn{},
|
pendingConn: map[pendingConnKey]*unclaimedConnection{},
|
||||||
removeSNI: removeSNI,
|
removeSNI: removeSNI,
|
||||||
}
|
}
|
||||||
rtImpl.init()
|
rtImpl.init()
|
||||||
|
@ -38,7 +39,7 @@ type uTLSHTTPRoundTripperImpl struct {
|
||||||
backdropTransport http.RoundTripper
|
backdropTransport http.RoundTripper
|
||||||
|
|
||||||
accessDialingConnection sync.Mutex
|
accessDialingConnection sync.Mutex
|
||||||
pendingConn map[pendingConnKey]net.Conn
|
pendingConn map[pendingConnKey]*unclaimedConnection
|
||||||
|
|
||||||
removeSNI bool
|
removeSNI bool
|
||||||
}
|
}
|
||||||
|
@ -50,6 +51,7 @@ type pendingConnKey struct {
|
||||||
|
|
||||||
var errEAGAIN = errors.New("incorrect ALPN negotiated, try again with another ALPN")
|
var errEAGAIN = errors.New("incorrect ALPN negotiated, try again with another ALPN")
|
||||||
var errEAGAINTooMany = errors.New("incorrect ALPN negotiated")
|
var errEAGAINTooMany = errors.New("incorrect ALPN negotiated")
|
||||||
|
var errExpired = errors.New("connection have expired")
|
||||||
|
|
||||||
func (r *uTLSHTTPRoundTripperImpl) RoundTrip(req *http.Request) (*http.Response, error) {
|
func (r *uTLSHTTPRoundTripperImpl) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
if req.URL.Scheme != "https" {
|
if req.URL.Scheme != "https" {
|
||||||
|
@ -99,12 +101,15 @@ func getPendingConnectionID(dest string, alpnIsH2 bool) pendingConnKey {
|
||||||
|
|
||||||
func (r *uTLSHTTPRoundTripperImpl) putConn(addr string, alpnIsH2 bool, conn net.Conn) {
|
func (r *uTLSHTTPRoundTripperImpl) putConn(addr string, alpnIsH2 bool, conn net.Conn) {
|
||||||
connId := getPendingConnectionID(addr, alpnIsH2)
|
connId := getPendingConnectionID(addr, alpnIsH2)
|
||||||
r.pendingConn[connId] = conn
|
r.pendingConn[connId] = NewUnclaimedConnection(conn, time.Minute)
|
||||||
}
|
}
|
||||||
func (r *uTLSHTTPRoundTripperImpl) getConn(addr string, alpnIsH2 bool) net.Conn {
|
func (r *uTLSHTTPRoundTripperImpl) getConn(addr string, alpnIsH2 bool) net.Conn {
|
||||||
connId := getPendingConnectionID(addr, alpnIsH2)
|
connId := getPendingConnectionID(addr, alpnIsH2)
|
||||||
if conn, ok := r.pendingConn[connId]; ok {
|
if conn, ok := r.pendingConn[connId]; ok {
|
||||||
return conn
|
delete(r.pendingConn, connId)
|
||||||
|
if claimedConnection, err := conn.claimConnection(); err == nil {
|
||||||
|
return claimedConnection
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -189,3 +194,37 @@ func (r *uTLSHTTPRoundTripperImpl) init() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewUnclaimedConnection(conn net.Conn, expireTime time.Duration) *unclaimedConnection {
|
||||||
|
c := &unclaimedConnection{
|
||||||
|
Conn: conn,
|
||||||
|
}
|
||||||
|
time.AfterFunc(expireTime, c.tick)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type unclaimedConnection struct {
|
||||||
|
net.Conn
|
||||||
|
claimed bool
|
||||||
|
access sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *unclaimedConnection) claimConnection() (net.Conn, error) {
|
||||||
|
c.access.Lock()
|
||||||
|
defer c.access.Unlock()
|
||||||
|
if !c.claimed {
|
||||||
|
c.claimed = true
|
||||||
|
return c.Conn, nil
|
||||||
|
}
|
||||||
|
return nil, errExpired
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *unclaimedConnection) tick() {
|
||||||
|
c.access.Lock()
|
||||||
|
defer c.access.Unlock()
|
||||||
|
if !c.claimed {
|
||||||
|
c.claimed = true
|
||||||
|
c.Conn.Close()
|
||||||
|
c.Conn = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue