proxyport/app/proxy.go

110 lines
2.0 KiB
Go
Raw Normal View History

2023-01-18 14:33:17 +08:00
package app
import (
2023-04-18 20:55:50 +08:00
"context"
2024-06-24 14:24:35 +08:00
"fmt"
2023-04-21 18:20:54 +08:00
"git.makemake.in/kzkzzzz/mycommon/mylog"
2023-01-18 14:33:17 +08:00
"io"
2023-01-19 11:34:30 +08:00
"math/rand"
2023-01-18 14:33:17 +08:00
"net"
2023-04-18 20:55:50 +08:00
"os"
"os/signal"
2023-01-19 11:34:30 +08:00
"sync"
2023-04-18 20:55:50 +08:00
"syscall"
2023-01-19 11:34:30 +08:00
"time"
)
2023-04-18 20:55:50 +08:00
var (
mainWg = &sync.WaitGroup{}
mainCtx, mainCancel = context.WithCancel(context.Background())
)
2023-01-18 14:33:17 +08:00
func Run() {
2024-06-24 14:24:35 +08:00
for name, item := range Conf.Proxy {
2023-01-19 11:34:30 +08:00
go listenTcp(name, item)
2023-01-18 14:33:17 +08:00
}
2023-04-18 20:55:50 +08:00
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
v := <-ch
mylog.Infof("捕获退出信号: %s", v.String())
mainCancel()
mainWg.Wait()
mylog.Info("stop")
2023-01-18 14:33:17 +08:00
}
2023-01-19 11:34:30 +08:00
func listenTcp(name string, item ProxyItem) {
2024-06-24 14:24:35 +08:00
fmt.Printf("%+v\n", item.LocalAddr)
2023-01-19 11:34:30 +08:00
listen, err := net.Listen("tcp", item.LocalAddr)
2023-01-18 14:33:17 +08:00
if err != nil {
2023-01-19 11:34:30 +08:00
mylog.Errorf("[%s] listen err: %s", name, err)
2023-01-18 14:33:17 +08:00
return
}
2023-01-19 11:34:30 +08:00
mylog.Infof("[%s] listen %s", name, item.LocalAddr)
2023-01-18 14:33:17 +08:00
for {
2023-04-18 11:07:36 +08:00
localConn, err := listen.Accept()
2023-01-18 14:33:17 +08:00
if err != nil {
2023-01-19 11:34:30 +08:00
mylog.Errorf("conn accept err: %s", item.LocalAddr, err)
2023-01-18 14:33:17 +08:00
return
}
2023-04-18 20:55:50 +08:00
mainWg.Add(1)
2023-04-18 11:07:36 +08:00
go proxyTcp(localConn, item)
2023-01-18 14:33:17 +08:00
}
}
2023-04-18 11:07:36 +08:00
func proxyTcp(localConn net.Conn, item ProxyItem) {
2023-04-18 20:55:50 +08:00
defer mainWg.Done()
2023-01-19 11:34:30 +08:00
randRemoteAddr := item.RemoteAddr[rand.Intn(len(item.RemoteAddr))]
2023-01-18 14:33:17 +08:00
2023-04-18 11:07:36 +08:00
remoteConn, err := net.DialTimeout("tcp", randRemoteAddr, time.Second*3)
2023-01-19 11:34:30 +08:00
if err != nil {
2023-04-18 11:07:36 +08:00
localConn.Close()
mylog.Errorf("connect remote err: %s", err)
2023-01-19 11:34:30 +08:00
return
2023-01-18 14:33:17 +08:00
}
2023-04-18 11:07:36 +08:00
mylog.Infof("start proxy %s -> %s", localConn.RemoteAddr(), randRemoteAddr)
2023-01-18 14:33:17 +08:00
2023-04-18 20:55:50 +08:00
waitCh := make(chan struct{})
go func() {
wg0 := &sync.WaitGroup{}
wg0.Add(2)
go copyConn(wg0, localConn, remoteConn)
go copyConn(wg0, remoteConn, localConn)
wg0.Wait()
close(waitCh)
}()
select {
case <-waitCh:
case <-mainCtx.Done():
localConn.Close()
remoteConn.Close()
}
2023-01-19 11:34:30 +08:00
2023-04-18 11:07:36 +08:00
mylog.Infof("stop proxy %s -> %s", localConn.RemoteAddr(), randRemoteAddr)
2023-01-18 14:33:17 +08:00
2023-04-18 11:07:36 +08:00
}
2023-01-18 14:33:17 +08:00
2023-04-18 11:07:36 +08:00
func copyConn(wg0 *sync.WaitGroup, localConn, remoteConn net.Conn) {
defer func() {
wg0.Done()
localConn.Close()
remoteConn.Close()
2023-01-19 11:34:30 +08:00
}()
2023-04-18 11:07:36 +08:00
_, err := io.Copy(remoteConn, localConn)
if err != nil {
mylog.Error(err)
}
2023-01-18 14:33:17 +08:00
}