Created
May 2, 2023 18:18
-
-
Save stzsch/2b1de33d55cf2de89498ea648ccaf182 to your computer and use it in GitHub Desktop.
mullvad ping windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"io/ioutil" | |
"net/http" | |
"os/exec" | |
"sort" | |
"strconv" | |
"strings" | |
"sync" | |
) | |
const URL = "https://api.mullvad.net/www/relays/all/" | |
const NumFastestServers = 10 | |
type Server struct { | |
Hostname string `json:"hostname"` | |
CountryCode string `json:"country_code"` | |
CountryName string `json:"country_name"` | |
CityCode string `json:"city_code"` | |
CityName string `json:"city_name"` | |
Active bool `json:"active"` | |
Type string `json:"type"` | |
IPv4AddrIn string `json:"ipv4_addr_in"` | |
IPv6AddrIn string `json:"ipv6_addr_in"` | |
NetworkPort int `json:"network_port_speed"` | |
Latency float64 // New field to store the calculated latency | |
} | |
var servers []*Server | |
func main() { | |
response, err := http.Get(URL) | |
if err != nil { | |
fmt.Println("Request Error", err.Error()) | |
return | |
} | |
defer response.Body.Close() | |
body, err := ioutil.ReadAll(response.Body) | |
jsonErr := json.Unmarshal(body, &servers) | |
if jsonErr != nil { | |
fmt.Println(jsonErr) | |
return | |
} | |
var wg sync.WaitGroup | |
fmt.Printf("There are %d active servers\n", len(servers)) | |
for _, server := range servers { | |
wg.Add(1) | |
go pingServer(server, &wg) | |
} | |
wg.Wait() | |
// Filter servers with latency over 0ms | |
fastServers := make([]*Server, 0) | |
for _, server := range servers { | |
if server.Latency > 0 { | |
fastServers = append(fastServers, server) | |
} | |
} | |
// Sort servers by latency in ascending order | |
sort.Slice(fastServers, func(i, j int) bool { | |
return fastServers[i].Latency < fastServers[j].Latency | |
}) | |
// Print the 10 fastest servers | |
fmt.Println("The 10 fastest servers:") | |
for i, server := range fastServers { | |
if i >= 10 { | |
break | |
} | |
fmt.Printf("%d. %s - Latency: %.2f ms\n", i+1, server.Hostname, server.Latency) | |
} | |
} | |
func pingServer(server *Server, wg *sync.WaitGroup) { | |
defer wg.Done() | |
cmd := exec.Command("ping", "-n", "4", server.IPv4AddrIn) | |
output, err := cmd.CombinedOutput() | |
if err != nil { | |
fmt.Printf("Failed to ping server %s: %s\n", server.Hostname, err) | |
return | |
} | |
lines := strings.Split(string(output), "\r\n") | |
var latency float64 | |
for _, line := range lines { | |
if strings.Contains(line, "Minimum =") && strings.Contains(line, "Maximum =") && strings.Contains(line, "Average =") { | |
fields := strings.Fields(line) | |
if len(fields) >= 9 { | |
latencyStr := strings.TrimSuffix(fields[8], "ms") | |
latency, err = strconv.ParseFloat(latencyStr, 64) | |
if err != nil { | |
fmt.Printf("Failed to parse latency for server %s: %s\n", server.Hostname, err) | |
return | |
} | |
} | |
break | |
} | |
} | |
server.Latency = latency | |
fmt.Printf("Server %s - Latency: %.2f ms\n", server.Hostname, server.Latency) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment