Make the proxy to report the number of clients to the broker

So the assignment of proxies is based on the load. The number of clients
is ronded down to 8. Existing proxies that doesn't report the number
of clients will be distributed equaly to new proxies until they get 8
clients, that is okish as the existing proxies do have a maximum
capacity of 10.

Fixes #40048
This commit is contained in:
meskio 2021-06-25 13:47:47 +02:00
parent 74bdb85b30
commit 7a1857c42f
No known key found for this signature in database
GPG key ID: 52B8F5AC97A2DA86
9 changed files with 165 additions and 77 deletions

View file

@ -15,6 +15,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
sid string
proxyType string
natType string
clients int
data string
err error
}{
@ -23,6 +24,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"ymbcCMto7KHNGYlp",
"",
"unknown",
0,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`,
nil,
},
@ -31,6 +33,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"ymbcCMto7KHNGYlp",
"standalone",
"unknown",
0,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.1","Type":"standalone"}`,
nil,
},
@ -39,14 +42,25 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"ymbcCMto7KHNGYlp",
"standalone",
"restricted",
0,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted"}`,
nil,
},
{
//Version 1.2 proxy message with clients
"ymbcCMto7KHNGYlp",
"standalone",
"restricted",
24,
`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.2","Type":"standalone", "NAT":"restricted","Clients":24}`,
nil,
},
{
//Version 0.X proxy message:
"",
"",
"",
0,
"",
&json.SyntaxError{},
},
@ -54,6 +68,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"",
"",
"",
0,
`{"Sid":"ymbcCMto7KHNGYlp"}`,
fmt.Errorf(""),
},
@ -61,6 +76,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"",
"",
"",
0,
"{}",
fmt.Errorf(""),
},
@ -68,6 +84,7 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"",
"",
"",
0,
`{"Version":"1.0"}`,
fmt.Errorf(""),
},
@ -75,14 +92,16 @@ func TestDecodeProxyPollRequest(t *testing.T) {
"",
"",
"",
0,
`{"Version":"2.0"}`,
fmt.Errorf(""),
},
} {
sid, proxyType, natType, err := DecodePollRequest([]byte(test.data))
sid, proxyType, natType, clients, err := DecodePollRequest([]byte(test.data))
So(sid, ShouldResemble, test.sid)
So(proxyType, ShouldResemble, test.proxyType)
So(natType, ShouldResemble, test.natType)
So(clients, ShouldEqual, test.clients)
So(err, ShouldHaveSameTypeAs, test.err)
}
@ -91,12 +110,13 @@ func TestDecodeProxyPollRequest(t *testing.T) {
func TestEncodeProxyPollRequests(t *testing.T) {
Convey("Context", t, func() {
b, err := EncodePollRequest("ymbcCMto7KHNGYlp", "standalone", "unknown")
b, err := EncodePollRequest("ymbcCMto7KHNGYlp", "standalone", "unknown", 16)
So(err, ShouldEqual, nil)
sid, proxyType, natType, err := DecodePollRequest(b)
sid, proxyType, natType, clients, err := DecodePollRequest(b)
So(sid, ShouldEqual, "ymbcCMto7KHNGYlp")
So(proxyType, ShouldEqual, "standalone")
So(natType, ShouldEqual, "unknown")
So(clients, ShouldEqual, 16)
So(err, ShouldEqual, nil)
})
}

View file

@ -17,8 +17,9 @@ const version = "1.2"
{
Sid: [generated session id of proxy],
Version: 1.2,
Type: ["badge"|"webext"|"standalone"]
NAT: ["unknown"|"restricted"|"unrestricted"]
Type: ["badge"|"webext"|"standalone"],
NAT: ["unknown"|"restricted"|"unrestricted"],
Clients: [number of current clients, rounded down to multiples of 8]
}
== ProxyPollResponse ==
@ -79,43 +80,48 @@ type ProxyPollRequest struct {
Version string
Type string
NAT string
Clients int
}
func EncodePollRequest(sid string, proxyType string, natType string) ([]byte, error) {
func EncodePollRequest(sid string, proxyType string, natType string, clients int) ([]byte, error) {
return json.Marshal(ProxyPollRequest{
Sid: sid,
Version: version,
Type: proxyType,
NAT: natType,
Clients: clients,
})
}
// 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, string, error) {
// sid, proxy type, nat type and clients of the proxy on success
// and an error if it failed
func DecodePollRequest(data []byte) (sid string, proxyType string, natType string, clients int, err error) {
var message ProxyPollRequest
err := json.Unmarshal(data, &message)
err = json.Unmarshal(data, &message)
if err != nil {
return "", "", "", err
return
}
majorVersion := strings.Split(message.Version, ".")[0]
if majorVersion != "1" {
return "", "", "", fmt.Errorf("using unknown version")
err = fmt.Errorf("using unknown version")
return
}
// Version 1.x requires an Sid
if message.Sid == "" {
return "", "", "", fmt.Errorf("no supplied session id")
err = fmt.Errorf("no supplied session id")
return
}
natType := message.NAT
natType = message.NAT
if natType == "" {
natType = "unknown"
}
return message.Sid, message.Type, natType, nil
return message.Sid, message.Type, natType, message.Clients, nil
}
type ProxyPollResponse struct {