add kcp config args
Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
74
config.go
74
config.go
@ -2,14 +2,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"crypto/sha1"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"snail007/proxy/services"
|
"snail007/proxy/services"
|
||||||
|
"snail007/proxy/services/kcpcfg"
|
||||||
"snail007/proxy/utils"
|
"snail007/proxy/utils"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
kcp "github.com/xtaci/kcp-go"
|
||||||
|
"golang.org/x/crypto/pbkdf2"
|
||||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,6 +44,7 @@ func initConfig() (err error) {
|
|||||||
udpArgs := services.UDPArgs{}
|
udpArgs := services.UDPArgs{}
|
||||||
socksArgs := services.SocksArgs{}
|
socksArgs := services.SocksArgs{}
|
||||||
spsArgs := services.SPSArgs{}
|
spsArgs := services.SPSArgs{}
|
||||||
|
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)
|
||||||
@ -47,6 +52,23 @@ func initConfig() (err error) {
|
|||||||
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
||||||
forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool()
|
forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool()
|
||||||
logfile := app.Flag("log", "log file path").Default("").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").String()
|
||||||
|
kcpArgs.Mode = app.Flag("kcp-mode", "profiles: fast3, fast2, fast, normal, manual").Default("fast").String()
|
||||||
|
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()
|
||||||
|
kcpArgs.DataShard = app.Flag("kcp-ds", "set reed-solomon erasure coding - datashard").Default("10").Int()
|
||||||
|
kcpArgs.ParityShard = app.Flag("kcp-ps", "set reed-solomon erasure coding - parityshard").Default("3").Int()
|
||||||
|
kcpArgs.DSCP = app.Flag("kcp-dscp", "set DSCP(6bit)").Default("0").Int()
|
||||||
|
kcpArgs.NoComp = app.Flag("kcp-nocomp", "disable compression").Default("false").Bool()
|
||||||
|
kcpArgs.AckNodelay = app.Flag("kcp-acknodelay", "be carefull! flush ack immediately when a packet is received").Default("true").Bool()
|
||||||
|
kcpArgs.NoDelay = app.Flag("kcp-nodelay", "be carefull!").Default("0").Int()
|
||||||
|
kcpArgs.Interval = app.Flag("kcp-interval", "be carefull!").Default("50").Int()
|
||||||
|
kcpArgs.Resend = app.Flag("kcp-resend", "be carefull!").Default("0").Int()
|
||||||
|
kcpArgs.NoCongestion = app.Flag("kcp-nc", "be carefull! no congestion").Default("0").Int()
|
||||||
|
kcpArgs.SockBuf = app.Flag("kcp-sockbuf", "be carefull!").Default("4194304").Int()
|
||||||
|
kcpArgs.KeepAlive = app.Flag("kcp-keepalive", "be carefull!").Default("10").Int()
|
||||||
|
|
||||||
//########http#########
|
//########http#########
|
||||||
http := app.Command("http", "proxy on http mode")
|
http := app.Command("http", "proxy on http mode")
|
||||||
@ -70,8 +92,6 @@ func initConfig() (err error) {
|
|||||||
httpArgs.SSHKeyFile = http.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String()
|
httpArgs.SSHKeyFile = http.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String()
|
||||||
httpArgs.SSHKeyFileSalt = http.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String()
|
httpArgs.SSHKeyFileSalt = http.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String()
|
||||||
httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
|
httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
|
||||||
httpArgs.KCPKey = http.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
|
||||||
httpArgs.KCPMethod = http.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
|
||||||
httpArgs.LocalIPS = http.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
httpArgs.LocalIPS = http.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
||||||
httpArgs.AuthURL = http.Flag("auth-url", "http basic auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
|
httpArgs.AuthURL = http.Flag("auth-url", "http basic auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
|
||||||
httpArgs.AuthURLTimeout = http.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
|
httpArgs.AuthURLTimeout = http.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
|
||||||
@ -91,8 +111,6 @@ func initConfig() (err error) {
|
|||||||
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.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.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()
|
tcpArgs.Local = tcp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||||
tcpArgs.KCPKey = tcp.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
|
||||||
tcpArgs.KCPMethod = tcp.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
|
||||||
|
|
||||||
//########udp#########
|
//########udp#########
|
||||||
udp := app.Command("udp", "proxy on udp mode")
|
udp := app.Command("udp", "proxy on udp mode")
|
||||||
@ -178,8 +196,6 @@ func initConfig() (err error) {
|
|||||||
socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
||||||
socksArgs.AuthFile = socks.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
|
socksArgs.AuthFile = socks.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
|
||||||
socksArgs.Auth = socks.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
|
socksArgs.Auth = socks.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
|
||||||
socksArgs.KCPKey = socks.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
|
||||||
socksArgs.KCPMethod = socks.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
|
||||||
socksArgs.LocalIPS = socks.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
socksArgs.LocalIPS = socks.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
||||||
socksArgs.AuthURL = socks.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
|
socksArgs.AuthURL = socks.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
|
||||||
socksArgs.AuthURLTimeout = socks.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
|
socksArgs.AuthURLTimeout = socks.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
|
||||||
@ -196,14 +212,56 @@ func initConfig() (err error) {
|
|||||||
spsArgs.ParentType = sps.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp")
|
spsArgs.ParentType = sps.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp")
|
||||||
spsArgs.LocalType = sps.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
|
spsArgs.LocalType = sps.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
|
||||||
spsArgs.Local = sps.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()
|
spsArgs.Local = sps.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()
|
||||||
spsArgs.KCPKey = sps.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
|
||||||
spsArgs.KCPMethod = sps.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
|
||||||
spsArgs.ParentServiceType = sps.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks")
|
spsArgs.ParentServiceType = sps.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks")
|
||||||
spsArgs.DNSAddress = sps.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
|
spsArgs.DNSAddress = sps.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
|
||||||
spsArgs.DNSTTL = sps.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
|
spsArgs.DNSTTL = sps.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
|
||||||
|
|
||||||
//parse args
|
//parse args
|
||||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
|
|
||||||
|
//set kcp config
|
||||||
|
|
||||||
|
switch *kcpArgs.Mode {
|
||||||
|
case "normal":
|
||||||
|
*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 0, 40, 2, 1
|
||||||
|
case "fast":
|
||||||
|
*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 0, 30, 2, 1
|
||||||
|
case "fast2":
|
||||||
|
*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 1, 20, 2, 1
|
||||||
|
case "fast3":
|
||||||
|
*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 1, 10, 2, 1
|
||||||
|
}
|
||||||
|
pass := pbkdf2.Key([]byte(*kcpArgs.Key), []byte("snail007-goproxy"), 4096, 32, sha1.New)
|
||||||
|
|
||||||
|
switch *kcpArgs.Crypt {
|
||||||
|
case "sm4":
|
||||||
|
kcpArgs.Block, _ = kcp.NewSM4BlockCrypt(pass[:16])
|
||||||
|
case "tea":
|
||||||
|
kcpArgs.Block, _ = kcp.NewTEABlockCrypt(pass[:16])
|
||||||
|
case "xor":
|
||||||
|
kcpArgs.Block, _ = kcp.NewSimpleXORBlockCrypt(pass)
|
||||||
|
case "none":
|
||||||
|
kcpArgs.Block, _ = kcp.NewNoneBlockCrypt(pass)
|
||||||
|
case "aes-128":
|
||||||
|
kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass[:16])
|
||||||
|
case "aes-192":
|
||||||
|
kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass[:24])
|
||||||
|
case "blowfish":
|
||||||
|
kcpArgs.Block, _ = kcp.NewBlowfishBlockCrypt(pass)
|
||||||
|
case "twofish":
|
||||||
|
kcpArgs.Block, _ = kcp.NewTwofishBlockCrypt(pass)
|
||||||
|
case "cast5":
|
||||||
|
kcpArgs.Block, _ = kcp.NewCast5BlockCrypt(pass[:16])
|
||||||
|
case "3des":
|
||||||
|
kcpArgs.Block, _ = kcp.NewTripleDESBlockCrypt(pass[:24])
|
||||||
|
case "xtea":
|
||||||
|
kcpArgs.Block, _ = kcp.NewXTEABlockCrypt(pass[:16])
|
||||||
|
case "salsa20":
|
||||||
|
kcpArgs.Block, _ = kcp.NewSalsa20BlockCrypt(pass)
|
||||||
|
default:
|
||||||
|
*kcpArgs.Crypt = "aes"
|
||||||
|
kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass)
|
||||||
|
}
|
||||||
flags := log.Ldate
|
flags := log.Ldate
|
||||||
if *debug {
|
if *debug {
|
||||||
flags |= log.Lshortfile | log.Lmicroseconds
|
flags |= log.Lshortfile | log.Lmicroseconds
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import "golang.org/x/crypto/ssh"
|
import (
|
||||||
|
"snail007/proxy/services/kcpcfg"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
// tcp := app.Command("tcp", "proxy on tcp mode")
|
// 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()
|
// t := tcp.Flag("tcp-timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
|
||||||
@ -102,8 +106,7 @@ type TCPArgs struct {
|
|||||||
Timeout *int
|
Timeout *int
|
||||||
PoolSize *int
|
PoolSize *int
|
||||||
CheckParentInterval *int
|
CheckParentInterval *int
|
||||||
KCPMethod *string
|
KCP kcpcfg.KCPConfigArgs
|
||||||
KCPKey *string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPArgs struct {
|
type HTTPArgs struct {
|
||||||
@ -135,8 +138,7 @@ type HTTPArgs struct {
|
|||||||
SSHUser *string
|
SSHUser *string
|
||||||
SSHKeyBytes []byte
|
SSHKeyBytes []byte
|
||||||
SSHAuthMethod ssh.AuthMethod
|
SSHAuthMethod ssh.AuthMethod
|
||||||
KCPMethod *string
|
KCP kcpcfg.KCPConfigArgs
|
||||||
KCPKey *string
|
|
||||||
LocalIPS *[]string
|
LocalIPS *[]string
|
||||||
DNSAddress *string
|
DNSAddress *string
|
||||||
DNSTTL *int
|
DNSTTL *int
|
||||||
@ -179,8 +181,7 @@ type SocksArgs struct {
|
|||||||
AuthURLOkCode *int
|
AuthURLOkCode *int
|
||||||
AuthURLTimeout *int
|
AuthURLTimeout *int
|
||||||
AuthURLRetry *int
|
AuthURLRetry *int
|
||||||
KCPMethod *string
|
KCP kcpcfg.KCPConfigArgs
|
||||||
KCPKey *string
|
|
||||||
UDPParent *string
|
UDPParent *string
|
||||||
UDPLocal *string
|
UDPLocal *string
|
||||||
LocalIPS *[]string
|
LocalIPS *[]string
|
||||||
@ -197,8 +198,7 @@ type SPSArgs struct {
|
|||||||
ParentType *string
|
ParentType *string
|
||||||
LocalType *string
|
LocalType *string
|
||||||
Timeout *int
|
Timeout *int
|
||||||
KCPMethod *string
|
KCP kcpcfg.KCPConfigArgs
|
||||||
KCPKey *string
|
|
||||||
ParentServiceType *string
|
ParentServiceType *string
|
||||||
DNSAddress *string
|
DNSAddress *string
|
||||||
DNSTTL *int
|
DNSTTL *int
|
||||||
|
|||||||
@ -130,7 +130,7 @@ func (s *HTTP) Start(args interface{}) (err error) {
|
|||||||
} else if *s.cfg.LocalType == TYPE_TLS {
|
} else if *s.cfg.LocalType == TYPE_TLS {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
||||||
} else if *s.cfg.LocalType == TYPE_KCP {
|
} else if *s.cfg.LocalType == TYPE_KCP {
|
||||||
err = sc.ListenKCP(*s.cfg.KCPMethod, *s.cfg.KCPKey, s.callback)
|
err = sc.ListenKCP(s.cfg.KCP, s.callback)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -320,8 +320,7 @@ func (s *HTTP) InitOutConnPool() {
|
|||||||
s.outPool = utils.NewOutPool(
|
s.outPool = utils.NewOutPool(
|
||||||
*s.cfg.CheckParentInterval,
|
*s.cfg.CheckParentInterval,
|
||||||
*s.cfg.ParentType,
|
*s.cfg.ParentType,
|
||||||
*s.cfg.KCPMethod,
|
s.cfg.KCP,
|
||||||
*s.cfg.KCPKey,
|
|
||||||
s.cfg.CertBytes, s.cfg.KeyBytes,
|
s.cfg.CertBytes, s.cfg.KeyBytes,
|
||||||
s.Resolve(*s.cfg.Parent),
|
s.Resolve(*s.cfg.Parent),
|
||||||
*s.cfg.Timeout,
|
*s.cfg.Timeout,
|
||||||
|
|||||||
24
services/kcpcfg/args.go
Normal file
24
services/kcpcfg/args.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package kcpcfg
|
||||||
|
|
||||||
|
import kcp "github.com/xtaci/kcp-go"
|
||||||
|
|
||||||
|
type KCPConfigArgs struct {
|
||||||
|
Key *string
|
||||||
|
Crypt *string
|
||||||
|
Mode *string
|
||||||
|
MTU *int
|
||||||
|
SndWnd *int
|
||||||
|
RcvWnd *int
|
||||||
|
DataShard *int
|
||||||
|
ParityShard *int
|
||||||
|
DSCP *int
|
||||||
|
NoComp *bool
|
||||||
|
AckNodelay *bool
|
||||||
|
NoDelay *int
|
||||||
|
Interval *int
|
||||||
|
Resend *int
|
||||||
|
NoCongestion *int
|
||||||
|
SockBuf *int
|
||||||
|
KeepAlive *int
|
||||||
|
Block kcp.BlockCrypt
|
||||||
|
}
|
||||||
@ -140,7 +140,7 @@ func (s *Socks) Start(args interface{}) (err error) {
|
|||||||
} else if *s.cfg.LocalType == TYPE_TLS {
|
} else if *s.cfg.LocalType == TYPE_TLS {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.socksConnCallback)
|
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.socksConnCallback)
|
||||||
} else if *s.cfg.LocalType == TYPE_KCP {
|
} else if *s.cfg.LocalType == TYPE_KCP {
|
||||||
err = sc.ListenKCP(*s.cfg.KCPMethod, *s.cfg.KCPKey, s.socksConnCallback)
|
err = sc.ListenKCP(s.cfg.KCP, s.socksConnCallback)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -474,7 +474,7 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
|
|||||||
_outConn, err = utils.TlsConnectHost(s.Resolve(*s.cfg.Parent), *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
_outConn, err = utils.TlsConnectHost(s.Resolve(*s.cfg.Parent), *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
||||||
outConn = net.Conn(&_outConn)
|
outConn = net.Conn(&_outConn)
|
||||||
} else if *s.cfg.ParentType == "kcp" {
|
} else if *s.cfg.ParentType == "kcp" {
|
||||||
outConn, err = utils.ConnectKCPHost(s.Resolve(*s.cfg.Parent), *s.cfg.KCPMethod, *s.cfg.KCPKey)
|
outConn, err = utils.ConnectKCPHost(s.Resolve(*s.cfg.Parent), s.cfg.KCP)
|
||||||
} else {
|
} else {
|
||||||
outConn, err = utils.ConnectHost(s.Resolve(*s.cfg.Parent), *s.cfg.Timeout)
|
outConn, err = utils.ConnectHost(s.Resolve(*s.cfg.Parent), *s.cfg.Timeout)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,8 +46,7 @@ func (s *SPS) InitOutConnPool() {
|
|||||||
s.outPool = utils.NewOutPool(
|
s.outPool = utils.NewOutPool(
|
||||||
0,
|
0,
|
||||||
*s.cfg.ParentType,
|
*s.cfg.ParentType,
|
||||||
*s.cfg.KCPMethod,
|
s.cfg.KCP,
|
||||||
*s.cfg.KCPKey,
|
|
||||||
s.cfg.CertBytes, s.cfg.KeyBytes,
|
s.cfg.CertBytes, s.cfg.KeyBytes,
|
||||||
*s.cfg.Parent,
|
*s.cfg.Parent,
|
||||||
*s.cfg.Timeout,
|
*s.cfg.Timeout,
|
||||||
@ -78,7 +77,7 @@ func (s *SPS) Start(args interface{}) (err error) {
|
|||||||
} else if *s.cfg.LocalType == TYPE_TLS {
|
} else if *s.cfg.LocalType == TYPE_TLS {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
||||||
} else if *s.cfg.LocalType == TYPE_KCP {
|
} else if *s.cfg.LocalType == TYPE_KCP {
|
||||||
err = sc.ListenKCP(*s.cfg.KCPMethod, *s.cfg.KCPKey, s.callback)
|
err = sc.ListenKCP(s.cfg.KCP, s.callback)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -58,7 +58,7 @@ func (s *TCP) Start(args interface{}) (err error) {
|
|||||||
} else if *s.cfg.LocalType == TYPE_TLS {
|
} else if *s.cfg.LocalType == TYPE_TLS {
|
||||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
||||||
} else if *s.cfg.LocalType == TYPE_KCP {
|
} else if *s.cfg.LocalType == TYPE_KCP {
|
||||||
err = sc.ListenKCP(*s.cfg.KCPMethod, *s.cfg.KCPKey, s.callback)
|
err = sc.ListenKCP(s.cfg.KCP, s.callback)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -171,8 +171,7 @@ func (s *TCP) InitOutConnPool() {
|
|||||||
s.outPool = utils.NewOutPool(
|
s.outPool = utils.NewOutPool(
|
||||||
*s.cfg.CheckParentInterval,
|
*s.cfg.CheckParentInterval,
|
||||||
*s.cfg.ParentType,
|
*s.cfg.ParentType,
|
||||||
*s.cfg.KCPMethod,
|
s.cfg.KCP,
|
||||||
*s.cfg.KCPKey,
|
|
||||||
s.cfg.CertBytes, s.cfg.KeyBytes,
|
s.cfg.CertBytes, s.cfg.KeyBytes,
|
||||||
*s.cfg.Parent,
|
*s.cfg.Parent,
|
||||||
*s.cfg.Timeout,
|
*s.cfg.Timeout,
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"snail007/proxy/services/kcpcfg"
|
||||||
"snail007/proxy/utils"
|
"snail007/proxy/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -208,7 +209,7 @@ func (s *UDP) InitOutConnPool() {
|
|||||||
s.outPool = utils.NewOutPool(
|
s.outPool = utils.NewOutPool(
|
||||||
*s.cfg.CheckParentInterval,
|
*s.cfg.CheckParentInterval,
|
||||||
*s.cfg.ParentType,
|
*s.cfg.ParentType,
|
||||||
"", "",
|
kcpcfg.KCPConfigArgs{},
|
||||||
s.cfg.CertBytes, s.cfg.KeyBytes,
|
s.cfg.CertBytes, s.cfg.KeyBytes,
|
||||||
*s.cfg.Parent,
|
*s.cfg.Parent,
|
||||||
*s.cfg.Timeout,
|
*s.cfg.Timeout,
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"snail007/proxy/services/kcpcfg"
|
||||||
|
|
||||||
"golang.org/x/crypto/pbkdf2"
|
"golang.org/x/crypto/pbkdf2"
|
||||||
|
|
||||||
@ -147,17 +148,23 @@ func ConnectHost(hostAndPort string, timeout int) (conn net.Conn, err error) {
|
|||||||
conn, err = net.DialTimeout("tcp", hostAndPort, time.Duration(timeout)*time.Millisecond)
|
conn, err = net.DialTimeout("tcp", hostAndPort, time.Duration(timeout)*time.Millisecond)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func ConnectKCPHost(hostAndPort, method, key string) (conn net.Conn, err error) {
|
func ConnectKCPHost(hostAndPort string, config kcpcfg.KCPConfigArgs) (conn net.Conn, err error) {
|
||||||
kcpconn, err := kcp.DialWithOptions(hostAndPort, GetKCPBlock(method, key), 10, 3)
|
kcpconn, err := kcp.DialWithOptions(hostAndPort, config.Block, *config.DataShard, *config.ParityShard)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kcpconn.SetNoDelay(1, 10, 2, 1)
|
kcpconn.SetStreamMode(true)
|
||||||
kcpconn.SetWindowSize(1024, 1024)
|
kcpconn.SetWriteDelay(true)
|
||||||
kcpconn.SetMtu(1400)
|
kcpconn.SetNoDelay(*config.NoDelay, *config.Interval, *config.Resend, *config.NoCongestion)
|
||||||
kcpconn.SetACKNoDelay(false)
|
kcpconn.SetMtu(*config.MTU)
|
||||||
|
kcpconn.SetWindowSize(*config.SndWnd, *config.RcvWnd)
|
||||||
|
kcpconn.SetACKNoDelay(*config.AckNodelay)
|
||||||
|
if *config.NoComp {
|
||||||
return kcpconn, err
|
return kcpconn, err
|
||||||
|
}
|
||||||
|
return NewCompStream(kcpconn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenTls(ip string, port int, certBytes, keyBytes []byte) (ln *net.Listener, err error) {
|
func ListenTls(ip string, port int, certBytes, keyBytes []byte) (ln *net.Listener, err error) {
|
||||||
block, _ := pem.Decode(certBytes)
|
block, _ := pem.Decode(certBytes)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"snail007/proxy/services/kcpcfg"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
kcp "github.com/xtaci/kcp-go"
|
kcp "github.com/xtaci/kcp-go"
|
||||||
@ -138,11 +139,19 @@ func (sc *ServerChannel) ListenUDP(fn func(packet []byte, localAddr, srcAddr *ne
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (sc *ServerChannel) ListenKCP(method, key string, fn func(conn net.Conn)) (err error) {
|
func (sc *ServerChannel) ListenKCP(config kcpcfg.KCPConfigArgs, fn func(conn net.Conn)) (err error) {
|
||||||
var l net.Listener
|
lis, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", sc.ip, sc.port), config.Block, *config.DataShard, *config.ParityShard)
|
||||||
l, err = kcp.ListenWithOptions(fmt.Sprintf("%s:%d", sc.ip, sc.port), GetKCPBlock(method, key), 10, 3)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sc.Listener = &l
|
if err := lis.SetDSCP(*config.DSCP); err != nil {
|
||||||
|
log.Println("SetDSCP:", err)
|
||||||
|
}
|
||||||
|
if err := lis.SetReadBuffer(*config.SockBuf); err != nil {
|
||||||
|
log.Println("SetReadBuffer:", err)
|
||||||
|
}
|
||||||
|
if err := lis.SetWriteBuffer(*config.SockBuf); err != nil {
|
||||||
|
log.Println("SetWriteBuffer:", err)
|
||||||
|
}
|
||||||
|
*sc.Listener = lis
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
@ -150,8 +159,8 @@ func (sc *ServerChannel) ListenKCP(method, key string, fn func(conn net.Conn)) (
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for {
|
for {
|
||||||
var conn net.Conn
|
//var conn net.Conn
|
||||||
conn, err = (*sc.Listener).Accept()
|
conn, err := lis.AcceptKCP()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -159,7 +168,18 @@ func (sc *ServerChannel) ListenKCP(method, key string, fn func(conn net.Conn)) (
|
|||||||
log.Printf("kcp connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
log.Printf("kcp connection handler crashed , err : %s , \ntrace:%s", e, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
conn.SetStreamMode(true)
|
||||||
|
conn.SetWriteDelay(true)
|
||||||
|
conn.SetNoDelay(*config.NoDelay, *config.Interval, *config.Resend, *config.NoCongestion)
|
||||||
|
conn.SetMtu(*config.MTU)
|
||||||
|
conn.SetWindowSize(*config.SndWnd, *config.RcvWnd)
|
||||||
|
conn.SetACKNoDelay(*config.AckNodelay)
|
||||||
|
if *config.NoComp {
|
||||||
fn(conn)
|
fn(conn)
|
||||||
|
} else {
|
||||||
|
cconn := NewCompStream(conn)
|
||||||
|
fn(cconn)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
sc.errAcceptHandler(err)
|
sc.errAcceptHandler(err)
|
||||||
|
|||||||
@ -12,11 +12,13 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"snail007/proxy/services/kcpcfg"
|
||||||
"snail007/proxy/utils/sni"
|
"snail007/proxy/utils/sni"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/snappy"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -494,20 +496,18 @@ type OutPool struct {
|
|||||||
typ string
|
typ string
|
||||||
certBytes []byte
|
certBytes []byte
|
||||||
keyBytes []byte
|
keyBytes []byte
|
||||||
kcpMethod string
|
kcp kcpcfg.KCPConfigArgs
|
||||||
kcpKey string
|
|
||||||
address string
|
address string
|
||||||
timeout int
|
timeout int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOutPool(dur int, typ, kcpMethod, kcpKey string, certBytes, keyBytes []byte, address string, timeout int, InitialCap int, MaxCap int) (op OutPool) {
|
func NewOutPool(dur int, typ string, kcp kcpcfg.KCPConfigArgs, certBytes, keyBytes []byte, address string, timeout int, InitialCap int, MaxCap int) (op OutPool) {
|
||||||
op = OutPool{
|
op = OutPool{
|
||||||
dur: dur,
|
dur: dur,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
certBytes: certBytes,
|
certBytes: certBytes,
|
||||||
keyBytes: keyBytes,
|
keyBytes: keyBytes,
|
||||||
kcpMethod: kcpMethod,
|
kcp: kcp,
|
||||||
kcpKey: kcpKey,
|
|
||||||
address: address,
|
address: address,
|
||||||
timeout: timeout,
|
timeout: timeout,
|
||||||
}
|
}
|
||||||
@ -548,7 +548,7 @@ func (op *OutPool) getConn() (conn interface{}, err error) {
|
|||||||
conn = net.Conn(&_conn)
|
conn = net.Conn(&_conn)
|
||||||
}
|
}
|
||||||
} else if op.typ == "kcp" {
|
} else if op.typ == "kcp" {
|
||||||
conn, err = ConnectKCPHost(op.address, op.kcpMethod, op.kcpKey)
|
conn, err = ConnectKCPHost(op.address, op.kcp)
|
||||||
} else {
|
} else {
|
||||||
conn, err = ConnectHost(op.address, op.timeout)
|
conn, err = ConnectHost(op.address, op.timeout)
|
||||||
}
|
}
|
||||||
@ -924,3 +924,45 @@ func (a *DomainResolver) PrintData() {
|
|||||||
fmt.Printf("%s:ip[%s],domain[%s],expired at[%d]\n", k, (*d).ip, (*d).domain, (*d).expiredAt)
|
fmt.Printf("%s:ip[%s],domain[%s],expired at[%d]\n", k, (*d).ip, (*d).domain, (*d).expiredAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func NewCompStream(conn net.Conn) *CompStream {
|
||||||
|
c := new(CompStream)
|
||||||
|
c.conn = conn
|
||||||
|
c.w = snappy.NewBufferedWriter(conn)
|
||||||
|
c.r = snappy.NewReader(conn)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompStream struct {
|
||||||
|
conn net.Conn
|
||||||
|
w *snappy.Writer
|
||||||
|
r *snappy.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompStream) Read(p []byte) (n int, err error) {
|
||||||
|
return c.r.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompStream) Write(p []byte) (n int, err error) {
|
||||||
|
n, err = c.w.Write(p)
|
||||||
|
err = c.w.Flush()
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompStream) Close() error {
|
||||||
|
return c.conn.Close()
|
||||||
|
}
|
||||||
|
func (c *CompStream) LocalAddr() net.Addr {
|
||||||
|
return c.conn.LocalAddr()
|
||||||
|
}
|
||||||
|
func (c *CompStream) RemoteAddr() net.Addr {
|
||||||
|
return c.conn.RemoteAddr()
|
||||||
|
}
|
||||||
|
func (c *CompStream) SetDeadline(t time.Time) error {
|
||||||
|
return c.conn.SetDeadline(t)
|
||||||
|
}
|
||||||
|
func (c *CompStream) SetReadDeadline(t time.Time) error {
|
||||||
|
return c.conn.SetReadDeadline(t)
|
||||||
|
}
|
||||||
|
func (c *CompStream) SetWriteDeadline(t time.Time) error {
|
||||||
|
return c.conn.SetWriteDeadline(t)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user