Stop storing version in ClientPollRequest

This continues to asserts the known version while decoding.  The client
will only ever generate the latest version while encoding and if the
response needs to change, the impetus will be a new feature, set in the
deserialized request, which can be used as a distinguisher.
This commit is contained in:
Arlo Breault 2022-03-16 20:26:40 -04:00
parent b73add1550
commit 281d917beb
6 changed files with 22 additions and 53 deletions

View file

@ -146,9 +146,8 @@ func clientOffers(i *IPC, w http.ResponseWriter, r *http.Request) {
if len(body) > 0 && body[0] == '{' {
isLegacy = true
req := messages.ClientPollRequest{
Offer: string(body),
NAT: r.Header.Get("Snowflake-NAT-Type"),
Version: messages.ClientVersion1_0,
Offer: string(body),
NAT: r.Header.Get("Snowflake-NAT-Type"),
}
body, err = req.EncodeClientPollRequest()
if err != nil {

View file

@ -129,15 +129,9 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
return sendClientResponse(&messages.ClientPollResponse{Error: err.Error()}, response)
}
var offer *ClientOffer
switch req.Version {
case messages.ClientVersion1_0:
offer = &ClientOffer{
natType: req.NAT,
sdp: []byte(req.Offer),
}
default:
panic("unknown version")
offer := &ClientOffer{
natType: req.NAT,
sdp: []byte(req.Offer),
}
// Only hand out known restricted snowflakes to unrestricted clients
@ -162,13 +156,8 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
i.ctx.metrics.clientRestrictedDeniedCount++
}
i.ctx.metrics.lock.Unlock()
switch req.Version {
case messages.ClientVersion1_0:
resp := &messages.ClientPollResponse{Error: messages.StrNoProxies}
return sendClientResponse(resp, response)
default:
panic("unknown version")
}
resp := &messages.ClientPollResponse{Error: messages.StrNoProxies}
return sendClientResponse(resp, response)
}
// Otherwise, find the most available snowflake proxy, and pass the offer to it.
@ -185,24 +174,14 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
i.ctx.metrics.clientProxyMatchCount++
i.ctx.metrics.promMetrics.ClientPollTotal.With(prometheus.Labels{"nat": offer.natType, "status": "matched"}).Inc()
i.ctx.metrics.lock.Unlock()
switch req.Version {
case messages.ClientVersion1_0:
resp := &messages.ClientPollResponse{Answer: answer}
err = sendClientResponse(resp, response)
default:
panic("unknown version")
}
resp := &messages.ClientPollResponse{Answer: answer}
err = sendClientResponse(resp, response)
// Initial tracking of elapsed time.
i.ctx.metrics.clientRoundtripEstimate = time.Since(startTime) / time.Millisecond
case <-time.After(time.Second * ClientTimeout):
log.Println("Client: Timed out.")
switch req.Version {
case messages.ClientVersion1_0:
resp := &messages.ClientPollResponse{Error: messages.StrTimedOut}
err = sendClientResponse(resp, response)
default:
panic("unknown version")
}
resp := &messages.ClientPollResponse{Error: messages.StrTimedOut}
err = sendClientResponse(resp, response)
}
i.ctx.snowflakeLock.Lock()

View file

@ -116,9 +116,8 @@ func (bc *BrokerChannel) Negotiate(offer *webrtc.SessionDescription) (
// Encode the client poll request.
bc.lock.Lock()
req := &messages.ClientPollRequest{
Offer: offerSDP,
NAT: bc.natType,
Version: messages.ClientVersion1_0,
Offer: offerSDP,
NAT: bc.natType,
}
encReq, err := req.EncodeClientPollRequest()
bc.lock.Unlock()

View file

@ -43,9 +43,8 @@ func (t errorTransport) RoundTrip(req *http.Request) (*http.Response, error) {
// offer.
func makeEncPollReq(offer string) []byte {
encPollReq, err := (&messages.ClientPollRequest{
Offer: offer,
NAT: nat.NATUnknown,
Version: messages.ClientVersion1_0,
Offer: offer,
NAT: nat.NATUnknown,
}).EncodeClientPollRequest()
if err != nil {
panic(err)

View file

@ -11,7 +11,7 @@ import (
"git.torproject.org/pluggable-transports/snowflake.git/v2/common/nat"
)
const ClientVersion1_0 = "1.0"
const ClientVersion = "1.0"
/* Client--Broker protocol v1.x specification:
@ -50,21 +50,17 @@ for the error.
*/
type ClientPollRequest struct {
Offer string `json:"offer"`
NAT string `json:"nat"`
Version string `json:"-"`
Offer string `json:"offer"`
NAT string `json:"nat"`
}
// Encodes a poll message from a snowflake client
func (req *ClientPollRequest) EncodeClientPollRequest() ([]byte, error) {
if req.Version != ClientVersion1_0 {
return nil, fmt.Errorf("unsupported message version")
}
body, err := json.Marshal(req)
if err != nil {
return nil, err
}
return append([]byte(req.Version+"\n"), body...), nil
return append([]byte(ClientVersion+"\n"), body...), nil
}
// Decodes a poll message from a snowflake client
@ -78,9 +74,7 @@ func DecodeClientPollRequest(data []byte) (*ClientPollRequest, error) {
var message ClientPollRequest
if string(parts[0]) == ClientVersion1_0 {
message.Version = ClientVersion1_0
} else {
if string(parts[0]) != ClientVersion {
return nil, fmt.Errorf("unsupported message version")
}

View file

@ -327,9 +327,8 @@ func TestDecodeClientPollRequest(t *testing.T) {
func TestEncodeClientPollRequests(t *testing.T) {
Convey("Context", t, func() {
req1 := &ClientPollRequest{
NAT: "unknown",
Offer: "fake",
Version: ClientVersion1_0,
NAT: "unknown",
Offer: "fake",
}
b, err := req1.EncodeClientPollRequest()
So(err, ShouldEqual, nil)