Files
zurg/pkg/realdebrid/network.go
2024-01-11 00:12:40 +01:00

115 lines
5.7 KiB
Go

package realdebrid
import (
"fmt"
"os/exec"
"sort"
"strconv"
"strings"
"sync"
"time"
)
type IPInfo struct {
Address string
Hops int
Latency time.Duration
}
func traceroute(ip string) (int, time.Duration, error) {
cmd := exec.Command("traceroute", "-n", "-q", "1", "-w", "1", ip)
out, err := cmd.CombinedOutput()
if err != nil {
return 0, 0, err
}
output := string(out)
lines := strings.Split(output, "\n")
hopCount := len(lines) - 1
var latency time.Duration
if hopCount > 0 {
lastLine := lines[hopCount-1]
fmt.Printf("IP: %s, last hop: %s\n", ip, lastLine)
parts := strings.Fields(lastLine)
if len(parts) >= 3 {
latencyValue, parseErr := strconv.ParseFloat(parts[2], 64)
if parseErr == nil {
latency = time.Duration(latencyValue * float64(time.Millisecond))
}
}
}
return hopCount, latency, nil
}
func RunTest() {
fmt.Println("Running network test...")
ips := []string{"20.download.real-debrid.cloud", "20.download.real-debrid.com", "21.download.real-debrid.cloud", "21.download.real-debrid.com", "22.download.real-debrid.cloud", "22.download.real-debrid.com", "23.download.real-debrid.cloud", "23.download.real-debrid.com", "30.download.real-debrid.cloud", "30.download.real-debrid.com", "31.download.real-debrid.cloud", "31.download.real-debrid.com", "32.download.real-debrid.cloud", "32.download.real-debrid.com", "34.download.real-debrid.cloud", "34.download.real-debrid.com", "40.download.real-debrid.cloud", "40.download.real-debrid.com", "41.download.real-debrid.cloud", "41.download.real-debrid.com", "42.download.real-debrid.cloud", "42.download.real-debrid.com", "43.download.real-debrid.cloud", "43.download.real-debrid.com", "44.download.real-debrid.cloud", "44.download.real-debrid.com", "45.download.real-debrid.cloud", "45.download.real-debrid.com", "50.download.real-debrid.cloud", "50.download.real-debrid.com", "51.download.real-debrid.cloud", "51.download.real-debrid.com", "52.download.real-debrid.cloud", "52.download.real-debrid.com", "53.download.real-debrid.cloud", "53.download.real-debrid.com", "54.download.real-debrid.cloud", "54.download.real-debrid.com", "55.download.real-debrid.cloud", "55.download.real-debrid.com", "56.download.real-debrid.cloud", "56.download.real-debrid.com", "57.download.real-debrid.cloud", "57.download.real-debrid.com", "58.download.real-debrid.cloud", "58.download.real-debrid.com", "59.download.real-debrid.cloud", "59.download.real-debrid.com", "60.download.real-debrid.cloud", "60.download.real-debrid.com", "61.download.real-debrid.cloud", "61.download.real-debrid.com", "62.download.real-debrid.cloud", "62.download.real-debrid.com", "63.download.real-debrid.cloud", "63.download.real-debrid.com", "64.download.real-debrid.cloud", "64.download.real-debrid.com", "65.download.real-debrid.cloud", "65.download.real-debrid.com", "66.download.real-debrid.cloud", "66.download.real-debrid.com", "67.download.real-debrid.cloud", "67.download.real-debrid.com", "68.download.real-debrid.cloud", "68.download.real-debrid.com", "69.download.real-debrid.cloud", "69.download.real-debrid.com", "70.download.real-debrid.cloud", "70.download.real-debrid.com", "71.download.real-debrid.cloud", "71.download.real-debrid.com", "72.download.real-debrid.cloud", "72.download.real-debrid.com", "73.download.real-debrid.cloud", "73.download.real-debrid.com", "74.download.real-debrid.cloud", "74.download.real-debrid.com", "75.download.real-debrid.cloud", "75.download.real-debrid.com", "76.download.real-debrid.cloud", "76.download.real-debrid.com", "77.download.real-debrid.cloud", "77.download.real-debrid.com", "78.download.real-debrid.cloud", "78.download.real-debrid.com", "79.download.real-debrid.cloud", "79.download.real-debrid.com", "80.download.real-debrid.com", "ams1.download.real-debrid.com", "hkg1.download.real-debrid.com", "jkt1.download.real-debrid.com", "lax1.download.real-debrid.com", "lax2.download.real-debrid.com", "lax3.download.real-debrid.com", "lax4.download.real-debrid.com", "lax5.download.real-debrid.com", "lon1.download.real-debrid.com", "mum1.download.real-debrid.com", "sgp1.download.real-debrid.com", "tlv1.download.real-debrid.com", "tyo1.download.real-debrid.com"}
var wg sync.WaitGroup
infoChan := make(chan IPInfo, len(ips))
semaphore := make(chan struct{}, 10)
for _, ip := range ips {
wg.Add(1)
semaphore <- struct{}{}
go func(ip string) {
defer wg.Done()
hops, latency, err := traceroute(ip)
if err != nil {
fmt.Println("Error performing traceroute:", err)
} else {
infoChan <- IPInfo{Address: ip, Hops: hops, Latency: latency}
}
<-semaphore
}(ip)
}
wg.Wait()
close(semaphore)
close(infoChan)
fmt.Printf("Network test complete.\n\n")
var ipInfos []IPInfo
for info := range infoChan {
ipInfos = append(ipInfos, info)
}
sort.Slice(ipInfos, func(i, j int) bool {
return ipInfos[i].Latency < ipInfos[j].Latency
})
const minResults = 10
const maxResults = 20
var okIPs []IPInfo
if len(ipInfos) > 0 {
// Start by adding the best IPs based on hops and latency up to the minResults
for i := 0; i < min(len(ipInfos), minResults); i++ {
okIPs = append(okIPs, ipInfos[i])
}
// Find the highest latency in the current okIPs list
highestLatency := okIPs[len(okIPs)-1].Latency
// Add any additional IPs that have latency within a reasonable range of the highest latency
for _, info := range ipInfos[minResults:] {
if len(okIPs) >= maxResults {
break // Stop adding IPs if maxResults is reached
}
if info.Latency <= highestLatency+(highestLatency/3) {
okIPs = append(okIPs, info)
}
}
}
fmt.Printf("Here are the results, you can copy-paste the following to your config.yml:\n\n")
fmt.Println("preferred_hosts:")
for _, info := range okIPs {
fmt.Printf(" - %s # hops: %d latency: %v\n", info.Address, info.Hops, info.Latency)
}
}