update
This commit is contained in:
parent
c485d070a3
commit
d2feccf3b3
2
go.mod
2
go.mod
@ -14,6 +14,7 @@ require (
|
||||
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9
|
||||
github.com/goftp/server v0.0.0-20200708154336-f64f7c2d8a42
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
github.com/inconshreveable/mousetrap v1.0.1
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/spf13/cobra v1.6.1
|
||||
)
|
||||
@ -22,7 +23,6 @@ require (
|
||||
b612.me/starmap v1.2.3 // indirect
|
||||
b612.me/starnet v0.1.7 // indirect
|
||||
b612.me/win32api v0.0.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jlaffaye/ftp v0.1.0 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/pkg/sftp v1.13.4 // indirect
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
var remote, config string
|
||||
var addr, key, cert, log string
|
||||
var port int
|
||||
var enablessl bool
|
||||
var enablessl, skipsslverify bool
|
||||
var host string
|
||||
|
||||
func init() {
|
||||
@ -23,6 +23,7 @@ func init() {
|
||||
Cmd.Flags().StringVarP(&cert, "cert", "c", "", "ssl 证书地址")
|
||||
Cmd.Flags().StringVarP(&log, "log", "l", "", "log日志地址")
|
||||
Cmd.Flags().BoolVarP(&enablessl, "enable-ssl", "s", false, "启用ssl")
|
||||
Cmd.Flags().BoolVarP(&skipsslverify, "skil-ssl-verify", "S", false, "跳过证书验证")
|
||||
Cmd.Flags().IntVarP(&port, "port", "p", 8080, "监听端口")
|
||||
}
|
||||
|
||||
@ -69,11 +70,12 @@ var Cmd = &cobra.Command{
|
||||
ReverseURL: map[string]*url.URL{
|
||||
"/": u,
|
||||
},
|
||||
Port: port,
|
||||
UsingSSL: enablessl,
|
||||
Key: key,
|
||||
Cert: cert,
|
||||
XForwardMode: 1,
|
||||
Port: port,
|
||||
UsingSSL: enablessl,
|
||||
SkipSSLVerify: skipsslverify,
|
||||
Key: key,
|
||||
Cert: cert,
|
||||
XForwardMode: 1,
|
||||
}
|
||||
go func() {
|
||||
sig := make(chan os.Signal)
|
||||
|
@ -12,23 +12,24 @@ import (
|
||||
)
|
||||
|
||||
type ReverseConfig struct {
|
||||
Name string
|
||||
Addr string
|
||||
ReverseURL map[string]*url.URL
|
||||
Port int
|
||||
UsingSSL bool
|
||||
Key string
|
||||
Cert string
|
||||
Host string
|
||||
InHeader [][2]string
|
||||
OutHeader [][2]string
|
||||
Cookie [][3]string //[3]string should contains path::key::value
|
||||
ReplaceList [][2]string
|
||||
ReplaceOnce bool
|
||||
proxy map[string]*httputil.ReverseProxy
|
||||
XForwardMode int //0=off 1=useremote 2=add
|
||||
httpmux http.ServeMux
|
||||
httpserver http.Server
|
||||
Name string
|
||||
Addr string
|
||||
ReverseURL map[string]*url.URL
|
||||
Port int
|
||||
UsingSSL bool
|
||||
Key string
|
||||
Cert string
|
||||
Host string
|
||||
SkipSSLVerify bool
|
||||
InHeader [][2]string
|
||||
OutHeader [][2]string
|
||||
Cookie [][3]string //[3]string should contains path::key::value
|
||||
ReplaceList [][2]string
|
||||
ReplaceOnce bool
|
||||
proxy map[string]*httputil.ReverseProxy
|
||||
XForwardMode int //0=off 1=useremote 2=add
|
||||
httpmux http.ServeMux
|
||||
httpserver http.Server
|
||||
|
||||
basicAuthUser string
|
||||
basicAuthPwd string
|
||||
|
@ -4,9 +4,11 @@ import (
|
||||
"b612.me/starlog"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
@ -75,10 +77,61 @@ func (h *ReverseConfig) Close() error {
|
||||
return h.httpserver.Shutdown(ctx)
|
||||
}
|
||||
|
||||
func (h *ReverseConfig) dialTLS(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
conn, err := net.DialTimeout(network, addr, time.Second*20)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.Host != "" {
|
||||
host = h.Host
|
||||
}
|
||||
cfg := &tls.Config{ServerName: host}
|
||||
tlsConn := tls.Client(conn, cfg)
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
conn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs := tlsConn.ConnectionState()
|
||||
cert := cs.PeerCertificates[0]
|
||||
|
||||
// Verify here
|
||||
if !h.SkipSSLVerify {
|
||||
err = cert.VerifyHostname(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return tlsConn, nil
|
||||
}
|
||||
|
||||
func (h *ReverseConfig) init() error {
|
||||
h.proxy = make(map[string]*httputil.ReverseProxy)
|
||||
for key, val := range h.ReverseURL {
|
||||
h.proxy[key] = httputil.NewSingleHostReverseProxy(val)
|
||||
h.proxy[key] = &httputil.ReverseProxy{
|
||||
Transport: &http.Transport{DialTLSContext: h.dialTLS},
|
||||
Director: func(req *http.Request) {
|
||||
targetQuery := val.RawQuery
|
||||
req.URL.Scheme = val.Scheme
|
||||
if h.Host == "" {
|
||||
req.Host = val.Host
|
||||
} else {
|
||||
req.Host = h.Host
|
||||
}
|
||||
req.URL.Host = val.Host
|
||||
req.URL.Path, req.URL.RawPath = joinURLPath(val, req.URL)
|
||||
if targetQuery == "" || req.URL.RawQuery == "" {
|
||||
req.URL.RawQuery = targetQuery + req.URL.RawQuery
|
||||
} else {
|
||||
req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
|
||||
}
|
||||
},
|
||||
}
|
||||
h.proxy[key].ModifyResponse = h.ModifyResponse()
|
||||
originalDirector := h.proxy[key].Director
|
||||
h.proxy[key].Director = func(req *http.Request) {
|
||||
|
5
main.go
5
main.go
@ -16,6 +16,7 @@ import (
|
||||
"b612.me/apps/b612/httpserver"
|
||||
"b612.me/apps/b612/image"
|
||||
"b612.me/apps/b612/merge"
|
||||
"b612.me/apps/b612/net"
|
||||
"b612.me/apps/b612/search"
|
||||
"b612.me/apps/b612/split"
|
||||
"b612.me/apps/b612/tcping"
|
||||
@ -29,7 +30,7 @@ import (
|
||||
|
||||
var cmdRoot = &cobra.Command{
|
||||
Use: "b612",
|
||||
Version: "2.0.1",
|
||||
Version: "2.0.2",
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -37,7 +38,7 @@ func init() {
|
||||
cmdRoot.AddCommand(tcping.Cmd, uac.Cmd, httpserver.Cmd, httpreverse.Cmd,
|
||||
base64.Cmd, base85.Cmd, base91.Cmd, attach.Cmd, detach.Cmd, df.Cmd, dfinder.Cmd,
|
||||
ftp.Cmd, generate.Cmd, hash.Cmd, image.Cmd, merge.Cmd, search.Cmd, split.Cmd, vic.Cmd,
|
||||
calc.Cmd)
|
||||
calc.Cmd, net.Cmd)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
14
net/cmd.go
14
net/cmd.go
@ -1 +1,15 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"b612.me/apps/b612/netforward"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var Cmd = &cobra.Command{
|
||||
Use: "net",
|
||||
Short: "net tools",
|
||||
}
|
||||
|
||||
func init() {
|
||||
Cmd.AddCommand(netforward.CmdNetforward)
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
package net
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestForward(t *testing.T) {
|
||||
var f = NetForward{
|
||||
LocalAddr: "127.0.0.1",
|
||||
LocalPort: 22232,
|
||||
RemoteURI: "127.0.0.1:1127",
|
||||
EnableTCP: true,
|
||||
EnableUDP: true,
|
||||
DialTimeout: 0,
|
||||
UDPTimeout: 0,
|
||||
}
|
||||
f.Run()
|
||||
}
|
159
net/natserver.go
159
net/natserver.go
@ -1,27 +1,27 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"b612.me/starlog"
|
||||
"bytes"
|
||||
"errors"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
var MSG_CMD_HELLO = []byte{11, 27, 19, 96, 182, 18, 25, 150, 17, 39}
|
||||
var MSG_NEW_CONN = []byte{0, 0, 0, 0, 255, 255, 255, 255, 11, 27}
|
||||
var MSG_NEW_CONN_REQ = []byte{0, 0, 0, 0, 255, 255, 255, 255, 19, 96}
|
||||
var MSG_CLOSE = []byte{255, 255, 0, 0, 255, 0, 0, 255, 255, 27}
|
||||
var MSG_HEARTBEAT = []byte{6, 66, 66, 6, 6, 66, 6, 66, 11, 27}
|
||||
// MSG_CMD_HELLO 控制链路主动链接参头 16byte
|
||||
var MSG_CMD_HELLO, _ = hex.DecodeString("B6121127AF7ECDA1")
|
||||
var MSG_CMD_HELLO_REPLY, _ = hex.DecodeString("B6121127AF7ECDA2")
|
||||
|
||||
type SimpleNatServer struct {
|
||||
mu sync.RWMutex
|
||||
// MSG_NEW_CONN_HELLO 交链路主动连接头 16byte
|
||||
var MSG_NEW_CONN_HELLO, _ = hex.DecodeString("B6121127AF7ECDFF")
|
||||
|
||||
type NatServer struct {
|
||||
sync.RWMutex
|
||||
cmdTCPConn net.Conn
|
||||
cmdUDPConn *net.UDPAddr
|
||||
listenTcp net.Listener
|
||||
listenUDP *net.UDPConn
|
||||
Addr string
|
||||
@ -32,107 +32,58 @@ type SimpleNatServer struct {
|
||||
DialTimeout int64
|
||||
UDPTimeout int64
|
||||
running int32
|
||||
|
||||
tcpConnPool chan net.Conn
|
||||
tcpAlived bool
|
||||
tcpConnPool chan net.Conn
|
||||
stopCtx context.Context
|
||||
stopFn context.CancelFunc
|
||||
}
|
||||
|
||||
func (s *SimpleNatServer) getConnfromTCPPool() (net.Conn, error) {
|
||||
select {
|
||||
case conn := <-s.tcpConnPool:
|
||||
return conn, nil
|
||||
case <-time.After(time.Second * 10):
|
||||
return nil, errors.New("no connection got")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SimpleNatServer) tcpCmdConn() net.Conn {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.cmdTCPConn
|
||||
}
|
||||
|
||||
func (s *SimpleNatServer) tcpCmdConnAlived() bool {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.tcpAlived
|
||||
}
|
||||
|
||||
func (s *SimpleNatServer) listenTCP() error {
|
||||
var err error
|
||||
s.tcpConnPool = make(chan net.Conn, 10)
|
||||
s.listenTcp, err = net.Listen("tcp", fmt.Sprintf("%s:d", s.Addr, s.Port))
|
||||
if err != nil {
|
||||
starlog.Errorln("failed to listen tcp", err)
|
||||
return err
|
||||
}
|
||||
for {
|
||||
conn, err := s.listenTcp.Accept()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if s.tcpCmdConnAlived() {
|
||||
go s.tcpClientServe(conn.(*net.TCPConn))
|
||||
continue
|
||||
}
|
||||
go s.waitingForTCPCmd(conn.(*net.TCPConn))
|
||||
func (n *NatServer) Run() error {
|
||||
if n.running != 0 {
|
||||
return fmt.Errorf("Server Already Run")
|
||||
}
|
||||
n.stopCtx, n.stopFn = context.WithCancel(context.Background())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SimpleNatServer) tcpClientServe(conn *net.TCPConn) {
|
||||
if !s.tcpCmdConnAlived() {
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
func (n *NatServer) cmdTcploop(conn net.Conn) error {
|
||||
var header = make([]byte, 16)
|
||||
for {
|
||||
c, err := conn.Read(header)
|
||||
if err != nil {
|
||||
//todo
|
||||
}
|
||||
if c != 16 {
|
||||
|
||||
if strings.Split(conn.RemoteAddr().String(), ":")[0] == strings.Split(s.tcpCmdConn().RemoteAddr().String(), ":")[0] {
|
||||
conn.SetReadDeadline(time.Now().Add(5 * time.Second))
|
||||
cmdBuf := make([]byte, 10)
|
||||
if _, err := io.ReadFull(conn, cmdBuf); err == nil {
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
if bytes.Equal(cmdBuf, MSG_NEW_CONN) {
|
||||
starlog.Noticef("Nat Server Recv New Client Conn From %v\n", conn.RemoteAddr().String())
|
||||
s.tcpConnPool <- conn
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NatServer) runTcpListen() error {
|
||||
atomic.AddInt32(&n.running, 1)
|
||||
defer atomic.AddInt32(&n.running, -1)
|
||||
listener, err := net.Listen("tcp", n.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.listenTcp = listener
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
headedr := make([]byte, 16)
|
||||
conn.SetReadDeadline(time.Now().Add(time.Millisecond * 700))
|
||||
c, err := conn.Read(headedr)
|
||||
if err == nil && c == 16 {
|
||||
if bytes.Equal(headedr, MSG_CMD_HELLO) {
|
||||
if n.cmdTCPConn != nil {
|
||||
n.cmdTCPConn.Close()
|
||||
}
|
||||
n.cmdTCPConn = conn
|
||||
conn.Write(MSG_CMD_HELLO_REPLY)
|
||||
//
|
||||
}
|
||||
}
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
}
|
||||
starlog.Noticef("Nat Server Recv New Side Conn From %v\n", conn.RemoteAddr().String())
|
||||
_, err := s.tcpCmdConn().Write(MSG_NEW_CONN_REQ)
|
||||
if err != nil {
|
||||
s.mu.Lock()
|
||||
s.cmdTCPConn.Close()
|
||||
s.tcpAlived = false
|
||||
s.mu.Unlock()
|
||||
starlog.Errorf("Failed to Write CMD To Client:%v\n", err)
|
||||
return
|
||||
}
|
||||
reverse, err := s.getConnfromTCPPool()
|
||||
if err != nil {
|
||||
starlog.Errorf("Nat Server Conn to %v Closed %v\n", conn.RemoteAddr(), err)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
starlog.Infof("Nat Server Conn %v<==>%v Connected\n", conn.RemoteAddr(), reverse.RemoteAddr())
|
||||
Copy(reverse, conn)
|
||||
starlog.Warningf("Nat Server Conn %v<==>%v Closed\n", conn.RemoteAddr(), reverse.RemoteAddr())
|
||||
}
|
||||
|
||||
func (s *SimpleNatServer) waitingForTCPCmd(conn *net.TCPConn) {
|
||||
conn.SetReadDeadline(time.Now().Add(time.Duration(s.DialTimeout) * time.Second))
|
||||
cmdBuf := make([]byte, 10)
|
||||
if _, err := io.ReadFull(conn, cmdBuf); err != nil {
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
if bytes.Equal(cmdBuf, MSG_CMD_HELLO) {
|
||||
s.mu.Lock()
|
||||
s.cmdTCPConn = conn
|
||||
s.tcpAlived = true
|
||||
conn.SetKeepAlive(true)
|
||||
conn.SetKeepAlivePeriod(time.Second * 20)
|
||||
s.mu.Unlock()
|
||||
io.ReadFull(conn, headedr)
|
||||
}
|
||||
}
|
||||
|
67
netforward/cmd.go
Normal file
67
netforward/cmd.go
Normal file
@ -0,0 +1,67 @@
|
||||
package netforward
|
||||
|
||||
import (
|
||||
"b612.me/stario"
|
||||
"b612.me/starlog"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var f = new(NetForward)
|
||||
var dialTimeout, udpTimeout int64
|
||||
|
||||
func init() {
|
||||
CmdNetforward.Flags().StringVarP(&f.LocalAddr, "local", "l", "0.0.0.0", "bind address")
|
||||
CmdNetforward.Flags().IntVarP(&f.LocalPort, "port", "p", 11270, "local listen port")
|
||||
CmdNetforward.Flags().BoolVarP(&f.EnableTCP, "enable-tcp-forward", "t", true, "enable tcp forward mode")
|
||||
CmdNetforward.Flags().BoolVarP(&f.EnableUDP, "enable-udp-forward", "u", true, "enable udp forward mode")
|
||||
CmdNetforward.Flags().Int64VarP(&dialTimeout, "dial-timeout", "d", 10000, "dial timeout milliseconds")
|
||||
CmdNetforward.Flags().Int64VarP(&udpTimeout, "udp-timeout", "D", 60000, "udp connection timeout milliseconds")
|
||||
}
|
||||
|
||||
var CmdNetforward = &cobra.Command{
|
||||
Use: "forward",
|
||||
Short: "net forward",
|
||||
Long: "forward tcp and udp packet",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
starlog.Errorln("please enter a target uri")
|
||||
os.Exit(1)
|
||||
}
|
||||
f.RemoteURI = strings.TrimSpace(args[0])
|
||||
if dialTimeout == 0 {
|
||||
dialTimeout = 10000
|
||||
}
|
||||
if udpTimeout == 0 {
|
||||
udpTimeout = 60000
|
||||
}
|
||||
f.DialTimeout = time.Duration(dialTimeout) * time.Millisecond
|
||||
f.UDPTimeout = time.Duration(udpTimeout) * time.Millisecond
|
||||
if err := f.Run(); err != nil {
|
||||
starlog.Errorln("run net forward failed:", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
sign := make(chan os.Signal)
|
||||
signal.Notify(sign, os.Interrupt, os.Kill)
|
||||
for {
|
||||
select {
|
||||
case <-sign:
|
||||
starlog.Noticeln("Recv Stop Signal From User")
|
||||
f.stopFn()
|
||||
case <-stario.WaitUntilFinished(func() error {
|
||||
for {
|
||||
if f.Status() == 0 {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}):
|
||||
starlog.Infoln("Service Stoped")
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net
|
||||
package netforward
|
||||
|
||||
import (
|
||||
"b612.me/starlog"
|
||||
@ -28,35 +28,33 @@ type NetForward struct {
|
||||
func (n *NetForward) Close() {
|
||||
n.stopFn()
|
||||
}
|
||||
|
||||
func (n *NetForward) Status() int32 {
|
||||
return n.running
|
||||
}
|
||||
|
||||
func (n *NetForward) Run() error {
|
||||
if !atomic.CompareAndSwapInt32(&n.running, 0, 1) {
|
||||
if n.running > 0 {
|
||||
starlog.Errorln("already running")
|
||||
return errors.New("already running")
|
||||
}
|
||||
n.stopCtx, n.stopFn = context.WithCancel(context.Background())
|
||||
if n.DialTimeout == 0 {
|
||||
n.DialTimeout = time.Second * 10
|
||||
n.DialTimeout = time.Second * 5
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
if n.EnableTCP {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
n.runTCP()
|
||||
}()
|
||||
go n.runTCP()
|
||||
}
|
||||
|
||||
if n.EnableUDP {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
n.runUDP()
|
||||
}()
|
||||
go n.runUDP()
|
||||
}
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NetForward) runTCP() error {
|
||||
atomic.AddInt32(&n.running, 1)
|
||||
defer atomic.AddInt32(&n.running, -1)
|
||||
listen, err := net.Listen("tcp", fmt.Sprintf("%s:%d", n.LocalAddr, n.LocalPort))
|
||||
if err != nil {
|
||||
starlog.Errorln("Listening On Tcp Failed:", err)
|
||||
@ -68,6 +66,11 @@ func (n *NetForward) runTCP() error {
|
||||
}()
|
||||
starlog.Infof("Listening TCP on %v\n", fmt.Sprintf("%s:%d", n.LocalAddr, n.LocalPort))
|
||||
for {
|
||||
select {
|
||||
case <-n.stopCtx.Done():
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
conn, err := listen.Accept()
|
||||
if err != nil {
|
||||
continue
|
||||
@ -77,13 +80,13 @@ func (n *NetForward) runTCP() error {
|
||||
go func(conn net.Conn) {
|
||||
rmt, err := net.DialTimeout("tcp", n.RemoteURI, n.DialTimeout)
|
||||
if err != nil {
|
||||
log.Errorf("Dial Remote %s Failed:%v\n", n.RemoteURI, err)
|
||||
log.Errorf("TCP:Dial Remote %s Failed:%v\n", n.RemoteURI, err)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
log.Infof("Connect %s <==> %s\n", conn.RemoteAddr().String(), n.RemoteURI)
|
||||
log.Infof("TCP Connect %s <==> %s\n", conn.RemoteAddr().String(), rmt.RemoteAddr().String())
|
||||
Copy(rmt, conn)
|
||||
log.Noticef("Connection Closed %s <==> %s", conn.RemoteAddr().String(), n.RemoteURI)
|
||||
log.Noticef("TCP Connection Closed %s <==> %s", conn.RemoteAddr().String(), n.RemoteURI)
|
||||
}(conn)
|
||||
}
|
||||
}
|
||||
@ -124,6 +127,8 @@ func (u UDPConn) Work() {
|
||||
|
||||
func (n *NetForward) runUDP() error {
|
||||
var mu sync.RWMutex
|
||||
atomic.AddInt32(&n.running, 1)
|
||||
defer atomic.AddInt32(&n.running, -1)
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%v", n.LocalAddr, n.LocalPort))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -148,7 +153,7 @@ func (n *NetForward) runUDP() error {
|
||||
for k, v := range udpMap {
|
||||
if time.Now().Unix() > int64(n.UDPTimeout.Seconds())+v.lastbeat {
|
||||
delete(udpMap, k)
|
||||
starlog.Noticef("Connection Closed %s <==> %s", v.remoteAddr.String(), n.RemoteURI)
|
||||
starlog.Noticef("UDP Connection Closed %s <==> %s\n", v.remoteAddr.String(), n.RemoteURI)
|
||||
}
|
||||
}
|
||||
mu.Unlock()
|
||||
@ -157,6 +162,11 @@ func (n *NetForward) runUDP() error {
|
||||
}()
|
||||
buf := make([]byte, 8192)
|
||||
for {
|
||||
select {
|
||||
case <-n.stopCtx.Done():
|
||||
return nil
|
||||
default:
|
||||
}
|
||||
count, rmt, err := listen.ReadFromUDP(buf)
|
||||
if err != nil || rmt.String() == n.RemoteURI {
|
||||
continue
|
||||
@ -169,7 +179,7 @@ func (n *NetForward) runUDP() error {
|
||||
log.Infof("Accept New UDP Conn from %v\n", rmt.String())
|
||||
conn, err := net.Dial("udp", n.RemoteURI)
|
||||
if err != nil {
|
||||
log.Errorf("Dial Remote %s Failed:%v\n", n.RemoteURI, err)
|
||||
log.Errorf("UDP:Dial Remote %s Failed:%v\n", n.RemoteURI, err)
|
||||
mu.Unlock()
|
||||
return
|
||||
}
|
||||
@ -181,7 +191,7 @@ func (n *NetForward) runUDP() error {
|
||||
}
|
||||
udpMap[rmt.String()] = addr
|
||||
go addr.Work()
|
||||
log.Infof("Connect %s <==> %s\n", rmt.String(), n.RemoteURI)
|
||||
log.Infof("UDP Connect %s <==> %s\n", rmt.String(), n.RemoteURI)
|
||||
}
|
||||
mu.Unlock()
|
||||
_, err := addr.Write(data)
|
||||
@ -190,7 +200,7 @@ func (n *NetForward) runUDP() error {
|
||||
addr.Close()
|
||||
delete(udpMap, addr.remoteAddr.String())
|
||||
mu.Unlock()
|
||||
log.Noticef("Connection Closed %s <==> %s", rmt.String(), n.RemoteURI)
|
||||
log.Noticef("UDP Connection Closed %s <==> %s\n", rmt.String(), n.RemoteURI)
|
||||
}
|
||||
}(buf[0:count], rmt)
|
||||
}
|
33
netforward/forward_test.go
Normal file
33
netforward/forward_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
package netforward
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestForward(t *testing.T) {
|
||||
var f = NetForward{
|
||||
LocalAddr: "127.0.0.1",
|
||||
LocalPort: 22232,
|
||||
RemoteURI: "192.168.2.1:80",
|
||||
EnableTCP: true,
|
||||
EnableUDP: true,
|
||||
DialTimeout: 6 * time.Second,
|
||||
UDPTimeout: 7 * time.Second,
|
||||
}
|
||||
f.Run()
|
||||
go func() {
|
||||
time.Sleep(time.Second * 10)
|
||||
fmt.Println("closing")
|
||||
f.Close()
|
||||
}()
|
||||
for {
|
||||
time.Sleep(time.Second * 2)
|
||||
if f.Status() > 0 {
|
||||
fmt.Println(f.Status())
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user