123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- 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)
- }
- }
|