@@ -19,6 +19,7 @@ import (
1919 "github.com/v2fly/v2ray-core/v5/features"
2020 "github.com/v2fly/v2ray-core/v5/features/policy"
2121 "github.com/v2fly/v2ray-core/v5/features/routing"
22+ "github.com/v2fly/v2ray-core/v5/transport"
2223 "github.com/v2fly/v2ray-core/v5/transport/internet"
2324 "github.com/v2fly/v2ray-core/v5/transport/internet/udp"
2425)
@@ -90,10 +91,11 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
9091 }
9192
9293 svrSession := & ServerSession {
93- config : s .config ,
94- address : inbound .Gateway .Address ,
95- port : inbound .Gateway .Port ,
96- clientAddress : inbound .Source .Address ,
94+ config : s .config ,
95+ address : inbound .Gateway .Address ,
96+ port : inbound .Gateway .Port ,
97+ clientAddress : inbound .Source .Address ,
98+ deferLastReply : true ,
9799 }
98100
99101 reader := & buf.BufferedReader {Reader : buf .NewReader (conn )}
@@ -129,16 +131,46 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
129131 })
130132 }
131133
134+ dispatcher = & handshakeFinalizingDispatcher {Feature : dispatcher , delegate : dispatcher , serverSession : svrSession }
132135 return s .transport (ctx , reader , conn , dest , dispatcher )
133136 }
134137
138+ svrSession .flushLastReply (true )
135139 if request .Command == protocol .RequestCommandUDP {
136140 return s .handleUDP (conn )
137141 }
138142
139143 return nil
140144}
141145
146+ // Wrapper to send final SOCKS reply only after Dispatch() returns
147+ type handshakeFinalizingDispatcher struct {
148+ features.Feature // do not inherit Dispatch() in case its signature changes
149+ delegate routing.Dispatcher
150+ serverSession * ServerSession
151+ }
152+
153+ func (d * handshakeFinalizingDispatcher ) Dispatch (ctx context.Context , dest net.Destination ) (* transport.Link , error ) {
154+ link , err := d .delegate .Dispatch (ctx , dest )
155+ if err == nil {
156+ closeInDefer := true
157+ defer func () {
158+ if closeInDefer {
159+ common .Interrupt (link .Reader )
160+ common .Interrupt (link .Writer )
161+ }
162+ }()
163+ err = d .serverSession .flushLastReply (true )
164+ if err != nil {
165+ return nil , err
166+ }
167+ closeInDefer = false
168+ } else {
169+ d .serverSession .flushLastReply (false )
170+ }
171+ return link , err
172+ }
173+
142174func (* Server ) handleUDP (c io.Reader ) error {
143175 // The TCP connection closes after this method returns. We need to wait until
144176 // the client closes it.
0 commit comments