From c64c91005c3e83f25e47de8b68a2bf2fb4b6fca3 Mon Sep 17 00:00:00 2001 From: skvarovski Date: Fri, 17 Jul 2026 00:57:27 +0300 Subject: [PATCH] finalmask/fragment: implement CloseWrite for reality.CloseWriteConn (#6509) After #6331 reversed the TCP mask wrapping order (slices.Backward), fragmentConn became the outermost finalmask wrapper for {fragment, sudoku} configs. The external github.com/xtls/reality library performs a hard type assertion 'raw.(CloseWriteConn)' (tls.go) on the connection passed to reality.Server, so a REALITY server inbound combined with finalmask fragment+sudoku panics on every client connection (crash-loop with Restart=always). Add CloseWrite(), mirroring sudoku/conn_tcp.go, so fragmentConn satisfies reality.CloseWriteConn. Additive and non-breaking. --- transport/internet/finalmask/fragment/conn.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/transport/internet/finalmask/fragment/conn.go b/transport/internet/finalmask/fragment/conn.go index 3c65a8bd509e..aa5303037d17 100644 --- a/transport/internet/finalmask/fragment/conn.go +++ b/transport/internet/finalmask/fragment/conn.go @@ -43,6 +43,17 @@ func (c *fragmentConn) Splice() bool { return true } +type closeWriteConn interface { + CloseWrite() error +} + +func (c *fragmentConn) CloseWrite() error { + if raw, ok := c.Conn.(closeWriteConn); ok { + return raw.CloseWrite() + } + return net.ErrClosed +} + // lengthForSegment returns the length range (min, max) for the given segment index (0-based). // Clamps to the last entry when the index exceeds the list length. func (c *fragmentConn) lengthForSegment(segIdx int) (int64, int64) {