|
|
@@ -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
|