Merge branch 'dev-snowflake-udp-rebase-extradata' into 'main'

Draft: Unreliable+unordered WebRTC data channel transport for Snowflake rev2

See merge request tpo/anti-censorship/pluggable-transports/snowflake!315
This commit is contained in:
shelikhoo 2025-02-12 16:55:11 +00:00
commit aae444478d
17 changed files with 506 additions and 91 deletions

View file

@ -35,6 +35,7 @@ import (
"net"
"net/http"
"net/url"
"os"
"strings"
"sync"
"time"
@ -342,7 +343,7 @@ func (sf *SnowflakeProxy) datachannelHandler(conn *webRTCConn, remoteAddr net.Ad
relayURL = sf.RelayURL
}
wsConn, err := connectToRelay(relayURL, remoteAddr)
wsConn, err := connectToRelay(relayURL, remoteAddr, conn.GetConnectionProtocol())
if err != nil {
log.Print(err)
return
@ -353,7 +354,11 @@ func (sf *SnowflakeProxy) datachannelHandler(conn *webRTCConn, remoteAddr net.Ad
log.Printf("datachannelHandler ends")
}
func connectToRelay(relayURL string, remoteAddr net.Addr) (*websocketconn.Conn, error) {
func connectToRelay(
relayURL string,
remoteAddr net.Addr,
webrtcConnProtocol string,
) (*websocketconn.Conn, error) {
u, err := url.Parse(relayURL)
if err != nil {
return nil, fmt.Errorf("invalid relay url: %s", err)
@ -369,6 +374,12 @@ func connectToRelay(relayURL string, remoteAddr net.Addr) (*websocketconn.Conn,
log.Printf("no remote address given in websocket")
}
{
q := u.Query()
q.Set("protocol", webrtcConnProtocol)
u.RawQuery = q.Encode()
}
ws, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
return nil, fmt.Errorf("error dialing relay: %s = %s", u.String(), err)
@ -449,7 +460,7 @@ func (sf *SnowflakeProxy) makePeerConnectionFromOffer(
close(dataChan)
pr, pw := io.Pipe()
conn := newWebRTCConn(pc, dc, pr, sf.bytesLogger)
conn := newWebRTCConn(pc, dc, pr, sf.bytesLogger, dc.Protocol())
dc.SetBufferedAmountLowThreshold(bufferedAmountLowThreshold)
@ -461,7 +472,7 @@ func (sf *SnowflakeProxy) makePeerConnectionFromOffer(
})
dc.OnOpen(func() {
log.Printf("Data Channel %s-%d open\n", dc.Label(), dc.ID())
log.Printf("Data Channel %s-%d;%s open\n", dc.Label(), dc.ID(), dc.Protocol())
sf.EventDispatcher.OnNewSnowflakeEvent(event.EventOnProxyClientConnected{})
if sf.OutboundAddress != "" {
@ -835,6 +846,11 @@ func (sf *SnowflakeProxy) Stop() {
func (sf *SnowflakeProxy) checkNATType(config webrtc.Configuration, probeURL string) error {
log.Printf("Checking our NAT type, contacting NAT check probe server at \"%v\"...", probeURL)
if os.Getenv("SNOWFLAKE_TEST_ASSUMEUNRESTRICTED") != "" {
currentNATType = NATUnrestricted
return nil
}
probe, err := newSignalingServer(probeURL)
if err != nil {
return fmt.Errorf("Error parsing url: %w", err)