From 50f5006c43c0be48cbbfba00064e5840f9684ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 7 Jan 2025 17:03:06 +0800 Subject: [PATCH] Fix leak in reality server --- common/tls/reality_client.go | 35 ++++++++++++++++++++++++++++++++++- common/tls/reality_server.go | 6 ++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/common/tls/reality_client.go b/common/tls/reality_client.go index 59ecf86003..f9a11a0b6c 100644 --- a/common/tls/reality_client.go +++ b/common/tls/reality_client.go @@ -184,7 +184,7 @@ func (e *RealityClientConfig) ClientHandshake(ctx context.Context, conn net.Conn return nil, E.New("reality verification failed") } - return &utlsConnWrapper{uConn}, nil + return &realityClientConnWrapper{uConn}, nil } func realityClientFallback(uConn net.Conn, serverName string, fingerprint utls.ClientHelloID) { @@ -249,3 +249,36 @@ func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChain } return nil } + +type realityClientConnWrapper struct { + *utls.UConn +} + +func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionState { + state := c.Conn.ConnectionState() + //nolint:staticcheck + return tls.ConnectionState{ + Version: state.Version, + HandshakeComplete: state.HandshakeComplete, + DidResume: state.DidResume, + CipherSuite: state.CipherSuite, + NegotiatedProtocol: state.NegotiatedProtocol, + NegotiatedProtocolIsMutual: state.NegotiatedProtocolIsMutual, + ServerName: state.ServerName, + PeerCertificates: state.PeerCertificates, + VerifiedChains: state.VerifiedChains, + SignedCertificateTimestamps: state.SignedCertificateTimestamps, + OCSPResponse: state.OCSPResponse, + TLSUnique: state.TLSUnique, + } +} + +func (c *realityClientConnWrapper) Upstream() any { + return c.UConn +} + +// Due to low implementation quality, the reality server intercepted half close and caused memory leaks. +// We fixed it by calling Close() directly. +func (c *realityClientConnWrapper) CloseWrite() error { + return c.Close() +} diff --git a/common/tls/reality_server.go b/common/tls/reality_server.go index 6395f65201..995b454d86 100644 --- a/common/tls/reality_server.go +++ b/common/tls/reality_server.go @@ -195,3 +195,9 @@ func (c *realityConnWrapper) ConnectionState() ConnectionState { func (c *realityConnWrapper) Upstream() any { return c.Conn } + +// Due to low implementation quality, the reality server intercepted half close and caused memory leaks. +// We fixed it by calling Close() directly. +func (c *realityConnWrapper) CloseWrite() error { + return c.Close() +}