From 29f16325d262b84792c842db558ddc84d3ffa8fd Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Fri, 4 Jul 2025 14:55:36 +0100 Subject: [PATCH] add server side first write delay --- transport/internet/tlsmirror/server/conn.go | 13 ++++++++ transport/internet/tlsmirror/server/server.go | 31 ++++++++++++++----- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/transport/internet/tlsmirror/server/conn.go b/transport/internet/tlsmirror/server/conn.go index 4f74fcb24..35f0cafaa 100644 --- a/transport/internet/tlsmirror/server/conn.go +++ b/transport/internet/tlsmirror/server/conn.go @@ -32,6 +32,9 @@ type connState struct { protocolVersion [2]byte + firstWrite bool + firstWriteDelay time.Duration + transportLayerPadding *TransportLayerPadding } @@ -66,6 +69,16 @@ func (s *connState) Read(b []byte) (n int, err error) { } func (s *connState) Write(b []byte) (n int, err error) { + if s.firstWrite { + firstWriteDelayTimer := time.NewTimer(s.firstWriteDelay) + defer firstWriteDelayTimer.Stop() + select { + case <-s.ctx.Done(): + return 0, s.ctx.Err() + case <-firstWriteDelayTimer.C: + s.firstWrite = false + } + } if s.transportLayerPadding != nil && s.transportLayerPadding.Enabled { b = Pack(b, 0) } diff --git a/transport/internet/tlsmirror/server/server.go b/transport/internet/tlsmirror/server/server.go index f40e10d89..602a0c60c 100644 --- a/transport/internet/tlsmirror/server/server.go +++ b/transport/internet/tlsmirror/server/server.go @@ -1,6 +1,8 @@ package server import ( + cryptoRand "crypto/rand" + "math/big" "strings" "time" @@ -77,14 +79,29 @@ func (s *Server) Addr() net.Addr { func (s *Server) accept(clientConn net.Conn, serverConn net.Conn) { ctx, cancel := context.WithCancel(s.ctx) + + firstWriteDelay := time.Duration(0) + if s.config.DeferFirstPayloadWriteTime != nil { + uniformRandomAdd := big.NewInt(int64(s.config.DeferFirstPayloadWriteTime.UniformRandomMultiplierNanoseconds)) + uniformRandomAddBigInt, err := cryptoRand.Int(cryptoRand.Reader, uniformRandomAdd) + if err != nil { + newError("failed to generate random delay").Base(err).AtWarning().WriteToLog() + return + } + uniformRandomAddU64 := uint64(uniformRandomAddBigInt.Int64()) + firstWriteDelay = time.Duration(s.config.DeferFirstPayloadWriteTime.BaseNanoseconds + uniformRandomAddU64) + } + conn := &connState{ - ctx: ctx, - done: cancel, - localAddr: clientConn.LocalAddr(), - remoteAddr: clientConn.RemoteAddr(), - primaryKey: s.config.PrimaryKey, - handler: s.onIncomingReadyConnection, - readPipe: make(chan []byte, 1), + ctx: ctx, + done: cancel, + localAddr: clientConn.LocalAddr(), + remoteAddr: clientConn.RemoteAddr(), + primaryKey: s.config.PrimaryKey, + handler: s.onIncomingReadyConnection, + readPipe: make(chan []byte, 1), + firstWrite: true, + firstWriteDelay: firstWriteDelay, } conn.mirrorConn = mirrorbase.NewMirroredTLSConn(ctx, clientConn, serverConn, conn.onC2SMessage, nil, conn,