Przeglądaj źródła

Parallelize IP detection and tighten OK() semantics

Review follow-ups:

- Run the IPv4 and IPv6 detection in runSNICheck concurrently. With
  the new three-endpoint fallback in getIP, sequential detection could
  extend proxy startup by up to 30s per family on a slow/blocked
  network. Parallel detection bounds the worst case to roughly 30s
  total instead of 60s.
- Make sniCheckResult.OK() self-consistent: it now returns false when
  the hostname cannot be resolved or no public IP family is known,
  so callers cannot mistakenly treat 'cannot check' as 'all clear'.
pull/474/head
dolonet 2 tygodni temu
rodzic
commit
ec5e97cf78
1 zmienionych plików z 31 dodań i 12 usunięć
  1. 31
    12
      internal/cli/sni_check.go

+ 31
- 12
internal/cli/sni_check.go Wyświetl plik

@@ -3,6 +3,7 @@ package cli
3 3
 import (
4 4
 	"context"
5 5
 	"net"
6
+	"sync"
6 7
 
7 8
 	"github.com/9seconds/mtg/v2/internal/config"
8 9
 	"github.com/9seconds/mtg/v2/mtglib"
@@ -29,15 +30,25 @@ func (r sniCheckResult) Known() bool {
29 30
 	return r.OurIPv4 != nil || r.OurIPv6 != nil
30 31
 }
31 32
 
32
-// OK reports whether every detected public IP family matches a resolved
33
-// record. A partial match (one family matches, another does not) is not OK.
33
+// OK reports whether the check produced a clean result: the hostname was
34
+// resolved, at least one public IP family is known, and every known family
35
+// matches a resolved record.
34 36
 func (r sniCheckResult) OK() bool {
35
-	return r.ResolveErr == nil && r.IPv4Match && r.IPv6Match
37
+	if r.Host == "" {
38
+		return true
39
+	}
40
+
41
+	if r.ResolveErr != nil || !r.Known() {
42
+		return false
43
+	}
44
+
45
+	return r.IPv4Match && r.IPv6Match
36 46
 }
37 47
 
38 48
 // runSNICheck resolves conf.Secret.Host and compares the result with the
39 49
 // server's public IPv4 and IPv6. Public IPs come from config first and fall
40
-// back to on-the-fly detection via ntw.
50
+// back to on-the-fly detection via ntw. IP detection for the two families
51
+// runs concurrently.
41 52
 func runSNICheck(ctx context.Context,
42 53
 	resolver *net.Resolver,
43 54
 	conf *config.Config,
@@ -64,15 +75,23 @@ func runSNICheck(ctx context.Context,
64 75
 		res.Resolved = append(res.Resolved, a.IP)
65 76
 	}
66 77
 
67
-	res.OurIPv4 = conf.PublicIPv4.Get(nil)
68
-	if res.OurIPv4 == nil {
69
-		res.OurIPv4 = getIP(ntw, "tcp4")
70
-	}
78
+	wg := sync.WaitGroup{}
71 79
 
72
-	res.OurIPv6 = conf.PublicIPv6.Get(nil)
73
-	if res.OurIPv6 == nil {
74
-		res.OurIPv6 = getIP(ntw, "tcp6")
75
-	}
80
+	wg.Go(func() {
81
+		res.OurIPv4 = conf.PublicIPv4.Get(nil)
82
+		if res.OurIPv4 == nil {
83
+			res.OurIPv4 = getIP(ntw, "tcp4")
84
+		}
85
+	})
86
+
87
+	wg.Go(func() {
88
+		res.OurIPv6 = conf.PublicIPv6.Get(nil)
89
+		if res.OurIPv6 == nil {
90
+			res.OurIPv6 = getIP(ntw, "tcp6")
91
+		}
92
+	})
93
+
94
+	wg.Wait()
76 95
 
77 96
 	res.IPv4Match = res.OurIPv4 == nil
78 97
 	res.IPv6Match = res.OurIPv6 == nil

Ładowanie…
Anuluj
Zapisz