@@ -13,15 +13,24 @@ import (
1313 "github.com/sagernet/sing/common/task"
1414)
1515
16+ // Deprecated: Use ServiceHandlerEx instead.
17+ //
18+ //nolint:staticcheck
1619type ServiceHandler interface {
1720 N.TCPConnectionHandler
1821 N.UDPConnectionHandler
1922}
2023
24+ type ServiceHandlerEx interface {
25+ N.TCPConnectionHandlerEx
26+ N.UDPConnectionHandlerEx
27+ }
28+
2129type Service struct {
2230 newStreamContext func (context.Context , net.Conn ) context.Context
2331 logger logger.ContextLogger
2432 handler ServiceHandler
33+ handlerEx ServiceHandlerEx
2534 padding bool
2635 brutal BrutalOptions
2736}
@@ -30,6 +39,7 @@ type ServiceOptions struct {
3039 NewStreamContext func (context.Context , net.Conn ) context.Context
3140 Logger logger.ContextLogger
3241 Handler ServiceHandler
42+ HandlerEx ServiceHandlerEx
3343 Padding bool
3444 Brutal BrutalOptions
3545}
@@ -42,12 +52,26 @@ func NewService(options ServiceOptions) (*Service, error) {
4252 newStreamContext : options .NewStreamContext ,
4353 logger : options .Logger ,
4454 handler : options .Handler ,
55+ handlerEx : options .HandlerEx ,
4556 padding : options .Padding ,
4657 brutal : options .Brutal ,
4758 }, nil
4859}
4960
61+ // Deprecated: Use NewConnectionEx instead.
5062func (s * Service ) NewConnection (ctx context.Context , conn net.Conn , metadata M.Metadata ) error {
63+ return s .newConnection (ctx , conn , metadata .Source )
64+ }
65+
66+ func (s * Service ) NewConnectionEx (ctx context.Context , conn net.Conn , source M.Socksaddr , destination M.Socksaddr , onClose N.CloseHandlerFunc ) {
67+ err := s .newConnection (ctx , conn , source )
68+ N .CloseOnHandshakeFailure (conn , onClose , err )
69+ if err != nil {
70+ s .logger .ErrorContext (ctx , E .Cause (err , "process multiplex connection from " , source ))
71+ }
72+ }
73+
74+ func (s * Service ) newConnection (ctx context.Context , conn net.Conn , source M.Socksaddr ) error {
5175 request , err := ReadRequest (conn )
5276 if err != nil {
5377 return err
@@ -70,9 +94,10 @@ func (s *Service) NewConnection(ctx context.Context, conn net.Conn, metadata M.M
7094 }
7195 streamCtx := s .newStreamContext (ctx , stream )
7296 go func () {
73- hErr := s .newConnection (streamCtx , conn , stream , metadata )
97+ hErr := s .newSession (streamCtx , conn , stream , source )
7498 if hErr != nil {
75- s .logger .ErrorContext (streamCtx , E .Cause (hErr , "handle connection" ))
99+ stream .Close ()
100+ s .logger .ErrorContext (streamCtx , E .Cause (hErr , "process multiplex stream" ))
76101 }
77102 }()
78103 }
@@ -83,13 +108,13 @@ func (s *Service) NewConnection(ctx context.Context, conn net.Conn, metadata M.M
83108 return group .Run (ctx )
84109}
85110
86- func (s * Service ) newConnection (ctx context.Context , sessionConn net.Conn , stream net.Conn , metadata M.Metadata ) error {
111+ func (s * Service ) newSession (ctx context.Context , sessionConn net.Conn , stream net.Conn , source M.Socksaddr ) error {
87112 stream = & wrapStream {stream }
88113 request , err := ReadStreamRequest (stream )
89114 if err != nil {
90115 return E .Cause (err , "read multiplex stream request" )
91116 }
92- metadata . Destination = request .Destination
117+ destination : = request .Destination
93118 if request .Network == N .NetworkTCP {
94119 conn := & serverConn {ExtendedConn : bufio .NewExtendedConn (stream )}
95120 if request .Destination .Fqdn == BrutalExchangeDomain {
@@ -127,20 +152,28 @@ func (s *Service) newConnection(ctx context.Context, sessionConn net.Conn, strea
127152 }
128153 return nil
129154 }
130- s .logger .InfoContext (ctx , "inbound multiplex connection to " , metadata .Destination )
131- s .handler .NewConnection (ctx , conn , metadata )
132- stream .Close ()
155+ s .logger .InfoContext (ctx , "inbound multiplex connection to " , destination )
156+ if s .handler != nil {
157+ //nolint:staticcheck
158+ s .handler .NewConnection (ctx , conn , M.Metadata {Source : source , Destination : destination })
159+ } else {
160+ s .handlerEx .NewConnectionEx (ctx , conn , source , destination , nil )
161+ }
133162 } else {
134163 var packetConn N.PacketConn
135164 if ! request .PacketAddr {
136- s .logger .InfoContext (ctx , "inbound multiplex packet connection to " , metadata . Destination )
165+ s .logger .InfoContext (ctx , "inbound multiplex packet connection to " , destination )
137166 packetConn = & serverPacketConn {ExtendedConn : bufio .NewExtendedConn (stream ), destination : request .Destination }
138167 } else {
139168 s .logger .InfoContext (ctx , "inbound multiplex packet connection" )
140169 packetConn = & serverPacketAddrConn {ExtendedConn : bufio .NewExtendedConn (stream )}
141170 }
142- s .handler .NewPacketConnection (ctx , packetConn , metadata )
143- stream .Close ()
171+ if s .handler != nil {
172+ //nolint:staticcheck
173+ s .handler .NewPacketConnection (ctx , packetConn , M.Metadata {Source : source , Destination : destination })
174+ } else {
175+ s .handlerEx .NewPacketConnectionEx (ctx , packetConn , source , destination , nil )
176+ }
144177 }
145178 return nil
146179}
0 commit comments