Fix 1/67000000 chance's server panic

https://github.com/XTLS/Xray-core/pull/4952#issuecomment-3188118918
This commit is contained in:
RPRX
2025-08-14 12:49:57 +00:00
committed by GitHub
parent 2807ee432a
commit 85a2663f4a
2 changed files with 13 additions and 9 deletions

View File

@@ -104,9 +104,9 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
if _, err := c.Conn.Write(clientHello); err != nil {
return nil, err
}
// client can send more padding / NFS AEAD messages if needed
// client can send more paddings / NFS AEAD messages if needed
_, t, l, err := ReadAndDiscardPaddings(c.Conn)
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before server hello
if err != nil {
return nil, err
}
@@ -190,9 +190,9 @@ func (c *ClientConn) Read(b []byte) (int, error) {
return 0, nil
}
if c.peerAead == nil {
_, t, l, err := ReadAndDiscardPaddings(c.Conn)
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before random hello
if err != nil {
if c.instance != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // from 0-RTT
if c.instance != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // 0-RTT's 0-RTT
c.instance.Lock()
if bytes.Equal(c.ticket, c.instance.ticket) {
c.instance.expire = time.Now() // expired

View File

@@ -97,7 +97,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
}
c := &ServerConn{Conn: conn}
_, t, l, err := ReadAndDiscardPaddings(c.Conn)
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before client/ticket hello
if err != nil {
return nil, err
}
@@ -118,7 +118,11 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
i.RUnlock()
if s == nil {
noise := make([]byte, crypto.RandBetween(100, 1000))
var err error
for err == nil {
rand.Read(noise)
_, _, err = DecodeHeader(noise)
}
c.Conn.Write(noise) // make client do new handshake
return nil, errors.New("expired ticket")
}
@@ -169,7 +173,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (net.Conn, error) {
if _, err := c.Conn.Write(serverHello); err != nil {
return nil, err
}
// server can send more padding / PFS AEAD messages if needed
// server can send more paddings / PFS AEAD messages if needed
if i.minutes > 0 {
i.Lock()
@@ -189,8 +193,8 @@ func (c *ServerConn) Read(b []byte) (int, error) {
return 0, nil
}
if c.peerAead == nil {
if c.peerRandom == nil { // from 1-RTT
_, t, l, err := ReadAndDiscardPaddings(c.Conn)
if c.peerRandom == nil { // 1-RTT's 0-RTT
_, t, l, err := ReadAndDiscardPaddings(c.Conn) // allow paddings before ticket hello
if err != nil {
return 0, err
}