urltest: Remember the last choice when there is no valid result

This commit is contained in:
世界 2024-02-02 11:27:36 +08:00
parent 17aebc56c1
commit b85725c009
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
1 changed files with 22 additions and 10 deletions

View File

@ -125,7 +125,18 @@ func (s *URLTest) CheckOutbounds() {
func (s *URLTest) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { func (s *URLTest) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
s.group.Touch() s.group.Touch()
outbound := s.group.Select(network) var outbound adapter.Outbound
switch N.NetworkName(network) {
case N.NetworkTCP:
outbound = s.group.selectedOutboundTCP
case N.NetworkUDP:
outbound = s.group.selectedOutboundUDP
default:
return nil, E.Extend(N.ErrUnknownNetwork, network)
}
if outbound == nil {
outbound, _ = s.group.Select(network)
}
if outbound == nil { if outbound == nil {
return nil, E.New("missing supported outbound") return nil, E.New("missing supported outbound")
} }
@ -140,7 +151,10 @@ func (s *URLTest) DialContext(ctx context.Context, network string, destination M
func (s *URLTest) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { func (s *URLTest) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
s.group.Touch() s.group.Touch()
outbound := s.group.Select(N.NetworkUDP) outbound := s.group.selectedOutboundUDP
if outbound == nil {
outbound, _ = s.group.Select(N.NetworkUDP)
}
if outbound == nil { if outbound == nil {
return nil, E.New("missing supported outbound") return nil, E.New("missing supported outbound")
} }
@ -271,7 +285,7 @@ func (g *URLTestGroup) Close() error {
return nil return nil
} }
func (g *URLTestGroup) Select(network string) adapter.Outbound { func (g *URLTestGroup) Select(network string) (adapter.Outbound, bool) {
var minDelay uint16 var minDelay uint16
var minTime time.Time var minTime time.Time
var minOutbound adapter.Outbound var minOutbound adapter.Outbound
@ -294,11 +308,11 @@ func (g *URLTestGroup) Select(network string) adapter.Outbound {
if !common.Contains(detour.Network(), network) { if !common.Contains(detour.Network(), network) {
continue continue
} }
minOutbound = detour return detour, false
break
} }
return nil, false
} }
return minOutbound return minOutbound, true
} }
func (g *URLTestGroup) loopCheck() { func (g *URLTestGroup) loopCheck() {
@ -382,14 +396,12 @@ func (g *URLTestGroup) urlTest(ctx context.Context, force bool) (map[string]uint
} }
func (g *URLTestGroup) performUpdateCheck() { func (g *URLTestGroup) performUpdateCheck() {
outbound := g.Select(N.NetworkTCP)
var updated bool var updated bool
if outbound != nil && outbound != g.selectedOutboundTCP { if outbound, exists := g.Select(N.NetworkTCP); outbound != nil && (g.selectedOutboundTCP == nil || (exists && outbound != g.selectedOutboundTCP)) {
g.selectedOutboundTCP = outbound g.selectedOutboundTCP = outbound
updated = true updated = true
} }
outbound = g.Select(N.NetworkUDP) if outbound, exists := g.Select(N.NetworkUDP); outbound != nil && (g.selectedOutboundUDP == nil || (exists && outbound != g.selectedOutboundUDP)) {
if outbound != nil && outbound != g.selectedOutboundUDP {
g.selectedOutboundUDP = outbound g.selectedOutboundUDP = outbound
updated = true updated = true
} }