Verified Commit 613ceaf9 authored by shelikhoo's avatar shelikhoo
Browse files

Add RelayURL and AllowedRelayPattern to snowflake signaling

parent 38f0e00e
......@@ -17,90 +17,103 @@ func TestDecodeProxyPollRequest(t *testing.T) {
clients int
data string
err error
acceptedRelayPattern string
}{
{
//Version 1.0 proxy message
"ymbcCMto7KHNGYlp",
"unknown",
"unknown",
0,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`,
nil,
sid: "ymbcCMto7KHNGYlp",
proxyType: "unknown",
natType: "unknown",
clients: 0,
data: `{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`,
err: nil,
},
{
//Version 1.1 proxy message
"ymbcCMto7KHNGYlp",
"standalone",
"unknown",
0,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.1","Type":"standalone"}`,
nil,
sid: "ymbcCMto7KHNGYlp",
proxyType: "standalone",
natType: "unknown",
clients: 0,
data: `{"Sid":"ymbcCMto7KHNGYlp","Version":"1.1","Type":"standalone"}`,
err: nil,
},
{
//Version 1.2 proxy message
"ymbcCMto7KHNGYlp",
"standalone",
"restricted",
0,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted"}`,
nil,
sid: "ymbcCMto7KHNGYlp",
proxyType: "standalone",
natType: "restricted",
clients: 0,
data: `{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted"}`,
err: nil,
},
{
//Version 1.2 proxy message with clients
"ymbcCMto7KHNGYlp",
"standalone",
"restricted",
24,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted","Clients":24}`,
nil,
sid: "ymbcCMto7KHNGYlp",
proxyType: "standalone",
natType: "restricted",
clients: 24,
data: `{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted","Clients":24}`,
err: nil,
},
{
//Version 1.3 proxy message with clients and proxyURL
sid: "ymbcCMto7KHNGYlp",
proxyType: "standalone",
natType: "restricted",
clients: 24,
acceptedRelayPattern: "snowfalke.torproject.org",
data: `{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted","Clients":24, "AcceptedRelayPattern":"snowfalke.torproject.org"}`,
err: nil,
},
{
//Version 0.X proxy message:
"",
"",
"",
0,
"",
&json.SyntaxError{},
sid: "",
proxyType: "",
natType: "",
clients: 0,
data: "",
err: &json.SyntaxError{},
},
{
"",
"",
"",
0,
`{"Sid":"ymbcCMto7KHNGYlp"}`,
fmt.Errorf(""),
sid: "",
proxyType: "",
natType: "",
clients: 0,
data: `{"Sid":"ymbcCMto7KHNGYlp"}`,
err: fmt.Errorf(""),
},
{
"",
"",
"",
0,
"{}",
fmt.Errorf(""),
sid: "",
proxyType: "",
natType: "",
clients: 0,
data: "{}",
err: fmt.Errorf(""),
},
{
"",
"",
"",
0,
`{"Version":"1.0"}`,
fmt.Errorf(""),
sid: "",
proxyType: "",
natType: "",
clients: 0,
data: `{"Version":"1.0"}`,
err: fmt.Errorf(""),
},
{
"",
"",
"",
0,
`{"Version":"2.0"}`,
fmt.Errorf(""),
sid: "",
proxyType: "",
natType: "",
clients: 0,
data: `{"Version":"2.0"}`,
err: fmt.Errorf(""),
},
} {
sid, proxyType, natType, clients, err := DecodeProxyPollRequest([]byte(test.data))
sid, proxyType, natType, clients, relayPattern, err := DecodeProxyPollRequestWithRelayPrefix([]byte(test.data))
So(sid, ShouldResemble, test.sid)
So(proxyType, ShouldResemble, test.proxyType)
So(natType, ShouldResemble, test.natType)
So(clients, ShouldEqual, test.clients)
So(relayPattern, ShouldResemble, test.acceptedRelayPattern)
So(err, ShouldHaveSameTypeAs, test.err)
}
......@@ -123,34 +136,42 @@ func TestEncodeProxyPollRequests(t *testing.T) {
func TestDecodeProxyPollResponse(t *testing.T) {
Convey("Context", t, func() {
for _, test := range []struct {
offer string
data string
err error
offer string
data string
relayURL string
err error
}{
{
"fake offer",
`{"Status":"client match","Offer":"fake offer","NAT":"unknown"}`,
nil,
offer: "fake offer",
data: `{"Status":"client match","Offer":"fake offer","NAT":"unknown"}`,
err: nil,
},
{
"",
`{"Status":"no match"}`,
nil,
offer: "fake offer",
data: `{"Status":"client match","Offer":"fake offer","NAT":"unknown", "RelayURL":"wss://snowflake.torproject.org/proxy"}`,
relayURL: "wss://snowflake.torproject.org/proxy",
err: nil,
},
{
"",
`{"Status":"client match"}`,
fmt.Errorf("no supplied offer"),
offer: "",
data: `{"Status":"no match"}`,
err: nil,
},
{
"",
`{"Test":"test"}`,
fmt.Errorf(""),
offer: "",
data: `{"Status":"client match"}`,
err: fmt.Errorf("no supplied offer"),
},
{
offer: "",
data: `{"Test":"test"}`,
err: fmt.Errorf(""),
},
} {
offer, _, err := DecodePollResponse([]byte(test.data))
offer, _, relayURL, err := DecodePollResponseWithRelayURL([]byte(test.data))
So(err, ShouldHaveSameTypeAs, test.err)
So(offer, ShouldResemble, test.offer)
So(relayURL, ShouldResemble, test.relayURL)
}
})
......
......@@ -5,6 +5,7 @@ package messages
import (
"encoding/json"
"errors"
"fmt"
"strings"
......@@ -23,6 +24,8 @@ var KnownProxyTypes = map[string]bool{
"iptproxy": true,
}
var ErrExtraInfo = errors.New("client sent extra info")
/* Version 1.2 specification:
== ProxyPollRequest ==
......@@ -93,22 +96,39 @@ type ProxyPollRequest struct {
Type string
NAT string
Clients int
AcceptedRelayPattern string
}
func EncodeProxyPollRequest(sid string, proxyType string, natType string, clients int) ([]byte, error) {
return EncodeProxyPollRequestWithRelayPrefix(sid, proxyType, natType, clients, "")
}
func EncodeProxyPollRequestWithRelayPrefix(sid string, proxyType string, natType string, clients int, relayPattern string) ([]byte, error) {
return json.Marshal(ProxyPollRequest{
Sid: sid,
Version: version,
Type: proxyType,
NAT: natType,
Clients: clients,
Sid: sid,
Version: version,
Type: proxyType,
NAT: natType,
Clients: clients,
AcceptedRelayPattern: relayPattern,
})
}
func DecodeProxyPollRequest(data []byte) (sid string, proxyType string, natType string, clients int, err error) {
var relayPrefix string
sid, proxyType, natType, clients, relayPrefix, err = DecodeProxyPollRequestWithRelayPrefix(data)
if relayPrefix != "" {
return "", "", "", 0, ErrExtraInfo
}
return
}
// Decodes a poll message from a snowflake proxy and returns the
// sid, proxy type, nat type and clients of the proxy on success
// and an error if it failed
func DecodeProxyPollRequest(data []byte) (sid string, proxyType string, natType string, clients int, err error) {
func DecodeProxyPollRequestWithRelayPrefix(data []byte) (
sid string, proxyType string, natType string, clients int, relayPrefix string, err error) {
var message ProxyPollRequest
err = json.Unmarshal(data, &message)
......@@ -145,21 +165,28 @@ func DecodeProxyPollRequest(data []byte) (sid string, proxyType string, natType
message.Type = ProxyUnknown
}
return message.Sid, message.Type, message.NAT, message.Clients, nil
return message.Sid, message.Type, message.NAT, message.Clients, message.AcceptedRelayPattern, nil
}
type ProxyPollResponse struct {
Status string
Offer string
NAT string
RelayURL string
}
func EncodePollResponse(offer string, success bool, natType string) ([]byte, error) {
return EncodePollResponseWithRelayURL(offer, success, natType, "")
}
func EncodePollResponseWithRelayURL(offer string, success bool, natType, relayURL string) ([]byte, error) {
if success {
return json.Marshal(ProxyPollResponse{
Status: "client match",
Offer: offer,
NAT: natType,
Status: "client match",
Offer: offer,
NAT: natType,
RelayURL: relayURL,
})
}
......@@ -167,23 +194,30 @@ func EncodePollResponse(offer string, success bool, natType string) ([]byte, err
Status: "no match",
})
}
func DecodePollResponse(data []byte) (string, string, error) {
offer, natType, relayURL, err := DecodePollResponseWithRelayURL(data)
if relayURL != "" {
return "", "", ErrExtraInfo
}
return offer, natType, err
}
// Decodes a poll response from the broker and returns an offer and the client's NAT type
// If there is a client match, the returned offer string will be non-empty
func DecodePollResponse(data []byte) (string, string, error) {
func DecodePollResponseWithRelayURL(data []byte) (string, string, string, error) {
var message ProxyPollResponse
err := json.Unmarshal(data, &message)
if err != nil {
return "", "", err
return "", "", "", err
}
if message.Status == "" {
return "", "", fmt.Errorf("received invalid data")
return "", "", "", fmt.Errorf("received invalid data")
}
if message.Status == "client match" {
if message.Offer == "" {
return "", "", fmt.Errorf("no supplied offer")
return "", "", "", fmt.Errorf("no supplied offer")
}
} else {
message.Offer = ""
......@@ -194,7 +228,7 @@ func DecodePollResponse(data []byte) (string, string, error) {
natType = "unknown"
}
return message.Offer, natType, nil
return message.Offer, natType, message.RelayURL, nil
}
type ProxyAnswerRequest struct {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment