package main import ( "container/list" "flag" "fmt" "io" "io/fs" "io/ioutil" "log" "net" "net/http" "os" "path/filepath" "time" ) var ( ipcenteraddr = flag.String("centeraddr", "127.0.0.1:60910", "IP代理中心地址") //IP代理中心地址 addr = flag.String("addr", ":18080", "跳板socks5监听地址") monitorAddr = flag.String("maddr", ":18081", "监控地址") connectTimeout = flag.Int64("cto", 90, "网络链接超时") currentTargetAddr = "" //当前环境IP cache = list.New() diskCacheDir = flag.String("cachedir", "./cache_dir", "用户缓存目录位置") //userDataDir = flag.String("userdir", "./user_dir", "用户数据目录位置") //poolMinLimit = flag.Int("pl", 3, "IP池最少容量") //ipOilLifeLimit = flag.Int("ipol", 90, "IP剩余最少可用秒数") //no = flag.String("no", "1", "编号") //ip *IpPool ) // init func init() { flag.Parse() } // forward func forward(src, dest io.ReadWriteCloser) { defer func() { //fmt.Print("@") if src != nil { _ = src.Close() } if dest != nil { _ = dest.Close() } }() if src == nil || dest == nil { return } _, _ = io.Copy(src, dest) } // processClient func processClient(client net.Conn) { defer func() { if err := recover(); err != nil { fmt.Printf("{err %v}", err) } }() var targetConn net.Conn var err error for { //默认复用上一次可用IP targetConn, err = net.DialTimeout("tcp", currentTargetAddr, time.Duration(*connectTimeout)*time.Second) //fmt.Println("check ip:", currentTargetAddr) if err == nil { break } //跳板主动切换IP currentTargetAddr = getIp() fmt.Println("自主检测,切换本机IP:", currentTargetAddr) } //fmt.Printf("{%s %s}", *no, currentTargetAddr) cache.PushBack([2]net.Conn{client, targetConn}) go forward(client, targetConn) go forward(targetConn, client) } // changeIp 切换代理IP,被动切换IP func changeIp() { currentTargetAddr = getIp() fmt.Println("ChangeIp:", currentTargetAddr) for e := cache.Front(); e != nil; e = e.Next() { connes, _ := e.Value.([2](net.Conn)) if connes[0].Close() != nil { connes[0].Close() } if connes[1].Close() != nil { connes[0].Close() } } } // clearTrace func clearTrace() { if *diskCacheDir != "" { filepath.Walk(*diskCacheDir, func(path string, info fs.FileInfo, err error) error { if err == nil && info != nil && !info.IsDir() { os.Remove(path) } return nil }) } } // monitor func monitor() { //最好是单实例调用 http.HandleFunc("/changeip", func(w http.ResponseWriter, r *http.Request) { changeIp() w.Write([]byte("ok")) }) http.HandleFunc("/cleartrace", func(w http.ResponseWriter, r *http.Request) { clearTrace() w.Write([]byte("ok")) }) http.ListenAndServe(*monitorAddr, nil) } func getIp() string { defer Catch() var ip string for i := 1; i <= 3; i++ { url := "http://" + *ipcenteraddr + "/getip" client := &http.Client{Timeout: time.Second * 5} resp, err := client.Get(url) //resp, err := http.Get(url) if err != nil { continue } bs, err := ioutil.ReadAll(resp.Body) if err != nil { continue } resp.Body.Close() ip = string(bs) break } return ip } // main func main() { conn, err := net.Listen("tcp", *addr) if err != nil { log.Fatal(err) return } // go monitor() // currentTargetAddr = getIp() fmt.Println("当前环境IP:", currentTargetAddr) // for { client, err := conn.Accept() if err != nil { log.Fatalf("Listen failed: %v\n", err) continue } go processClient(client) } }