diff --git a/AUTHORIZATION.md b/AUTHORIZATION.md new file mode 100644 index 0000000..e63463a --- /dev/null +++ b/AUTHORIZATION.md @@ -0,0 +1,13 @@ +# GoProxy特殊授权 + +1.goproxy采用GPLv3源代码开放协议,未经许可,基于本项目开发的软件,衍生软件,相关软件,必须严格遵守GPLv3,否则一经发现, +将严厉追责. + +2.如果公司或个人使用本项目代码开发相关软件,衍生软件,又不想遵守GPLv3协议,需要取得作者的"GoProxy特殊授权"书面授权. + +3.如果本页面查询不到"GoProxy特殊授权"书面授权信息,则"GoProxy特殊授权"书面授权无效. + +4.下面列出了有效的授权编号和有效期. + +授权编号 | 授权有效期 +:--- | :--- diff --git a/CHANGELOG b/CHANGELOG index df86b9e..b5c3541 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,14 @@ proxy更新日志 v6.1 1.黑白名单支持设置顶级域了,比如:com,匹配所有的.com域名 +2.优化TCPS内存释放. +3.优化了域名检查. +4.内网穿透增加了TCPS和TOU协议, + TCPS提供了多种自定义加密TCP方式传输. + TOU提供了TCP over UDP,多种自定义加密UDP方式传输TCP数据. +5.优化了DST,防止意外crash. +6.修复了mapx的Keys()方法的bug导致内网穿透bridge不稳定的问题. +7.修复了部分服务不能绑定IPv6地址的bug. v6.0 企业版开源啦 本次更新主要是把企业版开源,把企业版代码合并到现在的开源goproxy当中,继续遵循GPLv3,免费开源, diff --git a/README.md b/README.md index dcf266e..91312c8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5, ss **[全平台图形界面版本](/gui/README.md)** -**[全平台SDK](/sdk/README.md)** +**[全平台SDK](/sdk/README.md)** + +**[GoProxy特殊授权](/AUTHORIZATION.md)** ### How to contribute to the code (Pull Request)? diff --git a/README_ZH.md b/README_ZH.md index 867aae3..86c687e 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -13,6 +13,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5,ss代理服 **[全平台SDK](/sdk/README.md)** +**[GoProxy特殊授权](/AUTHORIZATION.md)** + ### 如何贡献代码(Pull Request)? 欢迎加入一起发展壮大proxy.首先需要clone本项目到自己的帐号下面, @@ -523,7 +525,7 @@ HTTP(S)代理支持上级负载均衡,多个上级重复-P参数即可. #### **1.14.3 使用目标地址选择上级** -`proxy http --lb-hashtarget --lb-method=leasttime -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -t tcp -p :33080` +`proxy http --lb-hashtarget --lb-method=hash -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -t tcp -p :33080` ### **1.15 限速** @@ -989,7 +991,7 @@ SOCKS代理支持上级负载均衡,多个上级重复-P参数即可. #### **5.12.3 使用目标地址选择上级** -`proxy socks --lb-hashtarget --lb-method=leasttime -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp` +`proxy socks --lb-hashtarget --lb-method=hash -T tcp -P 1.1.1.1:33080 -P 2.1.1.1:33080 -P 3.1.1.1:33080 -p :33080 -t tcp` #### **5.13 限速** diff --git a/config.go b/config.go index c97ebc7..5cbfc88 100755 --- a/config.go +++ b/config.go @@ -12,12 +12,14 @@ import ( "path/filepath" "runtime/debug" "runtime/pprof" + "strings" "time" + "github.com/snail007/goproxy/core/lib/kcpcfg" + encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt" sdk "github.com/snail007/goproxy/sdk/android-ios" services "github.com/snail007/goproxy/services" httpx "github.com/snail007/goproxy/services/http" - "github.com/snail007/goproxy/services/kcpcfg" keygenx "github.com/snail007/goproxy/services/keygen" mux "github.com/snail007/goproxy/services/mux" socksx "github.com/snail007/goproxy/services/socks" @@ -147,7 +149,7 @@ func initConfig() (err error) { //########mux-server######### muxServer := app.Command("server", "proxy on mux server mode") muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() - muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "kcp") + muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou") muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() @@ -157,11 +159,15 @@ func initConfig() (err error) { muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool() muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int() muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() + muxServerArgs.TCPSMethod = muxServer.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxServerArgs.TCPSPassword = muxServer.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() + muxServerArgs.TOUMethod = muxServer.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxServerArgs.TOUPassword = muxServer.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String() //########mux-client######### muxClient := app.Command("client", "proxy on mux client mode") muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() - muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "kcp") + muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou") muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() @@ -169,6 +175,10 @@ func initConfig() (err error) { muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool() muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int() muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() + muxClientArgs.TCPSMethod = muxClient.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxClientArgs.TCPSPassword = muxClient.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() + muxClientArgs.TOUMethod = muxClient.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxClientArgs.TOUPassword = muxClient.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String() //########mux-bridge######### muxBridge := app.Command("bridge", "proxy on mux bridge mode") @@ -176,7 +186,11 @@ func initConfig() (err error) { muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() - muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type ").Default("tls").Short('t').Enum("tls", "tcp", "kcp") + muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type ").Default("tls").Short('t').Enum("tls", "tcp", "tcps", "kcp", "tou") + muxBridgeArgs.TCPSMethod = muxBridge.Flag("tcps-method", "method of local tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxBridgeArgs.TCPSPassword = muxBridge.Flag("tcps-password", "password of local tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() + muxBridgeArgs.TOUMethod = muxBridge.Flag("tou-method", "method of local tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxBridgeArgs.TOUPassword = muxBridge.Flag("tou-password", "password of local tou's encrpyt/decrypt").Default("snail007's_goproxy").String() //########tunnel-server######### tunnelServer := app.Command("tserver", "proxy on tunnel server mode") @@ -418,7 +432,7 @@ func initConfig() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() for { @@ -442,7 +456,7 @@ func initConfig() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() for scanner.Scan() { @@ -452,7 +466,7 @@ func initConfig() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() for scannerStdErr.Scan() { diff --git a/core/cs/client/client.go b/core/cs/client/client.go index 43d5aa9..3e13a07 100644 --- a/core/cs/client/client.go +++ b/core/cs/client/client.go @@ -35,6 +35,9 @@ func TlsConnect(host string, port, timeout int, certBytes, keyBytes, caCertBytes } return *tls.Client(_conn, conf), err } +func TlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) { + return getRequestTlsConfig(certBytes, keyBytes, caCertBytes) +} func getRequestTlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) { var cert tls.Certificate diff --git a/core/cs/server/server.go b/core/cs/server/server.go index ff623f6..fd83c75 100644 --- a/core/cs/server/server.go +++ b/core/cs/server/server.go @@ -120,7 +120,7 @@ func (s *ServerChannel) listenTLS(ip string, port int, certBytes, keyBytes, caCe config.ClientCAs = clientCertPool config.ClientAuth = tls.RequireAndVerifyClientCert } - _ln, err := tls.Listen("tcp", fmt.Sprintf("%s:%d", ip, port), config) + _ln, err := tls.Listen("tcp", net.JoinHostPort(ip, fmt.Sprintf("%d", port)), config) if err == nil { ln = &_ln } @@ -141,7 +141,7 @@ func (s *ServerChannel) ListenTCPS(method, password string, compress bool, fn fu } func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) { var l net.Listener - l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.ip, s.port)) + l, err = net.Listen("tcp", net.JoinHostPort(s.ip, fmt.Sprintf("%d", s.port))) if err == nil { s.Listener = &l go func() { @@ -172,7 +172,7 @@ func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) { } return } -func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net.UDPAddr)) (err error) { +func (s *ServerChannel) ListenUDP(fn func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr)) (err error) { addr := &net.UDPAddr{IP: net.ParseIP(s.ip), Port: s.port} l, err := net.ListenUDP("udp", addr) if err == nil { @@ -194,7 +194,7 @@ func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net s.log.Printf("udp data handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) } }() - fn(packet, addr, srcAddr) + fn(s.UDPListener, packet, addr, srcAddr) }() } else { s.errAcceptHandler(err) @@ -207,7 +207,7 @@ func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net return } func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn), log *logger.Logger) (err error) { - lis, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", s.ip, s.port), config.Block, *config.DataShard, *config.ParityShard) + lis, err := kcp.ListenWithOptions(net.JoinHostPort(s.ip, fmt.Sprintf("%d", s.port)), config.Block, *config.DataShard, *config.ParityShard) if err == nil { if err = lis.SetDSCP(*config.DSCP); err != nil { log.Println("SetDSCP:", err) @@ -230,7 +230,6 @@ func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net. } }() for { - //var conn net.Conn conn, err := lis.AcceptKCP() if err == nil { go func() { diff --git a/core/dst/conn.go b/core/dst/conn.go index 4543ec1..3a32df7 100644 --- a/core/dst/conn.go +++ b/core/dst/conn.go @@ -137,7 +137,7 @@ func (c *Conn) start() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() c.reader() @@ -433,6 +433,12 @@ func (c *Conn) String() string { // Read can be made to time out and return a Error with Timeout() == true // after a fixed time limit; see SetDeadline and SetReadDeadline. func (c *Conn) Read(b []byte) (n int, err error) { + defer func() { + if e := recover(); e != nil { + n = 0 + err = io.EOF + } + }() c.inbufMut.Lock() defer c.inbufMut.Unlock() for c.inbuf.Len() == 0 { @@ -497,6 +503,9 @@ func (c *Conn) Write(b []byte) (n int, err error) { // Close closes the connection. // Any blocked Read or Write operations will be unblocked and return errors. func (c *Conn) Close() error { + defer func() { + _ = recover() + }() c.closeOnce.Do(func() { if debugConnection { log.Println(c, "explicit close start") diff --git a/core/dst/mux.go b/core/dst/mux.go index 967e73c..934deda 100644 --- a/core/dst/mux.go +++ b/core/dst/mux.go @@ -82,7 +82,7 @@ func NewMux(conn net.PacketConn, packetSize int) *Mux { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() m.readerLoop() diff --git a/core/dst/sendbuffer.go b/core/dst/sendbuffer.go index 5e53f17..406dcd5 100644 --- a/core/dst/sendbuffer.go +++ b/core/dst/sendbuffer.go @@ -56,7 +56,7 @@ func newSendBuffer(m *Mux) *sendBuffer { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() b.writerLoop() diff --git a/core/lib/mapx/map.go b/core/lib/mapx/map.go index 651a818..8d25ffb 100644 --- a/core/lib/mapx/map.go +++ b/core/lib/mapx/map.go @@ -155,7 +155,7 @@ func (m ConcurrentMap) Iter() <-chan Tuple { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() fanIn(chans, ch) @@ -174,7 +174,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() fanIn(chans, ch) @@ -195,7 +195,7 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) { go func(index int, shard *ConcurrentMapShared) { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() // Foreach key, value pair. @@ -221,7 +221,7 @@ func fanIn(chans []chan Tuple, out chan Tuple) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() func(ch chan Tuple) { @@ -274,7 +274,7 @@ func (m ConcurrentMap) Keys() []string { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() // Foreach shard. @@ -284,7 +284,7 @@ func (m ConcurrentMap) Keys() []string { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() func(shard *ConcurrentMapShared) { diff --git a/core/lib/udp/udp.go b/core/lib/udp/udp.go index cf417c5..386ae48 100644 --- a/core/lib/udp/udp.go +++ b/core/lib/udp/udp.go @@ -62,7 +62,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() buf := make([]byte, 1) @@ -75,7 +75,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() for { @@ -96,7 +96,7 @@ func (s *IOBinder) AliveWithClientConn(srcAddr string, outTCPConn *net.Conn) *IO go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() buf := make([]byte, 1) @@ -156,7 +156,7 @@ func (s *IOBinder) Run() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() defer func() { diff --git a/core/tproxy/tproxy.go b/core/tproxy/tproxy.go index ca754c2..221491c 100644 --- a/core/tproxy/tproxy.go +++ b/core/tproxy/tproxy.go @@ -81,7 +81,7 @@ func dtoi(s string, i0 int) (n int, i int, ok bool) { return n, i, true } -// IPTcpAddrToUnixSocksAddr --- +// IPTcpAddrToUnixSocksAddr returns Sockaddr for specified TCP addr. func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) { if Debug { fmt.Println("DEBUG: IPTcpAddrToUnixSocksAddr recieved address:", addr) @@ -97,7 +97,7 @@ func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) { return ipToSocksAddr(ipType(addr), tcpAddr.IP, tcpAddr.Port, tcpAddr.Zone) } -// IPv6UdpAddrToUnixSocksAddr --- +// IPv6UdpAddrToUnixSocksAddr returns Sockaddr for specified IPv6 addr. func IPv6UdpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) { tcpAddr, err := net.ResolveTCPAddr("udp6", addr) if err != nil { diff --git a/install_auto.sh b/install_auto.sh index 32bf059..5202b6b 100755 --- a/install_auto.sh +++ b/install_auto.sh @@ -5,7 +5,7 @@ if [ -e /tmp/proxy ]; then fi mkdir /tmp/proxy cd /tmp/proxy -wget https://github.com/snail007/goproxy/releases/download/v6.0/proxy-linux-amd64.tar.gz +wget https://github.com/snail007/goproxy/releases/download/v6.1/proxy-linux-amd64.tar.gz # #install proxy tar zxvf proxy-linux-amd64.tar.gz diff --git a/main.go b/main.go index 84345f6..b502e3b 100644 --- a/main.go +++ b/main.go @@ -36,7 +36,7 @@ func Clean(s *services.Service) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() for _ = range signalChan { diff --git a/sdk/android-ios/dns.go b/sdk/android-ios/dns.go index 9d74926..228f750 100644 --- a/sdk/android-ios/dns.go +++ b/sdk/android-ios/dns.go @@ -13,8 +13,8 @@ import ( "github.com/miekg/dns" gocache "github.com/pmylund/go-cache" + "github.com/snail007/goproxy/core/lib/kcpcfg" services "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" ) type DNSArgs struct { @@ -60,7 +60,7 @@ func (s *DNS) InitService() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() for { @@ -142,7 +142,7 @@ func (s *DNS) Start(args interface{}, log *logger.Logger) (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() log.Printf("dns server on udp %s", *s.cfg.Local) diff --git a/sdk/android-ios/sdk.go b/sdk/android-ios/sdk.go index 7178e03..1eb1252 100644 --- a/sdk/android-ios/sdk.go +++ b/sdk/android-ios/sdk.go @@ -10,9 +10,10 @@ import ( "path/filepath" "strings" + "github.com/snail007/goproxy/core/lib/kcpcfg" + encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt" "github.com/snail007/goproxy/services" httpx "github.com/snail007/goproxy/services/http" - "github.com/snail007/goproxy/services/kcpcfg" keygenx "github.com/snail007/goproxy/services/keygen" mux "github.com/snail007/goproxy/services/mux" socksx "github.com/snail007/goproxy/services/socks" @@ -166,7 +167,7 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback) //########mux-server######### muxServer := app.Command("server", "proxy on mux server mode") muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() - muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "kcp") + muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou") muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() @@ -176,11 +177,15 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback) muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool() muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int() muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() + muxServerArgs.TCPSMethod = muxServer.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxServerArgs.TCPSPassword = muxServer.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() + muxServerArgs.TOUMethod = muxServer.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxServerArgs.TOUPassword = muxServer.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String() //########mux-client######### muxClient := app.Command("client", "proxy on mux client mode") muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() - muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "kcp") + muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type ").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou") muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() @@ -188,6 +193,10 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback) muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool() muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int() muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() + muxClientArgs.TCPSMethod = muxClient.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxClientArgs.TCPSPassword = muxClient.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() + muxClientArgs.TOUMethod = muxClient.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxClientArgs.TOUPassword = muxClient.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String() //########mux-bridge######### muxBridge := app.Command("bridge", "proxy on mux bridge mode") @@ -195,7 +204,11 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback) muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() - muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type ").Default("tls").Short('t').Enum("tls", "tcp", "kcp") + muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type ").Default("tls").Short('t').Enum("tls", "tcp", "tcps", "kcp", "tou") + muxBridgeArgs.TCPSMethod = muxBridge.Flag("tcps-method", "method of local tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxBridgeArgs.TCPSPassword = muxBridge.Flag("tcps-password", "password of local tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() + muxBridgeArgs.TOUMethod = muxBridge.Flag("tou-method", "method of local tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() + muxBridgeArgs.TOUPassword = muxBridge.Flag("tou-password", "password of local tou's encrpyt/decrypt").Default("snail007's_goproxy").String() //########tunnel-server######### tunnelServer := app.Command("tserver", "proxy on tunnel server mode") diff --git a/services/http/http.go b/services/http/http.go index 5685342..5e5008a 100644 --- a/services/http/http.go +++ b/services/http/http.go @@ -12,8 +12,9 @@ import ( "strings" "time" + server "github.com/snail007/goproxy/core/cs/server" + "github.com/snail007/goproxy/core/lib/kcpcfg" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils/datasize" "github.com/snail007/goproxy/utils/dnsx" "github.com/snail007/goproxy/utils/iolimiter" @@ -83,7 +84,7 @@ type HTTP struct { lockChn chan bool domainResolver dnsx.DomainResolver isStop bool - serverChannels []*utils.ServerChannel + serverChannels []*server.ServerChannel userConns mapx.ConcurrentMap log *logger.Logger lb *lb.Group @@ -96,7 +97,7 @@ func NewHTTP() services.Service { basicAuth: utils.BasicAuth{}, lockChn: make(chan bool, 1), isStop: false, - serverChannels: []*utils.ServerChannel{}, + serverChannels: []*server.ServerChannel{}, userConns: mapx.NewConcurrentMap(), } } @@ -172,7 +173,7 @@ func (s *HTTP) InitService() (err error) { s.InitLB() } if *s.cfg.DNSAddress != "" { - (*s).domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log) + s.domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log) } if *s.cfg.ParentType == "ssh" { err = s.ConnectSSH() @@ -183,7 +184,7 @@ func (s *HTTP) InitService() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() //循环检查ssh网络连通性 @@ -273,11 +274,11 @@ func (s *HTTP) Start(args interface{}, log *logger.Logger) (err error) { if addr != "" { host, port, _ := net.SplitHostPort(addr) p, _ := strconv.Atoi(port) - sc := utils.NewServerChannel(host, p, s.log) + sc := server.NewServerChannel(host, p, s.log) if *s.cfg.LocalType == "tcp" { err = sc.ListenTCP(s.callback) } else if *s.cfg.LocalType == "tls" { - err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback) + err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback) } else if *s.cfg.LocalType == "kcp" { err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log) } diff --git a/services/mux/mux_bridge.go b/services/mux/mux_bridge.go index c589e66..c3f76c6 100644 --- a/services/mux/mux_bridge.go +++ b/services/mux/mux_bridge.go @@ -8,30 +8,33 @@ import ( "math/rand" "net" "runtime/debug" - "strconv" "strings" "sync" "time" + srvtransport "github.com/snail007/goproxy/core/cs/server" + "github.com/snail007/goproxy/core/lib/kcpcfg" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/mapx" - //"github.com/xtaci/smux" smux "github.com/hashicorp/yamux" ) type MuxBridgeArgs struct { - CertFile *string - KeyFile *string - CertBytes []byte - KeyBytes []byte - Local *string - LocalType *string - Timeout *int - IsCompress *bool - KCP kcpcfg.KCPConfigArgs + CertFile *string + KeyFile *string + CertBytes []byte + KeyBytes []byte + Local *string + LocalType *string + Timeout *int + IsCompress *bool + KCP kcpcfg.KCPConfigArgs + TCPSMethod *string + TCPSPassword *string + TOUMethod *string + TOUPassword *string } type MuxBridge struct { cfg MuxBridgeArgs @@ -40,7 +43,7 @@ type MuxBridge struct { router utils.ClientKeyRouter l *sync.Mutex isStop bool - sc *utils.ServerChannel + sc *srvtransport.ServerChannel log *logger.Logger } @@ -112,21 +115,27 @@ func (s *MuxBridge) Start(args interface{}, log *logger.Logger) (err error) { return } - host, port, _ := net.SplitHostPort(*s.cfg.Local) - p, _ := strconv.Atoi(port) - sc := utils.NewServerChannel(host, p, s.log) + sc := srvtransport.NewServerChannelHost(*s.cfg.Local, s.log) if *s.cfg.LocalType == "tcp" { err = sc.ListenTCP(s.handler) } else if *s.cfg.LocalType == "tls" { - err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.handler) + err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.handler) } else if *s.cfg.LocalType == "kcp" { err = sc.ListenKCP(s.cfg.KCP, s.handler, s.log) + } else if *s.cfg.LocalType == "tcps" { + err = sc.ListenTCPS(*s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, s.handler) + } else if *s.cfg.LocalType == "tou" { + err = sc.ListenTOU(*s.cfg.TOUMethod, *s.cfg.TOUPassword, false, s.handler) } if err != nil { return } s.sc = &sc - s.log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr()) + if *s.cfg.LocalType == "tou" { + s.log.Printf("%s bridge on %s", *s.cfg.LocalType, sc.UDPListener.LocalAddr()) + } else { + s.log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr()) + } return } func (s *MuxBridge) Clean() { @@ -206,21 +215,25 @@ func (s *MuxBridge) handler(inConn net.Conn) { index := keyInfo[1] s.l.Lock() defer s.l.Unlock() + var group *mapx.ConcurrentMap if !s.clientControlConns.Has(groupKey) { - item := mapx.NewConcurrentMap() - s.clientControlConns.Set(groupKey, &item) + _g := mapx.NewConcurrentMap() + group = &_g + s.clientControlConns.Set(groupKey, group) + //s.log.Printf("init client session group %s", groupKey) + } else { + _group, _ := s.clientControlConns.Get(groupKey) + group = _group.(*mapx.ConcurrentMap) } - _group, _ := s.clientControlConns.Get(groupKey) - group := _group.(*mapx.ConcurrentMap) if v, ok := group.Get(index); ok { v.(*smux.Session).Close() } group.Set(index, session) - // s.clientControlConns.Set(key, session) + //s.log.Printf("set client session %s to group %s,grouplen:%d", index, groupKey, group.Count()) go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() for { @@ -232,10 +245,12 @@ func (s *MuxBridge) handler(inConn net.Conn) { defer s.l.Unlock() if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() { group.Remove(index) + //s.log.Printf("client session %s removed from group %s, grouplen:%d", key, groupKey, group.Count()) s.log.Printf("client connection %s released", key) } if group.IsEmpty() { s.clientControlConns.Remove(groupKey) + //s.log.Printf("client session group %s removed", groupKey) } break } @@ -259,6 +274,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) { if key == "*" { key = s.router.GetKey() } + //s.log.Printf("server get client session %s", key) _group, ok := s.clientControlConns.Get(key) if !ok { s.log.Printf("client %s session not exists for server stream %s, retrying...", key, serverID) @@ -266,8 +282,12 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) { continue } group := _group.(*mapx.ConcurrentMap) - keys := group.Keys() + keys := []string{} + group.IterCb(func(key string, v interface{}) { + keys = append(keys, key) + }) keysLen := len(keys) + //s.log.Printf("client session %s , len:%d , keysLen: %d", key, group.Count(), keysLen) i := 0 if keysLen > 0 { i = rand.Intn(keysLen) @@ -293,7 +313,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() io.Copy(stream, inConn) @@ -302,7 +322,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() io.Copy(inConn, stream) diff --git a/services/mux/mux_client.go b/services/mux/mux_client.go index de445b8..9e9ab6a 100644 --- a/services/mux/mux_client.go +++ b/services/mux/mux_client.go @@ -8,15 +8,17 @@ import ( "net" "runtime/debug" "strings" + "sync" "time" + "github.com/golang/snappy" + clienttransport "github.com/snail007/goproxy/core/cs/client" + "github.com/snail007/goproxy/core/lib/kcpcfg" + encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/mapx" - - "github.com/golang/snappy" //"github.com/xtaci/smux" smux "github.com/hashicorp/yamux" ) @@ -34,6 +36,10 @@ type MuxClientArgs struct { SessionCount *int KCP kcpcfg.KCPConfigArgs Jumper *string + TCPSMethod *string + TCPSPassword *string + TOUMethod *string + TOUPassword *string } type ClientUDPConnItem struct { conn *smux.Stream @@ -140,7 +146,7 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) { defer func() { e := recover() if e != nil { - s.log.Printf("session worker crashed: %s", e) + s.log.Printf("session worker crashed: %s\nstack:%s", e, string(debug.Stack())) } }() for { @@ -154,7 +160,16 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) { continue } conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) - _, err = conn.Write(utils.BuildPacket(CONN_CLIENT, fmt.Sprintf("%s-%d", *s.cfg.Key, i))) + g := sync.WaitGroup{} + g.Add(1) + go func() { + defer func() { + _ = recover() + g.Done() + }() + _, err = conn.Write(utils.BuildPacket(CONN_CLIENT, fmt.Sprintf("%s-%d", *s.cfg.Key, i))) + }() + g.Wait() conn.SetDeadline(time.Time{}) if err != nil { conn.Close() @@ -222,7 +237,7 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) { if *s.cfg.ParentType == "tls" { if s.jumper == nil { var _conn tls.Conn - _conn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, nil) + _conn, err = clienttransport.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, nil) if err == nil { conn = net.Conn(&_conn) } @@ -239,10 +254,22 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) { } } else if *s.cfg.ParentType == "kcp" { - conn, err = utils.ConnectKCPHost(*s.cfg.Parent, s.cfg.KCP) + conn, err = clienttransport.KCPConnectHost(*s.cfg.Parent, s.cfg.KCP) + } else if *s.cfg.ParentType == "tcps" { + if s.jumper == nil { + conn, err = clienttransport.TCPSConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout) + } else { + conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout)) + if err == nil { + conn, err = encryptconn.NewConn(conn, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword) + } + } + + } else if *s.cfg.ParentType == "tou" { + conn, err = clienttransport.TOUConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout) } else { if s.jumper == nil { - conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout) + conn, err = clienttransport.TCPConnectHost(*s.cfg.Parent, *s.cfg.Timeout) } else { conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout)) } @@ -299,14 +326,17 @@ func (s *MuxClient) ServeUDP(inConn *smux.Stream, localAddr, ID string) { item = v.(*ClientUDPConnItem) } (*item).touchtime = time.Now().Unix() - go (*item).udpConn.Write(body) + go func() { + defer func() { _ = recover() }() + (*item).udpConn.Write(body) + }() } } func (s *MuxClient) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() s.log.Printf("udp conn %s connected", ID) @@ -336,7 +366,7 @@ func (s *MuxClient) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() cui.conn.SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) @@ -355,7 +385,7 @@ func (s *MuxClient) UDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() if s.isStop { @@ -414,7 +444,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() io.Copy(outConn, snappy.NewReader(inConn)) @@ -423,7 +453,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() io.Copy(snappy.NewWriter(inConn), outConn) diff --git a/services/mux/mux_server.go b/services/mux/mux_server.go index bb511e4..5d5fb2f 100644 --- a/services/mux/mux_server.go +++ b/services/mux/mux_server.go @@ -12,8 +12,11 @@ import ( "strings" "time" + clienttransport "github.com/snail007/goproxy/core/cs/client" + server "github.com/snail007/goproxy/core/cs/server" + "github.com/snail007/goproxy/core/lib/kcpcfg" + encryptconn "github.com/snail007/goproxy/core/lib/transport/encrypt" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/mapx" @@ -47,10 +50,14 @@ type MuxServerArgs struct { SessionCount *int KCP kcpcfg.KCPConfigArgs Jumper *string + TCPSMethod *string + TCPSPassword *string + TOUMethod *string + TOUPassword *string } type MuxServer struct { cfg MuxServerArgs - sc utils.ServerChannel + sc server.ServerChannel sessions mapx.ConcurrentMap lockChn chan bool isStop bool @@ -133,6 +140,10 @@ func (s *MuxServerManager) Start(args interface{}, log *logger.Logger) (err erro KCP: s.cfg.KCP, ParentType: s.cfg.ParentType, Jumper: s.cfg.Jumper, + TCPSMethod: s.cfg.TCPSMethod, + TCPSPassword: s.cfg.TCPSPassword, + TOUMethod: s.cfg.TOUMethod, + TOUPassword: s.cfg.TOUPassword, }, log) if err != nil { @@ -202,7 +213,7 @@ func (s *MuxServer) StopService() { s.jumper = nil s.lockChn = nil s.log = nil - s.sc = utils.ServerChannel{} + s.sc = server.ServerChannel{} s.sessions = nil s.udpConns = nil s = nil @@ -254,7 +265,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) { } host, port, _ := net.SplitHostPort(*s.cfg.Local) p, _ := strconv.Atoi(port) - s.sc = utils.NewServerChannel(host, p, s.log) + s.sc = server.NewServerChannel(host, p, s.log) if *s.cfg.IsUDP { err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) { s.UDPSend(packet, localAddr, srcAddr) @@ -293,7 +304,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() io.Copy(inConn, snappy.NewReader(outConn)) @@ -302,7 +313,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() io.Copy(snappy.NewWriter(outConn), inConn) @@ -397,7 +408,7 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() for { @@ -443,6 +454,18 @@ func (s *MuxServer) getParentConn() (conn net.Conn, err error) { } else if *s.cfg.ParentType == "kcp" { conn, err = utils.ConnectKCPHost(*s.cfg.Parent, s.cfg.KCP) + } else if *s.cfg.ParentType == "tcps" { + if s.jumper == nil { + conn, err = clienttransport.TCPSConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout) + } else { + conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout)) + if err == nil { + conn, err = encryptconn.NewConn(conn, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword) + } + } + + } else if *s.cfg.ParentType == "tou" { + conn, err = clienttransport.TOUConnectHost(*s.cfg.Parent, *s.cfg.TCPSMethod, *s.cfg.TCPSPassword, false, *s.cfg.Timeout) } else { if s.jumper == nil { conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout) @@ -457,7 +480,7 @@ func (s *MuxServer) UDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() if s.isStop { @@ -536,7 +559,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() s.log.Printf("udp conn %s connected", ID) @@ -569,7 +592,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() s.sc.UDPListener.WriteToUDP(body, uc.srcAddr) diff --git a/services/socks/socks.go b/services/socks/socks.go index 1ca388b..5f84431 100644 --- a/services/socks/socks.go +++ b/services/socks/socks.go @@ -12,8 +12,9 @@ import ( "strings" "time" + server "github.com/snail007/goproxy/core/cs/server" + "github.com/snail007/goproxy/core/lib/kcpcfg" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/conncrypt" "github.com/snail007/goproxy/utils/datasize" @@ -80,8 +81,8 @@ type Socks struct { basicAuth utils.BasicAuth sshClient *ssh.Client lockChn chan bool - udpSC utils.ServerChannel - sc *utils.ServerChannel + udpSC server.ServerChannel + sc *server.ServerChannel domainResolver dnsx.DomainResolver isStop bool userConns mapx.ConcurrentMap @@ -191,7 +192,7 @@ func (s *Socks) InitService() (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() //循环检查ssh网络连通性 @@ -243,7 +244,7 @@ func (s *Socks) StopService() { s.udpLocalKey = nil s.udpParentKey = nil s.udpRelatedPacketConns = nil - s.udpSC = utils.ServerChannel{} + s.udpSC = server.ServerChannel{} s.userConns = nil s = nil }() @@ -283,11 +284,11 @@ func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) { if len(*s.cfg.Parent) > 0 { s.log.Printf("use %s parent %v [ %s ]", *s.cfg.ParentType, *s.cfg.Parent, strings.ToUpper(*s.cfg.LoadBalanceMethod)) } - sc := utils.NewServerChannelHost(*s.cfg.Local, s.log) + sc := server.NewServerChannelHost(*s.cfg.Local, s.log) if *s.cfg.LocalType == "tcp" { err = sc.ListenTCP(s.socksConnCallback) } else if *s.cfg.LocalType == "tls" { - err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.socksConnCallback) + err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.socksConnCallback) } else if *s.cfg.LocalType == "kcp" { err = sc.ListenKCP(s.cfg.KCP, s.socksConnCallback, s.log) } @@ -462,11 +463,7 @@ func (s *Socks) proxyTCP(inConn *net.Conn, serverConn *socks.ServerConn) { } func (s *Socks) GetParentConn(parentAddress string, serverConn *socks.ServerConn) (outConn net.Conn, err interface{}) { switch *s.cfg.ParentType { - case "kcp": - fallthrough - case "tls": - fallthrough - case "tcp": + case "kcp", "tls", "tcp": if *s.cfg.ParentType == "tls" { var _conn tls.Conn _conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes) diff --git a/services/sps/sps.go b/services/sps/sps.go index da1bad9..b1e5c91 100644 --- a/services/sps/sps.go +++ b/services/sps/sps.go @@ -15,8 +15,9 @@ import ( "strings" "time" + "github.com/snail007/goproxy/core/cs/server" + "github.com/snail007/goproxy/core/lib/kcpcfg" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/conncrypt" "github.com/snail007/goproxy/utils/datasize" @@ -78,7 +79,7 @@ type SPS struct { cfg SPSArgs domainResolver dnsx.DomainResolver basicAuth utils.BasicAuth - serverChannels []*utils.ServerChannel + serverChannels []*server.ServerChannel userConns mapx.ConcurrentMap log *logger.Logger localCipher *ss.Cipher @@ -93,7 +94,7 @@ func NewSPS() services.Service { return &SPS{ cfg: SPSArgs{}, basicAuth: utils.BasicAuth{}, - serverChannels: []*utils.ServerChannel{}, + serverChannels: []*server.ServerChannel{}, userConns: mapx.NewConcurrentMap(), udpRelatedPacketConns: mapx.NewConcurrentMap(), } @@ -145,7 +146,7 @@ func (s *SPS) CheckArgs() (err error) { func (s *SPS) InitService() (err error) { if *s.cfg.DNSAddress != "" { - (*s).domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log) + s.domainResolver = dnsx.NewDomainResolver(*s.cfg.DNSAddress, *s.cfg.DNSTTL, s.log) } if len(*s.cfg.Parent) > 0 { @@ -230,12 +231,12 @@ func (s *SPS) Start(args interface{}, log *logger.Logger) (err error) { if addr != "" { host, port, _ := net.SplitHostPort(addr) p, _ := strconv.Atoi(port) - sc := utils.NewServerChannel(host, p, s.log) + sc := server.NewServerChannel(host, p, s.log) s.serverChannels = append(s.serverChannels, &sc) if *s.cfg.LocalType == "tcp" { err = sc.ListenTCP(s.callback) } else if *s.cfg.LocalType == "tls" { - err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback) + err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes, s.callback) } else if *s.cfg.LocalType == "tcp" { err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log) } @@ -273,11 +274,7 @@ func (s *SPS) callback(inConn net.Conn) { var err error lbAddr := "" switch *s.cfg.ParentType { - case "kcp": - fallthrough - case "tcp": - fallthrough - case "tls": + case "kcp", "tcp", "tls": lbAddr, err = s.OutToTCP(&inConn) default: err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) @@ -363,7 +360,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) { request.HTTPSReply() //s.log.Printf("https reply: %s", request.Host) } else { - //forwardBytes = bytes.TrimRight(request.HeadBuf,"\r\n") forwardBytes = request.HeadBuf } address = request.Host @@ -412,7 +408,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) { selectAddr = address } lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA) - //lbAddr = s.lb.Select((*inConn).RemoteAddr().String()) outConn, err = s.GetParentConn(lbAddr) if err != nil { s.log.Printf("connect to %s , err:%s", lbAddr, err) diff --git a/services/tcp/tcp.go b/services/tcp/tcp.go index 4f4c792..c6ae279 100644 --- a/services/tcp/tcp.go +++ b/services/tcp/tcp.go @@ -9,8 +9,9 @@ import ( "strings" "time" + "github.com/snail007/goproxy/core/cs/server" + "github.com/snail007/goproxy/core/lib/kcpcfg" "github.com/snail007/goproxy/services" - "github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/mapx" @@ -43,7 +44,7 @@ type UDPConnItem struct { } type TCP struct { cfg TCPArgs - sc *utils.ServerChannel + sc *server.ServerChannel isStop bool userConns mapx.ConcurrentMap log *logger.Logger @@ -131,12 +132,12 @@ func (s *TCP) Start(args interface{}, log *logger.Logger) (err error) { s.log.Printf("use %s parent %v", *s.cfg.ParentType, *s.cfg.Parent) host, port, _ := net.SplitHostPort(*s.cfg.Local) p, _ := strconv.Atoi(port) - sc := utils.NewServerChannel(host, p, s.log) + sc := server.NewServerChannel(host, p, s.log) if *s.cfg.LocalType == "tcp" { err = sc.ListenTCP(s.callback) } else if *s.cfg.LocalType == "tls" { - err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback) + err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback) } else if *s.cfg.LocalType == "kcp" { err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log) } @@ -160,11 +161,7 @@ func (s *TCP) callback(inConn net.Conn) { var err error lbAddr := "" switch *s.cfg.ParentType { - case "kcp": - fallthrough - case "tcp": - fallthrough - case "tls": + case "kcp", "tcp", "tls": err = s.OutToTCP(&inConn) case "udp": s.OutToUDP(&inConn) @@ -208,8 +205,8 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) { srcAddr := "" defer func() { if item != nil { - (*(*item).conn).Close() - (*item).udpConn.Close() + (*item.conn).Close() + item.udpConn.Close() s.udpConns.Remove(srcAddr) (*inConn).Close() } @@ -252,15 +249,15 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) { } else { item = v.(*UDPConnItem) } - (*item).touchtime = time.Now().Unix() - go (*item).udpConn.Write(body) + item.touchtime = time.Now().Unix() + go item.udpConn.Write(body) } } func (s *TCP) UDPRevecive(key string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() s.log.Printf("udp conn %s connected", key) @@ -290,7 +287,7 @@ func (s *TCP) UDPRevecive(key string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() (*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) @@ -309,7 +306,7 @@ func (s *TCP) UDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() if s.isStop { diff --git a/services/tunnel/tunnel_bridge.go b/services/tunnel/tunnel_bridge.go index 6dbc21b..5cdc7f3 100644 --- a/services/tunnel/tunnel_bridge.go +++ b/services/tunnel/tunnel_bridge.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/snail007/goproxy/core/cs/server" "github.com/snail007/goproxy/services" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/mapx" @@ -98,9 +99,9 @@ func (s *TunnelBridge) Start(args interface{}, log *logger.Logger) (err error) { } host, port, _ := net.SplitHostPort(*s.cfg.Local) p, _ := strconv.Atoi(port) - sc := utils.NewServerChannel(host, p, s.log) + sc := server.NewServerChannel(host, p, s.log) - err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback) + err = sc.ListenTLS(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.callback) if err != nil { return } diff --git a/services/tunnel/tunnel_client.go b/services/tunnel/tunnel_client.go index 9747934..d43f67e 100644 --- a/services/tunnel/tunnel_client.go +++ b/services/tunnel/tunnel_client.go @@ -159,7 +159,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() s.ServeUDP(localAddr, ID, serverID) @@ -168,7 +168,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() s.ServeConn(localAddr, ID, serverID) @@ -324,7 +324,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() (*item).udpConn.Write(body) @@ -335,7 +335,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() s.log.Printf("udp conn %s connected", ID) @@ -365,7 +365,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() (*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) @@ -384,7 +384,7 @@ func (s *TunnelClient) UDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() if s.isStop { diff --git a/services/tunnel/tunnel_server.go b/services/tunnel/tunnel_server.go index 4cdd220..57995a7 100644 --- a/services/tunnel/tunnel_server.go +++ b/services/tunnel/tunnel_server.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/snail007/goproxy/core/cs/server" "github.com/snail007/goproxy/services" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/jumper" @@ -38,7 +39,7 @@ type TunnelServerArgs struct { } type TunnelServer struct { cfg TunnelServerArgs - sc utils.ServerChannel + sc server.ServerChannel isStop bool udpConn *net.Conn userConns mapx.ConcurrentMap @@ -180,7 +181,7 @@ func (s *TunnelServer) StopService() { s.cfg = TunnelServerArgs{} s.jumper = nil s.log = nil - s.sc = utils.ServerChannel{} + s.sc = server.ServerChannel{} s.udpConn = nil s.udpConns = nil s.userConns = nil @@ -233,7 +234,7 @@ func (s *TunnelServer) Start(args interface{}, log *logger.Logger) (err error) { } host, port, _ := net.SplitHostPort(*s.cfg.Local) p, _ := strconv.Atoi(port) - s.sc = utils.NewServerChannel(host, p, s.log) + s.sc = server.NewServerChannel(host, p, s.log) if *s.cfg.IsUDP { err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) { s.UDPSend(packet, localAddr, srcAddr) @@ -368,7 +369,7 @@ func (s *TunnelServer) UDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() if s.isStop { @@ -439,7 +440,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() s.log.Printf("udp conn %s connected", ID) @@ -472,7 +473,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() s.sc.UDPListener.WriteToUDP(body, uc.srcAddr) diff --git a/services/udp/udp.go b/services/udp/udp.go index d6b32dc..b50f885 100644 --- a/services/udp/udp.go +++ b/services/udp/udp.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/snail007/goproxy/core/cs/server" "github.com/snail007/goproxy/services" "github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils/mapx" @@ -30,7 +31,7 @@ type UDPArgs struct { type UDP struct { p mapx.ConcurrentMap cfg UDPArgs - sc *utils.ServerChannel + sc *server.ServerChannel isStop bool log *logger.Logger outUDPConnCtxMap mapx.ConcurrentMap @@ -121,7 +122,7 @@ func (s *UDP) Start(args interface{}, log *logger.Logger) (err error) { } host, port, _ := net.SplitHostPort(*s.cfg.Local) p, _ := strconv.Atoi(port) - sc := utils.NewServerChannel(host, p, s.log) + sc := server.NewServerChannel(host, p, s.log) s.sc = &sc err = sc.ListenUDP(s.callback) if err != nil { @@ -141,9 +142,7 @@ func (s *UDP) callback(listener *net.UDPConn, packet []byte, localAddr, srcAddr } }() switch *s.cfg.ParentType { - case "tcp": - fallthrough - case "tls": + case "tcp", "tls": s.OutToTCP(packet, localAddr, srcAddr) case "udp": s.OutToUDP(packet, localAddr, srcAddr) @@ -175,7 +174,7 @@ func (s *UDP) OutToUDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() if s.isStop { @@ -217,7 +216,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() s.log.Printf("udp conn %s <--> %s connected", srcAddr.String(), localAddr.String()) @@ -239,7 +238,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() (*(s.sc).UDPListener).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) @@ -276,7 +275,7 @@ func (s *UDP) UDPGCDeamon() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() if s.isStop { @@ -353,7 +352,7 @@ func (s *UDP) UDPRevecive(key string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() s.log.Printf("udp conn %s connected", key) @@ -386,7 +385,7 @@ func (s *UDP) UDPRevecive(key string) { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack())) } }() s.sc.UDPListener.WriteToUDP(body, uc.srcAddr) diff --git a/utils/functions.go b/utils/functions.go index a00d334..56f91be 100755 --- a/utils/functions.go +++ b/utils/functions.go @@ -20,10 +20,9 @@ import ( "net" "net/http" "os" - "os/exec" "strings" - "github.com/snail007/goproxy/services/kcpcfg" + "github.com/snail007/goproxy/core/lib/kcpcfg" "github.com/snail007/goproxy/utils/lb" "golang.org/x/crypto/pbkdf2" @@ -245,98 +244,6 @@ func CloseConn(conn *net.Conn) { (*conn).Close() } } -func Keygen() (err error) { - CList := []string{"AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AR", "AT", "AU", "AZ", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BR", "BS", "BW", "BY", "BZ", "CA", "CF", "CG", "CH", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CY", "CZ", "DE", "DJ", "DK", "DO", "DZ", "EC", "EE", "EG", "ES", "ET", "FI", "FJ", "FR", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GM", "GN", "GR", "GT", "GU", "GY", "HK", "HN", "HT", "HU", "ID", "IE", "IL", "IN", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KP", "KR", "KT", "KW", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "ML", "MM", "MN", "MO", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NE", "NG", "NI", "NL", "NO", "NP", "NR", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PR", "PT", "PY", "QA", "RO", "RU", "SA", "SB", "SC", "SD", "SE", "SG", "SI", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TD", "TG", "TH", "TJ", "TM", "TN", "TO", "TR", "TT", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VC", "VE", "VN", "YE", "YU", "ZA", "ZM", "ZR", "ZW"} - domainSubfixList := []string{".com", ".edu", ".gov", ".int", ".mil", ".net", ".org", ".biz", ".info", ".pro", ".name", ".museum", ".coop", ".aero", ".xxx", ".idv", ".ac", ".ad", ".ae", ".af", ".ag", ".ai", ".al", ".am", ".an", ".ao", ".aq", ".ar", ".as", ".at", ".au", ".aw", ".az", ".ba", ".bb", ".bd", ".be", ".bf", ".bg", ".bh", ".bi", ".bj", ".bm", ".bn", ".bo", ".br", ".bs", ".bt", ".bv", ".bw", ".by", ".bz", ".ca", ".cc", ".cd", ".cf", ".cg", ".ch", ".ci", ".ck", ".cl", ".cm", ".cn", ".co", ".cr", ".cu", ".cv", ".cx", ".cy", ".cz", ".de", ".dj", ".dk", ".dm", ".do", ".dz", ".ec", ".ee", ".eg", ".eh", ".er", ".es", ".et", ".eu", ".fi", ".fj", ".fk", ".fm", ".fo", ".fr", ".ga", ".gd", ".ge", ".gf", ".gg", ".gh", ".gi", ".gl", ".gm", ".gn", ".gp", ".gq", ".gr", ".gs", ".gt", ".gu", ".gw", ".gy", ".hk", ".hm", ".hn", ".hr", ".ht", ".hu", ".id", ".ie", ".il", ".im", ".in", ".io", ".iq", ".ir", ".is", ".it", ".je", ".jm", ".jo", ".jp", ".ke", ".kg", ".kh", ".ki", ".km", ".kn", ".kp", ".kr", ".kw", ".ky", ".kz", ".la", ".lb", ".lc", ".li", ".lk", ".lr", ".ls", ".lt", ".lu", ".lv", ".ly", ".ma", ".mc", ".md", ".mg", ".mh", ".mk", ".ml", ".mm", ".mn", ".mo", ".mp", ".mq", ".mr", ".ms", ".mt", ".mu", ".mv", ".mw", ".mx", ".my", ".mz", ".na", ".nc", ".ne", ".nf", ".ng", ".ni", ".nl", ".no", ".np", ".nr", ".nu", ".nz", ".om", ".pa", ".pe", ".pf", ".pg", ".ph", ".pk", ".pl", ".pm", ".pn", ".pr", ".ps", ".pt", ".pw", ".py", ".qa", ".re", ".ro", ".ru", ".rw", ".sa", ".sb", ".sc", ".sd", ".se", ".sg", ".sh", ".si", ".sj", ".sk", ".sl", ".sm", ".sn", ".so", ".sr", ".st", ".sv", ".sy", ".sz", ".tc", ".td", ".tf", ".tg", ".th", ".tj", ".tk", ".tl", ".tm", ".tn", ".to", ".tp", ".tr", ".tt", ".tv", ".tw", ".tz", ".ua", ".ug", ".uk", ".um", ".us", ".uy", ".uz", ".va", ".vc", ".ve", ".vg", ".vi", ".vn", ".vu", ".wf", ".ws", ".ye", ".yt", ".yu", ".yr", ".za", ".zm", ".zw"} - C := CList[int(RandInt(4))%len(CList)] - ST := RandString(int(RandInt(4) % 10)) - O := RandString(int(RandInt(4) % 10)) - CN := strings.ToLower(RandString(int(RandInt(4)%10)) + domainSubfixList[int(RandInt(4))%len(domainSubfixList)]) - //log.Printf("C: %s, ST: %s, O: %s, CN: %s", C, ST, O, CN) - var out []byte - if len(os.Args) == 3 && os.Args[2] == "ca" { - cmd := exec.Command("sh", "-c", "openssl genrsa -out ca.key 2048") - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - fmt.Println(string(out)) - - cmdStr := fmt.Sprintf("openssl req -new -key ca.key -x509 -days 36500 -out ca.crt -subj /C=%s/ST=%s/O=%s/CN=%s", C, ST, O, "*."+CN) - cmd = exec.Command("sh", "-c", cmdStr) - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - fmt.Println(string(out)) - } else if len(os.Args) == 5 && os.Args[2] == "ca" && os.Args[3] != "" && os.Args[4] != "" { - certBytes, _ := ioutil.ReadFile("ca.crt") - block, _ := pem.Decode(certBytes) - if block == nil || certBytes == nil { - panic("failed to parse ca certificate PEM") - } - x509Cert, _ := x509.ParseCertificate(block.Bytes) - if x509Cert == nil { - panic("failed to parse block") - } - name := os.Args[3] - days := os.Args[4] - cmd := exec.Command("sh", "-c", "openssl genrsa -out "+name+".key 2048") - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - fmt.Println(string(out)) - - cmdStr := fmt.Sprintf("openssl req -new -key %s.key -out %s.csr -subj /C=%s/ST=%s/O=%s/CN=%s", name, name, C, ST, O, CN) - fmt.Printf("%s", cmdStr) - cmd = exec.Command("sh", "-c", cmdStr) - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - fmt.Println(string(out)) - - cmdStr = fmt.Sprintf("openssl x509 -req -days %s -in %s.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out %s.crt", days, name, name) - fmt.Printf("%s", cmdStr) - cmd = exec.Command("sh", "-c", cmdStr) - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - - fmt.Println(string(out)) - } else if len(os.Args) == 3 && os.Args[2] == "usage" { - fmt.Println(`proxy keygen //generate proxy.crt and proxy.key -proxy keygen ca //generate ca.crt and ca.key -proxy keygen ca client0 30 //generate client0.crt client0.key and use ca.crt sign it with 30 days - `) - } else if len(os.Args) == 2 { - cmd := exec.Command("sh", "-c", "openssl genrsa -out proxy.key 2048") - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - fmt.Println(string(out)) - - cmdStr := fmt.Sprintf("openssl req -new -key proxy.key -x509 -days 36500 -out proxy.crt -subj /C=%s/ST=%s/O=%s/CN=%s", C, ST, O, CN) - cmd = exec.Command("sh", "-c", cmdStr) - out, err = cmd.CombinedOutput() - if err != nil { - logger.Printf("err:%s", err) - return - } - fmt.Println(string(out)) - } - - return -} var allInterfaceAddrCache []net.IP diff --git a/utils/lb/backend.go b/utils/lb/backend.go index eac46ba..90678cd 100644 --- a/utils/lb/backend.go +++ b/utils/lb/backend.go @@ -116,7 +116,7 @@ func (b *Backend) startMuxHeartCheck() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() for { @@ -151,7 +151,7 @@ func (b *Backend) startTCPHeartCheck() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack())) } }() for { diff --git a/utils/lb/lb.go b/utils/lb/lb.go index 8d0b2b0..452bc26 100644 --- a/utils/lb/lb.go +++ b/utils/lb/lb.go @@ -36,6 +36,7 @@ type Group struct { lock *sync.Mutex last *Backend debug bool + bks []*Backend } func NewGroup(selectType int, configs BackendsConfig, dr *dnsx.DomainResolver, log *log.Logger, debug bool) Group { @@ -68,9 +69,13 @@ func NewGroup(selectType int, configs BackendsConfig, dr *dnsx.DomainResolver, l dr: dr, lock: &sync.Mutex{}, debug: debug, + bks: bks, } } func (g *Group) Select(srcAddr string, onlyHa bool) (addr string) { + if len(g.bks) == 1 { + return g.bks[0].Address + } if onlyHa { g.lock.Lock() defer g.lock.Unlock() @@ -121,6 +126,7 @@ func (g *Group) Reset(addrs []string) { configs = append(configs, &c) } (*g.selector).Reset(configs, g.dr, g.log) + g.bks = (*g.selector).Backends() } func (g *Group) Backends() []*Backend { return (*g.selector).Backends() diff --git a/utils/leakybuf.go b/utils/leakybuf.go index 95fbf26..513c90e 100644 --- a/utils/leakybuf.go +++ b/utils/leakybuf.go @@ -6,7 +6,7 @@ type LeakyBuf struct { freeList chan []byte } -const LeakyBufSize = 1024 // data.len(2) + hmacsha1(10) + data(4096) +const LeakyBufSize = 2048 // data.len(2) + hmacsha1(10) + data(4096) const maxNBuf = 2048 var LeakyBuffer = NewLeakyBuf(maxNBuf, LeakyBufSize) diff --git a/utils/mapx/map.go b/utils/mapx/map.go index 651a818..cd07511 100644 --- a/utils/mapx/map.go +++ b/utils/mapx/map.go @@ -152,14 +152,7 @@ type Tuple struct { func (m ConcurrentMap) Iter() <-chan Tuple { chans := snapshot(m) ch := make(chan Tuple) - go func() { - defer func() { - if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) - } - }() - fanIn(chans, ch) - }() + go fanIn(chans, ch) return ch } @@ -171,14 +164,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple { total += cap(c) } ch := make(chan Tuple, total) - go func() { - defer func() { - if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) - } - }() - fanIn(chans, ch) - }() + go fanIn(chans, ch) return ch } @@ -193,11 +179,6 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) { // Foreach shard. for index, shard := range m { go func(index int, shard *ConcurrentMapShared) { - defer func() { - if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) - } - }() // Foreach key, value pair. shard.RLock() chans[index] = make(chan Tuple, len(shard.items)) @@ -215,22 +196,25 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) { // fanIn reads elements from channels `chans` into channel `out` func fanIn(chans []chan Tuple, out chan Tuple) { + defer func() { + if e := recover(); e != nil { + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) + } + }() wg := sync.WaitGroup{} wg.Add(len(chans)) for _, ch := range chans { - go func() { + go func(ch chan Tuple) { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() - func(ch chan Tuple) { - for t := range ch { - out <- t - } - wg.Done() - }(ch) - }() + for t := range ch { + out <- t + } + wg.Done() + }(ch) } wg.Wait() close(out) @@ -274,29 +258,27 @@ func (m ConcurrentMap) Keys() []string { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() // Foreach shard. wg := sync.WaitGroup{} wg.Add(SHARD_COUNT) for _, shard := range m { - go func() { + go func(shard *ConcurrentMapShared) { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() - func(shard *ConcurrentMapShared) { - // Foreach key, value pair. - shard.RLock() - for key := range shard.items { - ch <- key - } - shard.RUnlock() - wg.Done() - }(shard) - }() + // Foreach key, value pair. + shard.RLock() + for key := range shard.items { + ch <- key + } + shard.RUnlock() + wg.Done() + }(shard) } wg.Wait() close(ch) diff --git a/utils/serve-channel.go b/utils/serve-channel.go deleted file mode 100644 index 621747f..0000000 --- a/utils/serve-channel.go +++ /dev/null @@ -1,230 +0,0 @@ -package utils - -import ( - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - logger "log" - "net" - "runtime/debug" - "strconv" - - "github.com/snail007/goproxy/services/kcpcfg" - - kcp "github.com/xtaci/kcp-go" -) - -type ServerChannel struct { - ip string - port int - Listener *net.Listener - UDPListener *net.UDPConn - errAcceptHandler func(err error) - log *logger.Logger -} - -func NewServerChannel(ip string, port int, log *logger.Logger) ServerChannel { - return ServerChannel{ - ip: ip, - port: port, - log: log, - errAcceptHandler: func(err error) { - log.Printf("accept error , ERR:%s", err) - }, - } -} -func NewServerChannelHost(host string, log *logger.Logger) ServerChannel { - h, port, _ := net.SplitHostPort(host) - p, _ := strconv.Atoi(port) - return ServerChannel{ - ip: h, - port: p, - log: log, - errAcceptHandler: func(err error) { - log.Printf("accept error , ERR:%s", err) - }, - } -} -func (sc *ServerChannel) SetErrAcceptHandler(fn func(err error)) { - sc.errAcceptHandler = fn -} -func (sc *ServerChannel) ListenTls(certBytes, keyBytes, caCertBytes []byte, fn func(conn net.Conn)) (err error) { - sc.Listener, err = sc.listenTls(sc.ip, sc.port, certBytes, keyBytes, caCertBytes) - if err == nil { - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("ListenTls crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - for { - var conn net.Conn - conn, err = (*sc.Listener).Accept() - if err == nil { - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("tls connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - fn(conn) - }() - } else { - sc.errAcceptHandler(err) - (*sc.Listener).Close() - break - } - } - }() - } - return -} -func (sc *ServerChannel) listenTls(ip string, port int, certBytes, keyBytes, caCertBytes []byte) (ln *net.Listener, err error) { - - var cert tls.Certificate - cert, err = tls.X509KeyPair(certBytes, keyBytes) - if err != nil { - return - } - clientCertPool := x509.NewCertPool() - caBytes := certBytes - if caCertBytes != nil { - caBytes = caCertBytes - } - ok := clientCertPool.AppendCertsFromPEM(caBytes) - if !ok { - err = errors.New("failed to parse root certificate") - } - config := &tls.Config{ - ClientCAs: clientCertPool, - Certificates: []tls.Certificate{cert}, - ClientAuth: tls.RequireAndVerifyClientCert, - } - _ln, err := tls.Listen("tcp", fmt.Sprintf("%s:%d", ip, port), config) - if err == nil { - ln = &_ln - } - return -} -func (sc *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) { - var l net.Listener - l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sc.ip, sc.port)) - if err == nil { - sc.Listener = &l - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("ListenTCP crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - for { - var conn net.Conn - conn, err = (*sc.Listener).Accept() - if err == nil { - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("tcp connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - fn(conn) - }() - } else { - sc.errAcceptHandler(err) - break - } - } - }() - } - return -} -func (sc *ServerChannel) ListenUDP(fn func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr)) (err error) { - addr := &net.UDPAddr{IP: net.ParseIP(sc.ip), Port: sc.port} - l, err := net.ListenUDP("udp", addr) - if err == nil { - sc.UDPListener = l - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("ListenUDP crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - for { - var buf = make([]byte, 2048) - n, srcAddr, err := (*sc.UDPListener).ReadFromUDP(buf) - if err == nil { - packet := buf[0:n] - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("udp data handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - fn(l, packet, addr, srcAddr) - }() - } else { - sc.errAcceptHandler(err) - break - } - } - }() - } - return -} - -func (sc *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn), log *logger.Logger) (err error) { - lis, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", sc.ip, sc.port), config.Block, *config.DataShard, *config.ParityShard) - if err == nil { - if err = lis.SetDSCP(*config.DSCP); err != nil { - log.Println("SetDSCP:", err) - return - } - if err = lis.SetReadBuffer(*config.SockBuf); err != nil { - log.Println("SetReadBuffer:", err) - return - } - if err = lis.SetWriteBuffer(*config.SockBuf); err != nil { - log.Println("SetWriteBuffer:", err) - return - } - sc.Listener = new(net.Listener) - *sc.Listener = lis - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("ListenKCP crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - for { - //var conn net.Conn - conn, err := lis.AcceptKCP() - if err == nil { - go func() { - defer func() { - if e := recover(); e != nil { - sc.log.Printf("kcp connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack())) - } - }() - conn.SetStreamMode(true) - conn.SetWriteDelay(true) - conn.SetNoDelay(*config.NoDelay, *config.Interval, *config.Resend, *config.NoCongestion) - conn.SetMtu(*config.MTU) - conn.SetWindowSize(*config.SndWnd, *config.RcvWnd) - conn.SetACKNoDelay(*config.AckNodelay) - if *config.NoComp { - fn(conn) - } else { - cconn := NewCompStream(conn) - fn(cconn) - } - }() - } else { - sc.errAcceptHandler(err) - break - } - } - }() - } - return -} diff --git a/utils/structs.go b/utils/structs.go index 570a29d..24fd8e0 100644 --- a/utils/structs.go +++ b/utils/structs.go @@ -90,7 +90,7 @@ func (c *Checker) start() { go func() { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() //log.Printf("checker started") @@ -100,7 +100,7 @@ func (c *Checker) start() { go func(item CheckerItem) { defer func() { if e := recover(); e != nil { - fmt.Printf("crashed:%s", string(debug.Stack())) + fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) } }() if c.isNeedCheck(item) { @@ -176,17 +176,9 @@ func (c *Checker) domainIsInMap(address string, blockedMap bool) bool { } domainSlice := strings.Split(u.Hostname(), ".") if len(domainSlice) > 1 { - subSlice := domainSlice[:len(domainSlice)-1] - topDomain := strings.Join(domainSlice[len(domainSlice)-1:], ".") - checkDomain := topDomain - if !blockedMap && c.directMap.Has(checkDomain) { - return true - } - if blockedMap && c.blockedMap.Has(checkDomain) { - return true - } - for i := len(subSlice) - 1; i >= 0; i-- { - checkDomain = subSlice[i] + "." + checkDomain + checkDomain := "" + for i := len(domainSlice) - 1; i >= 0; i-- { + checkDomain = strings.Join(domainSlice[i:], ".") if !blockedMap && c.directMap.Has(checkDomain) { return true }