Created
August 4, 2022 16:17
-
-
Save xiaokangwang/5cd4437d087b0159146b0cb9d09aa9a5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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