Fix truncated ClientHello parsing for some sizes

The handshake length expression combined shifts with +/|, so when bit 2
of the 24-bit length was set it computed four bytes too few. The
extensions block was then truncated, SNI and ALPN parsed as empty, and
the relay dropped the connection as "sni \"\" matches no tunnel
hostname". It only hit certain ClientHello sizes, so some routes or
ALPN choices reset while others worked.

Parenthesize the length and add a regression test with a synthetic
hello whose length sets bit 2.
This commit is contained in:
2026-10-25 23:54:40 +08:00
parent f4a63c884f
commit cba7d2366b
2 changed files with 72 additions and 1 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ func readClientHello(conn net.Conn) (raw []byte, sni string, alpn []string, err
if hello[0] != 1 { // client_hello
return nil, "", nil, fmt.Errorf("expected ClientHello, got handshake type %d", hello[0])
}
need = 4 + int(hello[1])<<16 | int(hello[2])<<8 | int(hello[3])
need = 4 + (int(hello[1])<<16 | int(hello[2])<<8 | int(hello[3]))
}
if len(hello) >= need {
sni, alpn = parseClientHello(hello[4:need])