add client side support for extra data based client id

This commit is contained in:
Shelikhoo 2024-04-29 14:53:02 +01:00 committed by WofWca
parent ad5edd3f01
commit bf165264b1
3 changed files with 65 additions and 17 deletions

View file

@ -13,6 +13,8 @@ import (
"sync" "sync"
"time" "time"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/turbotunnel"
"github.com/pion/webrtc/v4" "github.com/pion/webrtc/v4"
utls "github.com/refraction-networking/utls" utls "github.com/refraction-networking/utls"
@ -251,6 +253,7 @@ type WebRTCDialer struct {
eventLogger event.SnowflakeEventReceiver eventLogger event.SnowflakeEventReceiver
proxy *url.URL proxy *url.URL
connectionID turbotunnel.ClientID
} }
// Deprecated: Use NewWebRTCDialerWithNatPolicyAndEventsAndProxy instead // Deprecated: Use NewWebRTCDialerWithNatPolicyAndEventsAndProxy instead
@ -281,7 +284,6 @@ func NewWebRTCDialerWithEventsAndProxy(broker *BrokerChannel, iceServers []webrt
) )
} }
// NewWebRTCDialerWithNatPolicyAndEventsAndProxy constructs a new WebRTCDialer.
func NewWebRTCDialerWithNatPolicyAndEventsAndProxy( func NewWebRTCDialerWithNatPolicyAndEventsAndProxy(
broker *BrokerChannel, broker *BrokerChannel,
natPolicy *NATPolicy, natPolicy *NATPolicy,
@ -289,6 +291,27 @@ func NewWebRTCDialerWithNatPolicyAndEventsAndProxy(
max int, max int,
eventLogger event.SnowflakeEventReceiver, eventLogger event.SnowflakeEventReceiver,
proxy *url.URL, proxy *url.URL,
) *WebRTCDialer {
return NewWebRTCDialerWithNatPolicyAndEventsAndProxyAndClientID(
broker,
natPolicy,
iceServers,
max,
eventLogger,
proxy,
turbotunnel.NewClientID(),
)
}
// NewWebRTCDialerWithNatPolicyAndEventsAndProxy constructs a new WebRTCDialer.
func NewWebRTCDialerWithNatPolicyAndEventsAndProxyAndClientID(
broker *BrokerChannel,
natPolicy *NATPolicy,
iceServers []webrtc.ICEServer,
max int,
eventLogger event.SnowflakeEventReceiver,
proxy *url.URL,
clientID turbotunnel.ClientID,
) *WebRTCDialer { ) *WebRTCDialer {
config := webrtc.Configuration{ config := webrtc.Configuration{
ICEServers: iceServers, ICEServers: iceServers,
@ -302,6 +325,7 @@ func NewWebRTCDialerWithNatPolicyAndEventsAndProxy(
eventLogger: eventLogger, eventLogger: eventLogger,
proxy: proxy, proxy: proxy,
connectionID: clientID,
} }
} }
@ -309,9 +333,7 @@ func NewWebRTCDialerWithNatPolicyAndEventsAndProxy(
func (w WebRTCDialer) Catch() (*WebRTCPeer, error) { func (w WebRTCDialer) Catch() (*WebRTCPeer, error) {
// TODO: [#25591] Fetch ICE server information from Broker. // TODO: [#25591] Fetch ICE server information from Broker.
// TODO: [#25596] Consider TURN servers here too. // TODO: [#25596] Consider TURN servers here too.
return NewWebRTCPeerWithNatPolicyAndEventsAndProxy( return NewWebRTCPeerWithEventsAndProxy(w.webrtcConfig, w.BrokerChannel, w.eventLogger, w.proxy)
w.webrtcConfig, w.BrokerChannel, w.natPolicy, w.eventLogger, w.proxy,
)
} }
// GetMax returns the maximum number of snowflakes to collect. // GetMax returns the maximum number of snowflakes to collect.

View file

@ -78,6 +78,8 @@ type Transport struct {
// EventDispatcher is the event bus for snowflake events. // EventDispatcher is the event bus for snowflake events.
// When an important event happens, it will be distributed here. // When an important event happens, it will be distributed here.
eventDispatcher event.SnowflakeEventDispatcher eventDispatcher event.SnowflakeEventDispatcher
clientID turbotunnel.ClientID
} }
// ClientConfig defines how the SnowflakeClient will connect to the broker and Snowflake proxies. // ClientConfig defines how the SnowflakeClient will connect to the broker and Snowflake proxies.
@ -164,7 +166,11 @@ func NewSnowflakeClient(config ClientConfig) (*Transport, error) {
max = config.Max max = config.Max
} }
eventsLogger := event.NewSnowflakeEventDispatcher() eventsLogger := event.NewSnowflakeEventDispatcher()
transport := &Transport{dialer: NewWebRTCDialerWithNatPolicyAndEventsAndProxy(broker, natPolicy, iceServers, max, eventsLogger, config.CommunicationProxy), eventDispatcher: eventsLogger} clientID := turbotunnel.NewClientID()
transport := &Transport{
dialer: NewWebRTCDialerWithNatPolicyAndEventsAndProxy(broker, natPolicy, iceServers, max, eventsLogger, config.CommunicationProxy),
eventDispatcher: eventsLogger, clientID: clientID,
}
return transport, nil return transport, nil
} }
@ -198,7 +204,7 @@ func (t *Transport) Dial() (net.Conn, error) {
// Create a new smux session // Create a new smux session
log.Printf("---- SnowflakeConn: starting a new session ---") log.Printf("---- SnowflakeConn: starting a new session ---")
pconn, sess, err := newSession(snowflakes) pconn, sess, err := newSession(snowflakes, t.clientID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -324,8 +330,11 @@ func parseIceServers(addresses []string) []webrtc.ICEServer {
// newSession returns a new smux.Session and the net.PacketConn it is running // newSession returns a new smux.Session and the net.PacketConn it is running
// over. The net.PacketConn successively connects through Snowflake proxies // over. The net.PacketConn successively connects through Snowflake proxies
// pulled from snowflakes. // pulled from snowflakes.
func newSession(snowflakes SnowflakeCollector) (net.PacketConn, *smux.Session, error) { func newSession(snowflakes SnowflakeCollector, clientIDCandid turbotunnel.ClientID) (net.PacketConn, *smux.Session, error) {
clientID := turbotunnel.NewClientID() clientID := turbotunnel.NewClientID()
if clientIDCandid != (turbotunnel.ClientID{}) {
clientID = clientIDCandid
}
// We build a persistent KCP session on a sequence of ephemeral WebRTC // We build a persistent KCP session on a sequence of ephemeral WebRTC
// connections. This dialContext tells RedialPacketConn how to get a new // connections. This dialContext tells RedialPacketConn how to get a new
@ -342,9 +351,8 @@ func newSession(snowflakes SnowflakeCollector) (net.PacketConn, *smux.Session, e
log.Println("---- Handler: snowflake assigned ----") log.Println("---- Handler: snowflake assigned ----")
log.Printf("activeTransportMode = %c \n", conn.activeTransportMode) log.Printf("activeTransportMode = %c \n", conn.activeTransportMode)
if conn.activeTransportMode == 'u' { if conn.activeTransportMode == 'u' {
packetIDConn := newPacketClientIDConn(clientID, conn)
packetConnWrapper := &packetConnWrapper{ packetConnWrapper := &packetConnWrapper{
ReadWriter: packetIDConn, ReadWriter: conn,
remoteAddr: dummyAddr{}, remoteAddr: dummyAddr{},
localAddr: dummyAddr{}, localAddr: dummyAddr{},
} }

View file

@ -19,6 +19,7 @@ import (
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event" "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/proxy" "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/proxy"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/turbotunnel"
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/util" "gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/util"
) )
@ -46,6 +47,7 @@ type WebRTCPeer struct {
proxy *url.URL proxy *url.URL
activeTransportMode byte activeTransportMode byte
connectionID turbotunnel.ClientID
} }
// Deprecated: Use NewWebRTCPeerWithNatPolicyAndEventsAndProxy Instead. // Deprecated: Use NewWebRTCPeerWithNatPolicyAndEventsAndProxy Instead.
@ -77,15 +79,30 @@ func NewWebRTCPeerWithEventsAndProxy(
) )
} }
func NewWebRTCPeerWithNatPolicyAndEventsAndProxy(
config *webrtc.Configuration,
broker *BrokerChannel, natPolicy *NATPolicy, eventsLogger event.SnowflakeEventReceiver, proxy *url.URL,
) (*WebRTCPeer, error) {
return NewWebRTCPeerWithNatPolicyAndEventsProxyAndClientID(
config,
broker,
natPolicy,
eventsLogger,
proxy,
turbotunnel.ClientID{},
)
}
// NewWebRTCPeerWithNatPolicyAndEventsAndProxy constructs // NewWebRTCPeerWithNatPolicyAndEventsAndProxy constructs
// a WebRTC PeerConnection to a snowflake proxy. // a WebRTC PeerConnection to a snowflake proxy.
// //
// The creation of the peer handles the signaling to the Snowflake broker, including // The creation of the peer handles the signaling to the Snowflake broker, including
// the exchange of SDP information, the creation of a PeerConnection, and the establishment // the exchange of SDP information, the creation of a PeerConnection, and the establishment
// of a DataChannel to the Snowflake proxy. // of a DataChannel to the Snowflake proxy.
func NewWebRTCPeerWithNatPolicyAndEventsAndProxy( // connectionID is the hinted ID for the connection.
config *webrtc.Configuration, broker *BrokerChannel, natPolicy *NATPolicy, func NewWebRTCPeerWithNatPolicyAndEventsProxyAndClientID(config *webrtc.Configuration,
eventsLogger event.SnowflakeEventReceiver, proxy *url.URL, broker *BrokerChannel, natPolicy *NATPolicy, eventsLogger event.SnowflakeEventReceiver, proxy *url.URL,
clientID turbotunnel.ClientID,
) (*WebRTCPeer, error) { ) (*WebRTCPeer, error) {
if eventsLogger == nil { if eventsLogger == nil {
eventsLogger = event.NewSnowflakeEventDispatcher() eventsLogger = event.NewSnowflakeEventDispatcher()
@ -109,6 +126,7 @@ func NewWebRTCPeerWithNatPolicyAndEventsAndProxy(
connection.eventsLogger = eventsLogger connection.eventsLogger = eventsLogger
connection.proxy = proxy connection.proxy = proxy
connection.connectionID = clientID
err := connection.connect(config, broker, natPolicy) err := connection.connect(config, broker, natPolicy)
if err != nil { if err != nil {
@ -307,7 +325,7 @@ func (c *WebRTCPeer) preparePeerConnection(
maxRetransmissionVal := uint16(0) maxRetransmissionVal := uint16(0)
maxRetransmission = &maxRetransmissionVal maxRetransmission = &maxRetransmissionVal
} }
protocol := fmt.Sprintf("%c", c.activeTransportMode) protocol := fmt.Sprintf("%c %s", c.activeTransportMode, c.connectionID.String())
dataChannelOptions := &webrtc.DataChannelInit{ dataChannelOptions := &webrtc.DataChannelInit{
Ordered: &ordered, Ordered: &ordered,
Protocol: &protocol, Protocol: &protocol,