diff --git a/protocol/group/selector.go b/protocol/group/selector.go index f3f7377b61..86aa73c623 100644 --- a/protocol/group/selector.go +++ b/protocol/group/selector.go @@ -141,7 +141,11 @@ func (s *Selector) SelectOutbound(tag string) bool { } func (s *Selector) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { - conn, err := s.selected.Load().DialContext(ctx, network, destination) + selected := s.selected.Load() + if selected == nil { + return nil, E.New("no selected outbound") + } + conn, err := selected.DialContext(ctx, network, destination) if err != nil { return nil, err } @@ -149,7 +153,11 @@ func (s *Selector) DialContext(ctx context.Context, network string, destination } func (s *Selector) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { - conn, err := s.selected.Load().ListenPacket(ctx, destination) + selected := s.selected.Load() + if selected == nil { + return nil, E.New("no selected outbound") + } + conn, err := selected.ListenPacket(ctx, destination) if err != nil { return nil, err } @@ -159,6 +167,10 @@ func (s *Selector) ListenPacket(ctx context.Context, destination M.Socksaddr) (n func (s *Selector) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) { ctx = interrupt.ContextWithIsExternalConnection(ctx) selected := s.selected.Load() + if selected == nil { + N.CloseOnHandshakeFailure(conn, onClose, E.New("no selected outbound")) + return + } if outboundHandler, isHandler := selected.(adapter.ConnectionHandlerEx); isHandler { outboundHandler.NewConnectionEx(ctx, conn, metadata, onClose) } else { @@ -169,6 +181,10 @@ func (s *Selector) NewConnectionEx(ctx context.Context, conn net.Conn, metadata func (s *Selector) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) { ctx = interrupt.ContextWithIsExternalConnection(ctx) selected := s.selected.Load() + if selected == nil { + N.CloseOnHandshakeFailure(conn, onClose, E.New("no selected outbound")) + return + } if outboundHandler, isHandler := selected.(adapter.PacketConnectionHandlerEx); isHandler { outboundHandler.NewPacketConnectionEx(ctx, conn, metadata, onClose) } else { @@ -178,6 +194,9 @@ func (s *Selector) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, func (s *Selector) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) { selected := s.selected.Load() + if selected == nil { + return nil, E.New("no selected outbound") + } if !common.Contains(selected.Network(), metadata.Network) { return nil, E.New(metadata.Network, " is not supported by outbound: ", selected.Tag()) }