Get rid of legacy version

Move the logic for the legacy version into the http handlers and use a
shim when doing ipc.
This commit is contained in:
Arlo Breault 2021-06-03 17:04:58 -04:00
parent 0ced1cc324
commit 87ad06a5e2
3 changed files with 53 additions and 49 deletions

View file

@ -102,7 +102,6 @@ func proxyPolls(i *IPC, w http.ResponseWriter, r *http.Request) {
arg := messages.Arg{
Body: body,
RemoteAddr: r.RemoteAddr,
NatType: "",
}
var response []byte
@ -138,28 +137,57 @@ func clientOffers(i *IPC, w http.ResponseWriter, r *http.Request) {
return
}
// Handle the legacy version
isLegacy := false
if len(body) > 0 && body[0] == '{' {
isLegacy = true
req := messages.ClientPollRequest{
Offer: string(body),
NAT: r.Header.Get("Snowflake-NAT-Type"),
}
body, err = req.EncodePollRequest()
if err != nil {
log.Printf("Error shimming the legacy request: %s", err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
}
arg := messages.Arg{
Body: body,
RemoteAddr: "",
NatType: r.Header.Get("Snowflake-NAT-Type"),
}
var response []byte
err = i.ClientOffers(arg, &response)
switch {
case err == nil:
case errors.Is(err, messages.ErrUnavailable):
w.WriteHeader(http.StatusServiceUnavailable)
return
case errors.Is(err, messages.ErrTimeout):
w.WriteHeader(http.StatusGatewayTimeout)
return
default:
if err != nil {
// Assert err == messages.ErrInternal
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if isLegacy {
resp, err := messages.DecodeClientPollResponse(response)
if err != nil {
log.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
switch resp.Error {
case "":
response = []byte(resp.Answer)
case "no snowflake proxies currently available":
w.WriteHeader(http.StatusServiceUnavailable)
return
case "timed out waiting for answer!":
w.WriteHeader(http.StatusGatewayTimeout)
return
default:
panic("unknown error")
}
}
if _, err := w.Write(response); err != nil {
log.Printf("clientOffers unable to write answer with error: %v", err)
}
@ -181,7 +209,6 @@ func proxyAnswers(i *IPC, w http.ResponseWriter, r *http.Request) {
arg := messages.Arg{
Body: body,
RemoteAddr: "",
NatType: "",
}
var response []byte

View file

@ -21,14 +21,10 @@ const (
NATUnrestricted = "unrestricted"
)
// We support two client message formats. The legacy format is for backwards
// combatability and relies heavily on HTTP headers and status codes to convey
// information.
type clientVersion int
const (
v0 clientVersion = iota //legacy version
v1
v1 clientVersion = iota
)
type IPC struct {
@ -141,9 +137,6 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
startTime := time.Now()
body := arg.Body
if len(body) > 0 && body[0] == '{' {
version = v0
} else {
parts := bytes.SplitN(body, []byte("\n"), 2)
if len(parts) < 2 {
// no version number found
@ -153,20 +146,13 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
body = parts[1]
if string(parts[0]) == "1.0" {
version = v1
} else {
err := fmt.Errorf("unsupported message version")
return sendClientResponse(&messages.ClientPollResponse{Error: err.Error()}, response)
}
}
var offer *ClientOffer
switch version {
case v0:
offer = &ClientOffer{
natType: arg.NatType,
sdp: body,
}
case v1:
req, err := messages.DecodeClientPollRequest(body)
if err != nil {
@ -203,8 +189,6 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
}
i.ctx.metrics.lock.Unlock()
switch version {
case v0:
return messages.ErrUnavailable
case v1:
resp := &messages.ClientPollResponse{Error: "no snowflake proxies currently available"}
return sendClientResponse(resp, response)
@ -230,8 +214,6 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
i.ctx.metrics.promMetrics.ClientPollTotal.With(prometheus.Labels{"nat": offer.natType, "status": "matched"}).Inc()
i.ctx.metrics.lock.Unlock()
switch version {
case v0:
*response = []byte(answer)
case v1:
resp := &messages.ClientPollResponse{Answer: answer}
err = sendClientResponse(resp, response)
@ -243,8 +225,6 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
case <-time.After(time.Second * ClientTimeout):
log.Println("Client: Timed out.")
switch version {
case v0:
err = messages.ErrTimeout
case v1:
resp := &messages.ClientPollResponse{
Error: "timed out waiting for answer!"}

View file

@ -7,12 +7,9 @@ import (
type Arg struct {
Body []byte
RemoteAddr string
NatType string
}
var (
ErrBadRequest = errors.New("bad request")
ErrInternal = errors.New("internal error")
ErrUnavailable = errors.New("service unavailable")
ErrTimeout = errors.New("timeout")
)