github.com/bepass-org/wireguard-go@v1.0.4-rc2.0.20240304192354-ebce6572bc24/wiresocks/scanner.go (about) 1 package wiresocks 2 3 import ( 4 "context" 5 "crypto/rand" 6 "fmt" 7 "net" 8 "net/netip" 9 "strings" 10 "time" 11 12 "github.com/bepass-org/ipscanner" 13 "github.com/bepass-org/wireguard-go/warp" 14 "github.com/go-ini/ini" 15 ) 16 17 func canConnectIPv6(remoteAddr netip.AddrPort) bool { 18 dialer := net.Dialer{ 19 Timeout: 5 * time.Second, 20 } 21 22 conn, err := dialer.Dial("tcp6", remoteAddr.String()) 23 if err != nil { 24 return false 25 } 26 defer conn.Close() 27 return true 28 } 29 30 func RunScan(ctx context.Context, rtt time.Duration) (result []string, err error) { 31 cfg, err := ini.Load("./primary/wgcf-profile.ini") 32 if err != nil { 33 return nil, fmt.Errorf("failed to read file: %w", err) 34 } 35 36 // Reading the private key from the 'Interface' section 37 privateKey := cfg.Section("Interface").Key("PrivateKey").String() 38 39 // Reading the public key from the 'Peer' section 40 publicKey := cfg.Section("Peer").Key("PublicKey").String() 41 42 // TODO: ipscanner doesn't support netip.Prefix yet 43 prefixes := warp.WarpPrefixes() 44 stringedPrefixes := make([]string, len(prefixes)) 45 for i, p := range prefixes { 46 stringedPrefixes[i] = p.String() 47 } 48 49 // new scanner 50 scanner := ipscanner.NewScanner( 51 ipscanner.WithWarpPing(), 52 ipscanner.WithWarpPrivateKey(privateKey), 53 ipscanner.WithWarpPeerPublicKey(publicKey), 54 ipscanner.WithUseIPv6(canConnectIPv6(netip.MustParseAddrPort("[2001:4860:4860::8888]:80"))), 55 ipscanner.WithUseIPv4(true), 56 ipscanner.WithMaxDesirableRTT(int(rtt.Milliseconds())), 57 ipscanner.WithCidrList(stringedPrefixes), 58 ) 59 60 scanner.Run() 61 timeoutTimer := time.NewTimer(2 * time.Minute) 62 defer timeoutTimer.Stop() 63 64 for { 65 select { 66 case <-ctx.Done(): 67 // Context is done - canceled externally 68 scanner.Stop() 69 return nil, fmt.Errorf("user canceled the operation") 70 case <-timeoutTimer.C: 71 // Handle the internal timeout 72 scanner.Stop() 73 return nil, fmt.Errorf("scanner maximum time exceeded") 74 default: 75 ipList := scanner.GetAvailableIPS() 76 if len(ipList) > 1 { 77 scanner.Stop() 78 for i := 0; i < 2; i++ { 79 result = append(result, ipToAddress(ipList[i])) 80 } 81 return result, nil 82 } 83 time.Sleep(1 * time.Second) // Prevent the loop from spinning too fast 84 } 85 } 86 } 87 88 func ipToAddress(ip net.IP) string { 89 ports := []int{500, 854, 859, 864, 878, 880, 890, 891, 894, 903, 908, 928, 934, 939, 942, 90 943, 945, 946, 955, 968, 987, 988, 1002, 1010, 1014, 1018, 1070, 1074, 1180, 1387, 1701, 91 1843, 2371, 2408, 2506, 3138, 3476, 3581, 3854, 4177, 4198, 4233, 4500, 5279, 92 5956, 7103, 7152, 7156, 7281, 7559, 8319, 8742, 8854, 8886} 93 94 // Pick a random port number 95 b := make([]byte, 8) 96 n, err := rand.Read(b) 97 if n != 8 { 98 panic(n) 99 } else if err != nil { 100 panic(err) 101 } 102 serverAddress := fmt.Sprintf("%s:%d", ip.String(), ports[int(b[0])%len(ports)]) 103 if strings.Contains(ip.String(), ":") { 104 //ip6 105 serverAddress = fmt.Sprintf("[%s]:%d", ip.String(), ports[int(b[0])%len(ports)]) 106 } 107 return serverAddress 108 }