Skip to content

Instantly share code, notes, and snippets.

@xiaokangwang
Created August 4, 2022 16:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xiaokangwang/5cd4437d087b0159146b0cb9d09aa9a5 to your computer and use it in GitHub Desktop.
Save xiaokangwang/5cd4437d087b0159146b0cb9d09aa9a5 to your computer and use it in GitHub Desktop.
diff --git a/client/lib/rendezvous.go b/client/lib/rendezvous.go
index 38e4620..587009b 100644
--- a/client/lib/rendezvous.go
+++ b/client/lib/rendezvous.go
@@ -44,6 +44,7 @@ type BrokerChannel struct {
natType string
lock sync.Mutex
BridgeFingerprint string
+ hack bool
}
// We make a copy of DefaultTransport because we want the default Dial
@@ -94,6 +95,7 @@ func newBrokerChannelFromConfig(config ClientConfig) (*BrokerChannel, error) {
keepLocalAddresses: config.KeepLocalAddresses,
natType: nat.NATUnknown,
BridgeFingerprint: config.BridgeFingerprint,
+ hack: config.PoC,
}, nil
}
@@ -110,6 +112,13 @@ func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) (
SDP: util.StripLocalAddresses(offer.SDP),
}
}
+ if bc.hack {
+ offer = &webrtc.SessionDescription{
+ Type: offer.Type,
+ SDP: util.ChangeSetup(offer.SDP, true),
+ }
+ }
+ //log.Println("SDP offer:", offer.SDP)
offerSDP, err := util.SerializeSessionDescription(offer)
if err != nil {
return nil, err
@@ -143,7 +152,18 @@ func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) (
if resp.Error != "" {
return nil, errors.New(resp.Error)
}
- return util.DeserializeSessionDescription(resp.Answer)
+ answer, err := util.DeserializeSessionDescription(resp.Answer)
+ if err == nil && bc.hack {
+ if util.PionDetected(answer.SDP) {
+ return nil, errors.New("Hack: Pion detected.")
+ }
+ answer = &webrtc.SessionDescription{
+ Type: answer.Type,
+ SDP: util.ChangeSetup(answer.SDP, false),
+ }
+ //log.Println("SDP answer:", answer.SDP)
+ }
+ return answer, err
}
// SetNATType sets the NAT type of the client so we can send it to the WebRTC broker.
diff --git a/client/lib/snowflake.go b/client/lib/snowflake.go
index 7231d86..af4fff1 100644
--- a/client/lib/snowflake.go
+++ b/client/lib/snowflake.go
@@ -106,6 +106,7 @@ type ClientConfig struct {
// BridgeFingerprint is the fingerprint of the bridge that the client will eventually
// connect to, as specified in the Bridge line of the torrc.
BridgeFingerprint string
+ PoC bool
}
// NewSnowflakeClient creates a new Snowflake transport client that can spawn multiple
diff --git a/client/snowflake.go b/client/snowflake.go
index 2cb6549..ee00c43 100644
--- a/client/snowflake.go
+++ b/client/snowflake.go
@@ -155,6 +155,7 @@ func main() {
logToStateDir := flag.Bool("log-to-state-dir", false, "resolve the log file relative to tor's pt state dir")
keepLocalAddresses := flag.Bool("keep-local-addresses", false, "keep local LAN address ICE candidates")
unsafeLogging := flag.Bool("unsafe-logging", false, "prevent logs from being scrubbed")
+ hack := flag.Bool("hack", false, "DTLS-connect to non-Pion proxy")
max := flag.Int("max", DefaultSnowflakeCapacity,
"capacity for number of multiplexed WebRTC peers")
@@ -203,6 +204,7 @@ func main() {
FrontDomain: *frontDomain,
ICEAddresses: iceAddresses,
KeepLocalAddresses: *keepLocalAddresses || *oldKeepLocalAddresses,
+ PoC: *hack,
Max: *max,
}
diff --git a/common/util/util.go b/common/util/util.go
index 00f7302..42bfd21 100644
--- a/common/util/util.go
+++ b/common/util/util.go
@@ -2,6 +2,7 @@ package util
import (
"encoding/json"
+ "strings"
"errors"
"net"
@@ -97,3 +98,53 @@ func StripLocalAddresses(str string) string {
}
return string(bts)
}
+
+func ChangeSetup(str string, client bool) string {
+ var desc sdp.SessionDescription
+ err := desc.Unmarshal([]byte(str))
+ if err != nil {
+ return str
+ }
+ for _, m := range desc.MediaDescriptions {
+ attrs := make([]sdp.Attribute, 0)
+ for _, a := range m.Attributes {
+ if a.Key == sdp.AttrKeyConnectionSetup {
+ if client {
+ a.Value = sdp.ConnectionRoleActive.String()
+ } else {
+ a.Value = sdp.ConnectionRolePassive.String()
+ }
+ }
+ attrs = append(attrs, a)
+ }
+ m.Attributes = attrs
+ }
+ bts, err := desc.Marshal()
+ if err != nil {
+ return str
+ }
+ return string(bts)
+}
+
+func PionDetected(str string) bool {
+ var pionMediaNameStr string = "application 9 UDP/DTLS/SCTP webrtc-datachannel"
+ var pionOriginStart string = "- "
+ var desc sdp.SessionDescription
+ err := desc.Unmarshal([]byte(str))
+ if err != nil {
+ return false
+ }
+ pionOrigin := strings.HasPrefix(desc.Origin.String(), pionOriginStart)
+ for _, a := range desc.Attributes {
+ if a.Key == sdp.AttrKeySendRecv || a.Key == sdp.AttrKeyMsidSemantic {
+ return false
+ }
+ }
+ for _, m := range desc.MediaDescriptions {
+ pionMediaName := m.MediaName.String() == pionMediaNameStr
+ if pionMediaName && pionOrigin {
+ return true
+ }
+ }
+ return false
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment