Spaces:
Paused
Paused
File size: 1,485 Bytes
81205f1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | package utils
import (
"net"
"strings"
)
// ShouldForceRelay checks if the system is likely behind a restrictive VPN or CGNAT
// and returns true if we should force TURN usage.
func ShouldForceRelay() bool {
interfaces, err := net.Interfaces()
if err != nil {
return false
}
// 1. Define the CGNAT range (100.64.0.0/10)
// Cloudflare WARP, Tailscale, and Carrier Grade NATs use this.
// If we are on one of these, direct P2P often fails or requires relay anyway.
_, cgnatBlock, _ := net.ParseCIDR("100.64.0.0/10")
for _, iface := range interfaces {
// Ignore loopback and down interfaces
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
continue
}
// 2. Check Interface Name Heuristics
name := strings.ToLower(iface.Name)
if strings.Contains(name, "tun") || // Standard VPNs (OpenVPN, etc)
strings.Contains(name, "tap") || // Virtual adapters
strings.Contains(name, "wg") || // WireGuard
strings.Contains(name, "ppp") || // Point-to-Point
strings.Contains(name, "warp") { // Explicit WARP
return true
}
// 3. Check IP Addresses for CGNAT
addrs, err := iface.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
// If we find an IP inside 100.64.0.0/10, we are likely behind WARP or CGNAT
if cgnatBlock.Contains(ip) {
return true
}
}
}
return false
}
|