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
This commit is contained in:
Fijxu 2025-02-13 02:00:57 -03:00
parent 53d04ac79b
commit 197a807b90
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4

83
main.go
View file

@ -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 {