[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [snowflake/master] Implement NAT discover for go standalone proxies
commit f6cf9a453b0cae189e5ad6b25d57241fe418de91
Author: Cecylia Bocovich <cohosh@xxxxxxxxxxxxxx>
Date: Tue Jun 16 17:10:56 2020 -0400
Implement NAT discover for go standalone proxies
---
broker/broker.go | 2 +-
common/messages/proxy.go | 30 +++++++++++++++++++-----------
common/messages/proxy_test.go | 26 ++++++++++++++++++++++----
proxy/snowflake.go | 36 +++++++++++++++++++++++++++++++++++-
4 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/broker/broker.go b/broker/broker.go
index d9ef111..2d3cd4b 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -170,7 +170,7 @@ func proxyPolls(ctx *BrokerContext, w http.ResponseWriter, r *http.Request) {
return
}
- sid, proxyType, err := messages.DecodePollRequest(body)
+ sid, proxyType, _, err := messages.DecodePollRequest(body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
diff --git a/common/messages/proxy.go b/common/messages/proxy.go
index 89dd43c..923189b 100644
--- a/common/messages/proxy.go
+++ b/common/messages/proxy.go
@@ -9,15 +9,16 @@ import (
"strings"
)
-const version = "1.1"
+const version = "1.2"
-/* Version 1.1 specification:
+/* Version 1.2 specification:
== ProxyPollRequest ==
{
Sid: [generated session id of proxy],
- Version: 1.1,
+ Version: 1.2,
Type: ["badge"|"webext"|"standalone"]
+ NAT: ["unknown"|"restricted"|"unrestricted"]
}
== ProxyPollResponse ==
@@ -44,7 +45,7 @@ HTTP 400 BadRequest
== ProxyAnswerRequest ==
{
Sid: [generated session id of proxy],
- Version: 1.1,
+ Version: 1.2,
Answer:
{
type: answer,
@@ -76,37 +77,44 @@ type ProxyPollRequest struct {
Sid string
Version string
Type string
+ NAT string
}
-func EncodePollRequest(sid string, proxyType string) ([]byte, error) {
+func EncodePollRequest(sid string, proxyType string, natType string) ([]byte, error) {
return json.Marshal(ProxyPollRequest{
Sid: sid,
Version: version,
Type: proxyType,
+ NAT: natType,
})
}
// Decodes a poll message from a snowflake proxy and returns the
// sid and proxy type of the proxy on success and an error if it failed
-func DecodePollRequest(data []byte) (string, string, error) {
+func DecodePollRequest(data []byte) (string, string, string, error) {
var message ProxyPollRequest
err := json.Unmarshal(data, &message)
if err != nil {
- return "", "", err
+ return "", "", "", err
}
majorVersion := strings.Split(message.Version, ".")[0]
if majorVersion != "1" {
- return "", "", fmt.Errorf("using unknown version")
+ return "", "", "", fmt.Errorf("using unknown version")
}
// Version 1.x requires an Sid
if message.Sid == "" {
- return "", "", fmt.Errorf("no supplied session id")
+ return "", "", "", fmt.Errorf("no supplied session id")
}
- return message.Sid, message.Type, nil
+ natType := message.NAT
+ if natType == "" {
+ natType = "unknown"
+ }
+
+ return message.Sid, message.Type, natType, nil
}
type ProxyPollResponse struct {
@@ -159,7 +167,7 @@ type ProxyAnswerRequest struct {
func EncodeAnswerRequest(answer string, sid string) ([]byte, error) {
return json.Marshal(ProxyAnswerRequest{
- Version: "1.1",
+ Version: version,
Sid: sid,
Answer: answer,
})
diff --git a/common/messages/proxy_test.go b/common/messages/proxy_test.go
index 1570d4f..3aa67fb 100644
--- a/common/messages/proxy_test.go
+++ b/common/messages/proxy_test.go
@@ -13,6 +13,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
for _, test := range []struct {
sid string
proxyType string
+ natType string
data string
err error
}{
@@ -20,6 +21,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
//Version 1.0 proxy message
"ymbcCMto7KHNGYlp",
"",
+ "unknown",
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`,
nil,
},
@@ -27,44 +29,59 @@ func TestDecodeProxyPollRequest(t *testing.T) {
//Version 1.1 proxy message
"ymbcCMto7KHNGYlp",
"standalone",
+ "unknown",
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.1","Type":"standalone"}`,
nil,
},
+ {
+ //Version 1.2 proxy message
+ "ymbcCMto7KHNGYlp",
+ "standalone",
+ "restricted",
+ `{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted"}`,
+ nil,
+ },
{
//Version 0.X proxy message:
"",
"",
- "ymbcCMto7KHNGYlp",
+ "",
+ "",
&json.SyntaxError{},
},
{
+ "",
"",
"",
`{"Sid":"ymbcCMto7KHNGYlp"}`,
fmt.Errorf(""),
},
{
+ "",
"",
"",
"{}",
fmt.Errorf(""),
},
{
+ "",
"",
"",
`{"Version":"1.0"}`,
fmt.Errorf(""),
},
{
+ "",
"",
"",
`{"Version":"2.0"}`,
fmt.Errorf(""),
},
} {
- sid, proxyType, err := DecodePollRequest([]byte(test.data))
+ sid, proxyType, natType, err := DecodePollRequest([]byte(test.data))
So(sid, ShouldResemble, test.sid)
So(proxyType, ShouldResemble, test.proxyType)
+ So(natType, ShouldResemble, test.natType)
So(err, ShouldHaveSameTypeAs, test.err)
}
@@ -73,11 +90,12 @@ func TestDecodeProxyPollRequest(t *testing.T) {
func TestEncodeProxyPollRequests(t *testing.T) {
Convey("Context", t, func() {
- b, err := EncodePollRequest("ymbcCMto7KHNGYlp", "standalone")
+ b, err := EncodePollRequest("ymbcCMto7KHNGYlp", "standalone", "unknown")
So(err, ShouldEqual, nil)
- sid, proxyType, err := DecodePollRequest(b)
+ sid, proxyType, natType, err := DecodePollRequest(b)
So(sid, ShouldEqual, "ymbcCMto7KHNGYlp")
So(proxyType, ShouldEqual, "standalone")
+ So(natType, ShouldEqual, "unknown")
So(err, ShouldEqual, nil)
})
}
diff --git a/proxy/snowflake.go b/proxy/snowflake.go
index 4877e6f..ac67748 100644
--- a/proxy/snowflake.go
+++ b/proxy/snowflake.go
@@ -19,6 +19,7 @@ import (
"time"
"git.torproject.org/pluggable-transports/snowflake.git/common/messages"
+ "git.torproject.org/pluggable-transports/snowflake.git/common/nat"
"git.torproject.org/pluggable-transports/snowflake.git/common/safelog"
"git.torproject.org/pluggable-transports/snowflake.git/common/util"
"git.torproject.org/pluggable-transports/snowflake.git/common/websocketconn"
@@ -30,6 +31,11 @@ const defaultBrokerURL = "https://snowflake-broker.bamsoftware.com/"
const defaultRelayURL = "wss://snowflake.bamsoftware.com/"
const defaultSTUNURL = "stun:stun.l.google.com:19302"
const pollInterval = 5 * time.Second
+const (
+ NATUnknown = "unknown"
+ NATRestricted = "restricted"
+ NATUnrestricted = "unrestricted"
+)
//amount of time after sending an SDP answer before the proxy assumes the
//client is not going to connect
@@ -40,6 +46,8 @@ const readLimit = 100000 //Maximum number of bytes to be read from an HTTP reque
var broker *Broker
var relayURL string
+var currentNATType = NATUnknown
+
const (
sessionIDLength = 16
)
@@ -174,7 +182,7 @@ func (b *Broker) pollOffer(sid string) *webrtc.SessionDescription {
timeOfNextPoll = now
}
- body, err := messages.EncodePollRequest(sid, "standalone")
+ body, err := messages.EncodePollRequest(sid, "standalone", currentNATType)
if err != nil {
log.Printf("Error encoding poll message: %s", err.Error())
return nil
@@ -485,9 +493,35 @@ func main() {
tokens <- true
}
+ // determine NAT type before polling
+ updateNATType(config.ICEServers)
+ log.Printf("NAT type: %s", currentNATType)
+
for {
getToken()
sessionID := genSessionID()
runSession(sessionID)
}
}
+
+// use provided STUN server(s) to determine NAT type
+func updateNATType(servers []webrtc.ICEServer) {
+
+ var restrictedNAT bool
+ var err error
+ for _, server := range servers {
+ addr := strings.TrimPrefix(server.URLs[0], "stun:")
+ restrictedNAT, err = nat.CheckIfRestrictedNAT(addr)
+ if err == nil {
+ if restrictedNAT {
+ currentNATType = NATRestricted
+ } else {
+ currentNATType = NATUnrestricted
+ }
+ break
+ }
+ }
+ if err != nil {
+ currentNATType = NATUnknown
+ }
+}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits