lib/protocol: Hello message length is an int16
It used to be an int32, but that's unnecessary and the spec now says int16. Also relaxes the size requirement to that which fits in a signed int16 instead of limiting to 1024 bytes, to allow for future growth. As reported in https://forum.syncthing.net/t/difference-between-documented-and-implemented-protocol/7798 GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3406
This commit is contained in:
@@ -56,16 +56,19 @@ func IsVersionMismatch(err error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func readHello(c io.Reader) (HelloResult, error) {
|
func readHello(c io.Reader) (HelloResult, error) {
|
||||||
header := make([]byte, 8)
|
header := make([]byte, 4)
|
||||||
if _, err := io.ReadFull(c, header); err != nil {
|
if _, err := io.ReadFull(c, header); err != nil {
|
||||||
return HelloResult{}, err
|
return HelloResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch binary.BigEndian.Uint32(header[:4]) {
|
switch binary.BigEndian.Uint32(header) {
|
||||||
case HelloMessageMagic:
|
case HelloMessageMagic:
|
||||||
// This is a v0.14 Hello message in proto format
|
// This is a v0.14 Hello message in proto format
|
||||||
msgSize := binary.BigEndian.Uint32(header[4:])
|
if _, err := io.ReadFull(c, header[:2]); err != nil {
|
||||||
if msgSize > 1024 {
|
return HelloResult{}, err
|
||||||
|
}
|
||||||
|
msgSize := binary.BigEndian.Uint16(header[:2])
|
||||||
|
if msgSize > 32767 {
|
||||||
return HelloResult{}, fmt.Errorf("hello message too big")
|
return HelloResult{}, fmt.Errorf("hello message too big")
|
||||||
}
|
}
|
||||||
buf := make([]byte, msgSize)
|
buf := make([]byte, msgSize)
|
||||||
@@ -86,7 +89,10 @@ func readHello(c io.Reader) (HelloResult, error) {
|
|||||||
|
|
||||||
case Version13HelloMagic:
|
case Version13HelloMagic:
|
||||||
// This is a v0.13 Hello message in XDR format
|
// This is a v0.13 Hello message in XDR format
|
||||||
msgSize := binary.BigEndian.Uint32(header[4:])
|
if _, err := io.ReadFull(c, header[:4]); err != nil {
|
||||||
|
return HelloResult{}, err
|
||||||
|
}
|
||||||
|
msgSize := binary.BigEndian.Uint32(header[:4])
|
||||||
if msgSize > 1024 {
|
if msgSize > 1024 {
|
||||||
return HelloResult{}, fmt.Errorf("hello message too big")
|
return HelloResult{}, fmt.Errorf("hello message too big")
|
||||||
}
|
}
|
||||||
@@ -120,10 +126,14 @@ func writeHello(c io.Writer, h HelloIntf) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if len(msg) > 32767 {
|
||||||
|
// The header length must be a positive signed int16
|
||||||
|
panic("bug: attempting to serialize too large hello message")
|
||||||
|
}
|
||||||
|
|
||||||
header := make([]byte, 8)
|
header := make([]byte, 6)
|
||||||
binary.BigEndian.PutUint32(header[:4], h.Magic())
|
binary.BigEndian.PutUint32(header[:4], h.Magic())
|
||||||
binary.BigEndian.PutUint32(header[4:], uint32(len(msg)))
|
binary.BigEndian.PutUint16(header[4:], uint16(len(msg)))
|
||||||
|
|
||||||
_, err = c.Write(append(header, msg...))
|
_, err = c.Write(append(header, msg...))
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ func TestVersion14Hello(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hdrBuf := make([]byte, 8)
|
hdrBuf := make([]byte, 6)
|
||||||
binary.BigEndian.PutUint32(hdrBuf, HelloMessageMagic)
|
binary.BigEndian.PutUint32(hdrBuf, HelloMessageMagic)
|
||||||
binary.BigEndian.PutUint32(hdrBuf[4:], uint32(len(msgBuf)))
|
binary.BigEndian.PutUint16(hdrBuf[4:], uint16(len(msgBuf)))
|
||||||
|
|
||||||
outBuf := new(bytes.Buffer)
|
outBuf := new(bytes.Buffer)
|
||||||
outBuf.Write(hdrBuf)
|
outBuf.Write(hdrBuf)
|
||||||
|
|||||||
Reference in New Issue
Block a user