瀏覽代碼

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
Jakob Borg 9 年之前
父節點
當前提交
7b7e35d339
共有 2 個文件被更改,包括 19 次插入9 次删除
  1. 17 7
      lib/protocol/hello.go
  2. 2 2
      lib/protocol/hello_test.go

+ 17 - 7
lib/protocol/hello.go

@@ -56,16 +56,19 @@ func IsVersionMismatch(err error) bool {
 }
 
 func readHello(c io.Reader) (HelloResult, error) {
-	header := make([]byte, 8)
+	header := make([]byte, 4)
 	if _, err := io.ReadFull(c, header); err != nil {
 		return HelloResult{}, err
 	}
 
-	switch binary.BigEndian.Uint32(header[:4]) {
+	switch binary.BigEndian.Uint32(header) {
 	case HelloMessageMagic:
 		// This is a v0.14 Hello message in proto format
-		msgSize := binary.BigEndian.Uint32(header[4:])
-		if msgSize > 1024 {
+		if _, err := io.ReadFull(c, header[:2]); err != nil {
+			return HelloResult{}, err
+		}
+		msgSize := binary.BigEndian.Uint16(header[:2])
+		if msgSize > 32767 {
 			return HelloResult{}, fmt.Errorf("hello message too big")
 		}
 		buf := make([]byte, msgSize)
@@ -86,7 +89,10 @@ func readHello(c io.Reader) (HelloResult, error) {
 
 	case Version13HelloMagic:
 		// 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 {
 			return HelloResult{}, fmt.Errorf("hello message too big")
 		}
@@ -120,10 +126,14 @@ func writeHello(c io.Writer, h HelloIntf) error {
 	if err != nil {
 		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:], uint32(len(msg)))
+	binary.BigEndian.PutUint16(header[4:], uint16(len(msg)))
 
 	_, err = c.Write(append(header, msg...))
 	return err

+ 2 - 2
lib/protocol/hello_test.go

@@ -26,9 +26,9 @@ func TestVersion14Hello(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	hdrBuf := make([]byte, 8)
+	hdrBuf := make([]byte, 6)
 	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.Write(hdrBuf)