init commit
This commit is contained in:
78
core/ping.go
Normal file
78
core/ping.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PingResult contains the result of a ping to a server.
|
||||
type PingResult struct {
|
||||
Ms int64 // round-trip time in ms, -1 if failed
|
||||
Color string
|
||||
}
|
||||
|
||||
// PingAddress pings a single address using TCP connect (ICMP requires elevated privileges).
|
||||
// Returns round-trip time in ms or -1 on failure.
|
||||
func PingAddress(address string, timeout time.Duration) int64 {
|
||||
if timeout == 0 {
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
conn, err := net.DialTimeout("tcp", address+":443", timeout)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
conn.Close()
|
||||
return time.Since(start).Milliseconds()
|
||||
}
|
||||
|
||||
// PingConfig pings a VPN config and returns the result.
|
||||
func PingConfig(config *VpnConfig) PingResult {
|
||||
link := TryParseLink(config.Link)
|
||||
if link == nil {
|
||||
return PingResult{Ms: -1, Color: "#666"}
|
||||
}
|
||||
|
||||
ms := PingAddress(link.Address, 3*time.Second)
|
||||
if ms < 0 {
|
||||
return PingResult{Ms: -1, Color: "#666"}
|
||||
}
|
||||
return PingResult{Ms: ms, Color: GetPingColor(ms)}
|
||||
}
|
||||
|
||||
// PingAllConfigs pings all configs concurrently.
|
||||
func PingAllConfigs(configs []VpnConfig) []PingResult {
|
||||
results := make([]PingResult, len(configs))
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := range configs {
|
||||
wg.Add(1)
|
||||
go func(idx int) {
|
||||
defer wg.Done()
|
||||
results[idx] = PingConfig(&configs[idx])
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return results
|
||||
}
|
||||
|
||||
// GetPingColor returns a color hex code based on ping latency.
|
||||
func GetPingColor(ms int64) string {
|
||||
switch {
|
||||
case ms < 50:
|
||||
return "#4CAF50" // green
|
||||
case ms < 100:
|
||||
return "#8BC34A" // light green
|
||||
case ms < 150:
|
||||
return "#CDDC39" // lime
|
||||
case ms < 200:
|
||||
return "#FFC107" // amber
|
||||
case ms < 300:
|
||||
return "#FF9800" // orange
|
||||
default:
|
||||
return "#E53935" // red
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user