This is an automated email from the git hooks/post-receive script.
itchyonion pushed a change to branch main in repository pluggable-transports/snowflake.
from f723cf5 Merge remote-tracking branch 'gitlab/main' new 8e5ea82 Add a scanner error check to ClusterCounter.Count. new 07b5f07 Validate SDP offers and answers new 255cee6 Broker: soften non-critical log from error to warning new 6c43180 Broker: update unit tests after adding SDP validation new 88608ad Broker: add warning log when proxy couldn't mach with client
The 5 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference.
Summary of changes: broker/http.go | 29 ++++- broker/ipc.go | 6 +- broker/snowflake-broker_test.go | 187 +++++++++++++++++++++++---------- client/lib/webrtc.go | 23 ++-- common/ipsetsink/sinkcluster/reader.go | 4 + proxy/lib/snowflake.go | 17 ++- 6 files changed, 195 insertions(+), 71 deletions(-)
This is an automated email from the git hooks/post-receive script.
itchyonion pushed a commit to branch main in repository pluggable-transports/snowflake.
commit 07b5f07452d7b04c7ac2cd70b72115d61ab1e678 Author: itchyonion itchyonion@torproject.org AuthorDate: Tue Mar 14 12:39:57 2023 -0700
Validate SDP offers and answers --- broker/http.go | 29 +++++++++++++++++++++++++++-- client/lib/webrtc.go | 23 +++++++++++++++-------- proxy/lib/snowflake.go | 17 ++++++++++++++--- 3 files changed, 56 insertions(+), 13 deletions(-)
diff --git a/broker/http.go b/broker/http.go index 2f81f1d..32f6a71 100644 --- a/broker/http.go +++ b/broker/http.go @@ -1,7 +1,9 @@ package main
import ( + "bytes" "errors" + "fmt" "io" "io/ioutil" "log" @@ -137,10 +139,17 @@ func clientOffers(i *IPC, w http.ResponseWriter, r *http.Request) { return }
+ err = validateSDP(body) + if err != nil { + log.Println("Error client SDP: ", err.Error()) + w.WriteHeader(http.StatusBadRequest) + return + } + // Handle the legacy version // // We support two client message formats. The legacy format is for backwards - // combatability and relies heavily on HTTP headers and status codes to convey + // compatability and relies heavily on HTTP headers and status codes to convey // information. isLegacy := false if len(body) > 0 && body[0] == '{' { @@ -197,7 +206,7 @@ func clientOffers(i *IPC, w http.ResponseWriter, r *http.Request) { }
/* -Expects snowflake proxes which have previously successfully received +Expects snowflake proxies which have previously successfully received an offer from proxyHandler to respond with an answer in an HTTP POST, which the broker will pass back to the original client. */ @@ -209,6 +218,13 @@ func proxyAnswers(i *IPC, w http.ResponseWriter, r *http.Request) { return }
+ err = validateSDP(body) + if err != nil { + log.Println("Error proxy SDP: ", err.Error()) + w.WriteHeader(http.StatusBadRequest) + return + } + arg := messages.Arg{ Body: body, RemoteAddr: "", @@ -233,3 +249,12 @@ func proxyAnswers(i *IPC, w http.ResponseWriter, r *http.Request) { log.Printf("proxyAnswers unable to write answer response with error: %v", err) } } + +func validateSDP(SDP []byte) error { + // TODO: more validation likely needed + if !bytes.Contains(SDP, []byte("a=candidate")) { + return fmt.Errorf("SDP contains no candidate") + } + + return nil +} diff --git a/client/lib/webrtc.go b/client/lib/webrtc.go index d12688e..9afe1a4 100644 --- a/client/lib/webrtc.go +++ b/client/lib/webrtc.go @@ -4,8 +4,10 @@ import ( "crypto/rand" "encoding/hex" "errors" + "fmt" "io" "log" + "strings" "sync" "time"
@@ -143,10 +145,10 @@ func (c *WebRTCPeer) checkForStaleness(timeout time.Duration) { } }
+// connect does the bulk of the work: gather ICE candidates, send the SDP offer to broker, +// receive an answer from broker, and wait for data channel to open func (c *WebRTCPeer) connect(config *webrtc.Configuration, broker *BrokerChannel) error { log.Println(c.id, " connecting...") - // TODO: When go-webrtc is more stable, it's possible that a new - // PeerConnection won't need to be re-prepared each time. err := c.preparePeerConnection(config) localDescription := c.pc.LocalDescription() c.eventsLogger.OnNewSnowflakeEvent(event.EventOnOfferCreated{ @@ -187,7 +189,7 @@ func (c *WebRTCPeer) connect(config *webrtc.Configuration, broker *BrokerChannel }
// preparePeerConnection creates a new WebRTC PeerConnection and returns it -// after ICE candidate gathering is complete.. +// after non-trickle ICE candidate gathering is complete. func (c *WebRTCPeer) preparePeerConnection(config *webrtc.Configuration) error { var err error s := webrtc.SettingEngine{} @@ -240,10 +242,8 @@ func (c *WebRTCPeer) preparePeerConnection(config *webrtc.Configuration) error { }) c.transport = dc c.open = make(chan struct{}) - log.Println("WebRTC: DataChannel created.") + log.Println("WebRTC: DataChannel created")
- // Allow candidates to accumulate until ICEGatheringStateComplete. - done := webrtc.GatheringCompletePromise(c.pc) offer, err := c.pc.CreateOffer(nil) // TODO: Potentially timeout and retry if ICE isn't working. if err != nil { @@ -252,16 +252,23 @@ func (c *WebRTCPeer) preparePeerConnection(config *webrtc.Configuration) error { return err } log.Println("WebRTC: Created offer") + + // Allow candidates to accumulate until ICEGatheringStateComplete. + done := webrtc.GatheringCompletePromise(c.pc) + // Start gathering candidates err = c.pc.SetLocalDescription(offer) if err != nil { - log.Println("Failed to prepare offer", err) + log.Println("Failed to apply offer", err) c.pc.Close() return err } log.Println("WebRTC: Set local description")
<-done // Wait for ICE candidate gathering to complete. - log.Println("WebRTC: PeerConnection created.") + + if !strings.Contains(c.pc.LocalDescription().SDP, "\na=candidate:") { + return fmt.Errorf("SDP offer contains no candidate") + } return nil }
diff --git a/proxy/lib/snowflake.go b/proxy/lib/snowflake.go index 92d02dd..1dceb42 100644 --- a/proxy/lib/snowflake.go +++ b/proxy/lib/snowflake.go @@ -250,6 +250,8 @@ func (s *SignalingServer) pollOffer(sid string, proxyType string, acceptedRelayP return nil, "" }
+// sendAnswer encodes an SDP answer, sends it to the broker +// and wait for its response func (s *SignalingServer) sendAnswer(sid string, pc *webrtc.PeerConnection) error { ld := pc.LocalDescription() if !s.keepLocalAddresses { @@ -485,6 +487,10 @@ func (sf *SnowflakeProxy) makePeerConnectionFromOffer(sdp *webrtc.SessionDescrip
// Wait for ICE candidate gathering to complete <-done + + if !strings.Contains(pc.LocalDescription().SDP, "\na=candidate:") { + return nil, fmt.Errorf("SDP answer contains no candidate") + } log.Printf("Answer: \n\t%s", strings.ReplaceAll(pc.LocalDescription().SDP, "\n", "\n\t"))
return pc, nil @@ -524,15 +530,16 @@ func (sf *SnowflakeProxy) makeNewPeerConnection(config webrtc.Configuration, pc.Close() return nil, err } - log.Println("Probetest: Creating offer") + log.Println("Probetest: Created Offer")
// As of v3.0.0, pion-webrtc uses trickle ICE by default. // We have to wait for candidate gathering to complete // before we send the offer done := webrtc.GatheringCompletePromise(pc) + // start the gathering of ICE candidates err = pc.SetLocalDescription(offer) if err != nil { - log.Println("Failed to prepare offer", err) + log.Println("Failed to apply offer", err) pc.Close() return nil, err } @@ -540,6 +547,11 @@ func (sf *SnowflakeProxy) makeNewPeerConnection(config webrtc.Configuration,
// Wait for ICE candidate gathering to complete <-done + + if !strings.Contains(pc.LocalDescription().SDP, "\na=candidate:") { + return nil, fmt.Errorf("Probetest SDP offer contains no candidate") + } + return pc, nil }
@@ -701,7 +713,6 @@ func (sf *SnowflakeProxy) checkNATType(config webrtc.Configuration, probeURL str log.Printf("Error parsing url: %s", err.Error()) }
- // create offer used for probetest dataChan := make(chan struct{}) pc, err := sf.makeNewPeerConnection(config, dataChan) if err != nil {
This is an automated email from the git hooks/post-receive script.
itchyonion pushed a commit to branch main in repository pluggable-transports/snowflake.
commit 255cee69edcc3d5283ed0a796c080d488fa34983 Author: itchyonion itchyonion@torproject.org AuthorDate: Wed Mar 22 14:35:52 2023 -0700
Broker: soften non-critical log from error to warning --- broker/ipc.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/broker/ipc.go b/broker/ipc.go index 14db4d8..f9984c4 100644 --- a/broker/ipc.go +++ b/broker/ipc.go @@ -4,11 +4,12 @@ import ( "container/heap" "encoding/hex" "fmt" - "git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint" "log" "net" "time"
+ "git.torproject.org/pluggable-transports/snowflake.git/v2/common/bridgefingerprint" + "git.torproject.org/pluggable-transports/snowflake.git/v2/common/messages" "github.com/prometheus/client_golang/prometheus" ) @@ -102,7 +103,7 @@ func (i *IPC) ProxyPolls(arg messages.Arg, response *[]byte) error { // Log geoip stats remoteIP, _, err := net.SplitHostPort(arg.RemoteAddr) if err != nil { - log.Println("Error processing proxy IP: ", err.Error()) + log.Println("Warning: cannot process proxy IP: ", err.Error()) } else { i.ctx.metrics.lock.Lock() i.ctx.metrics.UpdateCountryStats(remoteIP, proxyType, natType)
This is an automated email from the git hooks/post-receive script.
itchyonion pushed a commit to branch main in repository pluggable-transports/snowflake.
commit 6c431800b06601a25c3372ebcd3da53cdbac602d Author: itchyonion itchyonion@torproject.org AuthorDate: Wed Mar 22 14:36:39 2023 -0700
Broker: update unit tests after adding SDP validation --- broker/snowflake-broker_test.go | 187 ++++++++++++++++++++++++++++------------ 1 file changed, 131 insertions(+), 56 deletions(-)
diff --git a/broker/snowflake-broker_test.go b/broker/snowflake-broker_test.go index a72f3ac..5eafd4a 100644 --- a/broker/snowflake-broker_test.go +++ b/broker/snowflake-broker_test.go @@ -4,6 +4,7 @@ import ( "bytes" "container/heap" "encoding/hex" + "fmt" "io" "io/ioutil" "log" @@ -15,6 +16,7 @@ import ( "time"
"git.torproject.org/pluggable-transports/snowflake.git/v2/common/amp" + "git.torproject.org/pluggable-transports/snowflake.git/v2/common/messages" . "github.com/smartystreets/goconvey/convey" )
@@ -26,6 +28,51 @@ func NullLogger() *log.Logger {
var promOnce sync.Once
+var ( + sdp = "v=0\r\n" + + "o=- 123456789 987654321 IN IP4 0.0.0.0\r\n" + + "s=-\r\n" + + "t=0 0\r\n" + + "a=fingerprint:sha-256 12:34\r\n" + + "a=extmap-allow-mixed\r\n" + + "a=group:BUNDLE 0\r\n" + + "m=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\n" + + "c=IN IP4 0.0.0.0\r\n" + + "a=setup:actpass\r\n" + + "a=mid:0\r\n" + + "a=sendrecv\r\n" + + "a=sctp-port:5000\r\n" + + "a=ice-ufrag:CoVEaiFXRGVzshXG\r\n" + + "a=ice-pwd:aOrOZXraTfFKzyeBxIXYYKjSgRVPGhUx\r\n" + + "a=candidate:1000 1 udp 2000 8.8.8.8 3000 typ host\r\n" + + "a=end-of-candidates\r\n" + + sid = "ymbcCMto7KHNGYlp" +) + +func createClientOffer(sdp, nat, fingerprint string) (*bytes.Reader, error) { + clientRequest := &messages.ClientPollRequest{ + Offer: sdp, + NAT: nat, + Fingerprint: fingerprint, + } + encOffer, err := clientRequest.EncodeClientPollRequest() + if err != nil { + return nil, err + } + offer := bytes.NewReader(encOffer) + return offer, nil +} + +func createProxyAnswer(sdp, sid string) (*bytes.Reader, error) { + proxyRequest, err := messages.EncodeAnswerRequest(sdp, sid) + if err != nil { + return nil, err + } + answer := bytes.NewReader(proxyRequest) + return answer, nil +} + func decodeAMPArmorToString(r io.Reader) (string, error) { dec, err := amp.NewArmorDecoder(r) if err != nil { @@ -86,11 +133,18 @@ func TestBroker(t *testing.T) {
Convey("Responds to HTTP client offers...", func() { w := httptest.NewRecorder() - data := bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "unknown"}")) + data, err := createClientOffer(sdp, NATUnknown, "") r, err := http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil)
+ Convey("with HTTP Bad Request when client offer contains invalid SDP", func() { + data, err = createClientOffer("fake", NATUnknown, "") + invalidRequest, err := http.NewRequest("POST", "snowflake.broker/client", data) + So(err, ShouldBeNil) + clientOffers(i, w, invalidRequest) + So(w.Code, ShouldEqual, http.StatusBadRequest) + }) + Convey("with error when no snowflakes are available.", func() { clientOffers(i, w, r) So(w.Code, ShouldEqual, http.StatusOK) @@ -100,16 +154,16 @@ func TestBroker(t *testing.T) { Convey("with a proxy answer if available.", func() { done := make(chan bool) // Prepare a fake proxy to respond with. - snowflake := ctx.AddSnowflake("fake", "", NATUnrestricted, 0) + snowflake := ctx.AddSnowflake("test", "", NATUnrestricted, 0) go func() { clientOffers(i, w, r) done <- true }() offer := <-snowflake.offerChannel - So(offer.sdp, ShouldResemble, []byte("fake")) - snowflake.answerChannel <- "fake answer" + So(offer.sdp, ShouldResemble, []byte(sdp)) + snowflake.answerChannel <- "test answer" <-done - So(w.Body.String(), ShouldEqual, `{"answer":"fake answer"}`) + So(w.Body.String(), ShouldEqual, `{"answer":"test answer"}`) So(w.Code, ShouldEqual, http.StatusOK) })
@@ -125,7 +179,7 @@ func TestBroker(t *testing.T) { done <- true }() offer := <-snowflake.offerChannel - So(offer.sdp, ShouldResemble, []byte("fake")) + So(offer.sdp, ShouldResemble, []byte(sdp)) <-done So(w.Code, ShouldEqual, http.StatusOK) So(w.Body.String(), ShouldEqual, `{"error":"timed out waiting for answer!"}`) @@ -134,11 +188,20 @@ func TestBroker(t *testing.T) {
Convey("Responds to HTTP legacy client offers...", func() { w := httptest.NewRecorder() - data := bytes.NewReader([]byte("{test}")) - r, err := http.NewRequest("POST", "snowflake.broker/client", data) + // legacy offer starts with { + offer := bytes.NewReader([]byte(fmt.Sprintf(`{%v}`, sdp))) + r, err := http.NewRequest("POST", "snowflake.broker/client", offer) So(err, ShouldBeNil) r.Header.Set("Snowflake-NAT-TYPE", "restricted")
+ Convey("with HTTP Bad Request when client offer contains invalid SDP", func() { + invalidOffer := bytes.NewReader([]byte("{test}")) + invalidRequest, err := http.NewRequest("POST", "snowflake.broker/client", invalidOffer) + So(err, ShouldBeNil) + clientOffers(i, w, invalidRequest) + So(w.Code, ShouldEqual, http.StatusBadRequest) + }) + Convey("with 503 when no snowflakes are available.", func() { clientOffers(i, w, r) So(w.Code, ShouldEqual, http.StatusServiceUnavailable) @@ -154,7 +217,7 @@ func TestBroker(t *testing.T) { done <- true }() offer := <-snowflake.offerChannel - So(offer.sdp, ShouldResemble, []byte("{test}")) + So(offer.sdp, ShouldResemble, []byte(fmt.Sprintf(`{%v}`, sdp))) snowflake.answerChannel <- "fake answer" <-done So(w.Body.String(), ShouldEqual, "fake answer") @@ -173,7 +236,7 @@ func TestBroker(t *testing.T) { done <- true }() offer := <-snowflake.offerChannel - So(offer.sdp, ShouldResemble, []byte("{test}")) + So(offer.sdp, ShouldResemble, []byte(fmt.Sprintf(`{%v}`, sdp))) <-done So(w.Code, ShouldEqual, http.StatusGatewayTimeout) }) @@ -281,9 +344,11 @@ func TestBroker(t *testing.T) {
Convey("Responds to proxy answers...", func() { done := make(chan bool) - s := ctx.AddSnowflake("test", "", NATUnrestricted, 0) + s := ctx.AddSnowflake(sid, "", NATUnrestricted, 0) w := httptest.NewRecorder() - data := bytes.NewReader([]byte(`{"Version":"1.0","Sid":"test","Answer":"test"}`)) + + data, err := createProxyAnswer(sdp, sid) + So(err, ShouldBeNil)
Convey("by passing to the client if valid.", func() { r, err := http.NewRequest("POST", "snowflake.broker/answer", data) @@ -295,11 +360,11 @@ func TestBroker(t *testing.T) { answer := <-s.answerChannel <-done So(w.Code, ShouldEqual, http.StatusOK) - So(answer, ShouldResemble, "test") + So(answer, ShouldResemble, sdp) })
- Convey("with client gone status if the proxy is not recognized", func() { - data = bytes.NewReader([]byte(`{"Version":"1.0","Sid":"invalid","Answer":"test"}`)) + Convey("with client gone status if the proxy ID is not recognized", func() { + data, err := createProxyAnswer(sdp, "invalid") r, err := http.NewRequest("POST", "snowflake.broker/answer", data) So(err, ShouldBeNil) proxyAnswers(i, w, r) @@ -307,7 +372,6 @@ func TestBroker(t *testing.T) { b, err := ioutil.ReadAll(w.Body) So(err, ShouldBeNil) So(b, ShouldResemble, []byte(`{"Status":"client gone"}`)) - })
Convey("with error if the proxy gives invalid answer", func() { @@ -353,7 +417,8 @@ func TestBroker(t *testing.T) {
// Client offer wc := httptest.NewRecorder() - datac := bytes.NewReader([]byte("test")) + datac, err := createClientOffer(sdp, NATUnknown, "") + So(err, ShouldBeNil) rc, err := http.NewRequest("POST", "snowflake.broker/client", datac) So(err, ShouldBeNil)
@@ -367,7 +432,8 @@ func TestBroker(t *testing.T) {
// Proxy answers wp = httptest.NewRecorder() - datap = bytes.NewReader([]byte(`{"Version":"1.0","Sid":"ymbcCMto7KHNGYlp","Answer":"test"}`)) + datap, err = createProxyAnswer(sdp, sid) + So(err, ShouldBeNil) rp, err = http.NewRequest("POST", "snowflake.broker/answer", datap) So(err, ShouldBeNil) go func(i *IPC) { @@ -405,9 +471,9 @@ func TestBroker(t *testing.T) { So(ctx.idToSnowflake["ymbcCMto7KHNGYlp"], ShouldNotBeNil)
// Client request blocks until proxy answer arrives. - dataC := bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "unknown"}")) wC := httptest.NewRecorder() + dataC, err := createClientOffer(sdp, NATUnknown, "") + So(err, ShouldBeNil) rC, err := http.NewRequest("POST", "snowflake.broker/client", dataC) So(err, ShouldBeNil) go func() { @@ -417,11 +483,13 @@ func TestBroker(t *testing.T) {
<-polled So(wP.Code, ShouldEqual, http.StatusOK) - So(wP.Body.String(), ShouldResemble, `{"Status":"client match","Offer":"fake","NAT":"unknown","RelayURL":"wss://snowflake.torproject.net/"}`) - So(ctx.idToSnowflake["ymbcCMto7KHNGYlp"], ShouldNotBeNil) + So(wP.Body.String(), ShouldResemble, fmt.Sprintf(`{"Status":"client match","Offer":%#q,"NAT":"unknown","RelayURL":"wss://snowflake.torproject.net/"}`, sdp)) + So(ctx.idToSnowflake[sid], ShouldNotBeNil) + // Follow up with the answer request afterwards wA := httptest.NewRecorder() - dataA := bytes.NewReader([]byte(`{"Version":"1.0","Sid":"ymbcCMto7KHNGYlp","Answer":"test"}`)) + dataA, err := createProxyAnswer(sdp, sid) + So(err, ShouldBeNil) rA, err := http.NewRequest("POST", "snowflake.broker/answer", dataA) So(err, ShouldBeNil) proxyAnswers(i, wA, rA) @@ -429,7 +497,7 @@ func TestBroker(t *testing.T) {
<-done So(wC.Code, ShouldEqual, http.StatusOK) - So(wC.Body.String(), ShouldEqual, `{"answer":"test"}`) + So(wC.Body.String(), ShouldEqual, fmt.Sprintf(`{"answer":%#q}`, sdp)) }) }) } @@ -566,8 +634,8 @@ func TestMetrics(t *testing.T) { //Test addition of client failures Convey("for no proxies available", func() { w := httptest.NewRecorder() - data := bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "unknown"}")) + data, err := createClientOffer(sdp, NATUnknown, "") + So(err, ShouldBeNil) r, err := http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil)
@@ -589,8 +657,8 @@ func TestMetrics(t *testing.T) { //Test addition of client matches Convey("for client-proxy match", func() { w := httptest.NewRecorder() - data := bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "unknown"}")) + data, err := createClientOffer(sdp, NATUnknown, "") + So(err, ShouldBeNil) r, err := http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil)
@@ -601,7 +669,7 @@ func TestMetrics(t *testing.T) { done <- true }() offer := <-snowflake.offerChannel - So(offer.sdp, ShouldResemble, []byte("fake")) + So(offer.sdp, ShouldResemble, []byte(sdp)) snowflake.answerChannel <- "fake answer" <-done
@@ -611,51 +679,57 @@ func TestMetrics(t *testing.T) { //Test rounding boundary Convey("binning boundary", func() { w := httptest.NewRecorder() - data := bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err := createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err := http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) - clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) @@ -664,11 +738,12 @@ func TestMetrics(t *testing.T) { So(buf.String(), ShouldContainSubstring, "client-denied-count 8\nclient-restricted-denied-count 8\nclient-unrestricted-denied-count 0\n")
w = httptest.NewRecorder() - data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err = createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil) clientOffers(i, w, r) + buf.Reset() ctx.metrics.printMetrics() So(buf.String(), ShouldContainSubstring, "client-denied-count 16\nclient-restricted-denied-count 16\nclient-unrestricted-denied-count 0\n") @@ -743,11 +818,11 @@ func TestMetrics(t *testing.T) { ctx.metrics.printMetrics() So(buf.String(), ShouldContainSubstring, "snowflake-ips-nat-restricted 1\nsnowflake-ips-nat-unrestricted 1\nsnowflake-ips-nat-unknown 0") }) - //Test client failures by NAT type + Convey("client failures by NAT type", func() { w := httptest.NewRecorder() - data := bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "restricted"}")) + data, err := createClientOffer(sdp, NATRestricted, "") + So(err, ShouldBeNil) r, err := http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil)
@@ -759,8 +834,8 @@ func TestMetrics(t *testing.T) { buf.Reset() ctx.metrics.zeroMetrics()
- data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "unrestricted"}")) + data, err = createClientOffer(sdp, NATUnrestricted, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil)
@@ -772,8 +847,8 @@ func TestMetrics(t *testing.T) { buf.Reset() ctx.metrics.zeroMetrics()
- data = bytes.NewReader( - []byte("1.0\n{"offer": "fake", "nat": "unknown"}")) + data, err = createClientOffer(sdp, NATUnknown, "") + So(err, ShouldBeNil) r, err = http.NewRequest("POST", "snowflake.broker/client", data) So(err, ShouldBeNil)
This is an automated email from the git hooks/post-receive script.
itchyonion pushed a commit to branch main in repository pluggable-transports/snowflake.
commit 88608ad44a00d2a23680800d54ed03b167c09c89 Author: itchyonion itchyonion@torproject.org AuthorDate: Wed Mar 22 21:26:46 2023 -0700
Broker: add warning log when proxy couldn't mach with client --- broker/ipc.go | 1 + 1 file changed, 1 insertion(+)
diff --git a/broker/ipc.go b/broker/ipc.go index f9984c4..a1397d8 100644 --- a/broker/ipc.go +++ b/broker/ipc.go @@ -266,6 +266,7 @@ func (i *IPC) ProxyAnswers(arg messages.Arg, response *[]byte) error { // The snowflake took too long to respond with an answer, so its client // disappeared / the snowflake is no longer recognized by the Broker. success = false + log.Printf("Warning: matching with snowflake client failed") }
b, err := messages.EncodeAnswerResponse(success)
tor-commits@lists.torproject.org