Merge branch 'dev'

This commit is contained in:
arraykeys@gmail.com
2018-09-19 12:15:15 +08:00
35 changed files with 331 additions and 547 deletions

13
AUTHORIZATION.md Normal file
View File

@ -0,0 +1,13 @@
# GoProxy特殊授权
1.goproxy采用GPLv3源代码开放协议,未经许可,基于本项目开发的软件,衍生软件,相关软件,必须严格遵守GPLv3,否则一经发现,
将严厉追责.
2.如果公司或个人使用本项目代码开发相关软件,衍生软件,又不想遵守GPLv3协议,需要取得作者的"GoProxy特殊授权"书面授权.
3.如果本页面查询不到"GoProxy特殊授权"书面授权信息,则"GoProxy特殊授权"书面授权无效.
4.下面列出了有效的授权编号和有效期.
授权编号 | 授权有效期
:--- | :---

View File

@ -2,6 +2,14 @@ proxy更新日志
v6.1 v6.1
1.黑白名单支持设置顶级域了,比如:com,匹配所有的.com域名 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 企业版开源啦 v6.0 企业版开源啦
本次更新主要是把企业版开源,把企业版代码合并到现在的开源goproxy当中,继续遵循GPLv3,免费开源, 本次更新主要是把企业版开源,把企业版代码合并到现在的开源goproxy当中,继续遵循GPLv3,免费开源,

View File

@ -12,6 +12,8 @@ Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5, ss
**[全平台SDK](/sdk/README.md)** **[全平台SDK](/sdk/README.md)**
**[GoProxy特殊授权](/AUTHORIZATION.md)**
### How to contribute to the code (Pull Request)? ### How to contribute to the code (Pull Request)?
Pull Request is welcomed. Pull Request is welcomed.

View File

@ -13,6 +13,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5,ss代理服
**[全平台SDK](/sdk/README.md)** **[全平台SDK](/sdk/README.md)**
**[GoProxy特殊授权](/AUTHORIZATION.md)**
### 如何贡献代码(Pull Request)? ### 如何贡献代码(Pull Request)?
欢迎加入一起发展壮大proxy.首先需要clone本项目到自己的帐号下面, 欢迎加入一起发展壮大proxy.首先需要clone本项目到自己的帐号下面,
@ -523,7 +525,7 @@ HTTP(S)代理支持上级负载均衡,多个上级重复-P参数即可.
#### **1.14.3 使用目标地址选择上级** #### **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 限速** ### **1.15 限速**
@ -989,7 +991,7 @@ SOCKS代理支持上级负载均衡,多个上级重复-P参数即可.
#### **5.12.3 使用目标地址选择上级** #### **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 限速** #### **5.13 限速**

View File

