From 197a807b90b58f1ad67e980d91abb2dd6082896f Mon Sep 17 00:00:00 2001 From: Fijxu Date: Thu, 13 Feb 2025 02:00:57 -0300 Subject: [PATCH] feat: func to rotate the IP address from gluetun automatically depending of the traffic this is supposed to execute every second to be able to calulate the difference of the transmitted bytes fuck fuck fuck: change block checker cooldown back to 60 seconds --- main.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/main.go b/main.go index 20b9f2b..b5985d1 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( "os" "regexp" "runtime" + "strconv" "strings" "sync/atomic" "syscall" @@ -21,6 +22,7 @@ import ( "github.com/conduitio/bwlimit" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/prometheus/procfs" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/http3" ) @@ -325,27 +327,57 @@ func requestPerMinute() { } } -func forbiddenRequestsPerSec() { - var last int64 +var tx uint64 + +func blockCheckerCalc(p *procfs.Proc) { + var last uint64 for { time.Sleep(1 * time.Second) - current := stats_.RequestsForbidden.Videoplayback - stats_.RequestsForbiddenPerSec.Videoplayback = current - last - // fmt.Println(aux) - // if aux > 15 { - // body := "{\"status\":\"stopped\"}\"" - // request, err := http.NewRequest("PUT", "http://gluetun:8000", strings.NewReader(body)) - // if err != nil { - // log.Panic(err) - // } - // client.Do(request) - // } - // metrics.RequestPerSecond.Set(float64(stats_.RequestPerSecond)) - // time.Sleep(60 * time.Second) + // p.NetDev should never fail. + stat, _ := p.NetDev() + current := stat.Total().TxBytes + tx = current - last last = current } } +// Detects if a backend has been blocked based on the amount of bandwidth +// reported by procfs. +// This may be the best way to detect if the IP has been blocked from googlevideo +// servers. I would like to detect blockages using the status code that googlevideo +// returns, which most of the time is 403 (Forbidden). But this error code is not +// exclusive to IP blocks, it's also returned for other reasons like a wrong +// query parameter like `pot` (po_token) or anything like that. +func blockChecker(gh string, cooldown int) { + log.Println("[INFO] Starting blockchecker") + // Sleep for 60 seconds before commencing the loop + time.Sleep(60 * time.Second) + url := "http://" + gh + "/v1/openvpn/status" + + p, err := procfs.Self() + if err != nil { + log.Printf("[ERROR] [procfs]: Could not get process: %s\n", err) + log.Println("[INFO] Blockchecker will not run, so if the VPN IP used on gluetun gets blocked, it will not be rotated!") + return + } + go blockCheckerCalc(&p) + + for { + time.Sleep(time.Duration(cooldown) * time.Second) + if float64(tx)*0.000008 < 2.0 { + body := "{\"status\":\"stopped\"}\"" + // This should never fail too + request, _ := http.NewRequest("PUT", url, strings.NewReader(body)) + _, err = client.Do(request) + if err != nil { + log.Printf("[ERROR] Failed to send request to gluetun.") + } else { + log.Printf("[INFO] Request to change IP sent to gluetun successfully") + } + } + } +} + func beforeMisc(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { defer panicHandler(w) @@ -408,6 +440,7 @@ func main() { var https bool = false var h3c bool = false var ipv6 bool = false + var bc bool = true if strings.ToLower(os.Getenv("HTTPS")) == "true" { https = true @@ -421,6 +454,9 @@ func main() { if strings.ToLower(os.Getenv("IPV6_ONLY")) == "true" { ipv6 = true } + if strings.ToLower(os.Getenv("BLOCK_CHECKER")) == "false" { + bc = false + } if strings.ToLower(os.Getenv("DOMAIN_ONLY_ACCESS")) == "true" { domain_only_access = true } @@ -445,6 +481,15 @@ func main() { if host == "" { host = defaultHost } + // gh is where the gluetun api is located + gh := os.Getenv("GLUETUN_HOSTNAME") + if gh == "" { + gh = "127.0.0.1:8000" + } + bc_cooldown := os.Getenv("BLOCK_CHECKER_COOLDOWN") + if bc_cooldown == "" { + bc_cooldown = "60" + } proxy = os.Getenv("PROXY") flag.BoolVar(&https, "https", https, "Use built-in https server (recommended)") @@ -508,7 +553,13 @@ func main() { go requestPerSecond() go requestPerMinute() - go forbiddenRequestsPerSec() + if bc { + num, err := strconv.Atoi(bc_cooldown) + if err != nil { + log.Fatalf("[FATAL] Error while setting BLOCK_CHECKER_COOLDOWN: %s", err) + } + go blockChecker(gh, num) + } ln, err := net.Listen("tcp", host+":"+port) if err != nil {