add secure dns proxy support

This commit is contained in:
arraykeys
2018-06-16 17:14:43 +08:00
parent dff1a6daaf
commit e849cbfcd8
25 changed files with 788 additions and 438 deletions

View File

@ -36,7 +36,8 @@ Proxy is a high performance HTTP, HTTPS, HTTPS, websocket, TCP, UDP, Socks5 prox
- ...   - ...  
This page is the v4.9 manual, and the other version of the manual can be checked by the following link. This page is the v5.0 manual, and the other version of the manual can be checked by the following link.
- [v4.9 manual](https://github.com/snail007/goproxy/tree/v4.9)
- [v4.8 manual](https://github.com/snail007/goproxy/tree/v4.8) - [v4.8 manual](https://github.com/snail007/goproxy/tree/v4.8)
- [v4.7 manual](https://github.com/snail007/goproxy/tree/v4.7) - [v4.7 manual](https://github.com/snail007/goproxy/tree/v4.7)
- [v4.6 manual](https://github.com/snail007/goproxy/tree/v4.6) - [v4.6 manual](https://github.com/snail007/goproxy/tree/v4.6)
@ -163,7 +164,7 @@ If the installation fails or your VPS is not a linux64 system, please follow the
Download address: https://github.com/snail007/goproxy/releases Download address: https://github.com/snail007/goproxy/releases
```shell ```shell
cd /root/proxy/ cd /root/proxy/
wget https://github.com/snail007/goproxy/releases/download/v4.9/proxy-linux-amd64.tar.gz wget https://github.com/snail007/goproxy/releases/download/v5.0/proxy-linux-amd64.tar.gz
``` ```
#### **2.Download the automatic installation script** #### **2.Download the automatic installation script**
```shell ```shell

View File

@ -26,6 +26,7 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
- 协议转换可以把已经存在的HTTP(S)或SOCKS5代理转换为一个端口同时支持HTTP(S)和SOCKS5代理转换后的SOCKS5代理不支持UDP功能,同时支持强大的级联认证功能。 - 协议转换可以把已经存在的HTTP(S)或SOCKS5代理转换为一个端口同时支持HTTP(S)和SOCKS5代理转换后的SOCKS5代理不支持UDP功能,同时支持强大的级联认证功能。
- 自定义底层加密传输http(s)\sps\socks代理在tcp之上可以通过tls标准加密以及kcp协议加密tcp数据,除此之外还支持在tls和kcp之后进行自定义加密,也就是说自定义加密和tls|kcp是可以联合使用的,内部采用AES256加密,使用的时候只需要自己定义一个密码即可。 - 自定义底层加密传输http(s)\sps\socks代理在tcp之上可以通过tls标准加密以及kcp协议加密tcp数据,除此之外还支持在tls和kcp之后进行自定义加密,也就是说自定义加密和tls|kcp是可以联合使用的,内部采用AES256加密,使用的时候只需要自己定义一个密码即可。
- 底层压缩高效传输http(s)\sps\socks代理在tcp之上可以通过自定义加密和tls标准加密以及kcp协议加密tcp数据,在加密之后还可以对数据进行压缩,也就是说压缩功能和自定义加密和tls|kcp是可以联合使用的。 - 底层压缩高效传输http(s)\sps\socks代理在tcp之上可以通过自定义加密和tls标准加密以及kcp协议加密tcp数据,在加密之后还可以对数据进行压缩,也就是说压缩功能和自定义加密和tls|kcp是可以联合使用的。
- 安全的DNS代理可以通过本地的proxy提供的DNS代理服务器与上级代理加密通讯实现安全防污染的DNS查询。
### Why need these? ### Why need these?
- 当由于某某原因,我们不能访问我们在其它地方的服务,我们可以通过多个相连的proxy节点建立起一个安全的隧道访问我们的服务. - 当由于某某原因,我们不能访问我们在其它地方的服务,我们可以通过多个相连的proxy节点建立起一个安全的隧道访问我们的服务.
@ -37,7 +38,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
- ... - ...
本页是v4.9手册,其他版本手册请点击下面链接查看. 本页是v5.0手册,其他版本手册请点击下面链接查看.
- [v4.9手册](https://github.com/snail007/goproxy/tree/v4.9)
- [v4.8手册](https://github.com/snail007/goproxy/tree/v4.8) - [v4.8手册](https://github.com/snail007/goproxy/tree/v4.8)
- [v4.7手册](https://github.com/snail007/goproxy/tree/v4.7) - [v4.7手册](https://github.com/snail007/goproxy/tree/v4.7)
- [v4.6手册](https://github.com/snail007/goproxy/tree/v4.6) - [v4.6手册](https://github.com/snail007/goproxy/tree/v4.6)
@ -145,6 +147,9 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
- [7. KCP配置](#7kcp配置) - [7. KCP配置](#7kcp配置)
- [7.1 配置介绍](#71-配置介绍) - [7.1 配置介绍](#71-配置介绍)
- [7.2 详细配置](#72-详细配置) - [7.2 详细配置](#72-详细配置)
- [8. DNS防污染服务器](#8dns防污染服务器)
- [8.1 介绍](#81-介绍)
- [8.2 使用示例](#82-使用示例)
### Fast Start ### Fast Start
提示:所有操作需要root权限. 提示:所有操作需要root权限.
@ -162,7 +167,7 @@ curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.s
下载地址:https://github.com/snail007/goproxy/releases 下载地址:https://github.com/snail007/goproxy/releases
```shell ```shell
cd /root/proxy/ cd /root/proxy/
wget https://github.com/snail007/goproxy/releases/download/v4.9/proxy-linux-amd64.tar.gz wget https://github.com/snail007/goproxy/releases/download/v5.0/proxy-linux-amd64.tar.gz
``` ```
#### **2.下载自动安装脚本** #### **2.下载自动安装脚本**
```shell ```shell
@ -1041,6 +1046,73 @@ fast `--nodelay=0 --interval=30 --resend=2 --nc=1`
fast2`--nodelay=1 --interval=20 --resend=2 --nc=1` fast2`--nodelay=1 --interval=20 --resend=2 --nc=1`
fast3`--nodelay=1 --interval=10 --resend=2 --nc=1` fast3`--nodelay=1 --interval=10 --resend=2 --nc=1`
### **8.DNS防污染服务器**
#### **8.1 介绍**
众所周知DNS是UDP端口53提供的服务但是随着网络的发展一些知名DNS服务器也支持TCP方式dns查询比如谷歌的8.8.8.8proxy的DNS防污染服务器原理就是在本地启动一个proxy的DNS代理服务器它用TCP的方式通过上级代理进行dns查询。如果它和上级代理通讯采用加密的方式那么就可以进行安全无污染的DNS解析。
#### **8.2 使用示例**
***8.2.1 普通HTTP(S)上级代理***
假设有一个上级代理2.2.2.2:33080
本地执行:
`proxy dns -S http -T tcp -P 2.2.2.2:33080 -p :53`
那么本地的UDP端口53就提供了DNS解析功能。
***8.2.2 普通SOCKS5上级代理***
假设有一个上级代理2.2.2.2:33080
本地执行:
`proxy dns -S socks -T tcp -P 2.2.2.2:33080 -p :53`
那么本地的UDP端口53就提供了DNS解析功能。
***8.2.3 TLS加密的HTTP(S)上级代理***
假设有一个上级代理2.2.2.2:33080
上级代理执行的命令是:
`proxy http -t tls -C proxy.crt -K proxy.key -p :33080`
本地执行:
`proxy dns -S http -T tls -P 2.2.2.2:33080 -C proxy.crt -K proxy.key -p :53`
那么本地的UDP端口53就提供了安全防污染DNS解析功能。
***8.2.4 TLS加密的SOCKS5上级代理***
假设有一个上级代理2.2.2.2:33080
上级代理执行的命令是:
`proxy socks -t tls -C proxy.crt -K proxy.key -p :33080`
本地执行:
`proxy dns -S socks -T tls -P 2.2.2.2:33080 -C proxy.crt -K proxy.key -p :53`
那么本地的UDP端口53就提供了安全防污染DNS解析功能。
***8.2.5 KCP加密的HTTP(S)上级代理***
假设有一个上级代理2.2.2.2:33080
上级代理执行的命令是:
`proxy http -t kcp -p :33080`
本地执行:
`proxy dns -S http -T kcp -P 2.2.2.2:33080 -p :53`
那么本地的UDP端口53就提供了安全防污染DNS解析功能。
***8.2.6 KCP加密的SOCKS5上级代理***
假设有一个上级代理2.2.2.2:33080
上级代理执行的命令是:
`proxy socks -t kcp -p :33080`
本地执行:
`proxy dns -S socks -T kcp -P 2.2.2.2:33080 -p :53`
那么本地的UDP端口53就提供了安全防污染DNS解析功能。
***8.2.7 自定义加密的HTTP(S)上级代理***
假设有一个上级代理2.2.2.2:33080
上级代理执行的命令是:
`proxy http -t tcp -p :33080 -z password`
本地执行:
`proxy dns -S http -T tcp -Z password -P 2.2.2.2:33080 -p :53`
那么本地的UDP端口53就提供了安全防污染DNS解析功能。
***8.2.8 自定义加密的SOCKS5上级代理***
假设有一个上级代理2.2.2.2:33080
上级代理执行的命令是:
`proxy socks -t kcp -p :33080 -z password`
本地执行:
`proxy dns -S socks -T tcp -Z password -P 2.2.2.2:33080 -p :53`
那么本地的UDP端口53就提供了安全防污染DNS解析功能。
### TODO ### TODO
- http,socks代理多个上级负载均衡? - http,socks代理多个上级负载均衡?
- http(s)代理增加pac支持? - http(s)代理增加pac支持?

View File

@ -7,13 +7,24 @@ import (
logger "log" logger "log"
"os" "os"
"os/exec" "os/exec"
"path"
"path/filepath"
"runtime/pprof" "runtime/pprof"
"time" "time"
sdk "github.com/snail007/goproxy/sdk/android-ios"
"github.com/snail007/goproxy/services" "github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
httpx "github.com/snail007/goproxy/services/http"
mux "github.com/snail007/goproxy/services/mux"
socksx "github.com/snail007/goproxy/services/socks"
spsx "github.com/snail007/goproxy/services/sps"
tcpx "github.com/snail007/goproxy/services/tcp"
tunnel "github.com/snail007/goproxy/services/tunnel"
udpx "github.com/snail007/goproxy/services/udp"
kcp "github.com/xtaci/kcp-go" kcp "github.com/xtaci/kcp-go"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
kingpin "gopkg.in/alecthomas/kingpin.v2" kingpin "gopkg.in/alecthomas/kingpin.v2"
@ -37,18 +48,20 @@ func initConfig() (err error) {
} }
//define args //define args
tcpArgs := services.TCPArgs{} tcpArgs := tcpx.TCPArgs{}
httpArgs := services.HTTPArgs{} httpArgs := httpx.HTTPArgs{}
tunnelServerArgs := services.TunnelServerArgs{} tunnelServerArgs := tunnel.TunnelServerArgs{}
tunnelClientArgs := services.TunnelClientArgs{} tunnelClientArgs := tunnel.TunnelClientArgs{}
tunnelBridgeArgs := services.TunnelBridgeArgs{} tunnelBridgeArgs := tunnel.TunnelBridgeArgs{}
muxServerArgs := services.MuxServerArgs{} muxServerArgs := mux.MuxServerArgs{}
muxClientArgs := services.MuxClientArgs{} muxClientArgs := mux.MuxClientArgs{}
muxBridgeArgs := services.MuxBridgeArgs{} muxBridgeArgs := mux.MuxBridgeArgs{}
udpArgs := services.UDPArgs{} udpArgs := udpx.UDPArgs{}
socksArgs := services.SocksArgs{} socksArgs := socksx.SocksArgs{}
spsArgs := services.SPSArgs{} spsArgs := spsx.SPSArgs{}
dnsArgs := sdk.DNSArgs{}
kcpArgs := kcpcfg.KCPConfigArgs{} kcpArgs := kcpcfg.KCPConfigArgs{}
//build srvice args //build srvice args
app = kingpin.New("proxy", "happy with proxy") app = kingpin.New("proxy", "happy with proxy")
app.Author("snail").Version(APP_VERSION) app.Author("snail").Version(APP_VERSION)
@ -248,6 +261,24 @@ func initConfig() (err error) {
spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool() spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool()
spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool() spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool()
//########dns#########
dns := app.Command("dns", "proxy on dns server mode")
dnsArgs.Parent = dns.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
dnsArgs.CertFile = dns.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
dnsArgs.KeyFile = dns.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
dnsArgs.CaCertFile = dns.Flag("ca", "ca cert file for tls").Default("").String()
dnsArgs.Timeout = dns.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('i').Default("2000").Int()
dnsArgs.ParentType = dns.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp")
dnsArgs.Local = dns.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":53").String()
dnsArgs.ParentServiceType = dns.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks")
dnsArgs.RemoteDNSAddress = dns.Flag("dns-address", "remote dns for resolve doamin").Short('q').Default("8.8.8.8:53").String()
dnsArgs.DNSTTL = dns.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
dnsArgs.ParentAuth = dns.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String()
dnsArgs.ParentKey = dns.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
dnsArgs.ParentCompress = dns.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
dnsArgs.CacheFile = dns.Flag("cache-file", "dns result cached file").Short('f').Default(filepath.Join(path.Dir(os.Args[0]), "cache.dat")).String()
dnsArgs.LocalSocks5Port = dns.Flag("socks-port", "local socks5 port").Short('s').Default("65501").String()
//parse args //parse args
serviceName := kingpin.MustParse(app.Parse(os.Args[1:])) serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
@ -304,6 +335,7 @@ func initConfig() (err error) {
muxBridgeArgs.KCP = kcpArgs muxBridgeArgs.KCP = kcpArgs
muxServerArgs.KCP = kcpArgs muxServerArgs.KCP = kcpArgs
muxClientArgs.KCP = kcpArgs muxClientArgs.KCP = kcpArgs
dnsArgs.KCP = kcpArgs
log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime) log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
@ -409,28 +441,31 @@ func initConfig() (err error) {
//regist services and run service //regist services and run service
switch serviceName { switch serviceName {
case "http": case "http":
services.Regist(serviceName, services.NewHTTP(), httpArgs, log) services.Regist(serviceName, httpx.NewHTTP(), httpArgs, log)
case "tcp": case "tcp":
services.Regist(serviceName, services.NewTCP(), tcpArgs, log) services.Regist(serviceName, tcpx.NewTCP(), tcpArgs, log)
case "udp": case "udp":
services.Regist(serviceName, services.NewUDP(), udpArgs, log) services.Regist(serviceName, udpx.NewUDP(), udpArgs, log)
case "tserver": case "tserver":
services.Regist(serviceName, services.NewTunnelServerManager(), tunnelServerArgs, log) services.Regist(serviceName, tunnel.NewTunnelServerManager(), tunnelServerArgs, log)
case "tclient": case "tclient":
services.Regist(serviceName, services.NewTunnelClient(), tunnelClientArgs, log) services.Regist(serviceName, tunnel.NewTunnelClient(), tunnelClientArgs, log)
case "tbridge": case "tbridge":
services.Regist(serviceName, services.NewTunnelBridge(), tunnelBridgeArgs, log) services.Regist(serviceName, tunnel.NewTunnelBridge(), tunnelBridgeArgs, log)
case "server": case "server":
services.Regist(serviceName, services.NewMuxServerManager(), muxServerArgs, log) services.Regist(serviceName, mux.NewMuxServerManager(), muxServerArgs, log)
case "client": case "client":
services.Regist(serviceName, services.NewMuxClient(), muxClientArgs, log) services.Regist(serviceName, mux.NewMuxClient(), muxClientArgs, log)
case "bridge": case "bridge":
services.Regist(serviceName, services.NewMuxBridge(), muxBridgeArgs, log) services.Regist(serviceName, mux.NewMuxBridge(), muxBridgeArgs, log)
case "socks": case "socks":
services.Regist(serviceName, services.NewSocks(), socksArgs, log) services.Regist(serviceName, socksx.NewSocks(), socksArgs, log)
case "sps": case "sps":
services.Regist(serviceName, services.NewSPS(), spsArgs, log) services.Regist(serviceName, spsx.NewSPS(), spsArgs, log)
case "dns":
services.Regist(serviceName, sdk.NewDNS(), dnsArgs, log)
} }
service, err = services.Run(serviceName, nil) service, err = services.Run(serviceName, nil)
if err != nil { if err != nil {
log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err) log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err)

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/v4.9/proxy-linux-amd64.tar.gz wget https://github.com/snail007/goproxy/releases/download/v5.0/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

@ -9,7 +9,7 @@ import (
"github.com/snail007/goproxy/services" "github.com/snail007/goproxy/services"
) )
const APP_VERSION = "4.9" const APP_VERSION = "5.0"
func main() { func main() {
err := initConfig() err := initConfig()

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
VER="4.9" VER="5.0"
RELEASE="release-${VER}" RELEASE="release-${VER}"
rm -rf .cert rm -rf .cert
mkdir .cert mkdir .cert

256
sdk/android-ios/dns.go Normal file
View File

@ -0,0 +1,256 @@
package proxy
import (
"crypto/md5"
"encoding/hex"
"fmt"
logger "log"
"net"
"runtime/debug"
"time"
"golang.org/x/net/proxy"
"github.com/miekg/dns"
gocache "github.com/pmylund/go-cache"
services "github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
)
type DNSArgs struct {
ParentServiceType *string
ParentType *string
Parent *string
ParentAuth *string
ParentKey *string
ParentCompress *bool
KCP kcpcfg.KCPConfigArgs
CertFile *string
KeyFile *string
CaCertFile *string
Local *string
Timeout *int
RemoteDNSAddress *string
DNSTTL *int
CacheFile *string
LocalSocks5Port *string
}
type DNS struct {
cfg DNSArgs
log *logger.Logger
cache *gocache.Cache
exitSig chan bool
serviceKey string
dialer proxy.Dialer
}
func NewDNS() services.Service {
return &DNS{
cfg: DNSArgs{},
exitSig: make(chan bool, 1),
serviceKey: "dns-service-" + fmt.Sprintf("%d", time.Now().UnixNano()),
}
}
func (s *DNS) CheckArgs() (err error) {
return
}
func (s *DNS) InitService() (err error) {
s.cache = gocache.New(time.Second*time.Duration(*s.cfg.DNSTTL), time.Second*60)
s.cache.LoadFile(*s.cfg.CacheFile)
go func() {
for {
select {
case <-s.exitSig:
return
case <-time.After(time.Second * 60):
err := s.cache.SaveFile(*s.cfg.CacheFile)
if err == nil {
//s.log.Printf("cache saved: %s", *s.cfg.CacheFile)
} else {
s.log.Printf("cache save failed: %s, %s", *s.cfg.CacheFile, err)
}
}
}
}()
s.dialer, err = proxy.SOCKS5("tcp", *s.cfg.Parent,
nil,
&net.Dialer{
Timeout: 5 * time.Second,
KeepAlive: 5 * time.Second,
},
)
if err != nil {
return
}
sdkArgs := fmt.Sprintf("sps -S %s -T %s -P %s -C %s -K %s -i %d -p 127.0.0.1:%s --disable-http",
*s.cfg.ParentServiceType,
*s.cfg.ParentType,
*s.cfg.Parent,
*s.cfg.CertFile,
*s.cfg.KeyFile,
*s.cfg.Timeout,
*s.cfg.LocalSocks5Port,
)
if *s.cfg.ParentKey != "" {
sdkArgs += " -Z " + *s.cfg.ParentKey
}
if *s.cfg.ParentAuth != "" {
sdkArgs += " -A " + *s.cfg.ParentAuth
}
if *s.cfg.CaCertFile != "" {
sdkArgs += " --ca " + *s.cfg.CaCertFile
}
if *s.cfg.ParentCompress {
sdkArgs += " -M"
}
s.log.Printf("start sps with : %s", sdkArgs)
errStr := Start(s.serviceKey, sdkArgs)
if errStr != "" {
err = fmt.Errorf("start sps service fail,%s", errStr)
}
return
}
func (s *DNS) StopService() {
defer func() {
e := recover()
if e != nil {
s.log.Printf("stop dns service crashed,%s", e)
} else {
s.log.Printf("service dns stoped")
}
}()
Stop(s.serviceKey)
s.cache.Flush()
s.exitSig <- true
}
func (s *DNS) Start(args interface{}, log *logger.Logger) (err error) {
s.log = log
s.cfg = args.(DNSArgs)
if err = s.CheckArgs(); err != nil {
return
}
if err = s.InitService(); err != nil {
return
}
dns.HandleFunc(".", s.callback)
go func() {
log.Printf("dns server on udp %s", *s.cfg.Local)
err := dns.ListenAndServe(*s.cfg.Local, "udp", nil)
if err != nil {
log.Printf("dns listen error: %s", err)
}
}()
return
}
func (s *DNS) Clean() {
s.StopService()
}
func (s *DNS) callback(w dns.ResponseWriter, req *dns.Msg) {
defer func() {
if err := recover(); err != nil {
s.log.Printf("dns handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
}
}()
var (
key string
m *dns.Msg
err error
data []byte
id uint16
query []string
questions []dns.Question
)
if req.MsgHdr.Response == true {
return
}
query = make([]string, len(req.Question))
for i, q := range req.Question {
if q.Qtype != dns.TypeAAAA {
questions = append(questions, q)
}
query[i] = fmt.Sprintf("(%s %s %s)", q.Name, dns.ClassToString[q.Qclass], dns.TypeToString[q.Qtype])
}
if len(questions) == 0 {
return
}
req.Question = questions
id = req.Id
req.Id = 0
key = s.toMd5(req.String())
req.Id = id
if reply, ok := s.cache.Get(key); ok {
data, _ = reply.([]byte)
}
if data != nil && len(data) > 0 {
m = &dns.Msg{}
m.Unpack(data)
m.Id = id
err = w.WriteMsg(m)
s.log.Printf("id: %5d cache: HIT %v", id, query)
return
} else {
s.log.Printf("id: %5d cache: MISS %v", id, query)
}
s.log.Printf("id: %5d resolve: %v %s", id, query, *s.cfg.RemoteDNSAddress)
rawConn, err := s.dialer.Dial("tcp", *s.cfg.RemoteDNSAddress)
if err != nil {
s.log.Printf("dail to %s fail,%s", *s.cfg.RemoteDNSAddress, err)
return
}
defer rawConn.Close()
co := new(dns.Conn)
co.Conn = rawConn
defer co.Close()
if err = co.WriteMsg(req); err != nil {
s.log.Printf("write dns query fail,%s", err)
return
}
m, err = co.ReadMsg()
if err == nil && m.Id != req.Id {
s.log.Printf("id: %5d mismath", id)
return
}
if err != nil || len(m.Answer) == 0 {
s.log.Printf("dns query fail,%s", err)
return
}
data, err = m.Pack()
if err != nil {
s.log.Printf("dns query fail,%s", err)
return
}
_, err = w.Write(data)
if err != nil {
s.log.Printf("dns query fail,%s", err)
return
}
m.Id = 0
data, _ = m.Pack()
ttl := 0
if len(m.Answer) > 0 {
if *s.cfg.DNSTTL > 0 {
ttl = *s.cfg.DNSTTL
} else {
ttl = int(m.Answer[0].Header().Ttl)
if ttl < 0 {
ttl = *s.cfg.DNSTTL
}
}
}
s.cache.Set(key, data, time.Second*time.Duration(ttl))
m.Id = id
s.log.Printf("id: %5d cache: CACHED %v TTL %v", id, query, ttl)
}
func (s *DNS) toMd5(data string) string {
m := md5.New()
m.Write([]byte(data))
return hex.EncodeToString(m.Sum(nil))
}

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.9" VER="v5.0"
rm -rf sdk-android-*.tar.gz rm -rf sdk-android-*.tar.gz
rm -rf android rm -rf android
mkdir android mkdir android

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.9" VER="v5.0"
rm -rf sdk-ios-*.tar.gz rm -rf sdk-ios-*.tar.gz
rm -rf ios rm -rf ios
mkdir ios mkdir ios

View File

@ -5,17 +5,25 @@ import (
"fmt" "fmt"
logger "log" logger "log"
"os" "os"
"path"
"path/filepath"
"strings" "strings"
"github.com/snail007/goproxy/services" "github.com/snail007/goproxy/services"
httpx "github.com/snail007/goproxy/services/http"
"github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/services/kcpcfg"
mux "github.com/snail007/goproxy/services/mux"
socksx "github.com/snail007/goproxy/services/socks"
spsx "github.com/snail007/goproxy/services/sps"
tcpx "github.com/snail007/goproxy/services/tcp"
tunnel "github.com/snail007/goproxy/services/tunnel"
udpx "github.com/snail007/goproxy/services/udp"
kcp "github.com/xtaci/kcp-go" kcp "github.com/xtaci/kcp-go"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
kingpin "gopkg.in/alecthomas/kingpin.v2" kingpin "gopkg.in/alecthomas/kingpin.v2"
) )
const SDK_VERSION = "4.9" const SDK_VERSION = "5.0"
var ( var (
app *kingpin.Application app *kingpin.Application
@ -32,17 +40,18 @@ var (
//if start success, errStr is empty. //if start success, errStr is empty.
func Start(serviceID, serviceArgsStr string) (errStr string) { func Start(serviceID, serviceArgsStr string) (errStr string) {
//define args //define args
tcpArgs := services.TCPArgs{} tcpArgs := tcpx.TCPArgs{}
httpArgs := services.HTTPArgs{} httpArgs := httpx.HTTPArgs{}
tunnelServerArgs := services.TunnelServerArgs{} tunnelServerArgs := tunnel.TunnelServerArgs{}
tunnelClientArgs := services.TunnelClientArgs{} tunnelClientArgs := tunnel.TunnelClientArgs{}
tunnelBridgeArgs := services.TunnelBridgeArgs{} tunnelBridgeArgs := tunnel.TunnelBridgeArgs{}
muxServerArgs := services.MuxServerArgs{} muxServerArgs := mux.MuxServerArgs{}
muxClientArgs := services.MuxClientArgs{} muxClientArgs := mux.MuxClientArgs{}
muxBridgeArgs := services.MuxBridgeArgs{} muxBridgeArgs := mux.MuxBridgeArgs{}
udpArgs := services.UDPArgs{} udpArgs := udpx.UDPArgs{}
socksArgs := services.SocksArgs{} socksArgs := socksx.SocksArgs{}
spsArgs := services.SPSArgs{} spsArgs := spsx.SPSArgs{}
dnsArgs := DNSArgs{}
kcpArgs := kcpcfg.KCPConfigArgs{} kcpArgs := kcpcfg.KCPConfigArgs{}
//build srvice args //build srvice args
app = kingpin.New("proxy", "happy with proxy") app = kingpin.New("proxy", "happy with proxy")
@ -240,6 +249,23 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
spsArgs.ParentCompress = sps.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool() spsArgs.ParentCompress = sps.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool() spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool()
spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool() spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool()
//########dns#########
dns := app.Command("dns", "proxy on dns server mode")
dnsArgs.Parent = dns.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
dnsArgs.CertFile = dns.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
dnsArgs.KeyFile = dns.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
dnsArgs.CaCertFile = dns.Flag("ca", "ca cert file for tls").Default("").String()
dnsArgs.Timeout = dns.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('i').Default("2000").Int()
dnsArgs.ParentType = dns.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp")
dnsArgs.Local = dns.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":33080").String()
dnsArgs.ParentServiceType = dns.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks")
dnsArgs.RemoteDNSAddress = dns.Flag("dns-address", "remote dns for resolve doamin").Short('q').Default("8.8.8.8:53").String()
dnsArgs.DNSTTL = dns.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
dnsArgs.ParentAuth = dns.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String()
dnsArgs.ParentKey = dns.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
dnsArgs.ParentCompress = dns.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
dnsArgs.CacheFile = dns.Flag("cache-file", "dns result cached file").Short('f').Default(filepath.Join(path.Dir(os.Args[0]), "cache.dat")).String()
dnsArgs.LocalSocks5Port = dns.Flag("socks-port", "local socks5 port").Short('s').Default("65501").String()
//parse args //parse args
_args := strings.Fields(strings.Trim(serviceArgsStr, " ")) _args := strings.Fields(strings.Trim(serviceArgsStr, " "))
@ -302,6 +328,7 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
muxBridgeArgs.KCP = kcpArgs muxBridgeArgs.KCP = kcpArgs
muxServerArgs.KCP = kcpArgs muxServerArgs.KCP = kcpArgs
muxClientArgs.KCP = kcpArgs muxClientArgs.KCP = kcpArgs
dnsArgs.KCP = kcpArgs
log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime) log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime)
flags := logger.Ldate flags := logger.Ldate
@ -323,27 +350,29 @@ func Start(serviceID, serviceArgsStr string) (errStr string) {
//regist services and run service //regist services and run service
switch serviceName { switch serviceName {
case "http": case "http":
services.Regist(serviceID, services.NewHTTP(), httpArgs, log) services.Regist(serviceID, httpx.NewHTTP(), httpArgs, log)
case "tcp": case "tcp":
services.Regist(serviceID, services.NewTCP(), tcpArgs, log) services.Regist(serviceID, tcpx.NewTCP(), tcpArgs, log)
case "udp": case "udp":
services.Regist(serviceID, services.NewUDP(), udpArgs, log) services.Regist(serviceID, udpx.NewUDP(), udpArgs, log)
case "tserver": case "tserver":
services.Regist(serviceID, services.NewTunnelServerManager(), tunnelServerArgs, log) services.Regist(serviceID, tunnel.NewTunnelServerManager(), tunnelServerArgs, log)
case "tclient": case "tclient":
services.Regist(serviceID, services.NewTunnelClient(), tunnelClientArgs, log) services.Regist(serviceID, tunnel.NewTunnelClient(), tunnelClientArgs, log)
case "tbridge": case "tbridge":
services.Regist(serviceID, services.NewTunnelBridge(), tunnelBridgeArgs, log) services.Regist(serviceID, tunnel.NewTunnelBridge(), tunnelBridgeArgs, log)
case "server": case "server":
services.Regist(serviceID, services.NewMuxServerManager(), muxServerArgs, log) services.Regist(serviceID, mux.NewMuxServerManager(), muxServerArgs, log)
case "client": case "client":
services.Regist(serviceID, services.NewMuxClient(), muxClientArgs, log) services.Regist(serviceID, mux.NewMuxClient(), muxClientArgs, log)
case "bridge": case "bridge":
services.Regist(serviceID, services.NewMuxBridge(), muxBridgeArgs, log) services.Regist(serviceID, mux.NewMuxBridge(), muxBridgeArgs, log)
case "socks": case "socks":
services.Regist(serviceID, services.NewSocks(), socksArgs, log) services.Regist(serviceID, socksx.NewSocks(), socksArgs, log)
case "sps": case "sps":
services.Regist(serviceID, services.NewSPS(), spsArgs, log) services.Regist(serviceID, spsx.NewSPS(), spsArgs, log)
case "dns":
services.Regist(serviceName, NewDNS(), dnsArgs, log)
} }
_, err = services.Run(serviceID, nil) _, err = services.Run(serviceID, nil)
if err != nil { if err != nil {

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.9" VER="v5.0"
rm -rf sdk-linux-*.tar.gz rm -rf sdk-linux-*.tar.gz
rm -rf README.md libproxy-sdk.so libproxy-sdk.h libproxy-sdk.a rm -rf README.md libproxy-sdk.so libproxy-sdk.h libproxy-sdk.a

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.9" VER="v5.0"
rm -rf *.tar.gz rm -rf *.tar.gz
rm -rf README.md libproxy-sdk.dylib libproxy-sdk.h rm -rf README.md libproxy-sdk.dylib libproxy-sdk.h

View File

@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
VER="v4.9" VER="v5.0"
sudo rm /usr/local/go sudo rm /usr/local/go
sudo ln -s /usr/local/go1.10.1 /usr/local/go sudo ln -s /usr/local/go1.10.1 /usr/local/go

View File

@ -1,285 +0,0 @@
package services
import (
"github.com/snail007/goproxy/services/kcpcfg"
"golang.org/x/crypto/ssh"
)
// tcp := app.Command("tcp", "proxy on tcp mode")
// t := tcp.Flag("tcp-timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
const (
TYPE_TCP = "tcp"
TYPE_UDP = "udp"
TYPE_HTTP = "http"
TYPE_TLS = "tls"
TYPE_KCP = "kcp"
CONN_CLIENT_CONTROL = uint8(1)
CONN_CLIENT_HEARBEAT = uint8(2)
CONN_SERVER_HEARBEAT = uint8(3)
CONN_SERVER = uint8(4)
CONN_CLIENT = uint8(5)
CONN_SERVER_MUX = uint8(6)
CONN_CLIENT_MUX = uint8(7)
)
type MuxServerArgs struct {
Parent *string
ParentType *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
IsUDP *bool
Key *string
Remote *string
Timeout *int
Route *[]string
Mgr *MuxServerManager
IsCompress *bool
SessionCount *int
KCP kcpcfg.KCPConfigArgs
}
type MuxClientArgs struct {
Parent *string
ParentType *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Key *string
Timeout *int
IsCompress *bool
SessionCount *int
KCP kcpcfg.KCPConfigArgs
}
type MuxBridgeArgs struct {
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
LocalType *string
Timeout *int
IsCompress *bool
KCP kcpcfg.KCPConfigArgs
}
type TunnelServerArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
IsUDP *bool
Key *string
Remote *string
Timeout *int
Route *[]string
Mgr *TunnelServerManager
Mux *bool
}
type TunnelClientArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Key *string
Timeout *int
Mux *bool
}
type TunnelBridgeArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
Timeout *int
Mux *bool
}
type TCPArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
LocalType *string
Timeout *int
CheckParentInterval *int
KCP kcpcfg.KCPConfigArgs
}
type HTTPArgs struct {
Parent *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
Local *string
Always *bool
HTTPTimeout *int
Interval *int
Blocked *string
Direct *string
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
ParentType *string
LocalType *string
Timeout *int
CheckParentInterval *int
SSHKeyFile *string
SSHKeyFileSalt *string
SSHPassword *string
SSHUser *string
SSHKeyBytes []byte
SSHAuthMethod ssh.AuthMethod
KCP kcpcfg.KCPConfigArgs
LocalIPS *[]string
DNSAddress *string
DNSTTL *int
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
}
type UDPArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
Timeout *int
CheckParentInterval *int
}
type SocksArgs struct {
Parent *string
ParentType *string
Local *string
LocalType *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
SSHKeyFile *string
SSHKeyFileSalt *string
SSHPassword *string
SSHUser *string
SSHKeyBytes []byte
SSHAuthMethod ssh.AuthMethod
Timeout *int
Always *bool
Interval *int
Blocked *string
Direct *string
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
KCP kcpcfg.KCPConfigArgs
UDPParent *string
UDPLocal *string
LocalIPS *[]string
DNSAddress *string
DNSTTL *int
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
}
type SPSArgs struct {
Parent *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
LocalType *string
Timeout *int
KCP kcpcfg.KCPConfigArgs
ParentServiceType *string
DNSAddress *string
DNSTTL *int
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
LocalIPS *[]string
ParentAuth *string
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
DisableHTTP *bool
DisableSocks5 *bool
}
type DNSArgs struct {
Parent *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
LocalType *string
Timeout *int
KCP kcpcfg.KCPConfigArgs
ParentServiceType *string
DNSAddress *string
DNSTTL *int
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
LocalIPS *[]string
ParentAuth *string
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
DisableHTTP *bool
DisableSocks5 *bool
}
func (a *SPSArgs) Protocol() string {
return ProtocoStrl(*a.LocalType)
}
func (a *TCPArgs) Protocol() string {
return ProtocoStrl(*a.LocalType)
}
func ProtocoStrl(t string) string {
switch t {
case TYPE_TLS:
return TYPE_TLS
case TYPE_TCP:
return TYPE_TCP
case TYPE_KCP:
return TYPE_KCP
}
return "unknown"
}

View File

@ -11,12 +11,53 @@ import (
"strings" "strings"
"time" "time"
"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"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
type HTTPArgs struct {
Parent *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
Local *string
Always *bool
HTTPTimeout *int
Interval *int
Blocked *string
Direct *string
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
ParentType *string
LocalType *string
Timeout *int
CheckParentInterval *int
SSHKeyFile *string
SSHKeyFileSalt *string
SSHPassword *string
SSHUser *string
SSHKeyBytes []byte
SSHAuthMethod ssh.AuthMethod
KCP kcpcfg.KCPConfigArgs
LocalIPS *[]string
DNSAddress *string
DNSTTL *int
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
}
type HTTP struct { type HTTP struct {
outPool utils.OutConn outPool utils.OutConn
cfg HTTPArgs cfg HTTPArgs
@ -31,7 +72,7 @@ type HTTP struct {
log *logger.Logger log *logger.Logger
} }
func NewHTTP() Service { func NewHTTP() services.Service {
return &HTTP{ return &HTTP{
outPool: utils.OutConn{}, outPool: utils.OutConn{},
cfg: HTTPArgs{}, cfg: HTTPArgs{},
@ -182,11 +223,11 @@ func (s *HTTP) Start(args interface{}, log *logger.Logger) (err error) {
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 := utils.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == TYPE_TCP { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.callback) err = sc.ListenTCP(s.callback)
} else if *s.cfg.LocalType == TYPE_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 == TYPE_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)
} }
if err != nil { if err != nil {
@ -396,7 +437,7 @@ func (s *HTTP) ConnectSSH() (err error) {
return return
} }
func (s *HTTP) InitOutConnPool() { func (s *HTTP) InitOutConnPool() {
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.ParentType == TYPE_TCP || *s.cfg.ParentType == TYPE_KCP { if *s.cfg.ParentType == "tls" || *s.cfg.ParentType == "tcp" || *s.cfg.ParentType == "kcp" {
//dur int, isTLS bool, certBytes, keyBytes []byte, //dur int, isTLS bool, certBytes, keyBytes []byte,
//parent string, timeout int, InitialCap int, MaxCap int //parent string, timeout int, InitialCap int, MaxCap int
s.outPool = utils.NewOutConn( s.outPool = utils.NewOutConn(

View File

@ -1,4 +1,4 @@
package services package mux
import ( import (
"bufio" "bufio"
@ -12,12 +12,29 @@ import (
"sync" "sync"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
const (
CONN_SERVER = uint8(4)
CONN_CLIENT = uint8(5)
)
type MuxBridgeArgs struct {
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
LocalType *string
Timeout *int
IsCompress *bool
KCP kcpcfg.KCPConfigArgs
}
type MuxBridge struct { type MuxBridge struct {
cfg MuxBridgeArgs cfg MuxBridgeArgs
clientControlConns utils.ConcurrentMap clientControlConns utils.ConcurrentMap
@ -29,7 +46,7 @@ type MuxBridge struct {
log *logger.Logger log *logger.Logger
} }
func NewMuxBridge() Service { func NewMuxBridge() services.Service {
b := &MuxBridge{ b := &MuxBridge{
cfg: MuxBridgeArgs{}, cfg: MuxBridgeArgs{},
clientControlConns: utils.NewConcurrentMap(), clientControlConns: utils.NewConcurrentMap(),
@ -49,7 +66,7 @@ func (s *MuxBridge) CheckArgs() (err error) {
err = fmt.Errorf("cert and key file required") err = fmt.Errorf("cert and key file required")
return return
} }
if *s.cfg.LocalType == TYPE_TLS { if *s.cfg.LocalType == "tls" {
s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile) s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
if err != nil { if err != nil {
return return
@ -69,7 +86,7 @@ func (s *MuxBridge) StopService() {
s.isStop = true s.isStop = true
if s.sc != nil && (*s.sc).Listener != nil { if s.sc != nil && (*s.sc).Listener != nil {
(*(*s.sc).Listener).Close() (*(*s.sc).Listener).Close()
} }
for _, g := range s.clientControlConns.Items() { for _, g := range s.clientControlConns.Items() {
for _, session := range g.(utils.ConcurrentMap).Items() { for _, session := range g.(utils.ConcurrentMap).Items() {
(session.(*smux.Session)).Close() (session.(*smux.Session)).Close()
@ -92,11 +109,11 @@ func (s *MuxBridge) 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 := utils.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == TYPE_TCP { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.handler) err = sc.ListenTCP(s.handler)
} else if *s.cfg.LocalType == TYPE_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 == TYPE_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)
} }
if err != nil { if err != nil {

View File

@ -1,4 +1,4 @@
package services package mux
import ( import (
"crypto/tls" "crypto/tls"
@ -8,13 +8,27 @@ import (
"net" "net"
"time" "time"
"github.com/snail007/goproxy/utils"
"github.com/golang/snappy" "github.com/golang/snappy"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
type MuxClientArgs struct {
Parent *string
ParentType *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Key *string
Timeout *int
IsCompress *bool
SessionCount *int
KCP kcpcfg.KCPConfigArgs
}
type MuxClient struct { type MuxClient struct {
cfg MuxClientArgs cfg MuxClientArgs
isStop bool isStop bool
@ -22,7 +36,7 @@ type MuxClient struct {
log *logger.Logger log *logger.Logger
} }
func NewMuxClient() Service { func NewMuxClient() services.Service {
return &MuxClient{ return &MuxClient{
cfg: MuxClientArgs{}, cfg: MuxClientArgs{},
isStop: false, isStop: false,

View File

@ -1,4 +1,4 @@
package services package mux
import ( import (
"crypto/tls" "crypto/tls"
@ -12,6 +12,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"github.com/golang/snappy" "github.com/golang/snappy"
@ -19,31 +21,45 @@ import (
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
type MuxServer struct { type MuxServerArgs struct {
cfg MuxServerArgs Parent *string
udpChn chan MuxUDPItem ParentType *string
sc utils.ServerChannel CertFile *string
sessions utils.ConcurrentMap KeyFile *string
lockChn chan bool CertBytes []byte
isStop bool KeyBytes []byte
udpConn *net.Conn Local *string
log *logger.Logger IsUDP *bool
Key *string
Remote *string
Timeout *int
Route *[]string
Mgr *MuxServerManager
IsCompress *bool
SessionCount *int
KCP kcpcfg.KCPConfigArgs
}
type MuxUDPItem struct {
packet *[]byte
localAddr *net.UDPAddr
srcAddr *net.UDPAddr
} }
type MuxServerManager struct { type MuxServerManager struct {
cfg MuxServerArgs cfg MuxServerArgs
udpChn chan MuxUDPItem udpChn chan MuxUDPItem
serverID string serverID string
servers []*Service servers []*services.Service
log *logger.Logger log *logger.Logger
} }
func NewMuxServerManager() Service { func NewMuxServerManager() services.Service {
return &MuxServerManager{ return &MuxServerManager{
cfg: MuxServerArgs{}, cfg: MuxServerArgs{},
udpChn: make(chan MuxUDPItem, 50000), udpChn: make(chan MuxUDPItem, 50000),
serverID: utils.Uniqueid(), serverID: utils.Uniqueid(),
servers: []*Service{}, servers: []*services.Service{},
} }
} }
@ -139,7 +155,18 @@ func (s *MuxServerManager) InitService() (err error) {
return return
} }
func NewMuxServer() Service { type MuxServer struct {
cfg MuxServerArgs
udpChn chan MuxUDPItem
sc utils.ServerChannel
sessions utils.ConcurrentMap
lockChn chan bool
isStop bool
udpConn *net.Conn
log *logger.Logger
}
func NewMuxServer() services.Service {
return &MuxServer{ return &MuxServer{
cfg: MuxServerArgs{}, cfg: MuxServerArgs{},
udpChn: make(chan MuxUDPItem, 50000), udpChn: make(chan MuxUDPItem, 50000),
@ -149,12 +176,6 @@ func NewMuxServer() Service {
} }
} }
type MuxUDPItem struct {
packet *[]byte
localAddr *net.UDPAddr
srcAddr *net.UDPAddr
}
func (s *MuxServer) StopService() { func (s *MuxServer) StopService() {
defer func() { defer func() {
e := recover() e := recover()

View File

@ -10,14 +10,54 @@ import (
"strings" "strings"
"time" "time"
"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/aes" "github.com/snail007/goproxy/utils/aes"
"github.com/snail007/goproxy/utils/conncrypt" "github.com/snail007/goproxy/utils/conncrypt"
"github.com/snail007/goproxy/utils/socks" "github.com/snail007/goproxy/utils/socks"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
type SocksArgs struct {
Parent *string
ParentType *string
Local *string
LocalType *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
SSHKeyFile *string
SSHKeyFileSalt *string
SSHPassword *string
SSHUser *string
SSHKeyBytes []byte
SSHAuthMethod ssh.AuthMethod
Timeout *int
Always *bool
Interval *int
Blocked *string
Direct *string
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
KCP kcpcfg.KCPConfigArgs
UDPParent *string
UDPLocal *string
LocalIPS *[]string
DNSAddress *string
DNSTTL *int
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
}
type Socks struct { type Socks struct {
cfg SocksArgs cfg SocksArgs
checker utils.Checker checker utils.Checker
@ -32,7 +72,7 @@ type Socks struct {
log *logger.Logger log *logger.Logger
} }
func NewSocks() Service { func NewSocks() services.Service {
return &Socks{ return &Socks{
cfg: SocksArgs{}, cfg: SocksArgs{},
checker: utils.Checker{}, checker: utils.Checker{},
@ -198,11 +238,11 @@ func (s *Socks) Start(args interface{}, log *logger.Logger) (err error) {
s.log.Printf("use socks udp parent %s", *s.cfg.UDPParent) s.log.Printf("use socks udp parent %s", *s.cfg.UDPParent)
} }
sc := utils.NewServerChannelHost(*s.cfg.Local, s.log) sc := utils.NewServerChannelHost(*s.cfg.Local, s.log)
if *s.cfg.LocalType == TYPE_TCP { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.socksConnCallback) err = sc.ListenTCP(s.socksConnCallback)
} else if *s.cfg.LocalType == TYPE_TLS { } else if *s.cfg.LocalType == "tls" {
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.socksConnCallback) err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, nil, s.socksConnCallback)
} else if *s.cfg.LocalType == TYPE_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)
} }
if err != nil { if err != nil {

View File

@ -13,11 +13,44 @@ import (
"strings" "strings"
"time" "time"
"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/socks" "github.com/snail007/goproxy/utils/socks"
) )
type SPSArgs struct {
Parent *string
CertFile *string
KeyFile *string
CaCertFile *string
CaCertBytes []byte
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
LocalType *string
Timeout *int
KCP kcpcfg.KCPConfigArgs
ParentServiceType *string
DNSAddress *string
DNSTTL *int
AuthFile *string
Auth *[]string
AuthURL *string
AuthURLOkCode *int
AuthURLTimeout *int
AuthURLRetry *int
LocalIPS *[]string
ParentAuth *string
LocalKey *string
ParentKey *string
LocalCompress *bool
ParentCompress *bool
DisableHTTP *bool
DisableSocks5 *bool
}
type SPS struct { type SPS struct {
outPool utils.OutConn outPool utils.OutConn
cfg SPSArgs cfg SPSArgs
@ -28,7 +61,7 @@ type SPS struct {
log *logger.Logger log *logger.Logger
} }
func NewSPS() Service { func NewSPS() services.Service {
return &SPS{ return &SPS{
outPool: utils.OutConn{}, outPool: utils.OutConn{},
cfg: SPSArgs{}, cfg: SPSArgs{},
@ -39,14 +72,14 @@ func NewSPS() Service {
} }
func (s *SPS) CheckArgs() (err error) { func (s *SPS) CheckArgs() (err error) {
if *s.cfg.Parent == "" { if *s.cfg.Parent == "" {
err = fmt.Errorf("parent required for %s %s", s.cfg.Protocol(), *s.cfg.Local) err = fmt.Errorf("parent required for %s %s", *s.cfg.LocalType, *s.cfg.Local)
return return
} }
if *s.cfg.ParentType == "" { if *s.cfg.ParentType == "" {
err = fmt.Errorf("parent type unkown,use -T <tls|tcp|kcp>") err = fmt.Errorf("parent type unkown,use -T <tls|tcp|kcp>")
return return
} }
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.LocalType == TYPE_TLS { if *s.cfg.ParentType == "tls" || *s.cfg.LocalType == "tls" {
s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile) s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
if err != nil { if err != nil {
return return
@ -70,7 +103,7 @@ func (s *SPS) InitService() (err error) {
return return
} }
func (s *SPS) InitOutConnPool() { func (s *SPS) InitOutConnPool() {
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.ParentType == TYPE_TCP || *s.cfg.ParentType == TYPE_KCP { if *s.cfg.ParentType == "tls" || *s.cfg.ParentType == "tcp" || *s.cfg.ParentType == "kcp" {
//dur int, isTLS bool, certBytes, keyBytes []byte, //dur int, isTLS bool, certBytes, keyBytes []byte,
//parent string, timeout int, InitialCap int, MaxCap int //parent string, timeout int, InitialCap int, MaxCap int
s.outPool = utils.NewOutConn( s.outPool = utils.NewOutConn(
@ -125,17 +158,17 @@ func (s *SPS) 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 := utils.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == TYPE_TCP { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.callback) err = sc.ListenTCP(s.callback)
} else if *s.cfg.LocalType == TYPE_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 == TYPE_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)
} }
if err != nil { if err != nil {
return return
} }
s.log.Printf("%s http(s)+socks proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr()) s.log.Printf("%s http(s)+socks proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
s.serverChannels = append(s.serverChannels, &sc) s.serverChannels = append(s.serverChannels, &sc)
} }
} }
@ -148,7 +181,7 @@ func (s *SPS) Clean() {
func (s *SPS) callback(inConn net.Conn) { func (s *SPS) callback(inConn net.Conn) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack())) s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", *s.cfg.LocalType, err, string(debug.Stack()))
} }
}() }()
if *s.cfg.LocalCompress { if *s.cfg.LocalCompress {
@ -161,11 +194,11 @@ func (s *SPS) callback(inConn net.Conn) {
} }
var err error var err error
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case TYPE_KCP: case "kcp":
fallthrough fallthrough
case TYPE_TCP: case "tcp":
fallthrough fallthrough
case TYPE_TLS: case "tls":
err = s.OutToTCP(&inConn) 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)

View File

@ -9,11 +9,27 @@ import (
"runtime/debug" "runtime/debug"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
"strconv" "strconv"
) )
type TCPArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
LocalType *string
Timeout *int
CheckParentInterval *int
KCP kcpcfg.KCPConfigArgs
}
type TCP struct { type TCP struct {
outPool utils.OutConn outPool utils.OutConn
cfg TCPArgs cfg TCPArgs
@ -23,7 +39,7 @@ type TCP struct {
log *logger.Logger log *logger.Logger
} }
func NewTCP() Service { func NewTCP() services.Service {
return &TCP{ return &TCP{
outPool: utils.OutConn{}, outPool: utils.OutConn{},
cfg: TCPArgs{}, cfg: TCPArgs{},
@ -33,14 +49,14 @@ func NewTCP() Service {
} }
func (s *TCP) CheckArgs() (err error) { func (s *TCP) CheckArgs() (err error) {
if *s.cfg.Parent == "" { if *s.cfg.Parent == "" {
err = fmt.Errorf("parent required for %s %s", s.cfg.Protocol(), *s.cfg.Local) err = fmt.Errorf("parent required for %s %s", *s.cfg.LocalType, *s.cfg.Local)
return return
} }
if *s.cfg.ParentType == "" { if *s.cfg.ParentType == "" {
err = fmt.Errorf("parent type unkown,use -T <tls|tcp|kcp|udp>") err = fmt.Errorf("parent type unkown,use -T <tls|tcp|kcp|udp>")
return return
} }
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.LocalType == TYPE_TLS { if *s.cfg.ParentType == "tls" || *s.cfg.LocalType == "tls" {
s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile) s.cfg.CertBytes, s.cfg.KeyBytes, err = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
if err != nil { if err != nil {
return return
@ -86,17 +102,17 @@ func (s *TCP) Start(args interface{}, log *logger.Logger) (err error) {
p, _ := strconv.Atoi(port) p, _ := strconv.Atoi(port)
sc := utils.NewServerChannel(host, p, s.log) sc := utils.NewServerChannel(host, p, s.log)
if *s.cfg.LocalType == TYPE_TCP { if *s.cfg.LocalType == "tcp" {
err = sc.ListenTCP(s.callback) err = sc.ListenTCP(s.callback)
} else if *s.cfg.LocalType == TYPE_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 == TYPE_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)
} }
if err != nil { if err != nil {
return return
} }
s.log.Printf("%s proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr()) s.log.Printf("%s proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
s.sc = &sc s.sc = &sc
return return
} }
@ -107,18 +123,18 @@ func (s *TCP) Clean() {
func (s *TCP) callback(inConn net.Conn) { func (s *TCP) callback(inConn net.Conn) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack())) s.log.Printf("%s conn handler crashed with err : %s \nstack: %s", *s.cfg.LocalType, err, string(debug.Stack()))
} }
}() }()
var err error var err error
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case TYPE_KCP: case "kcp":
fallthrough fallthrough
case TYPE_TCP: case "tcp":
fallthrough fallthrough
case TYPE_TLS: case "tls":
err = s.OutToTCP(&inConn) err = s.OutToTCP(&inConn)
case TYPE_UDP: case "udp":
err = s.OutToUDP(&inConn) err = s.OutToUDP(&inConn)
default: default:
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
@ -204,7 +220,7 @@ func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
} }
func (s *TCP) InitOutConnPool() { func (s *TCP) InitOutConnPool() {
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.ParentType == TYPE_TCP || *s.cfg.ParentType == TYPE_KCP { if *s.cfg.ParentType == "tls" || *s.cfg.ParentType == "tcp" || *s.cfg.ParentType == "kcp" {
//dur int, isTLS bool, certBytes, keyBytes []byte, //dur int, isTLS bool, certBytes, keyBytes []byte,
//parent string, timeout int, InitialCap int, MaxCap int //parent string, timeout int, InitialCap int, MaxCap int
s.outPool = utils.NewOutConn( s.outPool = utils.NewOutConn(

View File

@ -9,12 +9,29 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
const (
CONN_CLIENT_CONTROL = uint8(1)
CONN_SERVER = uint8(4)
CONN_CLIENT = uint8(5)
)
type TunnelBridgeArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
Timeout *int
Mux *bool
}
type ServerConn struct { type ServerConn struct {
//ClientLocalAddr string //tcp:2.2.22:333@ID //ClientLocalAddr string //tcp:2.2.22:333@ID
Conn *net.Conn Conn *net.Conn
@ -27,7 +44,7 @@ type TunnelBridge struct {
log *logger.Logger log *logger.Logger
} }
func NewTunnelBridge() Service { func NewTunnelBridge() services.Service {
return &TunnelBridge{ return &TunnelBridge{
cfg: TunnelBridgeArgs{}, cfg: TunnelBridgeArgs{},
serverConns: utils.NewConcurrentMap(), serverConns: utils.NewConcurrentMap(),

View File

@ -9,12 +9,27 @@ import (
"os" "os"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
const (
CONN_SERVER_MUX = uint8(6)
CONN_CLIENT_MUX = uint8(7)
)
type TunnelClientArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Key *string
Timeout *int
Mux *bool
}
type TunnelClient struct { type TunnelClient struct {
cfg TunnelClientArgs cfg TunnelClientArgs
ctrlConn net.Conn ctrlConn net.Conn
@ -23,7 +38,7 @@ type TunnelClient struct {
log *logger.Logger log *logger.Logger
} }
func NewTunnelClient() Service { func NewTunnelClient() services.Service {
return &TunnelClient{ return &TunnelClient{
cfg: TunnelClientArgs{}, cfg: TunnelClientArgs{},
userConns: utils.NewConcurrentMap(), userConns: utils.NewConcurrentMap(),

View File

@ -12,36 +12,47 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
//"github.com/xtaci/smux" //"github.com/xtaci/smux"
smux "github.com/hashicorp/yamux" smux "github.com/hashicorp/yamux"
) )
type TunnelServer struct { type TunnelServerArgs struct {
cfg TunnelServerArgs Parent *string
udpChn chan UDPItem CertFile *string
sc utils.ServerChannel KeyFile *string
isStop bool CertBytes []byte
udpConn *net.Conn KeyBytes []byte
userConns utils.ConcurrentMap Local *string
log *logger.Logger IsUDP *bool
Key *string
Remote *string
Timeout *int
Route *[]string
Mgr *TunnelServerManager
Mux *bool
}
type UDPItem struct {
packet *[]byte
localAddr *net.UDPAddr
srcAddr *net.UDPAddr
} }
type TunnelServerManager struct { type TunnelServerManager struct {
cfg TunnelServerArgs cfg TunnelServerArgs
udpChn chan UDPItem udpChn chan UDPItem
serverID string serverID string
servers []*Service servers []*services.Service
log *logger.Logger log *logger.Logger
} }
func NewTunnelServerManager() Service { func NewTunnelServerManager() services.Service {
return &TunnelServerManager{ return &TunnelServerManager{
cfg: TunnelServerArgs{}, cfg: TunnelServerArgs{},
udpChn: make(chan UDPItem, 50000), udpChn: make(chan UDPItem, 50000),
serverID: utils.Uniqueid(), serverID: utils.Uniqueid(),
servers: []*Service{}, servers: []*services.Service{},
} }
} }
func (s *TunnelServerManager) Start(args interface{}, log *logger.Logger) (err error) { func (s *TunnelServerManager) Start(args interface{}, log *logger.Logger) (err error) {
@ -146,7 +157,18 @@ func (s *TunnelServerManager) GetConn() (conn net.Conn, err error) {
} }
return return
} }
func NewTunnelServer() Service {
type TunnelServer struct {
cfg TunnelServerArgs
udpChn chan UDPItem
sc utils.ServerChannel
isStop bool
udpConn *net.Conn
userConns utils.ConcurrentMap
log *logger.Logger
}
func NewTunnelServer() services.Service {
return &TunnelServer{ return &TunnelServer{
cfg: TunnelServerArgs{}, cfg: TunnelServerArgs{},
udpChn: make(chan UDPItem, 50000), udpChn: make(chan UDPItem, 50000),
@ -155,12 +177,6 @@ func NewTunnelServer() Service {
} }
} }
type UDPItem struct {
packet *[]byte
localAddr *net.UDPAddr
srcAddr *net.UDPAddr
}
func (s *TunnelServer) StopService() { func (s *TunnelServer) StopService() {
defer func() { defer func() {
e := recover() e := recover()

View File

@ -12,10 +12,22 @@ import (
"strings" "strings"
"time" "time"
"github.com/snail007/goproxy/services"
"github.com/snail007/goproxy/services/kcpcfg" "github.com/snail007/goproxy/services/kcpcfg"
"github.com/snail007/goproxy/utils" "github.com/snail007/goproxy/utils"
) )
type UDPArgs struct {
Parent *string
CertFile *string
KeyFile *string
CertBytes []byte
KeyBytes []byte
Local *string
ParentType *string
Timeout *int
CheckParentInterval *int
}
type UDP struct { type UDP struct {
p utils.ConcurrentMap p utils.ConcurrentMap
outPool utils.OutConn outPool utils.OutConn
@ -25,7 +37,7 @@ type UDP struct {
log *logger.Logger log *logger.Logger
} }
func NewUDP() Service { func NewUDP() services.Service {
return &UDP{ return &UDP{
outPool: utils.OutConn{}, outPool: utils.OutConn{},
p: utils.NewConcurrentMap(), p: utils.NewConcurrentMap(),
@ -50,7 +62,7 @@ func (s *UDP) CheckArgs() (err error) {
return return
} }
func (s *UDP) InitService() (err error) { func (s *UDP) InitService() (err error) {
if *s.cfg.ParentType != TYPE_UDP { if *s.cfg.ParentType != "udp" {
s.InitOutConnPool() s.InitOutConnPool()
} }
return return
@ -105,11 +117,11 @@ func (s *UDP) callback(packet []byte, localAddr, srcAddr *net.UDPAddr) {
}() }()
var err error var err error
switch *s.cfg.ParentType { switch *s.cfg.ParentType {
case TYPE_TCP: case "tcp":
fallthrough fallthrough
case TYPE_TLS: case "tls":
err = s.OutToTCP(packet, localAddr, srcAddr) err = s.OutToTCP(packet, localAddr, srcAddr)
case TYPE_UDP: case "udp":
err = s.OutToUDP(packet, localAddr, srcAddr) err = s.OutToUDP(packet, localAddr, srcAddr)
default: default:
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType) err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
@ -234,7 +246,7 @@ func (s *UDP) OutToUDP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err erro
return return
} }
func (s *UDP) InitOutConnPool() { func (s *UDP) InitOutConnPool() {
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.ParentType == TYPE_TCP { if *s.cfg.ParentType == "tls" || *s.cfg.ParentType == "tcp" {
//dur int, isTLS bool, certBytes, keyBytes []byte, //dur int, isTLS bool, certBytes, keyBytes []byte,
//parent string, timeout int, InitialCap int, MaxCap int //parent string, timeout int, InitialCap int, MaxCap int
s.outPool = utils.NewOutConn( s.outPool = utils.NewOutConn(