@ -12,12 +12,14 @@ import (
"path/filepath" "path/filepath"
"runtime/debug" "runtime/debug"
"runtime/pprof" "runtime/pprof"
"strings"
"time" "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" sdk "github.com/snail007/goproxy/sdk/android-ios"
services "github.com/snail007/goproxy/services" services "github.com/snail007/goproxy/services"
httpx "github.com/snail007/goproxy/services/http" httpx "github.com/snail007/goproxy/services/http"
"github.com/snail007/goproxy/services/kcpcfg"
keygenx "github.com/snail007/goproxy/services/keygen" keygenx "github.com/snail007/goproxy/services/keygen"
mux "github.com/snail007/goproxy/services/mux" mux "github.com/snail007/goproxy/services/mux"
socksx "github.com/snail007/goproxy/services/socks" socksx "github.com/snail007/goproxy/services/socks"
@ -147,7 +149,7 @@ func initConfig() (err error) {
//########mux-server######### //########mux-server#########
muxServer := app.Command("server", "proxy on mux server mode") 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.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 <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp") muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").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.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.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() 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.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.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.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######### //########mux-client#########
muxClient := app.Command("client", "proxy on mux client mode") 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.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 <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp") muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").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.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.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() 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.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.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.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######### //########mux-bridge#########
muxBridge := app.Command("bridge", "proxy on mux bridge mode") 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.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.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.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tls").Short('t').Enum("tls", "tcp", "kcp") muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|tcps|kcp|tou>").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######### //########tunnel-server#########
tunnelServer := app.Command("tserver", "proxy on tunnel server mode") tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
@ -418,7 +432,7 @@ func initConfig() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
} }
}() }()
for { for {
@ -442,7 +456,7 @@ func initConfig() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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() { for scanner.Scan() {
@ -452,7 +466,7 @@ func initConfig() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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() { for scannerStdErr.Scan() {

View File

@ -35,6 +35,9 @@ func TlsConnect(host string, port, timeout int, certBytes, keyBytes, caCertBytes
} }
return *tls.Client(_conn, conf), err 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) { func getRequestTlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) {
var cert tls.Certificate var cert tls.Certificate

View File

@ -120,7 +120,7 @@ func (s *ServerChannel) listenTLS(ip string, port int, certBytes, keyBytes, caCe
config.ClientCAs = clientCertPool config.ClientCAs = clientCertPool
config.ClientAuth = tls.RequireAndVerifyClientCert 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 { if err == nil {
ln = &_ln 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) { func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
var l net.Listener 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 { if err == nil {
s.Listener = &l s.Listener = &l
go func() { go func() {
@ -172,7 +172,7 @@ func (s *ServerChannel) ListenTCP(fn func(conn net.Conn)) (err error) {
} }
return 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} addr := &net.UDPAddr{IP: net.ParseIP(s.ip), Port: s.port}
l, err := net.ListenUDP("udp", addr) l, err := net.ListenUDP("udp", addr)
if err == nil { 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())) 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 { } else {
s.errAcceptHandler(err) s.errAcceptHandler(err)
@ -207,7 +207,7 @@ func (s *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *net
return return
} }
func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn), log *logger.Logger) (err error) { 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 == nil {
if err = lis.SetDSCP(*config.DSCP); err != nil { if err = lis.SetDSCP(*config.DSCP); err != nil {
log.Println("SetDSCP:", err) log.Println("SetDSCP:", err)
@ -230,7 +230,6 @@ func (s *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.
} }
}() }()
for { for {
//var conn net.Conn
conn, err := lis.AcceptKCP() conn, err := lis.AcceptKCP()
if err == nil { if err == nil {
go func() { go func() {

View File

@ -137,7 +137,7 @@ func (c *Conn) start() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
} }
}() }()
c.reader() 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 // Read can be made to time out and return a Error with Timeout() == true
// after a fixed time limit; see SetDeadline and SetReadDeadline. // after a fixed time limit; see SetDeadline and SetReadDeadline.
func (c *Conn) Read(b []byte) (n int, err error) { 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() c.inbufMut.Lock()
defer c.inbufMut.Unlock() defer c.inbufMut.Unlock()
for c.inbuf.Len() == 0 { for c.inbuf.Len() == 0 {
@ -497,6 +503,9 @@ func (c *Conn) Write(b []byte) (n int, err error) {
// Close closes the connection. // Close closes the connection.
// Any blocked Read or Write operations will be unblocked and return errors. // Any blocked Read or Write operations will be unblocked and return errors.
func (c *Conn) Close() error { func (c *Conn) Close() error {
defer func() {
_ = recover()
}()
c.closeOnce.Do(func() { c.closeOnce.Do(func() {
if debugConnection { if debugConnection {
log.Println(c, "explicit close start") log.Println(c, "explicit close start")

View File

@ -82,7 +82,7 @@ func NewMux(conn net.PacketConn, packetSize int) *Mux {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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() m.readerLoop()

View File

@ -56,7 +56,7 @@ func newSendBuffer(m *Mux) *sendBuffer {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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() b.writerLoop()

View File

@ -155,7 +155,7 @@ func (m ConcurrentMap) Iter() <-chan Tuple {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) fanIn(chans, ch)
@ -174,7 +174,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) fanIn(chans, ch)
@ -195,7 +195,7 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
go func(index int, shard *ConcurrentMapShared) { go func(index int, shard *ConcurrentMapShared) {
defer func() { defer func() {
if e := recover(); e != nil { 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. // Foreach key, value pair.
@ -221,7 +221,7 @@ func fanIn(chans []chan Tuple, out chan Tuple) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) { func(ch chan Tuple) {
@ -274,7 +274,7 @@ func (m ConcurrentMap) Keys() []string {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
} }
}() }()
// Foreach shard. // Foreach shard.
@ -284,7 +284,7 @@ func (m ConcurrentMap) Keys() []string {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) { func(shard *ConcurrentMapShared) {

View File

@ -62,7 +62,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) buf := make([]byte, 1)
@ -75,7 +75,7 @@ func (s *IOBinder) AliveWithServeConn(srcAddr string, inTCPConn *net.Conn) *IOBi
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
} }
}() }()
for { for {
@ -96,7 +96,7 @@ func (s *IOBinder) AliveWithClientConn(srcAddr string, outTCPConn *net.Conn) *IO
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) buf := make([]byte, 1)
@ -156,7 +156,7 @@ func (s *IOBinder) Run() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
} }
}() }()
defer func() { defer func() {

View File

@ -81,7 +81,7 @@ func dtoi(s string, i0 int) (n int, i int, ok bool) {
return n, i, true return n, i, true
} }
// IPTcpAddrToUnixSocksAddr --- // IPTcpAddrToUnixSocksAddr returns Sockaddr for specified TCP addr.
func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) { func IPTcpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
if Debug { if Debug {
fmt.Println("DEBUG: IPTcpAddrToUnixSocksAddr recieved address:", addr) 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) 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) { func IPv6UdpAddrToUnixSocksAddr(addr string) (sa unix.Sockaddr, err error) {
tcpAddr, err := net.ResolveTCPAddr("udp6", addr) tcpAddr, err := net.ResolveTCPAddr("udp6", addr)
if err != nil { if err != nil {

View File

@ -5,7 +5,7 @@ if [ -e /tmp/proxy ]; then
fi fi
mkdir /tmp/proxy mkdir /tmp/proxy
cd /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 # #install proxy
tar zxvf proxy-linux-amd64.tar.gz tar zxvf proxy-linux-amd64.tar.gz

View File

@ -36,7 +36,7 @@ func Clean(s *services.Service) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { for _ = range signalChan {

View File

@ -13,8 +13,8 @@ import (
"github.com/miekg/dns" "github.com/miekg/dns"
gocache "github.com/pmylund/go-cache" gocache "github.com/pmylund/go-cache"
"github.com/snail007/goproxy/core/lib/kcpcfg"
services "github.com/snail007/goproxy/services" services "github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
) )
type DNSArgs struct { type DNSArgs struct {
@ -60,7 +60,7 @@ func (s *DNS) InitService() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
} }
}() }()
for { for {
@ -142,7 +142,7 @@ func (s *DNS) Start(args interface{}, log *logger.Logger) (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) log.Printf("dns server on udp %s", *s.cfg.Local)

View File

@ -10,9 +10,10 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"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"
httpx "github.com/snail007/goproxy/services/http" httpx "github.com/snail007/goproxy/services/http"
"github.com/snail007/goproxy/services/kcpcfg"
keygenx "github.com/snail007/goproxy/services/keygen" keygenx "github.com/snail007/goproxy/services/keygen"
mux "github.com/snail007/goproxy/services/mux" mux "github.com/snail007/goproxy/services/mux"
socksx "github.com/snail007/goproxy/services/socks" socksx "github.com/snail007/goproxy/services/socks"
@ -166,7 +167,7 @@ func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback)
//########mux-server######### //########mux-server#########
muxServer := app.Command("server", "proxy on mux server mode") 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.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 <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp") muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").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.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.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() 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.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.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.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######### //########mux-client#########
muxClient := app.Command("client", "proxy on mux client mode") 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.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 <tls|tcp|kcp>").Default("tls").Short('T').Enum("tls", "tcp", "kcp") muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").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.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.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() 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.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.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.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######### //########mux-bridge#########
muxBridge := app.Command("bridge", "proxy on mux bridge mode") 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.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.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.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tls").Short('t').Enum("tls", "tcp", "kcp") muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|tcps|kcp|tou>").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######### //########tunnel-server#########
tunnelServer := app.Command("tserver", "proxy on tunnel server mode") tunnelServer := app.Command("tserver", "proxy on tunnel server mode")

View File

@ -12,8 +12,9 @@ import (
"strings" "strings"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils/datasize" "github.com/snail007/goproxy/utils/datasize"
"github.com/snail007/goproxy/utils/dnsx" "github.com/snail007/goproxy/utils/dnsx"
"github.com/snail007/goproxy/utils/iolimiter" "github.com/snail007/goproxy/utils/iolimiter"
@ -83,7 +84,7 @@ type HTTP struct {
lockChn chan bool lockChn chan bool
domainResolver dnsx.DomainResolver domainResolver dnsx.DomainResolver
isStop bool isStop bool
serverChannels []*utils.ServerChannel serverChannels []*server.ServerChannel
userConns mapx.ConcurrentMap userConns mapx.ConcurrentMap
log *logger.Logger log *logger.Logger
lb *lb.Group lb *lb.Group
@ -96,7 +97,7 @@ func NewHTTP() services.Service {
basicAuth: utils.BasicAuth{}, basicAuth: utils.BasicAuth{},
lockChn: make(chan bool, 1), lockChn: make(chan bool, 1),
isStop: false, isStop: false,
serverChannels: []*utils.ServerChannel{}, serverChannels: []*server.ServerChannel{},
userConns: mapx.NewConcurrentMap(), userConns: mapx.NewConcurrentMap(),
} }
} }
@ -172,7 +173,7 @@ func (s *HTTP) InitService() (err error) {
s.InitLB() s.InitLB()
} }
if *s.cfg.DNSAddress != "" { 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" { if *s.cfg.ParentType == "ssh" {
err = s.ConnectSSH() err = s.ConnectSSH()
@ -183,7 +184,7 @@ func (s *HTTP) InitService() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
} }
}() }()
//循环检查ssh网络连通性 //循环检查ssh网络连通性
@ -273,11 +274,11 @@ func (s *HTTP) Start(args interface{}, log *logger.Logger) (err error) {
if addr != "" { if addr != "" {
host, port, _ := net.SplitHostPort(addr) host, port, _ := net.SplitHostPort(addr)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p, s.log) sc := server.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == "tcp" { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.callback) err = sc.ListenTCP(s.callback)
} else if *s.cfg.LocalType == "tls" { } 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" { } else if *s.cfg.LocalType == "kcp" {
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log) err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
} }

View File

@ -8,16 +8,15 @@ import (
"math/rand" "math/rand"
"net" "net"
"runtime/debug" "runtime/debug"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/mapx" "github.com/snail007/goproxy/utils/mapx"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
@ -32,6 +31,10 @@ type MuxBridgeArgs struct {
Timeout *int Timeout *int
IsCompress *bool IsCompress *bool
KCP kcpcfg.KCPConfigArgs KCP kcpcfg.KCPConfigArgs
TCPSMethod *string
TCPSPassword *string
TOUMethod *string
TOUPassword *string
} }
type MuxBridge struct { type MuxBridge struct {
cfg MuxBridgeArgs cfg MuxBridgeArgs
@ -40,7 +43,7 @@ type MuxBridge struct {
router utils.ClientKeyRouter router utils.ClientKeyRouter
l *sync.Mutex l *sync.Mutex
isStop bool isStop bool
sc *utils.ServerChannel sc *srvtransport.ServerChannel
log *logger.Logger log *logger.Logger
} }
@ -112,21 +115,27 @@ func (s *MuxBridge) Start(args interface{}, log *logger.Logger) (err error) {
return return
} }
host, port, _ := net.SplitHostPort(*s.cfg.Local) sc := srvtransport.NewServerChannelHost(*s.cfg.Local, s.log)
p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == "tcp" { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.handler) err = sc.ListenTCP(s.handler)
} else if *s.cfg.LocalType == "tls" { } 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" { } else if *s.cfg.LocalType == "kcp" {
err = sc.ListenKCP(s.cfg.KCP, s.handler, s.log) 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 { if err != nil {
return return
} }
s.sc = &sc s.sc = &sc
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()) s.log.Printf("%s bridge on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
}
return return
} }
func (s *MuxBridge) Clean() { func (s *MuxBridge) Clean() {
@ -206,21 +215,25 @@ func (s *MuxBridge) handler(inConn net.Conn) {
index := keyInfo[1] index := keyInfo[1]
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
var group *mapx.ConcurrentMap
if !s.clientControlConns.Has(groupKey) { if !s.clientControlConns.Has(groupKey) {
item := mapx.NewConcurrentMap() _g := mapx.NewConcurrentMap()
s.clientControlConns.Set(groupKey, &item) group = &_g
} s.clientControlConns.Set(groupKey, group)
//s.log.Printf("init client session group %s", groupKey)
} else {
_group, _ := s.clientControlConns.Get(groupKey) _group, _ := s.clientControlConns.Get(groupKey)
group := _group.(*mapx.ConcurrentMap) group = _group.(*mapx.ConcurrentMap)
}
if v, ok := group.Get(index); ok { if v, ok := group.Get(index); ok {
v.(*smux.Session).Close() v.(*smux.Session).Close()
} }
group.Set(index, session) 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() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
} }
}() }()
for { for {
@ -232,10 +245,12 @@ func (s *MuxBridge) handler(inConn net.Conn) {
defer s.l.Unlock() defer s.l.Unlock()
if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() { if sess, ok := group.Get(index); ok && sess.(*smux.Session).IsClosed() {
group.Remove(index) 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) s.log.Printf("client connection %s released", key)
} }
if group.IsEmpty() { if group.IsEmpty() {
s.clientControlConns.Remove(groupKey) s.clientControlConns.Remove(groupKey)
//s.log.Printf("client session group %s removed", groupKey)
} }
break break
} }
@ -259,6 +274,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
if key == "*" { if key == "*" {
key = s.router.GetKey() key = s.router.GetKey()
} }
//s.log.Printf("server get client session %s", key)
_group, ok := s.clientControlConns.Get(key) _group, ok := s.clientControlConns.Get(key)
if !ok { if !ok {
s.log.Printf("client %s session not exists for server stream %s, retrying...", key, serverID) 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 continue
} }
group := _group.(*mapx.ConcurrentMap) group := _group.(*mapx.ConcurrentMap)
keys := group.Keys() keys := []string{}
group.IterCb(func(key string, v interface{}) {
keys = append(keys, key)
})
keysLen := len(keys) keysLen := len(keys)
//s.log.Printf("client session %s , len:%d , keysLen: %d", key, group.Count(), keysLen)
i := 0 i := 0
if keysLen > 0 { if keysLen > 0 {
i = rand.Intn(keysLen) i = rand.Intn(keysLen)
@ -293,7 +313,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) io.Copy(stream, inConn)
@ -302,7 +322,7 @@ func (s *MuxBridge) callback(inConn net.Conn, serverID, key string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) io.Copy(inConn, stream)

View File

@ -8,15 +8,17 @@ import (
"net" "net"
"runtime/debug" "runtime/debug"
"strings" "strings"
"sync"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/jumper"
"github.com/snail007/goproxy/utils/mapx" "github.com/snail007/goproxy/utils/mapx"
"github.com/golang/snappy"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
@ -34,6 +36,10 @@ type MuxClientArgs struct {
SessionCount *int SessionCount *int
KCP kcpcfg.KCPConfigArgs KCP kcpcfg.KCPConfigArgs
Jumper *string Jumper *string
TCPSMethod *string
TCPSPassword *string
TOUMethod *string
TOUPassword *string
} }
type ClientUDPConnItem struct { type ClientUDPConnItem struct {
conn *smux.Stream conn *smux.Stream
@ -140,7 +146,7 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
defer func() { defer func() {
e := recover() e := recover()
if e != nil { 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 { for {
@ -154,7 +160,16 @@ func (s *MuxClient) Start(args interface{}, log *logger.Logger) (err error) {
continue continue
} }
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout))) conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
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))) _, err = conn.Write(utils.BuildPacket(CONN_CLIENT, fmt.Sprintf("%s-%d", *s.cfg.Key, i)))
}()
g.Wait()
conn.SetDeadline(time.Time{}) conn.SetDeadline(time.Time{})
if err != nil { if err != nil {
conn.Close() conn.Close()
@ -222,7 +237,7 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) {
if *s.cfg.ParentType == "tls" { if *s.cfg.ParentType == "tls" {
if s.jumper == nil { if s.jumper == nil {
var _conn tls.Conn 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 { if err == nil {
conn = net.Conn(&_conn) conn = net.Conn(&_conn)
} }
@ -239,10 +254,22 @@ func (s *MuxClient) getParentConn() (conn net.Conn, err error) {
} }
} else if *s.cfg.ParentType == "kcp" { } 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 { } else {
if s.jumper == nil { 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 { } else {
conn, err = s.jumper.Dial(*s.cfg.Parent, time.Millisecond*time.Duration(*s.cfg.Timeout)) 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 = v.(*ClientUDPConnItem)
} }
(*item).touchtime = time.Now().Unix() (*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) { func (s *MuxClient) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.log.Printf("udp conn %s connected", ID)
@ -336,7 +366,7 @@ func (s *MuxClient) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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))) cui.conn.SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
@ -355,7 +385,7 @@ func (s *MuxClient) UDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {
@ -414,7 +444,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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)) io.Copy(outConn, snappy.NewReader(inConn))
@ -423,7 +453,7 @@ func (s *MuxClient) ServeConn(inConn *smux.Stream, localAddr, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) io.Copy(snappy.NewWriter(inConn), outConn)

View File

@ -12,8 +12,11 @@ import (
"strings" "strings"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/jumper"
"github.com/snail007/goproxy/utils/mapx" "github.com/snail007/goproxy/utils/mapx"
@ -47,10 +50,14 @@ type MuxServerArgs struct {
SessionCount *int SessionCount *int
KCP kcpcfg.KCPConfigArgs KCP kcpcfg.KCPConfigArgs
Jumper *string Jumper *string
TCPSMethod *string
TCPSPassword *string
TOUMethod *string
TOUPassword *string
} }
type MuxServer struct { type MuxServer struct {
cfg MuxServerArgs cfg MuxServerArgs
sc utils.ServerChannel sc server.ServerChannel
sessions mapx.ConcurrentMap sessions mapx.ConcurrentMap
lockChn chan bool lockChn chan bool
isStop bool isStop bool
@ -133,6 +140,10 @@ func (s *MuxServerManager) Start(args interface{}, log *logger.Logger) (err erro
KCP: s.cfg.KCP, KCP: s.cfg.KCP,
ParentType: s.cfg.ParentType, ParentType: s.cfg.ParentType,
Jumper: s.cfg.Jumper, Jumper: s.cfg.Jumper,
TCPSMethod: s.cfg.TCPSMethod,
TCPSPassword: s.cfg.TCPSPassword,
TOUMethod: s.cfg.TOUMethod,
TOUPassword: s.cfg.TOUPassword,
}, log) }, log)
if err != nil { if err != nil {
@ -202,7 +213,7 @@ func (s *MuxServer) StopService() {
s.jumper = nil s.jumper = nil
s.lockChn = nil s.lockChn = nil
s.log = nil s.log = nil
s.sc = utils.ServerChannel{} s.sc = server.ServerChannel{}
s.sessions = nil s.sessions = nil
s.udpConns = nil s.udpConns = nil
s = 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) host, port, _ := net.SplitHostPort(*s.cfg.Local)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
s.sc = utils.NewServerChannel(host, p, s.log) s.sc = server.NewServerChannel(host, p, s.log)
if *s.cfg.IsUDP { if *s.cfg.IsUDP {
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) { err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
s.UDPSend(packet, localAddr, srcAddr) s.UDPSend(packet, localAddr, srcAddr)
@ -293,7 +304,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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)) io.Copy(inConn, snappy.NewReader(outConn))
@ -302,7 +313,7 @@ func (s *MuxServer) Start(args interface{}, log *logger.Logger) (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) io.Copy(snappy.NewWriter(outConn), inConn)
@ -397,7 +408,7 @@ func (s *MuxServer) GetConn(index string) (conn net.Conn, err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack()))
} }
}() }()
for { for {
@ -443,6 +454,18 @@ func (s *MuxServer) getParentConn() (conn net.Conn, err error) {
} else if *s.cfg.ParentType == "kcp" { } else if *s.cfg.ParentType == "kcp" {
conn, err = utils.ConnectKCPHost(*s.cfg.Parent, s.cfg.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 { } else {
if s.jumper == nil { if s.jumper == nil {
conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout) conn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
@ -457,7 +480,7 @@ func (s *MuxServer) UDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {
@ -536,7 +559,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.log.Printf("udp conn %s connected", ID)
@ -569,7 +592,7 @@ func (s *MuxServer) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)

View File

@ -12,8 +12,9 @@ import (
"strings" "strings"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt" "github.com/snail007/goproxy/utils/conncrypt"
"github.com/snail007/goproxy/utils/datasize" "github.com/snail007/goproxy/utils/datasize"
@ -80,8 +81,8 @@ type Socks struct {
basicAuth utils.BasicAuth basicAuth utils.BasicAuth
sshClient *ssh.Client sshClient *ssh.Client
lockChn chan bool lockChn chan bool
udpSC utils.ServerChannel udpSC server.ServerChannel
sc *utils.ServerChannel sc *server.ServerChannel
domainResolver dnsx.DomainResolver domainResolver dnsx.DomainResolver
isStop bool isStop bool
userConns mapx.ConcurrentMap userConns mapx.ConcurrentMap
@ -191,7 +192,7 @@ func (s *Socks) InitService() (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:", e, string(debug.Stack()))
} }
}() }()
//循环检查ssh网络连通性 //循环检查ssh网络连通性
@ -243,7 +244,7 @@ func (s *Socks) StopService() {
s.udpLocalKey = nil s.udpLocalKey = nil
s.udpParentKey = nil s.udpParentKey = nil
s.udpRelatedPacketConns = nil s.udpRelatedPacketConns = nil
s.udpSC = utils.ServerChannel{} s.udpSC = server.ServerChannel{}
s.userConns = nil s.userConns = nil
s = nil s = nil
}() }()
@ -283,11 +284,11 @@ func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) {
if len(*s.cfg.Parent) > 0 { 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)) 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" { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.socksConnCallback) err = sc.ListenTCP(s.socksConnCallback)
} else if *s.cfg.LocalType == "tls" { } 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" { } else if *s.cfg.LocalType == "kcp" {
err = sc.ListenKCP(s.cfg.KCP, s.socksConnCallback, s.log) 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{}) { func (s *Socks) GetParentConn(parentAddress string, serverConn *socks.ServerConn) (outConn net.Conn, err interface{}) {
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case "kcp": case "kcp", "tls", "tcp":
fallthrough
case "tls":
fallthrough
case "tcp":
if *s.cfg.ParentType == "tls" { if *s.cfg.ParentType == "tls" {
var _conn tls.Conn var _conn tls.Conn
_conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes) _conn, err = utils.TlsConnectHost(parentAddress, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes)

View File

@ -15,8 +15,9 @@ import (
"strings" "strings"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/conncrypt" "github.com/snail007/goproxy/utils/conncrypt"
"github.com/snail007/goproxy/utils/datasize" "github.com/snail007/goproxy/utils/datasize"
@ -78,7 +79,7 @@ type SPS struct {
cfg SPSArgs cfg SPSArgs
domainResolver dnsx.DomainResolver domainResolver dnsx.DomainResolver
basicAuth utils.BasicAuth basicAuth utils.BasicAuth
serverChannels []*utils.ServerChannel serverChannels []*server.ServerChannel
userConns mapx.ConcurrentMap userConns mapx.ConcurrentMap
log *logger.Logger log *logger.Logger
localCipher *ss.Cipher localCipher *ss.Cipher
@ -93,7 +94,7 @@ func NewSPS() services.Service {
return &SPS{ return &SPS{
cfg: SPSArgs{}, cfg: SPSArgs{},
basicAuth: utils.BasicAuth{}, basicAuth: utils.BasicAuth{},
serverChannels: []*utils.ServerChannel{}, serverChannels: []*server.ServerChannel{},
userConns: mapx.NewConcurrentMap(), userConns: mapx.NewConcurrentMap(),
udpRelatedPacketConns: mapx.NewConcurrentMap(), udpRelatedPacketConns: mapx.NewConcurrentMap(),
} }
@ -145,7 +146,7 @@ func (s *SPS) CheckArgs() (err error) {
func (s *SPS) InitService() (err error) { func (s *SPS) InitService() (err error) {
if *s.cfg.DNSAddress != "" { 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 { if len(*s.cfg.Parent) > 0 {
@ -230,12 +231,12 @@ func (s *SPS) Start(args interface{}, log *logger.Logger) (err error) {
if addr != "" { if addr != "" {
host, port, _ := net.SplitHostPort(addr) host, port, _ := net.SplitHostPort(addr)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p, s.log) sc := server.NewServerChannel(host, p, s.log)
s.serverChannels = append(s.serverChannels, &sc) s.serverChannels = append(s.serverChannels, &sc)
if *s.cfg.LocalType == "tcp" { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.callback) err = sc.ListenTCP(s.callback)
} else if *s.cfg.LocalType == "tls" { } 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" { } else if *s.cfg.LocalType == "tcp" {
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log) err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
} }
@ -273,11 +274,7 @@ func (s *SPS) callback(inConn net.Conn) {
var err error var err error
lbAddr := "" lbAddr := ""
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case "kcp": case "kcp", "tcp", "tls":
fallthrough
case "tcp":
fallthrough
case "tls":
lbAddr, err = s.OutToTCP(&inConn) lbAddr, err = s.OutToTCP(&inConn)
default: default:
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) 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() request.HTTPSReply()
//s.log.Printf("https reply: %s", request.Host) //s.log.Printf("https reply: %s", request.Host)
} else { } else {
//forwardBytes = bytes.TrimRight(request.HeadBuf,"\r\n")
forwardBytes = request.HeadBuf forwardBytes = request.HeadBuf
} }
address = request.Host address = request.Host
@ -412,7 +408,6 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
selectAddr = address selectAddr = address
} }
lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA) lbAddr = s.lb.Select(selectAddr, *s.cfg.LoadBalanceOnlyHA)
//lbAddr = s.lb.Select((*inConn).RemoteAddr().String())
outConn, err = s.GetParentConn(lbAddr) outConn, err = s.GetParentConn(lbAddr)
if err != nil { if err != nil {
s.log.Printf("connect to %s , err:%s", lbAddr, err) s.log.Printf("connect to %s , err:%s", lbAddr, err)

View File

@ -9,8 +9,9 @@ import (
"strings" "strings"
"time" "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"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/jumper"
"github.com/snail007/goproxy/utils/mapx" "github.com/snail007/goproxy/utils/mapx"
@ -43,7 +44,7 @@ type UDPConnItem struct {
} }
type TCP struct { type TCP struct {
cfg TCPArgs cfg TCPArgs
sc *utils.ServerChannel sc *server.ServerChannel
isStop bool isStop bool
userConns mapx.ConcurrentMap userConns mapx.ConcurrentMap
log *logger.Logger 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) s.log.Printf("use %s parent %v", *s.cfg.ParentType, *s.cfg.Parent)
host, port, _ := net.SplitHostPort(*s.cfg.Local) host, port, _ := net.SplitHostPort(*s.cfg.Local)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p, s.log) sc := server.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == "tcp" { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.callback) err = sc.ListenTCP(s.callback)
} else if *s.cfg.LocalType == "tls" { } 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" { } else if *s.cfg.LocalType == "kcp" {
err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log) err = sc.ListenKCP(s.cfg.KCP, s.callback, s.log)
} }
@ -160,11 +161,7 @@ func (s *TCP) callback(inConn net.Conn) {
var err error var err error
lbAddr := "" lbAddr := ""
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case "kcp": case "kcp", "tcp", "tls":
fallthrough
case "tcp":
fallthrough
case "tls":
err = s.OutToTCP(&inConn) err = s.OutToTCP(&inConn)
case "udp": case "udp":
s.OutToUDP(&inConn) s.OutToUDP(&inConn)
@ -208,8 +205,8 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
srcAddr := "" srcAddr := ""
defer func() { defer func() {
if item != nil { if item != nil {
(*(*item).conn).Close() (*item.conn).Close()
(*item).udpConn.Close() item.udpConn.Close()
s.udpConns.Remove(srcAddr) s.udpConns.Remove(srcAddr)
(*inConn).Close() (*inConn).Close()
} }
@ -252,15 +249,15 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
} else { } else {
item = v.(*UDPConnItem) item = v.(*UDPConnItem)
} }
(*item).touchtime = time.Now().Unix() item.touchtime = time.Now().Unix()
go (*item).udpConn.Write(body) go item.udpConn.Write(body)
} }
} }
func (s *TCP) UDPRevecive(key string) { func (s *TCP) UDPRevecive(key string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.log.Printf("udp conn %s connected", key)
@ -290,7 +287,7 @@ func (s *TCP) UDPRevecive(key string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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))) (*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
@ -309,7 +306,7 @@ func (s *TCP) UDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {

View File

@ -10,6 +10,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/core/cs/server"
"github.com/snail007/goproxy/services" "github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/mapx" "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) host, port, _ := net.SplitHostPort(*s.cfg.Local)
p, _ := strconv.Atoi(port) 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 { if err != nil {
return return
} }

View File

@ -159,7 +159,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.ServeUDP(localAddr, ID, serverID)
@ -168,7 +168,7 @@ func (s *TunnelClient) Start(args interface{}, log *logger.Logger) (err error) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.ServeConn(localAddr, ID, serverID)
@ -324,7 +324,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) (*item).udpConn.Write(body)
@ -335,7 +335,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.log.Printf("udp conn %s connected", ID)
@ -365,7 +365,7 @@ func (s *TunnelClient) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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))) (*cui.conn).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
@ -384,7 +384,7 @@ func (s *TunnelClient) UDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {

View File

@ -12,6 +12,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/core/cs/server"
"github.com/snail007/goproxy/services" "github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/jumper" "github.com/snail007/goproxy/utils/jumper"
@ -38,7 +39,7 @@ type TunnelServerArgs struct {
} }
type TunnelServer struct { type TunnelServer struct {
cfg TunnelServerArgs cfg TunnelServerArgs
sc utils.ServerChannel sc server.ServerChannel
isStop bool isStop bool
udpConn *net.Conn udpConn *net.Conn
userConns mapx.ConcurrentMap userConns mapx.ConcurrentMap
@ -180,7 +181,7 @@ func (s *TunnelServer) StopService() {
s.cfg = TunnelServerArgs{} s.cfg = TunnelServerArgs{}
s.jumper = nil s.jumper = nil
s.log = nil s.log = nil
s.sc = utils.ServerChannel{} s.sc = server.ServerChannel{}
s.udpConn = nil s.udpConn = nil
s.udpConns = nil s.udpConns = nil
s.userConns = 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) host, port, _ := net.SplitHostPort(*s.cfg.Local)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
s.sc = utils.NewServerChannel(host, p, s.log) s.sc = server.NewServerChannel(host, p, s.log)
if *s.cfg.IsUDP { if *s.cfg.IsUDP {
err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) { err = s.sc.ListenUDP(func(listener *net.UDPConn, packet []byte, localAddr, srcAddr *net.UDPAddr) {
s.UDPSend(packet, localAddr, srcAddr) s.UDPSend(packet, localAddr, srcAddr)
@ -368,7 +369,7 @@ func (s *TunnelServer) UDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {
@ -439,7 +440,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.log.Printf("udp conn %s connected", ID)
@ -472,7 +473,7 @@ func (s *TunnelServer) UDPRevecive(key, ID string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)

View File

@ -11,6 +11,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/core/cs/server"
"github.com/snail007/goproxy/services" "github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/snail007/goproxy/utils/mapx" "github.com/snail007/goproxy/utils/mapx"
@ -30,7 +31,7 @@ type UDPArgs struct {
type UDP struct { type UDP struct {
p mapx.ConcurrentMap p mapx.ConcurrentMap
cfg UDPArgs cfg UDPArgs
sc *utils.ServerChannel sc *server.ServerChannel
isStop bool isStop bool
log *logger.Logger log *logger.Logger
outUDPConnCtxMap mapx.ConcurrentMap 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) host, port, _ := net.SplitHostPort(*s.cfg.Local)
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p, s.log) sc := server.NewServerChannel(host, p, s.log)
s.sc = &sc s.sc = &sc
err = sc.ListenUDP(s.callback) err = sc.ListenUDP(s.callback)
if err != nil { if err != nil {
@ -141,9 +142,7 @@ func (s *UDP) callback(listener *net.UDPConn, packet []byte, localAddr, srcAddr
} }
}() }()
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case "tcp": case "tcp", "tls":
fallthrough
case "tls":
s.OutToTCP(packet, localAddr, srcAddr) s.OutToTCP(packet, localAddr, srcAddr)
case "udp": case "udp":
s.OutToUDP(packet, localAddr, srcAddr) s.OutToUDP(packet, localAddr, srcAddr)
@ -175,7 +174,7 @@ func (s *UDP) OutToUDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {
@ -217,7 +216,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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()) 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() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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))) (*(s.sc).UDPListener).SetWriteDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
@ -276,7 +275,7 @@ func (s *UDP) UDPGCDeamon() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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 { if s.isStop {
@ -353,7 +352,7 @@ func (s *UDP) UDPRevecive(key string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.log.Printf("udp conn %s connected", key)
@ -386,7 +385,7 @@ func (s *UDP) UDPRevecive(key string) {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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) s.sc.UDPListener.WriteToUDP(body, uc.srcAddr)

View File

@ -20,10 +20,9 @@ import (
"net" "net"
"net/http" "net/http"
"os" "os"
"os/exec"
"strings" "strings"
"github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/core/lib/kcpcfg"
"github.com/snail007/goproxy/utils/lb" "github.com/snail007/goproxy/utils/lb"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
@ -245,98 +244,6 @@ func CloseConn(conn *net.Conn) {
(*conn).Close() (*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 var allInterfaceAddrCache []net.IP

View File

@ -116,7 +116,7 @@ func (b *Backend) startMuxHeartCheck() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
} }
}() }()
for { for {
@ -151,7 +151,7 @@ func (b *Backend) startTCPHeartCheck() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack())) fmt.Printf("crashed, err: %s\nstack:",e, string(debug.Stack()))
} }
}() }()
for { for {

View File

@ -36,6 +36,7 @@ type Group struct {
lock *sync.Mutex lock *sync.Mutex
last *Backend last *Backend
debug bool debug bool
bks []*Backend
} }
func NewGroup(selectType int, configs BackendsConfig, dr *dnsx.DomainResolver, log *log.Logger, debug bool) Group { 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, dr: dr,
lock: &sync.Mutex{}, lock: &sync.Mutex{},
debug: debug, debug: debug,
bks: bks,
} }
} }
func (g *Group) Select(srcAddr string, onlyHa bool) (addr string) { func (g *Group) Select(srcAddr string, onlyHa bool) (addr string) {
if len(g.bks) == 1 {
return g.bks[0].Address
}
if onlyHa { if onlyHa {
g.lock.Lock() g.lock.Lock()
defer g.lock.Unlock() defer g.lock.Unlock()
@ -121,6 +126,7 @@ func (g *Group) Reset(addrs []string) {
configs = append(configs, &c) configs = append(configs, &c)
} }
(*g.selector).Reset(configs, g.dr, g.log) (*g.selector).Reset(configs, g.dr, g.log)
g.bks = (*g.selector).Backends()
} }
func (g *Group) Backends() []*Backend { func (g *Group) Backends() []*Backend {
return (*g.selector).Backends() return (*g.selector).Backends()

View File

@ -6,7 +6,7 @@ type LeakyBuf struct {
freeList chan []byte 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 const maxNBuf = 2048
var LeakyBuffer = NewLeakyBuf(maxNBuf, LeakyBufSize) var LeakyBuffer = NewLeakyBuf(maxNBuf, LeakyBufSize)

View File

@ -152,14 +152,7 @@ type Tuple struct {
func (m ConcurrentMap) Iter() <-chan Tuple { func (m ConcurrentMap) Iter() <-chan Tuple {
chans := snapshot(m) chans := snapshot(m)
ch := make(chan Tuple) ch := make(chan Tuple)
go func() { go fanIn(chans, ch)
defer func() {
if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack()))
}
}()
fanIn(chans, ch)
}()
return ch return ch
} }
@ -171,14 +164,7 @@ func (m ConcurrentMap) IterBuffered() <-chan Tuple {
total += cap(c) total += cap(c)
} }
ch := make(chan Tuple, total) ch := make(chan Tuple, total)
go func() { go fanIn(chans, ch)
defer func() {
if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack()))
}
}()
fanIn(chans, ch)
}()
return ch return ch
} }
@ -193,11 +179,6 @@ func snapshot(m ConcurrentMap) (chans []chan Tuple) {
// Foreach shard. // Foreach shard.
for index, shard := range m { for index, shard := range m {
go func(index int, shard *ConcurrentMapShared) { go func(index int, shard *ConcurrentMapShared) {
defer func() {
if e := recover(); e != nil {
fmt.Printf("crashed:%s", string(debug.Stack()))
}
}()
// Foreach key, value pair. // Foreach key, value pair.
shard.RLock() shard.RLock()
chans[index] = make(chan Tuple, len(shard.items)) 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` // fanIn reads elements from channels `chans` into channel `out`
func fanIn(chans []chan Tuple, out chan Tuple) { 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 := sync.WaitGroup{}
wg.Add(len(chans)) wg.Add(len(chans))
for _, ch := range chans { for _, ch := range chans {
go func() { go func(ch chan Tuple) {
defer func() { defer func() {
if e := recover(); e != nil { 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 { for t := range ch {
out <- t out <- t
} }
wg.Done() wg.Done()
}(ch) }(ch)
}()
} }
wg.Wait() wg.Wait()
close(out) close(out)
@ -274,20 +258,19 @@ func (m ConcurrentMap) Keys() []string {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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. // Foreach shard.
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(SHARD_COUNT) wg.Add(SHARD_COUNT)
for _, shard := range m { for _, shard := range m {
go func() { go func(shard *ConcurrentMapShared) {
defer func() { defer func() {
if e := recover(); e != nil { 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. // Foreach key, value pair.
shard.RLock() shard.RLock()
for key := range shard.items { for key := range shard.items {
@ -296,7 +279,6 @@ func (m ConcurrentMap) Keys() []string {
shard.RUnlock() shard.RUnlock()
wg.Done() wg.Done()
}(shard) }(shard)
}()
} }
wg.Wait() wg.Wait()
close(ch) close(ch)

View File

@ -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
}

View File

@ -90,7 +90,7 @@ func (c *Checker) start() {
go func() { go func() {
defer func() { defer func() {
if e := recover(); e != nil { 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") //log.Printf("checker started")
@ -100,7 +100,7 @@ func (c *Checker) start() {
go func(item CheckerItem) { go func(item CheckerItem) {
defer func() { defer func() {
if e := recover(); e != nil { 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) { if c.isNeedCheck(item) {
@ -176,17 +176,9 @@ func (c *Checker) domainIsInMap(address string, blockedMap bool) bool {
} }
domainSlice := strings.Split(u.Hostname(), ".") domainSlice := strings.Split(u.Hostname(), ".")
if len(domainSlice) > 1 { if len(domainSlice) > 1 {
subSlice := domainSlice[:len(domainSlice)-1] checkDomain := ""
topDomain := strings.Join(domainSlice[len(domainSlice)-1:], ".") for i := len(domainSlice) - 1; i >= 0; i-- {
checkDomain := topDomain checkDomain = strings.Join(domainSlice[i:], ".")
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
if !blockedMap && c.directMap.Has(checkDomain) { if !blockedMap && c.directMap.Has(checkDomain) {
return true return true
} }