Fix URLTest group hang on unresponsive outbound

This commit is contained in:
世界
2026-08-21 18:21:51 +08:00
parent 9d8d4b8796
commit e4a4e8c790
6 changed files with 84 additions and 15 deletions
+18 -6
View File
@@ -35,7 +35,6 @@ var _ adapter.InterfaceUpdateListener = (*Outbound)(nil)
type Outbound struct {
outbound.Adapter
ctx context.Context
logger logger.ContextLogger
dialer N.Dialer
serverAddr M.Socksaddr
@@ -56,7 +55,6 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
}
outbound := &Outbound{
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSSH, tag, []string{N.NetworkTCP}, options.DialerOptions),
ctx: ctx,
logger: logger,
dialer: outboundDialer,
serverAddr: options.ServerOptions.Build(),
@@ -121,7 +119,7 @@ func randomVersion() string {
return version
}
func (s *Outbound) connect() (*ssh.Client, error) {
func (s *Outbound) connect(ctx context.Context) (client *ssh.Client, err error) {
if s.client != nil {
return s.client, nil
}
@@ -133,10 +131,24 @@ func (s *Outbound) connect() (*ssh.Client, error) {
return s.client, nil
}
conn, err := s.dialer.DialContext(s.ctx, N.NetworkTCP, s.serverAddr)
conn, err := s.dialer.DialContext(ctx, N.NetworkTCP, s.serverAddr)
if err != nil {
return nil, err
}
if ctx.Done() != nil {
handshakeConn := conn
stopContext := context.AfterFunc(ctx, func() {
_ = handshakeConn.Close()
})
defer func() {
if !stopContext() {
s.client = nil
s.clientConn = nil
client = nil
err = ctx.Err()
}
}()
}
config := &ssh.ClientConfig{
User: s.user,
Auth: s.authMethod,
@@ -161,7 +173,7 @@ func (s *Outbound) connect() (*ssh.Client, error) {
return nil, E.Cause(err, "connect to ssh server")
}
client := ssh.NewClient(clientConn, chans, reqs)
client = ssh.NewClient(clientConn, chans, reqs)
s.clientConn = conn
s.client = client
@@ -187,7 +199,7 @@ func (s *Outbound) Close() error {
}
func (s *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
client, err := s.connect()
client, err := s.connect(ctx)
if err != nil {
return nil, err
}