12
CHANGELOG
12
CHANGELOG
@ -1,13 +1,13 @@
|
||||
proxy更新日志
|
||||
v4.7
|
||||
1.优化了bridge的日志,增加了client和server的掉线日志.
|
||||
2.优化了sps读取http(s)代理响应的缓冲大小,同时优化了CONNECT请求,
|
||||
1.增加了基于gomobile的sdk,对安卓/IOS提供SDK支持.
|
||||
2.优化了bridge的日志,增加了client和server的掉线日志.
|
||||
3.优化了sps读取http(s)代理响应的缓冲大小,同时优化了CONNECT请求,
|
||||
避免了某些代理服务器返回过多数据导致不能正常通讯的问题.
|
||||
3.去除了鸡肋连接池功能.
|
||||
4.增加了gomobile sdk,对安卓/IOS提供支持.
|
||||
4.去除了鸡肋连接池功能.
|
||||
5.优化了所有服务代码,方便对sdk提供支持.
|
||||
|
||||
|
||||
6.增加了SDK手册.
|
||||
7.增加了GUI客户端(windows/web/android/ios)介绍主页.
|
||||
|
||||
v4.6
|
||||
1.sps,http(s),socks5,内网穿透都做了大量的超时优化处理,更加稳定.
|
||||
|
||||
@ -86,7 +86,6 @@ func initConfig() (err error) {
|
||||
httpArgs.Direct = http.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
||||
httpArgs.AuthFile = http.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
|
||||
httpArgs.Auth = http.Flag("auth", "http basic auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
|
||||
httpArgs.PoolSize = http.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
httpArgs.CheckParentInterval = http.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
httpArgs.Local = http.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()
|
||||
httpArgs.SSHUser = http.Flag("ssh-user", "user for ssh").Short('u').Default("").String()
|
||||
@ -109,7 +108,6 @@ func initConfig() (err error) {
|
||||
tcpArgs.Timeout = tcp.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('e').Default("2000").Int()
|
||||
tcpArgs.ParentType = tcp.Flag("parent-type", "parent protocol type <tls|tcp|kcp|udp>").Short('T').Enum("tls", "tcp", "udp", "kcp")
|
||||
tcpArgs.LocalType = tcp.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
|
||||
tcpArgs.PoolSize = tcp.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
tcpArgs.CheckParentInterval = tcp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
tcpArgs.Local = tcp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
|
||||
@ -120,7 +118,6 @@ func initConfig() (err error) {
|
||||
udpArgs.KeyFile = udp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
udpArgs.Timeout = udp.Flag("timeout", "tcp timeout milliseconds when connect to parent proxy").Short('t').Default("2000").Int()
|
||||
udpArgs.ParentType = udp.Flag("parent-type", "parent protocol type <tls|tcp|udp>").Short('T').Enum("tls", "tcp", "udp")
|
||||
udpArgs.PoolSize = udp.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
udpArgs.CheckParentInterval = udp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
|
||||
|
||||
77
sdk/README.md
Normal file
77
sdk/README.md
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
# Proxy SDK 使用说明
|
||||
|
||||
proxy使用gombile实现了一份go代码编译为android和ios平台下面可以直接调用的sdk类库,
|
||||
基于这些类库,APP开发者可以轻松的开发出各种形式的代理工具.
|
||||
|
||||
### 下面分平台介绍SDK的用法
|
||||
|
||||
#### Android SDK
|
||||
|
||||
[](https://github.com/snail007/goproxy/) []() [](https://github.com/snail007/goproxy/releases) [](https://github.com/snail007/goproxy/releases)
|
||||
|
||||
[点击下载Android-SDK](https://github.com/snail007/goproxy-sdk-android/releases)
|
||||
在Android系统提供的sdk形式是一个后缀为.aar的类库文件,开发的时候只需要把arr类库文件引入android项目即可.
|
||||
|
||||
### Android-SDK使用实例
|
||||
|
||||
#### 1.导入包
|
||||
```java
|
||||
import snail007.proxy.Porxy
|
||||
```
|
||||
|
||||
#### 2.启动一个服务
|
||||
```java
|
||||
String args="http -p :8080"
|
||||
String err=Proxy.start(args)
|
||||
if (err.isEmpty()){
|
||||
//启动失败
|
||||
System.out.println("start fail,error:"+err)
|
||||
}else{
|
||||
//启动成功
|
||||
}
|
||||
```
|
||||
#### 3.判断一个服务是否在运行
|
||||
|
||||
```java
|
||||
String args="http -p :8080"
|
||||
boolean isRunning=Proxy.isRunning(args)//这里传递http也可以,最终使用的就是args里面的第一个参数http
|
||||
if(isRunning){
|
||||
//正在运行
|
||||
}else{
|
||||
//没有运行
|
||||
}
|
||||
```
|
||||
#### 4.停止一个服务
|
||||
|
||||
```java
|
||||
String args="http -p :8080"
|
||||
Proxy.stop(args)//这里传递http也可以,最终使用的就是args里面的第一个参数http
|
||||
//停止完毕
|
||||
|
||||
```
|
||||
|
||||
|
||||
### IOS-SDK使用实例
|
||||
|
||||
#### todo
|
||||
|
||||
|
||||
### 关于服务
|
||||
proxy的服务有11种,分别是:
|
||||
|
||||
```shell
|
||||
http
|
||||
socks
|
||||
sps
|
||||
tcp
|
||||
udp
|
||||
bridge
|
||||
server
|
||||
client
|
||||
tbridge
|
||||
tserver
|
||||
tclient
|
||||
```
|
||||
每个服务只能启动一个,如果相同的服务启动多次,那么之前的服务会被停掉,后面启动的服务覆盖之前的服务.
|
||||
上面这些服务的具体使用方式和具体参数,可以参考[proxy手册](https://github.com/snail007/goproxy/blob/master/README_ZH.md)
|
||||
@ -1,41 +1,56 @@
|
||||
#/bin/bash
|
||||
VER="v4.7"
|
||||
rm -rf proxy-sdk-release-*
|
||||
rm -rf android
|
||||
rm -rf ios
|
||||
mkdir android
|
||||
mkdir ios
|
||||
|
||||
#arm
|
||||
gomobile bind -v -target=android/arm
|
||||
mkdir proxy-sdk-arm
|
||||
mv sdk.aar proxy-sdk-arm/proxy-sdk-arm.aar
|
||||
mv sdk-sources.jar proxy-sdk-arm/proxy-sdk-arm-sources.jar
|
||||
tar zcfv proxy-sdk-arm-${VER}.tar.gz proxy-sdk-arm
|
||||
rm -rf proxy-sdk-arm
|
||||
gomobile bind -v -target=android/arm -javapkg=snail007 -ldflags="-s -w"
|
||||
mkdir arm
|
||||
mv proxy.aar arm/snail007.goproxy.sdk.aar
|
||||
mv proxy-sources.jar arm/snail007.goproxy.sdk-sources.jar
|
||||
tar zcfv sdk-arm-${VER}.tar.gz arm
|
||||
mv sdk-arm-${VER}.tar.gz android
|
||||
rm -rf arm
|
||||
|
||||
|
||||
#arm64
|
||||
gomobile bind -v -target=android/arm64
|
||||
mkdir proxy-sdk-arm64
|
||||
mv sdk.aar proxy-sdk-arm64/proxy-sdk-arm64.aar
|
||||
mv sdk-sources.jar proxy-sdk-arm64/proxy-sdk-arm64-sources.jar
|
||||
tar zcfv proxy-sdk-arm64-${VER}.tar.gz proxy-sdk-arm64
|
||||
rm -rf proxy-sdk-arm64
|
||||
gomobile bind -v -target=android/arm64 -javapkg=snail007 -ldflags="-s -w"
|
||||
mkdir arm64
|
||||
mv proxy.aar arm64/snail007.goproxy.sdk.aar
|
||||
mv proxy-sources.jar arm64/snail007.goproxy.sdk-sources.jar
|
||||
tar zcfv sdk-arm64-${VER}.tar.gz arm64
|
||||
mv sdk-arm64-${VER}.tar.gz android
|
||||
rm -rf arm64
|
||||
|
||||
|
||||
#386
|
||||
gomobile bind -v -target=android/386
|
||||
mkdir proxy-sdk-386
|
||||
mv sdk.aar proxy-sdk-386/proxy-sdk-386.aar
|
||||
mv sdk-sources.jar proxy-sdk-386/proxy-sdk-386-sources.jar
|
||||
tar zcfv proxy-sdk-386-${VER}.tar.gz proxy-sdk-386
|
||||
rm -rf proxy-sdk-386
|
||||
gomobile bind -v -target=android/386 -javapkg=snail007 -ldflags="-s -w"
|
||||
mkdir 386
|
||||
mv proxy.aar 386/snail007.goproxy.sdk.aar
|
||||
mv proxy-sources.jar 386/snail007.goproxy.sdk-sources.jar
|
||||
tar zcfv sdk-386-${VER}.tar.gz 386
|
||||
mv sdk-386-${VER}.tar.gz android
|
||||
rm -rf 386
|
||||
|
||||
#amd64
|
||||
gomobile bind -v -target=android/amd64
|
||||
mkdir proxy-sdk-amd64
|
||||
mv sdk.aar proxy-sdk-amd64/proxy-sdk-amd64.aar
|
||||
mv sdk-sources.jar proxy-sdk-amd64/proxy-sdk-amd64-sources.jar
|
||||
tar zcfv proxy-sdk-amd64-${VER}.tar.gz proxy-sdk-amd64
|
||||
rm -rf proxy-sdk-amd64
|
||||
gomobile bind -v -target=android/amd64 -javapkg=snail007 -ldflags="-s -w"
|
||||
mkdir amd64
|
||||
mv proxy.aar amd64/snail007.goproxy.sdk.aar
|
||||
mv proxy-sources.jar amd64/snail007.goproxy.sdk-sources.jar
|
||||
tar zcfv sdk-amd64-${VER}.tar.gz amd64
|
||||
mv sdk-amd64-${VER}.tar.gz android
|
||||
rm -rf amd64
|
||||
|
||||
|
||||
#all-in-one
|
||||
gomobile bind -v -target=android
|
||||
mkdir proxy-sdk-all
|
||||
mv sdk.aar proxy-sdk-all/proxy-sdk-all.aar
|
||||
mv sdk-sources.jar proxy-sdk-all/proxy-sdk-all-sources.jar
|
||||
tar zcfv proxy-sdk-all-${VER}.tar.gz proxy-sdk-all
|
||||
rm -rf proxy-sdk-all
|
||||
mkdir proxy-sdk-release-${VER}
|
||||
mv *.tar.gz proxy-sdk-release-${VER}
|
||||
gomobile bind -v -target=android -javapkg=snail007 -ldflags="-s -w"
|
||||
mkdir all
|
||||
mv proxy.aar all/snail007.goproxy.sdk.aar
|
||||
mv proxy-sources.jar all/snail007.goproxy.sdk-sources.jar
|
||||
tar zcfv sdk-all-${VER}.tar.gz all
|
||||
mv sdk-all-${VER}.tar.gz android
|
||||
rm -rf all
|
||||
|
||||
echo "done."
|
||||
|
||||
133
sdk/sdk.go
133
sdk/sdk.go
@ -1,13 +1,16 @@
|
||||
package sdk
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"snail007/proxy/services"
|
||||
"snail007/proxy/services/kcpcfg"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
@ -15,8 +18,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
app *kingpin.Application
|
||||
service *services.ServiceItem
|
||||
app *kingpin.Application
|
||||
)
|
||||
|
||||
//Start argsStr: is the whole command line args string
|
||||
@ -47,7 +49,7 @@ func Start(argsStr string) (errStr string) {
|
||||
logfile := app.Flag("log", "log file path").Default("").String()
|
||||
kcpArgs.Key = app.Flag("kcp-key", "pre-shared secret between client and server").Default("secrect").String()
|
||||
kcpArgs.Crypt = app.Flag("kcp-method", "encrypt/decrypt method, can be: aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none").Default("aes").Enum("aes", "aes-128", "aes-192", "salsa20", "blowfish", "twofish", "cast5", "3des", "tea", "xtea", "xor", "sm4", "none")
|
||||
kcpArgs.Mode = app.Flag("kcp-mode", "profiles: fast3, fast2, fast, normal, manual").Default("fast").Enum("fast3", "fast2", "fast", "normal", "manual")
|
||||
kcpArgs.Mode = app.Flag("kcp-mode", "profiles: fast3, fast2, fast, normal, manual").Default("fast3").Enum("fast3", "fast2", "fast", "normal", "manual")
|
||||
kcpArgs.MTU = app.Flag("kcp-mtu", "set maximum transmission unit for UDP packets").Default("1350").Int()
|
||||
kcpArgs.SndWnd = app.Flag("kcp-sndwnd", "set send window size(num of packets)").Default("1024").Int()
|
||||
kcpArgs.RcvWnd = app.Flag("kcp-rcvwnd", "set receive window size(num of packets)").Default("1024").Int()
|
||||
@ -79,7 +81,6 @@ func Start(argsStr string) (errStr string) {
|
||||
httpArgs.Direct = http.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
||||
httpArgs.AuthFile = http.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
|
||||
httpArgs.Auth = http.Flag("auth", "http basic auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
|
||||
httpArgs.PoolSize = http.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
httpArgs.CheckParentInterval = http.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
httpArgs.Local = http.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()
|
||||
httpArgs.SSHUser = http.Flag("ssh-user", "user for ssh").Short('u').Default("").String()
|
||||
@ -102,7 +103,6 @@ func Start(argsStr string) (errStr string) {
|
||||
tcpArgs.Timeout = tcp.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('e').Default("2000").Int()
|
||||
tcpArgs.ParentType = tcp.Flag("parent-type", "parent protocol type <tls|tcp|kcp|udp>").Short('T').Enum("tls", "tcp", "udp", "kcp")
|
||||
tcpArgs.LocalType = tcp.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
|
||||
tcpArgs.PoolSize = tcp.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
tcpArgs.CheckParentInterval = tcp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
tcpArgs.Local = tcp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
|
||||
@ -113,7 +113,6 @@ func Start(argsStr string) (errStr string) {
|
||||
udpArgs.KeyFile = udp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
udpArgs.Timeout = udp.Flag("timeout", "tcp timeout milliseconds when connect to parent proxy").Short('t').Default("2000").Int()
|
||||
udpArgs.ParentType = udp.Flag("parent-type", "parent protocol type <tls|tcp|udp>").Short('T').Enum("tls", "tcp", "udp")
|
||||
udpArgs.PoolSize = udp.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
udpArgs.CheckParentInterval = udp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
|
||||
@ -225,7 +224,11 @@ func Start(argsStr string) (errStr string) {
|
||||
spsArgs.AuthURLRetry = sps.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int()
|
||||
spsArgs.ParentAuth = sps.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String()
|
||||
//parse args
|
||||
args := strings.Fields(strings.Trim(argsStr, " "))
|
||||
_args := strings.Fields(strings.Trim(argsStr, " "))
|
||||
args := []string{}
|
||||
for _, a := range _args {
|
||||
args = append(args, strings.Trim(a, "\""))
|
||||
}
|
||||
serviceName, err := app.Parse(args)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("parse args fail,err: %s", err)
|
||||
@ -323,16 +326,120 @@ func Start(argsStr string) (errStr string) {
|
||||
case "sps":
|
||||
services.Regist("sps", services.NewSPS(), spsArgs)
|
||||
}
|
||||
|
||||
service, err = services.Run(serviceName)
|
||||
_, err = services.Run(serviceName)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("run service [%s] fail, ERR:%s", serviceName, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Stop() {
|
||||
if service != nil && service.S != nil {
|
||||
service.S.Clean()
|
||||
func Stop(service string) {
|
||||
s := getServiceName(service)
|
||||
if s == "" {
|
||||
return
|
||||
}
|
||||
services.Stop(s)
|
||||
}
|
||||
|
||||
func IsRunning(service string) bool {
|
||||
s := getServiceName(service)
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
srv := services.GetService(s)
|
||||
if srv == nil {
|
||||
return false
|
||||
}
|
||||
typ := "tcp"
|
||||
addr := ""
|
||||
route := ""
|
||||
switch srv.Name {
|
||||
case "http":
|
||||
addr = *srv.Args.(services.HTTPArgs).Local
|
||||
case "socks":
|
||||
addr = *srv.Args.(services.SocksArgs).Local
|
||||
case "sps":
|
||||
addr = *srv.Args.(services.SPSArgs).Local
|
||||
case "tcp":
|
||||
addr = *srv.Args.(services.TCPArgs).Local
|
||||
case "bridge":
|
||||
addr = *srv.Args.(services.MuxBridgeArgs).Local
|
||||
|
||||
case "tbridge":
|
||||
addr = *srv.Args.(services.TunnelBridgeArgs).Local
|
||||
case "server":
|
||||
if len(*srv.Args.(services.MuxServerArgs).Route) > 0 {
|
||||
route = (*srv.Args.(services.MuxServerArgs).Route)[0]
|
||||
}
|
||||
case "tserver":
|
||||
if len(*srv.Args.(services.TunnelServerArgs).Route) > 0 {
|
||||
route = (*srv.Args.(services.TunnelServerArgs).Route)[0]
|
||||
}
|
||||
case "client":
|
||||
case "tclient":
|
||||
case "udp":
|
||||
typ = "udp"
|
||||
}
|
||||
if route != "" {
|
||||
if strings.HasPrefix(route, "udp://") {
|
||||
typ = "udp"
|
||||
}
|
||||
info := strings.TrimPrefix(route, "udp://")
|
||||
info = strings.TrimPrefix(info, "tcp://")
|
||||
_routeInfo := strings.Split(info, "@")
|
||||
addr = _routeInfo[0]
|
||||
}
|
||||
a := strings.Split(addr, ",")
|
||||
if len(a) > 0 {
|
||||
return PortIsAlive(a[0], typ) == ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getServiceName(args string) string {
|
||||
s := strings.Fields(strings.Trim(args, " \t"))
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
return s[0]
|
||||
}
|
||||
|
||||
func PortIsAlive(address string, network ...string) string {
|
||||
time.Sleep(time.Second)
|
||||
n := "tcp"
|
||||
if len(network) == 1 {
|
||||
n = network[0]
|
||||
}
|
||||
if n == "tcp" {
|
||||
conn, err := net.DialTimeout(n, address, time.Second)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("connect %s is failed!,err:%v\n", address, err)
|
||||
}
|
||||
conn.Close()
|
||||
} else {
|
||||
ip, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
portI, _ := strconv.Atoi(port)
|
||||
dstAddr := &net.UDPAddr{IP: net.ParseIP(ip), Port: portI}
|
||||
conn, err := net.DialUDP(n, &net.UDPAddr{IP: net.IPv4zero, Port: 0}, dstAddr)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
conn.SetDeadline(time.Now().Add(time.Millisecond * 200))
|
||||
_, err = conn.Write([]byte{0x00})
|
||||
conn.SetDeadline(time.Now().Add(time.Millisecond * 200))
|
||||
b := make([]byte, 1)
|
||||
_, err = conn.Read(b)
|
||||
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "refused") {
|
||||
return err.Error()
|
||||
}
|
||||
} else {
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -111,7 +111,6 @@ type TCPArgs struct {
|
||||
ParentType *string
|
||||
LocalType *string
|
||||
Timeout *int
|
||||
PoolSize *int
|
||||
CheckParentInterval *int
|
||||
KCP kcpcfg.KCPConfigArgs
|
||||
}
|
||||
@ -139,7 +138,6 @@ type HTTPArgs struct {
|
||||
ParentType *string
|
||||
LocalType *string
|
||||
Timeout *int
|
||||
PoolSize *int
|
||||
CheckParentInterval *int
|
||||
SSHKeyFile *string
|
||||
SSHKeyFileSalt *string
|
||||
@ -161,7 +159,6 @@ type UDPArgs struct {
|
||||
Local *string
|
||||
ParentType *string
|
||||
Timeout *int
|
||||
PoolSize *int
|
||||
CheckParentInterval *int
|
||||
}
|
||||
type SocksArgs struct {
|
||||
|
||||
@ -25,6 +25,7 @@ type HTTP struct {
|
||||
domainResolver utils.DomainResolver
|
||||
isStop bool
|
||||
serverChannels []*utils.ServerChannel
|
||||
userConns utils.ConcurrentMap
|
||||
}
|
||||
|
||||
func NewHTTP() Service {
|
||||
@ -36,6 +37,7 @@ func NewHTTP() Service {
|
||||
lockChn: make(chan bool, 1),
|
||||
isStop: false,
|
||||
serverChannels: []*utils.ServerChannel{},
|
||||
userConns: utils.NewConcurrentMap(),
|
||||
}
|
||||
}
|
||||
func (s *HTTP) CheckArgs() (err error) {
|
||||
@ -139,7 +141,7 @@ func (s *HTTP) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop http(s) service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service http(s) stoped,%s", e)
|
||||
log.Printf("service http(s) stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
@ -230,7 +232,6 @@ func (s *HTTP) callback(inConn net.Conn) {
|
||||
log.Printf("use proxy : %v, %s", useProxy, address)
|
||||
|
||||
err = s.OutToTCP(useProxy, address, &inConn, &req)
|
||||
|
||||
if err != nil {
|
||||
if *s.cfg.Parent == "" {
|
||||
log.Printf("connect to %s fail, ERR:%s", address, err)
|
||||
@ -298,9 +299,13 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
|
||||
|
||||
utils.IoBind((*inConn), outConn, func(err interface{}) {
|
||||
log.Printf("conn %s - %s released [%s]", inAddr, outAddr, req.Host)
|
||||
s.userConns.Remove(inAddr)
|
||||
})
|
||||
log.Printf("conn %s - %s connected [%s]", inAddr, outAddr, req.Host)
|
||||
|
||||
if c, ok := s.userConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
s.userConns.Set(inAddr, inConn)
|
||||
return
|
||||
}
|
||||
|
||||
@ -372,8 +377,6 @@ func (s *HTTP) InitOutConnPool() {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes, s.cfg.CaCertBytes,
|
||||
s.Resolve(*s.cfg.Parent),
|
||||
*s.cfg.Timeout,
|
||||
*s.cfg.PoolSize,
|
||||
*s.cfg.PoolSize*2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import (
|
||||
type MuxBridge struct {
|
||||
cfg MuxBridgeArgs
|
||||
clientControlConns utils.ConcurrentMap
|
||||
serverConns utils.ConcurrentMap
|
||||
router utils.ClientKeyRouter
|
||||
l *sync.Mutex
|
||||
isStop bool
|
||||
@ -29,6 +30,7 @@ func NewMuxBridge() Service {
|
||||
b := &MuxBridge{
|
||||
cfg: MuxBridgeArgs{},
|
||||
clientControlConns: utils.NewConcurrentMap(),
|
||||
serverConns: utils.NewConcurrentMap(),
|
||||
l: &sync.Mutex{},
|
||||
isStop: false,
|
||||
}
|
||||
@ -58,7 +60,7 @@ func (s *MuxBridge) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop bridge service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service bridge stoped,%s", e)
|
||||
log.Printf("service bridge stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
@ -70,6 +72,9 @@ func (s *MuxBridge) StopService() {
|
||||
(session.(*smux.Session)).Close()
|
||||
}
|
||||
}
|
||||
for _, c := range s.serverConns.Items() {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
}
|
||||
func (s *MuxBridge) Start(args interface{}) (err error) {
|
||||
s.cfg = args.(MuxBridgeArgs)
|
||||
@ -116,6 +121,7 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
||||
switch connType {
|
||||
case CONN_SERVER:
|
||||
var serverID string
|
||||
inAddr := inConn.RemoteAddr().String()
|
||||
inConn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout)))
|
||||
err = utils.ReadPacketData(reader, &serverID)
|
||||
inConn.SetDeadline(time.Time{})
|
||||
@ -124,6 +130,10 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
||||
return
|
||||
}
|
||||
log.Printf("server connection %s %s connected", serverID, key)
|
||||
if c, ok := s.serverConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
s.serverConns.Set(inAddr, &inConn)
|
||||
session, err := smux.Server(inConn, nil)
|
||||
if err != nil {
|
||||
utils.CloseConn(&inConn)
|
||||
@ -138,6 +148,7 @@ func (s *MuxBridge) handler(inConn net.Conn) {
|
||||
if err != nil {
|
||||
session.Close()
|
||||
utils.CloseConn(&inConn)
|
||||
s.serverConns.Remove(inAddr)
|
||||
log.Printf("server connection %s %s released", serverID, key)
|
||||
return
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ func (s *MuxClient) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop client service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service client stoped,%s", e)
|
||||
log.Printf("service client stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
|
||||
@ -155,7 +155,7 @@ func (s *MuxServer) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop server service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service server stoped,%s", e)
|
||||
log.Printf("service server stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
|
||||
@ -18,13 +18,20 @@ type ServiceItem struct {
|
||||
var servicesMap = map[string]*ServiceItem{}
|
||||
|
||||
func Regist(name string, s Service, args interface{}) {
|
||||
|
||||
Stop(name)
|
||||
servicesMap[name] = &ServiceItem{
|
||||
S: s,
|
||||
Args: args,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
func GetService(name string) *ServiceItem {
|
||||
if s, ok := servicesMap[name]; ok && s.S != nil {
|
||||
return s
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
func Stop(name string) {
|
||||
if s, ok := servicesMap[name]; ok && s.S != nil {
|
||||
s.S.Clean()
|
||||
|
||||
@ -26,6 +26,7 @@ type Socks struct {
|
||||
sc *utils.ServerChannel
|
||||
domainResolver utils.DomainResolver
|
||||
isStop bool
|
||||
userConns utils.ConcurrentMap
|
||||
}
|
||||
|
||||
func NewSocks() Service {
|
||||
@ -35,6 +36,7 @@ func NewSocks() Service {
|
||||
basicAuth: utils.BasicAuth{},
|
||||
lockChn: make(chan bool, 1),
|
||||
isStop: false,
|
||||
userConns: utils.NewConcurrentMap(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +149,7 @@ func (s *Socks) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop socks service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service socks stoped,%s", e)
|
||||
log.Printf("service socks stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
@ -161,6 +163,9 @@ func (s *Socks) StopService() {
|
||||
if s.sc != nil && (*s.sc).Listener != nil {
|
||||
(*(*s.sc).Listener).Close()
|
||||
}
|
||||
for _, c := range s.userConns.Items() {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
}
|
||||
func (s *Socks) Start(args interface{}) (err error) {
|
||||
//start()
|
||||
@ -526,6 +531,11 @@ func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
|
||||
utils.IoBind(*inConn, outConn, func(err interface{}) {
|
||||
log.Printf("conn %s - %s released", inAddr, request.Addr())
|
||||
})
|
||||
if c, ok := s.userConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
s.userConns.Remove(inAddr)
|
||||
}
|
||||
s.userConns.Set(inAddr, inConn)
|
||||
}
|
||||
func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn net.Conn, err interface{}) {
|
||||
switch *s.cfg.ParentType {
|
||||
|
||||
@ -22,6 +22,7 @@ type SPS struct {
|
||||
domainResolver utils.DomainResolver
|
||||
basicAuth utils.BasicAuth
|
||||
serverChannels []*utils.ServerChannel
|
||||
userConns utils.ConcurrentMap
|
||||
}
|
||||
|
||||
func NewSPS() Service {
|
||||
@ -30,6 +31,7 @@ func NewSPS() Service {
|
||||
cfg: SPSArgs{},
|
||||
basicAuth: utils.BasicAuth{},
|
||||
serverChannels: []*utils.ServerChannel{},
|
||||
userConns: utils.NewConcurrentMap(),
|
||||
}
|
||||
}
|
||||
func (s *SPS) CheckArgs() (err error) {
|
||||
@ -75,8 +77,6 @@ func (s *SPS) InitOutConnPool() {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes, nil,
|
||||
*s.cfg.Parent,
|
||||
*s.cfg.Timeout,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,7 @@ func (s *SPS) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop sps service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service sps stoped,%s", e)
|
||||
log.Printf("service sps stoped")
|
||||
}
|
||||
}()
|
||||
for _, sc := range s.serverChannels {
|
||||
@ -98,6 +98,9 @@ func (s *SPS) StopService() {
|
||||
(*sc.UDPListener).Close()
|
||||
}
|
||||
}
|
||||
for _, c := range s.userConns.Items() {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
}
|
||||
func (s *SPS) Start(args interface{}) (err error) {
|
||||
s.cfg = args.(SPSArgs)
|
||||
@ -304,8 +307,13 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
|
||||
outAddr := outConn.RemoteAddr().String()
|
||||
utils.IoBind((*inConn), outConn, func(err interface{}) {
|
||||
log.Printf("conn %s - %s released", inAddr, outAddr)
|
||||
s.userConns.Remove(inAddr)
|
||||
})
|
||||
log.Printf("conn %s - %s connected", inAddr, outAddr)
|
||||
if c, ok := s.userConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
s.userConns.Set(inAddr, &inConn)
|
||||
return
|
||||
}
|
||||
func (s *SPS) InitBasicAuth() (err error) {
|
||||
|
||||
@ -14,17 +14,19 @@ import (
|
||||
)
|
||||
|
||||
type TCP struct {
|
||||
outPool utils.OutConn
|
||||
cfg TCPArgs
|
||||
sc *utils.ServerChannel
|
||||
isStop bool
|
||||
outPool utils.OutConn
|
||||
cfg TCPArgs
|
||||
sc *utils.ServerChannel
|
||||
isStop bool
|
||||
userConns utils.ConcurrentMap
|
||||
}
|
||||
|
||||
func NewTCP() Service {
|
||||
return &TCP{
|
||||
outPool: utils.OutConn{},
|
||||
cfg: TCPArgs{},
|
||||
isStop: false,
|
||||
outPool: utils.OutConn{},
|
||||
cfg: TCPArgs{},
|
||||
isStop: false,
|
||||
userConns: utils.NewConcurrentMap(),
|
||||
}
|
||||
}
|
||||
func (s *TCP) CheckArgs() (err error) {
|
||||
@ -54,7 +56,7 @@ func (s *TCP) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop tcp service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service tcp stoped,%s", e)
|
||||
log.Printf("service tcp stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
@ -64,6 +66,9 @@ func (s *TCP) StopService() {
|
||||
if s.sc.UDPListener != nil {
|
||||
(*s.sc.UDPListener).Close()
|
||||
}
|
||||
for _, c := range s.userConns.Items() {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
}
|
||||
func (s *TCP) Start(args interface{}) (err error) {
|
||||
s.cfg = args.(TCPArgs)
|
||||
@ -134,14 +139,20 @@ func (s *TCP) OutToTCP(inConn *net.Conn) (err error) {
|
||||
//outLocalAddr := outConn.LocalAddr().String()
|
||||
utils.IoBind((*inConn), outConn, func(err interface{}) {
|
||||
log.Printf("conn %s - %s released", inAddr, outAddr)
|
||||
s.userConns.Remove(inAddr)
|
||||
})
|
||||
log.Printf("conn %s - %s connected", inAddr, outAddr)
|
||||
if c, ok := s.userConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
s.userConns.Set(inAddr, &inConn)
|
||||
return
|
||||
}
|
||||
func (s *TCP) OutToUDP(inConn *net.Conn) (err error) {
|
||||
log.Printf("conn created , remote : %s ", (*inConn).RemoteAddr())
|
||||
for {
|
||||
if s.isStop {
|
||||
(*inConn).Close()
|
||||
return
|
||||
}
|
||||
srcAddr, body, err := utils.ReadUDPPacket(bufio.NewReader(*inConn))
|
||||
@ -200,8 +211,6 @@ func (s *TCP) InitOutConnPool() {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes, nil,
|
||||
*s.cfg.Parent,
|
||||
*s.cfg.Timeout,
|
||||
*s.cfg.PoolSize,
|
||||
*s.cfg.PoolSize*2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ func (s *TunnelBridge) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop tbridge service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service tbridge stoped,%s", e)
|
||||
log.Printf("service tbridge stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
|
||||
@ -11,17 +11,17 @@ import (
|
||||
)
|
||||
|
||||
type TunnelClient struct {
|
||||
cfg TunnelClientArgs
|
||||
// cm utils.ConnManager
|
||||
ctrlConn net.Conn
|
||||
isStop bool
|
||||
cfg TunnelClientArgs
|
||||
ctrlConn net.Conn
|
||||
isStop bool
|
||||
userConns utils.ConcurrentMap
|
||||
}
|
||||
|
||||
func NewTunnelClient() Service {
|
||||
return &TunnelClient{
|
||||
cfg: TunnelClientArgs{},
|
||||
// cm: utils.NewConnManager(),
|
||||
isStop: false,
|
||||
cfg: TunnelClientArgs{},
|
||||
userConns: utils.NewConcurrentMap(),
|
||||
isStop: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,13 +49,16 @@ func (s *TunnelClient) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop tclient service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service tclient stoped,%s", e)
|
||||
log.Printf("service tclient stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
if s.ctrlConn != nil {
|
||||
s.ctrlConn.Close()
|
||||
}
|
||||
for _, c := range s.userConns.Items() {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
}
|
||||
func (s *TunnelClient) Start(args interface{}) (err error) {
|
||||
s.cfg = args.(TunnelClientArgs)
|
||||
@ -139,6 +142,9 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
|
||||
// for {
|
||||
for {
|
||||
if s.isStop {
|
||||
if inConn != nil {
|
||||
inConn.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
// s.cm.RemoveOne(*s.cfg.Key, ID)
|
||||
@ -252,10 +258,14 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
|
||||
log.Printf("build connection error, err: %s", err)
|
||||
return
|
||||
}
|
||||
inAddr := inConn.RemoteAddr().String()
|
||||
utils.IoBind(inConn, outConn, func(err interface{}) {
|
||||
log.Printf("conn %s released", ID)
|
||||
// s.cm.RemoveOne(*s.cfg.Key, ID)
|
||||
s.userConns.Remove(inAddr)
|
||||
})
|
||||
// s.cm.Add(*s.cfg.Key, ID, &inConn)
|
||||
if c, ok := s.userConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
s.userConns.Set(inAddr, &inConn)
|
||||
log.Printf("conn %s created", ID)
|
||||
}
|
||||
|
||||
@ -14,11 +14,12 @@ import (
|
||||
)
|
||||
|
||||
type TunnelServer struct {
|
||||
cfg TunnelServerArgs
|
||||
udpChn chan UDPItem
|
||||
sc utils.ServerChannel
|
||||
isStop bool
|
||||
udpConn *net.Conn
|
||||
cfg TunnelServerArgs
|
||||
udpChn chan UDPItem
|
||||
sc utils.ServerChannel
|
||||
isStop bool
|
||||
udpConn *net.Conn
|
||||
userConns utils.ConcurrentMap
|
||||
}
|
||||
|
||||
type TunnelServerManager struct {
|
||||
@ -139,9 +140,10 @@ func (s *TunnelServerManager) GetConn() (conn net.Conn, err error) {
|
||||
}
|
||||
func NewTunnelServer() Service {
|
||||
return &TunnelServer{
|
||||
cfg: TunnelServerArgs{},
|
||||
udpChn: make(chan UDPItem, 50000),
|
||||
isStop: false,
|
||||
cfg: TunnelServerArgs{},
|
||||
udpChn: make(chan UDPItem, 50000),
|
||||
isStop: false,
|
||||
userConns: utils.NewConcurrentMap(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +159,7 @@ func (s *TunnelServer) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop server service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service server stoped,%s", e)
|
||||
log.Printf("service server stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
@ -171,6 +173,9 @@ func (s *TunnelServer) StopService() {
|
||||
if s.udpConn != nil {
|
||||
(*s.udpConn).Close()
|
||||
}
|
||||
for _, c := range s.userConns.Items() {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
}
|
||||
func (s *TunnelServer) InitService() (err error) {
|
||||
s.UDPConnDeamon()
|
||||
@ -230,12 +235,15 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
inAddr := inConn.RemoteAddr().String()
|
||||
utils.IoBind(inConn, outConn, func(err interface{}) {
|
||||
// s.cfg.Mgr.cm.RemoveOne(s.cfg.Mgr.serverID, ID)
|
||||
s.userConns.Remove(inAddr)
|
||||
log.Printf("%s conn %s released", *s.cfg.Key, ID)
|
||||
})
|
||||
//add conn
|
||||
// s.cfg.Mgr.cm.Add(s.cfg.Mgr.serverID, ID, &inConn)
|
||||
if c, ok := s.userConns.Get(inAddr); ok {
|
||||
(*c.(*net.Conn)).Close()
|
||||
}
|
||||
s.userConns.Set(inAddr, &inConn)
|
||||
log.Printf("%s conn %s created", *s.cfg.Key, ID)
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@ -59,7 +59,7 @@ func (s *UDP) StopService() {
|
||||
if e != nil {
|
||||
log.Printf("stop udp service crashed,%s", e)
|
||||
} else {
|
||||
log.Printf("service udp stoped,%s", e)
|
||||
log.Printf("service udp stoped")
|
||||
}
|
||||
}()
|
||||
s.isStop = true
|
||||
@ -133,7 +133,7 @@ func (s *UDP) GetConn(connKey string) (conn net.Conn, isNew bool, err error) {
|
||||
func (s *UDP) OutToTCP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err error) {
|
||||
numLocal := crc32.ChecksumIEEE([]byte(localAddr.String()))
|
||||
numSrc := crc32.ChecksumIEEE([]byte(srcAddr.String()))
|
||||
mod := uint32(*s.cfg.PoolSize)
|
||||
mod := uint32(10)
|
||||
if mod == 0 {
|
||||
mod = 10
|
||||
}
|
||||
@ -153,6 +153,7 @@ func (s *UDP) OutToTCP(packet []byte, localAddr, srcAddr *net.UDPAddr) (err erro
|
||||
log.Printf("conn %d created , local: %s", connKey, srcAddr.String())
|
||||
for {
|
||||
if s.isStop {
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
srcAddrFromConn, body, err := utils.ReadUDPPacket(bufio.NewReader(conn))
|
||||
@ -240,8 +241,6 @@ func (s *UDP) InitOutConnPool() {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes, nil,
|
||||
*s.cfg.Parent,
|
||||
*s.cfg.Timeout,
|
||||
*s.cfg.PoolSize,
|
||||
*s.cfg.PoolSize*2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ func NewServerChannel(ip string, port int) ServerChannel {
|
||||
ip: ip,
|
||||
port: port,
|
||||
errAcceptHandler: func(err error) {
|
||||
fmt.Printf("accept error , ERR:%s", err)
|
||||
log.Printf("accept error , ERR:%s", err)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,7 +516,7 @@ type OutConn struct {
|
||||
timeout int
|
||||
}
|
||||
|
||||
func NewOutConn(dur int, typ string, kcp kcpcfg.KCPConfigArgs, certBytes, keyBytes, caCertBytes []byte, address string, timeout int, InitialCap int, MaxCap int) (op OutConn) {
|
||||
func NewOutConn(dur int, typ string, kcp kcpcfg.KCPConfigArgs, certBytes, keyBytes, caCertBytes []byte, address string, timeout int) (op OutConn) {
|
||||
return OutConn{
|
||||
dur: dur,
|
||||
typ: typ,
|
||||
|
||||
Reference in New Issue
Block a user