package app import ( "git.makemake.in/test/mycommon/mylog" "io" "math/rand" "net" "sync" "time" ) var ( wg = &sync.WaitGroup{} ) func Run() { rand.Seed(time.Now().UnixNano()) for name, item := range ProxyMap { wg.Add(1) go listenTcp(name, item) } wg.Wait() } func listenTcp(name string, item ProxyItem) { defer wg.Done() listen, err := net.Listen("tcp", item.LocalAddr) if err != nil { mylog.Errorf("[%s] listen err: %s", name, err) return } mylog.Infof("[%s] listen %s", name, item.LocalAddr) for { conn, err := listen.Accept() if err != nil { mylog.Errorf("conn accept err: %s", item.LocalAddr, err) return } go proxyTcp(conn, item) } } func proxyTcp(conn net.Conn, item ProxyItem) { randRemoteAddr := item.RemoteAddr[rand.Intn(len(item.RemoteAddr))] remoteConn, err := net.Dial("tcp", randRemoteAddr) if err != nil { mylog.Errorf("connect remote err: %s\n", err) return } go copyConn(randRemoteAddr, conn, remoteConn) } func copyConn(addr string, conn, remoteConn net.Conn) { mylog.Infof("start proxy: %s", addr) wg2 := &sync.WaitGroup{} wg2.Add(2) go func() { _, err := io.Copy(conn, remoteConn) if err != nil { mylog.Error(err) return } wg2.Done() }() go func() { _, err := io.Copy(remoteConn, conn) if err != nil { mylog.Error(err) return } wg2.Done() }() wg2.Wait() mylog.Infof("stop proxy: %s", addr) }