mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-14 05:11:19 -04:00
Add UDP Like transport mode to snowflake
This commit is contained in:
parent
fa122efb61
commit
457c4fbf15
8 changed files with 275 additions and 5 deletions
109
client/lib/packetIDConnClient.go
Normal file
109
client/lib/packetIDConnClient.go
Normal file
|
@ -0,0 +1,109 @@
|
|||
package snowflake_client
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/turbotunnel"
|
||||
)
|
||||
|
||||
const (
|
||||
packetClientIDConn_StateNew = iota
|
||||
packetClientIDConn_StateConnectionIDAcknowledged
|
||||
)
|
||||
|
||||
type ClientID = turbotunnel.ClientID
|
||||
|
||||
func newPacketClientIDConn(ClientID ClientID, transport io.ReadWriter) *packetClientIDConn {
|
||||
return &packetClientIDConn{
|
||||
state: packetClientIDConn_StateNew,
|
||||
ConnID: ClientID,
|
||||
transport: transport,
|
||||
}
|
||||
}
|
||||
|
||||
type packetClientIDConn struct {
|
||||
state int
|
||||
ConnID ClientID
|
||||
transport io.ReadWriter
|
||||
}
|
||||
|
||||
func (c *packetClientIDConn) Write(p []byte) (int, error) {
|
||||
switch c.state {
|
||||
case packetClientIDConn_StateConnectionIDAcknowledged:
|
||||
packet := make([]byte, len(p)+1)
|
||||
packet[0] = 0xff
|
||||
copy(packet[1:], p)
|
||||
_, err := c.transport.Write(packet)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(p), nil
|
||||
case packetClientIDConn_StateNew:
|
||||
packet := make([]byte, len(p)+1+len(c.ConnID))
|
||||
packet[0] = 0xfe
|
||||
copy(packet[1:], c.ConnID[:])
|
||||
copy(packet[1+len(c.ConnID):], p)
|
||||
_, err := c.transport.Write(packet)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(p), nil
|
||||
default:
|
||||
panic("invalid state")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *packetClientIDConn) Read(p []byte) (int, error) {
|
||||
n, err := c.transport.Read(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if p[0] == 0xff {
|
||||
c.state = packetClientIDConn_StateConnectionIDAcknowledged
|
||||
return copy(p, p[1:n]), nil
|
||||
} else {
|
||||
log.Println("discarded unknown packet")
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
type packetConnWrapper struct {
|
||||
io.ReadWriter
|
||||
remoteAddr net.Addr
|
||||
localAddr net.Addr
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
n, err = pcw.Read(p)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
return n, pcw.remoteAddr, nil
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
return pcw.Write(p)
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) LocalAddr() net.Addr {
|
||||
return pcw.localAddr
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) SetReadDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pcw *packetConnWrapper) SetWriteDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
|
@ -339,6 +339,16 @@ func newSession(snowflakes SnowflakeCollector) (net.PacketConn, *smux.Session, e
|
|||
return nil, errors.New("handler: Received invalid Snowflake")
|
||||
}
|
||||
log.Println("---- Handler: snowflake assigned ----")
|
||||
log.Printf("activeTransportMode = %c \n", conn.activeTransportMode)
|
||||
if conn.activeTransportMode == 'u' {
|
||||
packetIDConn := newPacketClientIDConn(clientID, conn)
|
||||
packetConnWrapper := &packetConnWrapper{
|
||||
ReadWriter: packetIDConn,
|
||||
remoteAddr: dummyAddr{},
|
||||
localAddr: dummyAddr{},
|
||||
}
|
||||
return packetConnWrapper, nil
|
||||
}
|
||||
// Send the magic Turbo Tunnel token.
|
||||
_, err := conn.Write(turbotunnel.Token[:])
|
||||
if err != nil {
|
||||
|
@ -363,7 +373,7 @@ func newSession(snowflakes SnowflakeCollector) (net.PacketConn, *smux.Session, e
|
|||
return nil, nil, err
|
||||
}
|
||||
// Permit coalescing the payloads of consecutive sends.
|
||||
conn.SetStreamMode(true)
|
||||
conn.SetStreamMode(false)
|
||||
// Set the maximum send and receive window sizes to a high number
|
||||
// Removes KCP bottlenecks: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40026
|
||||
conn.SetWindowSize(WindowSize, WindowSize)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
|
@ -43,6 +44,8 @@ type WebRTCPeer struct {
|
|||
bytesLogger bytesLogger
|
||||
eventsLogger event.SnowflakeEventReceiver
|
||||
proxy *url.URL
|
||||
|
||||
activeTransportMode byte
|
||||
}
|
||||
|
||||
// Deprecated: Use NewWebRTCPeerWithNatPolicyAndEventsAndProxy Instead.
|
||||
|
@ -191,6 +194,7 @@ func (c *WebRTCPeer) connect(
|
|||
) error {
|
||||
log.Println(c.id, " connecting...")
|
||||
|
||||
c.activeTransportMode = 'u'
|
||||
err := c.preparePeerConnection(config, broker.keepLocalAddresses)
|
||||
localDescription := c.pc.LocalDescription()
|
||||
c.eventsLogger.OnNewSnowflakeEvent(event.EventOnOfferCreated{
|
||||
|
@ -297,8 +301,17 @@ func (c *WebRTCPeer) preparePeerConnection(
|
|||
return err
|
||||
}
|
||||
ordered := true
|
||||
var maxRetransmission *uint16
|
||||
if c.activeTransportMode == 'u' {
|
||||
ordered = false
|
||||
maxRetransmissionVal := uint16(0)
|
||||
maxRetransmission = &maxRetransmissionVal
|
||||
}
|
||||
protocol := fmt.Sprintf("%c", c.activeTransportMode)
|
||||
dataChannelOptions := &webrtc.DataChannelInit{
|
||||
Ordered: &ordered,
|
||||
Ordered: &ordered,
|
||||
Protocol: &protocol,
|
||||
MaxRetransmits: maxRetransmission,
|
||||
}
|
||||
// We must create the data channel before creating an offer
|
||||
// https://github.com/pion/webrtc/wiki/Release-WebRTC@v3.0.0#a-data-channel-is-no-longer-implicitly-created-with-a-peerconnection
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue