Compare commits

...
34 Commits
Author SHA1 Message Date
xtaci 7e648ff260 upgrade to kcp-go@5.4.10 2019-09-24 13:28:31 +08:00
xtaci 00db8d26ec upgrade to kcp-go@5.4.9 2019-09-23 22:02:38 +08:00
xtaci f45e756fca upgrade to kcp-go@5.4.8 2019-09-23 21:32:37 +08:00
xtaci 3530c325ba upgrade smux@v2.0.10 -> smux@v2.0.11 2019-09-22 21:59:51 +08:00
xtaci 6d6114bf26 update example json for smux v2 2019-09-22 20:51:39 +08:00
xtaci cda9de7d8d go mod tidy 2019-09-22 18:41:19 +08:00
xtaci 9004bf3170 update Dockerfile to support GO111MODULE 2019-09-22 18:06:09 +08:00
xtaci 903cb9f9f1 update .travis.yml 2019-09-22 17:45:40 +08:00
xtaci 6c46285010 upd to kcp-go@5.4.7 2019-09-22 17:42:01 +08:00
xtaci 1b72bf39d8 verbose logging on smux establishment 2019-09-22 16:41:23 +08:00
xtaci 112870d870 1->2 2019-09-22 16:31:02 +08:00
xtaci a859f419f6 verbose error handling for smux protocol 2019-09-22 14:47:38 +08:00
xtaci fa728236d4 only output protocol error in streamCopy 2019-09-22 14:40:14 +08:00
xtaci ade7ee06a0 stream copy print high-level error 2019-09-22 13:47:11 +08:00
xtaci 30cca4d7db half default streambuf to 2097152 bytes 2019-09-22 12:43:54 +08:00
xtaci 0f18b17a8a fix spelling 2019-09-22 12:32:07 +08:00
xtaci 1b756aeb3d adjust sequence of startup log 2019-09-22 11:12:55 +08:00
xtaci a69b0a90ed fix generic.Stream interface type error 2019-09-22 11:03:16 +08:00
xtaci 8778495915 upd deps smuxv2 2019-09-22 10:54:30 +08:00
xtaci 13deb22077 upd deps 2019-09-22 00:18:30 +08:00
xtaci 1635649aa5 upd deps 2019-09-22 00:02:21 +08:00
xtaci 3425d6288b upd deps 2019-09-21 23:56:05 +08:00
xtaci fe3227db22 update smux deps 2019-09-21 23:43:22 +08:00
xtaci 2684e47946 upd default value for streambuf 2019-09-21 22:30:26 +08:00
xtaci fcb6a5e141 add -smuxver to support smux version 2 2019-09-21 20:59:41 +08:00
xtaci ff9a67e931 upgrade kcp-go to v5.4.5 2019-09-10 22:14:24 +08:00
xtaci f288fe9ea6 upd deps 2019-09-10 20:57:21 +08:00
xtaci 7a42a51643 remove obsolete file 2019-09-06 14:18:02 +08:00
xtaci bd4051bd02 make server listen dual stack on tcp & udp if -tcp is specified 2019-09-06 14:15:18 +08:00
xtaci bab23e05b0 upd deps 2019-09-05 13:54:25 +08:00
xtaciandGitHub 4200cc7ef6 Update README.md 2019-08-13 18:14:24 +08:00
xtaci d9df85de52 upd deps 2019-08-08 12:53:24 +00:00
xtaci 379ce89334 upd deps 2019-08-08 09:33:05 +00:00
xtaci 34aaf35425 upd deps 2019-07-25 16:30:34 +08:00
14 changed files with 375 additions and 394 deletions
+5 -5
View File
@@ -1,18 +1,18 @@
language: go
go:
- 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
install:
- go get github.com/xtaci/kcptun/client
- go get github.com/xtaci/kcptun/server
- env GO111MODULE=on go get github.com/xtaci/kcptun/client
- env GO111MODULE=on go get github.com/xtaci/kcptun/server
before_script:
script:
- cd $HOME/gopath/src/github.com/xtaci/kcptun/client
- $HOME/gopath/bin/goveralls -service=travis-ci
- env GO111MODULE=on $HOME/gopath/bin/goveralls -service=travis-ci
- cd $HOME/gopath/src/github.com/xtaci/kcptun/server
- $HOME/gopath/bin/goveralls -service=travis-ci
- env GO111MODULE=on $HOME/gopath/bin/goveralls -service=travis-ci
- exit 0
+1
View File
@@ -1,5 +1,6 @@
FROM golang:alpine as builder
MAINTAINER xtaci <daniel820313@gmail.com>
ENV GO111MODULE=on
RUN apk update && \
apk upgrade && \
apk add git gcc libc-dev linux-headers
+1
View File
@@ -364,6 +364,7 @@ The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
1. http://http2.github.io/ -- What is HTTP/2?
1. http://www.lartc.org/ -- Linux Advanced Routing & Traffic Control
1. https://en.wikipedia.org/wiki/Noisy-channel_coding_theorem -- Noisy channel coding theorem
1. https://zhuanlan.zhihu.com/p/53849089 -- kcptun开发小记
### Donate
+2
View File
@@ -28,7 +28,9 @@ type Config struct {
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxVer int `json:"smuxver"`
SmuxBuf int `json:"smuxbuf"`
StreamBuf int `json:"streambuf"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
+109 -47
View File
@@ -18,25 +18,29 @@ import (
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/kcptun/generic"
"github.com/xtaci/smux"
smuxv2 "github.com/xtaci/smux/v2"
)
// SALT is use for pbkdf2 key expansion
const SALT = "kcp-go"
// maximum supported smux version
const maxSmuxVer = 2
// VERSION is injected by buildflags
var VERSION = "SELFBUILD"
// A pool for stream copying
var xmitBuf sync.Pool
func handleClient(sess *smux.Session, p1 net.Conn, quiet bool) {
func handleClient(mux generic.Mux, p1 net.Conn, quiet bool) {
logln := func(v ...interface{}) {
if !quiet {
log.Println(v...)
}
}
defer p1.Close()
p2, err := sess.OpenStream()
p2, err := mux.Open()
if err != nil {
logln(err)
return
@@ -44,15 +48,32 @@ func handleClient(sess *smux.Session, p1 net.Conn, quiet bool) {
defer p2.Close()
logln("stream opened", "in:", p1.RemoteAddr(), "out:", fmt.Sprint(p2.RemoteAddr(), "(", p2.ID(), ")"))
defer logln("stream closed", "in:", p1.RemoteAddr(), "out:", fmt.Sprint(p2.RemoteAddr(), "(", p2.ID(), ")"))
if s2, ok := p2.(generic.Stream); ok {
logln("stream opened", "in:", p1.RemoteAddr(), "out:", fmt.Sprint(s2.RemoteAddr(), "(", s2.ID(), ")"))
defer logln("stream closed", "in:", p1.RemoteAddr(), "out:", fmt.Sprint(s2.RemoteAddr(), "(", s2.ID(), ")"))
}
// start tunnel & wait for tunnel termination
streamCopy := func(dst io.Writer, src io.ReadCloser) chan struct{} {
die := make(chan struct{})
go func() {
buf := xmitBuf.Get().([]byte)
generic.CopyBuffer(dst, src, buf)
if _, err := generic.CopyBuffer(dst, src, buf); err != nil {
if s2, ok := p2.(generic.Stream); ok {
// verbose error handling
cause := err
if e, ok := err.(interface{ Cause() error }); ok {
cause = e.Cause()
}
switch cause {
case smux.ErrInvalidProtocol:
log.Println("smux version:1", err, "in:", p1.RemoteAddr(), "out:", fmt.Sprint(s2.RemoteAddr(), "(", s2.ID(), ")"))
case smuxv2.ErrInvalidProtocol:
log.Println("smux version:2", err, "in:", p1.RemoteAddr(), "out:", fmt.Sprint(s2.RemoteAddr(), "(", s2.ID(), ")"))
}
}
}
xmitBuf.Put(buf)
close(die)
}()
@@ -192,11 +213,21 @@ func main() {
Value: 4194304, // socket buffer size in bytes
Usage: "per-socket buffer in bytes",
},
cli.IntFlag{
Name: "smuxver",
Value: 1,
Usage: "specify smux version, available 1,2",
},
cli.IntFlag{
Name: "smuxbuf",
Value: 4194304,
Usage: "the overall de-mux buffer in bytes",
},
cli.IntFlag{
Name: "streambuf",
Value: 2097152,
Usage: "per stream receive buffer in bytes, smux v2+",
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
@@ -255,6 +286,8 @@ func main() {
config.NoCongestion = c.Int("nc")
config.SockBuf = c.Int("sockbuf")
config.SmuxBuf = c.Int("smuxbuf")
config.StreamBuf = c.Int("streambuf")
config.SmuxVer = c.Int("smuxver")
config.KeepAlive = c.Int("keepalive")
config.Log = c.String("log")
config.SnmpLog = c.String("snmplog")
@@ -292,8 +325,37 @@ func main() {
listener, err := net.ListenTCP("tcp", addr)
checkError(err)
log.Println("smux version:", config.SmuxVer)
log.Println("listening on:", listener.Addr())
log.Println("encryption:", config.Crypt)
log.Println("nodelay parameters:", config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
log.Println("remote address:", config.RemoteAddr)
log.Println("sndwnd:", config.SndWnd, "rcvwnd:", config.RcvWnd)
log.Println("compression:", !config.NoComp)
log.Println("mtu:", config.MTU)
log.Println("datashard:", config.DataShard, "parityshard:", config.ParityShard)
log.Println("acknodelay:", config.AckNodelay)
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("smuxbuf:", config.SmuxBuf)
log.Println("streambuf:", config.StreamBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("conn:", config.Conn)
log.Println("autoexpire:", config.AutoExpire)
log.Println("scavengettl:", config.ScavengeTTL)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("quiet:", config.Quiet)
log.Println("tcp:", config.TCP)
// parameters check
if config.SmuxVer > maxSmuxVer {
log.Fatal("unsupported smux version:", config.SmuxVer)
}
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
log.Println("key derivation done")
var block kcp.BlockCrypt
switch config.Crypt {
case "sm4":
@@ -325,32 +387,7 @@ func main() {
block, _ = kcp.NewAESBlockCrypt(pass)
}
log.Println("listening on:", listener.Addr())
log.Println("encryption:", config.Crypt)
log.Println("nodelay parameters:", config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
log.Println("remote address:", config.RemoteAddr)
log.Println("sndwnd:", config.SndWnd, "rcvwnd:", config.RcvWnd)
log.Println("compression:", !config.NoComp)
log.Println("mtu:", config.MTU)
log.Println("datashard:", config.DataShard, "parityshard:", config.ParityShard)
log.Println("acknodelay:", config.AckNodelay)
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("smuxbuf:", config.SmuxBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("conn:", config.Conn)
log.Println("autoexpire:", config.AutoExpire)
log.Println("scavengettl:", config.ScavengeTTL)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("quiet:", config.Quiet)
log.Println("tcp:", config.TCP)
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
createConn := func() (*smux.Session, error) {
createConn := func() (generic.Mux, error) {
kcpconn, err := dial(&config, block)
if err != nil {
return nil, errors.Wrap(err, "dial()")
@@ -371,23 +408,48 @@ func main() {
if err := kcpconn.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
log.Println("smux version:", config.SmuxVer, "on connection:", kcpconn.LocalAddr(), "->", kcpconn.RemoteAddr())
switch config.SmuxVer {
case 1:
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
// stream multiplex
var session *smux.Session
if config.NoComp {
session, err = smux.Client(kcpconn, smuxConfig)
} else {
session, err = smux.Client(generic.NewCompStream(kcpconn), smuxConfig)
// stream multiplex
var session *smux.Session
if config.NoComp {
session, err = smux.Client(kcpconn, smuxConfig)
} else {
session, err = smux.Client(generic.NewCompStream(kcpconn), smuxConfig)
}
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
return session, nil
case 2:
smuxConfig := smuxv2.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.MaxStreamBuffer = config.StreamBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
// stream multiplex
var session *smuxv2.Session
if config.NoComp {
session, err = smuxv2.Client(kcpconn, smuxConfig)
} else {
session, err = smuxv2.Client(generic.NewCompStream(kcpconn), smuxConfig)
}
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
return session, nil
default:
panic("incorrect smux version")
}
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
log.Println("connection:", kcpconn.LocalAddr(), "->", kcpconn.RemoteAddr())
return session, nil
}
// wait until a connection is ready
waitConn := func() *smux.Session {
waitConn := func() generic.Mux {
for {
if session, err := createConn(); err == nil {
return session
@@ -400,7 +462,7 @@ func main() {
numconn := uint16(config.Conn)
muxes := make([]struct {
session *smux.Session
session generic.Mux
ttl time.Time
}, numconn)
@@ -409,7 +471,7 @@ func main() {
muxes[k].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
}
chScavenger := make(chan *smux.Session, 128)
chScavenger := make(chan generic.Mux, 128)
go scavenger(chScavenger, config.ScavengeTTL)
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
rr := uint16(0)
@@ -435,11 +497,11 @@ func main() {
}
type scavengeSession struct {
session *smux.Session
session generic.Mux
ts time.Time
}
func scavenger(ch chan *smux.Session, ttl int) {
func scavenger(ch chan generic.Mux, ttl int) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
var sessionList []scavengeSession
+25 -23
View File
@@ -1,25 +1,27 @@
{
"localaddr": ":2000",
"remoteaddr": "11.22.33.44:2000",
"key": "PASSWORD",
"crypt": "aes-128",
"mode": "fast3",
"mtu": 1400,
"sndwnd": 128,
"rcvwnd": 1024,
"datashard": 10,
"parityshard": 3,
"dscp": 46,
"nocomp": true,
"acknodelay": false,
"nodelay": 1,
"interval": 40,
"resend": 2,
"nc": 1,
"sockbuf": 16777217,
"smuxbuf": 16777217,
"keepalive": 10,
"autoexpire":1800,
"quiet":false,
"tcp":false
"localaddr": ":2000",
"remoteaddr": "11.22.33.44:2000",
"key": "PASSWORD",
"crypt": "aes-128",
"mode": "fast3",
"mtu": 1400,
"sndwnd": 128,
"rcvwnd": 1024,
"datashard": 10,
"parityshard": 3,
"dscp": 46,
"nocomp": true,
"acknodelay": false,
"nodelay": 1,
"interval": 40,
"resend": 2,
"nc": 1,
"sockbuf": 16777217,
"smuxver": 1,
"smuxbuf": 16777217,
"streambuf": 2097152,
"keepalive": 10,
"autoexpire": 1800,
"quiet": false,
"tcp": false
}
+2
View File
@@ -17,7 +17,9 @@
"resend": 2,
"nc": 1,
"sockbuf": 16777217,
"smuxver": 1,
"smuxbuf": 16777217,
"streambuf": 2097152,
"keepalive": 10,
"pprof":false,
"quiet":false,
+15 -12
View File
@@ -2,6 +2,7 @@ package generic
import (
"net"
"time"
"github.com/golang/snappy"
"github.com/pkg/errors"
@@ -33,21 +34,23 @@ func (c *CompStream) Close() error {
}
func (c *CompStream) LocalAddr() net.Addr {
if ts, ok := c.conn.(interface {
LocalAddr() net.Addr
}); ok {
return ts.LocalAddr()
}
return nil
return c.conn.LocalAddr()
}
func (c *CompStream) RemoteAddr() net.Addr {
if ts, ok := c.conn.(interface {
RemoteAddr() net.Addr
}); ok {
return ts.RemoteAddr()
}
return nil
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)
}
func NewCompStream(conn net.Conn) *CompStream {
+21
View File
@@ -0,0 +1,21 @@
package generic
import (
"io"
"net"
)
type Mux interface {
Open() (io.ReadWriteCloser, error)
Accept() (io.ReadWriteCloser, error)
IsClosed() bool
NumStreams() int
RemoteAddr() net.Addr
Close() error
}
type Stream interface {
io.ReadWriteCloser
ID() uint32
RemoteAddr() net.Addr
}
+12 -10
View File
@@ -1,7 +1,7 @@
module github.com/xtaci/kcptun
require (
github.com/coreos/go-iptables v0.4.1 // indirect
github.com/coreos/go-iptables v0.4.2 // indirect
github.com/golang/snappy v0.0.1
github.com/google/gopacket v1.1.17 // indirect
github.com/klauspost/cpuid v1.2.1 // indirect
@@ -10,13 +10,15 @@ require (
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
github.com/tjfoc/gmsm v1.0.1 // indirect
github.com/urfave/cli v1.20.0
github.com/xtaci/kcp-go v5.4.2+incompatible
github.com/xtaci/smux v1.3.4
github.com/xtaci/tcpraw v1.2.22
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7 // indirect
github.com/urfave/cli v1.21.0
github.com/xtaci/kcp-go v5.4.10+incompatible
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae // indirect
github.com/xtaci/smux v1.4.4
github.com/xtaci/smux/v2 v2.0.11
github.com/xtaci/tcpraw v1.2.25
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b // indirect
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b // indirect
)
go 1.13
+31 -215
View File
@@ -1,15 +1,12 @@
github.com/coreos/go-iptables v0.4.1 h1:TyEMaK2xD/EcB0385QcvX/OvI2XI7s4SJEI2EhZFfEU=
github.com/coreos/go-iptables v0.4.1/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/coreos/go-iptables v0.4.2 h1:KH0EwId05JwWIfb96gWvkiT2cbuOu8ygqUaB+yPAwIg=
github.com/coreos/go-iptables v0.4.2/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.1 h1:kYrT1MlR4JH6PqOpC+okdb9CDTcwEC/BqpzK4WFyXL8=
github.com/klauspost/reedsolomon v1.9.1/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/klauspost/reedsolomon v1.9.2 h1:E9CMS2Pqbv+C7tsrYad4YC9MfhnMVWhMRsTi7U0UB18=
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
@@ -20,218 +17,37 @@ github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkB
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/tjfoc/gmsm v1.0.1 h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU=
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/xtaci/kcp-go v5.0.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.1+incompatible h1:A6zXUGblo98vosfEdaHcy0cTBZKY2dByJxICuaV+L5g=
github.com/xtaci/kcp-go v5.1.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.2+incompatible h1:UafCgw2Yk3QOf8MRm8jYEWJt1l4J61BgLpMsROkJQxo=
github.com/xtaci/kcp-go v5.1.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.3+incompatible h1:s96+ulBrZlxk4DPRPgEGPBV8o55kYKKFVivDwVgZNcA=
github.com/xtaci/kcp-go v5.1.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.4+incompatible h1:GHIUAicdHMKwTys8sx2ZnZbFaK8lvmwDniQlFa2BOo4=
github.com/xtaci/kcp-go v5.1.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.3+incompatible h1:LD/Go8xYxtcyvOvFzeo387BV3UNPcwJvMY+8H+JDhfk=
github.com/xtaci/kcp-go v5.2.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.4+incompatible h1:96bjdOFrUFfU4wYXqGwPJkEOdvnVwciGlAGOHEDpgy8=
github.com/xtaci/kcp-go v5.2.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.5+incompatible h1:9C3xCFYCw6HUMN1/DQhLlUcbx1DmFiLbpiNA/moLYPM=
github.com/xtaci/kcp-go v5.2.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.6+incompatible h1:WokjD7IJJopwivFVIleBjmuHYlhGTlR/JAhCsapl1dk=
github.com/xtaci/kcp-go v5.2.6+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.7+incompatible h1:NkJrwfMj3K6lRHfppR8H+oayahPS6GkGGF4BKiRAiFg=
github.com/xtaci/kcp-go v5.2.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.8+incompatible h1:WRlKHMAWdB08NEmWW0cpdEQcJsOYRdFwP7lA62AhpWo=
github.com/xtaci/kcp-go v5.2.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.2+incompatible h1:sWzdr6Wcs/ZlRY0U8PeeMgpmtimIutFNfrxgQTPoA9U=
github.com/xtaci/kcp-go v5.3.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.3+incompatible h1:zlvskph4pBYpt5C8Y22GO2EL3saYpE/2WSZRUEKZXbE=
github.com/xtaci/kcp-go v5.3.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.4+incompatible h1:vHlrCvUC4nDSGQQxbgzwwF35sup3mKAxr5Wj3Yzg4c4=
github.com/xtaci/kcp-go v5.3.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.5+incompatible h1:PD0cqKLJDAMKgX2qzWfK98fbcrVPYDEdstlY0SN0q20=
github.com/xtaci/kcp-go v5.3.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.6+incompatible h1:g3/sc8dtbFG6td3W7BTyJNr/5Sb0zMNBFgEtqnSuxmw=
github.com/xtaci/kcp-go v5.3.6+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.7+incompatible h1:iWiEoXj7BnFNR1XUPAQssR8DJGw9E7BE0l1rqFCAi3Y=
github.com/xtaci/kcp-go v5.3.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.8+incompatible h1:1f9hBNbkoMfLryf0P82GzrMkSkqBLUztOmmqKqh7XxM=
github.com/xtaci/kcp-go v5.3.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.9+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.1+incompatible h1:zRYDrtFx/DBNI2pngZNOYxEDvWyGN6zZlIB2QcXHL9M=
github.com/xtaci/kcp-go v5.4.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.2+incompatible h1:srUoSnFj4dkRzo2b+yz1WENGB32vAv0iuMS8wjYmaEI=
github.com/xtaci/kcp-go v5.4.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/smux v1.1.1 h1:ZyIo9XHuHkAeENzHR8yGWC+6xUSCTeP2tPTRE8mnLvc=
github.com/xtaci/smux v1.1.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.1.2 h1:AeAzHKqvDeFEcicL9Q06LTjIVW2I55iooUbpDRGHth4=
github.com/xtaci/smux v1.1.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.2 h1:pF/P78jvAXNG3yddhxKYTXMmNLzxXxdGKKjUBvxF8lk=
github.com/xtaci/smux v1.2.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.3/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.4 h1:l+peIfF3MUC5OmA93nKlezj8Nhejjv76BvnTyQEB2RI=
github.com/xtaci/smux v1.2.4/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.5 h1:p5K13hQEKeMo/H0XwO7jNxuT2G4/guo7Z7blfxBWBpI=
github.com/xtaci/smux v1.2.5/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.6 h1:lcooP+CKdWf1IE0d35eJ4MuUt7+kA3hwtQN0uPdd5lo=
github.com/xtaci/smux v1.2.6/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.7 h1:h7m7UL5zNZRaqEAtFXReqAVuStI3Al85zvJSGxqDqF0=
github.com/xtaci/smux v1.2.7/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.8 h1:mNFGEdnACCih1aER/JF4JVJIcOl7Mkf5yrQNzdDY6jg=
github.com/xtaci/smux v1.2.8/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.9 h1:aLBpFdORtDMzFJnrktW5hhe6UScbiS9inicP01KWR7M=
github.com/xtaci/smux v1.2.9/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.10 h1:DQiH08XfO+33X7l5XOGV5urQHrgK8PRFWYxT/z9Hrnw=
github.com/xtaci/smux v1.2.10/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.11 h1:QI4M2HgkkpsVU3Bfcmyx10qURBEeHfKi7xDhGEORfu0=
github.com/xtaci/smux v1.2.11/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.12 h1:POGYLDuR61+XZlVzKUdI4fTLtJnyVba++XS4Q6T5e3M=
github.com/xtaci/smux v1.2.12/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.1 h1:qMkK+dTu8ozfYz13UaX5q9GRIx0Qwux3FvcjtKZmDF8=
github.com/xtaci/smux v1.3.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.2 h1:8NsGbxBW6oSaeLu5E6V8AmklZm6EhBz7BeCOU3Zdhwc=
github.com/xtaci/smux v1.3.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.3 h1:+vnzZHTLGHrj+LzUZEkKmvu4KkG7fj4jwMPqhawvErg=
github.com/xtaci/smux v1.3.3/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.4 h1:7BJNo6A3d8CJXV1cCwwN9lZaGigNB2BbSDKIbtf7bHE=
github.com/xtaci/smux v1.3.4/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/tcpraw v1.1.3 h1:9kYm8HlXn0G/bNH7Xkm7Ypn/w17vnl/JfDQxBWueUAY=
github.com/xtaci/tcpraw v1.1.3/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.4 h1:AUO0vsyx0e3gbhOXC13iQ4FHjYoGwYZjf+I28HyZJ6g=
github.com/xtaci/tcpraw v1.1.4/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.5 h1:/1AhipCVBsFF5aperX3ioqtO/UnBgv9QbO/NnApwu08=
github.com/xtaci/tcpraw v1.1.5/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.6 h1:QlLq9NcyMn+t90URntTd/EETMxBMNwuiJ6JLek/8W7I=
github.com/xtaci/tcpraw v1.1.6/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.7 h1:5M1VRTJTAPnLj7fNHaWLjFzRKTv+ooS1s8A1PChHhMA=
github.com/xtaci/tcpraw v1.1.7/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.8 h1:4oh8U6muwXZrnEnMIv1f5cDCv7e3sIQnCd4k6hAIIIQ=
github.com/xtaci/tcpraw v1.1.8/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.9 h1:8IvLbvBnqYLzXSU1DazMSGjE2GsR/MbQYubQSXO3uVw=
github.com/xtaci/tcpraw v1.1.9/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.11 h1:yzeuBhNbvfo7U8q4LsFgeyxGyXqVUIr8kxEguSguG3U=
github.com/xtaci/tcpraw v1.1.11/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.12 h1:IgYqbZUd9CQiOyVahwtGBC7f6WlYrR9toI+omhgAShM=
github.com/xtaci/tcpraw v1.1.12/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.13 h1:uL09wQfiqAm2s95WhId1SBiWSU4K7S0v+X7zIQNcz38=
github.com/xtaci/tcpraw v1.1.13/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.14 h1:aaVZkMAOzGihIZTizUzhEHczD0+V3zkSxkK1ynTJGyo=
github.com/xtaci/tcpraw v1.1.14/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.15 h1:w3FN0U2TxXMAVPvRg0ChxQrJ6x4PdSstXAKyYnmpWC0=
github.com/xtaci/tcpraw v1.1.15/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.16 h1:L7Yd9ai+mY3axAZY+tAW9aV3IPoTMbt9g8mLSYjsW5w=
github.com/xtaci/tcpraw v1.1.16/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.17 h1:2bKo62lMFYAnkYx5NXDHOW1NWqsBYdO37zmJ+3lfZ5E=
github.com/xtaci/tcpraw v1.1.17/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.1.18 h1:Jl5UpGZ6Ck0bwXSWdOZ3ExUa6DXx30mCaqvpRnhB3TY=
github.com/xtaci/tcpraw v1.1.18/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.0 h1:ktu8W19TkPj3Av2tDhnp7YGKG9tk1Jz3LI8bI5usT6Q=
github.com/xtaci/tcpraw v1.2.0/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.1 h1:NdMZTNgIK9R9payI0ISU1LZs24fzOPk10z4wSsMnOTM=
github.com/xtaci/tcpraw v1.2.1/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.2 h1:/4m5yUO/b3xJBUQmPzxW4SzgnbfVku8g26jFVJ4n/YQ=
github.com/xtaci/tcpraw v1.2.2/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.3 h1:Wf47jXep3tCP3qXwj12gyiSe90fvuOV2pofMDMEt89A=
github.com/xtaci/tcpraw v1.2.3/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.4 h1:Euz3j4DJzaTgqHmPuF0YPnvJ9w+6pLWPw27f5skFXEo=
github.com/xtaci/tcpraw v1.2.4/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.5 h1:SbSGUqGsSjtP+Ejn14X5EFg4cIyYHACHZGsTSEItySI=
github.com/xtaci/tcpraw v1.2.5/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.6 h1:kBdM4tXKt40nwZgTDYdWiO0vY0i6gdwGAOJOp9LVM7E=
github.com/xtaci/tcpraw v1.2.6/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.7 h1:ImTm0CorUW1c6dn+lM2TpC8vt5Xps2kOd5i7vIlg98Y=
github.com/xtaci/tcpraw v1.2.7/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.8 h1:QyMKfDE61fAWCf25+6CFmpxJF11+ORiATGcWqOlDZoQ=
github.com/xtaci/tcpraw v1.2.8/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.9 h1:PmQIlNkVsXwpHkoe7pab/WDGlg+TNod8UXMMvSVaVhQ=
github.com/xtaci/tcpraw v1.2.9/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.10 h1:MXgrEuA9Fng5rLr/TdCRY8tV7xy88dcQxr5ybJf/wOI=
github.com/xtaci/tcpraw v1.2.10/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.11 h1:xauEjUvrApWnVWml5g5jwAbOI9N+iorXASLPwawP5Bk=
github.com/xtaci/tcpraw v1.2.11/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.13 h1:Z5FMbVgrcWkdx3e3Uz3Bvf6w0XC8LhLESKP+G2RwM4g=
github.com/xtaci/tcpraw v1.2.13/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.14 h1:95m5qpenPSxdz1N46caRvAycOViMD15oIadoD0fIFz8=
github.com/xtaci/tcpraw v1.2.14/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.16 h1:p1DgHiWXYVKUwmPbwi6090LaB2QuA+tovLqnnSuVkrk=
github.com/xtaci/tcpraw v1.2.16/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.17 h1:xO4dPmfN/KYEUoyM23IwOcJvjJBCKLMUs2vLDmfqapY=
github.com/xtaci/tcpraw v1.2.17/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.18 h1:517ANDJ7s4BF7HMSea4a0JeGlO9T2oA8fu/qd/DRQBY=
github.com/xtaci/tcpraw v1.2.18/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.19 h1:lnBCK1/1NQd8SC88AQW8r0KHjXCmvyIXV/IjeaDUdOI=
github.com/xtaci/tcpraw v1.2.19/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/xtaci/tcpraw v1.2.22 h1:v//4xkRLE4T3r1oH7YLm21Cl7O1rrmu2iGYmOf1oOBo=
github.com/xtaci/tcpraw v1.2.22/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE=
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
github.com/xtaci/kcp-go v5.4.7+incompatible h1:0WXorSb87WBIVjXWv618klAeCh8H32NcDpWq+g04x2E=
github.com/xtaci/kcp-go v5.4.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.8+incompatible h1:4GnTyiiC1S7ZFBMKvsF0gMJ3MoN1BoiFRCQ7IuAeUB0=
github.com/xtaci/kcp-go v5.4.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.9+incompatible h1:wrMgJXB/UFch+ERT0Qr4wO9CSqPAXWblbnH9uGK7TM4=
github.com/xtaci/kcp-go v5.4.9+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.10+incompatible h1:FgH1ji3efEmRFaHEeyim1RYN4Q/c8BT8VqXMklBmh84=
github.com/xtaci/kcp-go v5.4.10+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/xtaci/smux v1.4.4 h1:FukIfahko+KHhS9Gxppkp6756opZymvPOLNmpny1is4=
github.com/xtaci/smux v1.4.4/go.mod h1:LuA3S0xssf4fmGRJ7ow3EehgmDUzib4EcobaFNKvlMA=
github.com/xtaci/smux/v2 v2.0.10 h1:EKYuZH06sfoId5REZXyHmKTSgIeU5Ko27JICc0YI6ys=
github.com/xtaci/smux/v2 v2.0.10/go.mod h1:Iqy5a3Gax2p7WCKHOHkSNo/COthNFXd3/vqrcKNtzqI=
github.com/xtaci/smux/v2 v2.0.11 h1:thVWmgGRciZ8iaATwpY2B/51aHzmMI6wrF7DfcJSckU=
github.com/xtaci/smux/v2 v2.0.11/go.mod h1:Iqy5a3Gax2p7WCKHOHkSNo/COthNFXd3/vqrcKNtzqI=
github.com/xtaci/tcpraw v1.2.25 h1:VDlqo0op17JeXBM6e2G9ocCNLOJcw9mZbobMbJjo0vk=
github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a h1:Igim7XhdOpBnWPuYJ70XcNpq8q3BCACtVgNfoJxOV7g=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af h1:6qGQw30u837TXZbCmLFR9AVA+RjJU1LIbvk0oIkDZGY=
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd h1:sMHc2rZHuzQmrbVoSpt9HgerkXPyIeCSO6k0zUMGfFk=
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 h1:rlLehGeYg6jfoyz/eDqDU1iRXLKfR42nnNh57ytKEWo=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87 h1:yh5/K199RObPR6zqVBYf+AyJuweAqx+fOe9s3cekn1Y=
golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190328230028-74de082e2cca h1:hyA6yiAgbUwuWqtscNvWAI7U1CtlaD1KilQ6iudt1aI=
golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83 h1:mgAKeshyNqWKdENOnQsg+8dRTwZFIwFaO3HNl52sweA=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190415214537-1da14a5a36f2 h1:iC0Y6EDq+rhnAePxGvJs2kzUAYcwESqdcGRPzEUfzTU=
golang.org/x/net v0.0.0-20190415214537-1da14a5a36f2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 h1:HdqqaWmYAUI7/dmByKKEw+yxDksGSo+9GjkUc9Zp34E=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424024845-afe8014c977f h1:uALRiwYevCJtciRa4mKKFkrs5jY4F2OTf1D2sfi1swY=
golang.org/x/net v0.0.0-20190424024845-afe8014c977f/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 h1:FP8hkuE6yUEaJnK7O2eTuejKWwW+Rhfj80dQ2JcKxCU=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190329044733-9eb1bfa1ce65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190415145633-3fd5a3612ccd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190416152802-12500544f89f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b h1:3S2h5FadpNr0zUUCVZjlKIEYF+KaX/OBplTGo89CYHI=
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190424031103-cb2dda6eabdf/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190428024724-550556f78a90/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190509153222-73554e0f7805/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190511041617-99f201b6807e/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190513233021-7d589f28aaf4/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+2
View File
@@ -26,6 +26,8 @@ type Config struct {
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxBuf int `json:"smuxbuf"`
StreamBuf int `json:"streambuf"`
SmuxVer int `json:"smuxver"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
-18
View File
@@ -1,18 +0,0 @@
package main
import (
"github.com/pkg/errors"
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/tcpraw"
)
func listen(config *Config, block kcp.BlockCrypt) (*kcp.Listener, error) {
if config.TCP {
conn, err := tcpraw.Listen("tcp", config.Listen)
if err != nil {
return nil, errors.Wrap(err, "tcpraw.Listen()")
}
return kcp.ServeConn(block, config.DataShard, config.ParityShard, conn)
}
return kcp.ListenWithOptions(config.Listen, block, config.DataShard, config.ParityShard)
}
+149 -64
View File
@@ -19,11 +19,16 @@ import (
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/kcptun/generic"
"github.com/xtaci/smux"
smuxv2 "github.com/xtaci/smux/v2"
"github.com/xtaci/tcpraw"
)
// SALT is use for pbkdf2 key expansion
const SALT = "kcp-go"
// maximum supported smux version
const maxSmuxVer = 2
// VERSION is injected by buildflags
var VERSION = "SELFBUILD"
@@ -31,33 +36,54 @@ var VERSION = "SELFBUILD"
var xmitBuf sync.Pool
// handle multiplex-ed connection
func handleMux(conn io.ReadWriteCloser, config *Config) {
// stream multiplex
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
mux, err := smux.Server(conn, smuxConfig)
if err != nil {
log.Println(err)
return
}
defer mux.Close()
func handleMux(conn net.Conn, config *Config) {
// check if target is unix domain socket
var isUnix bool
if _, _, err := net.SplitHostPort(config.Target); err != nil {
isUnix = true
}
log.Println("smux version:", config.SmuxVer, "on connection:", conn.LocalAddr(), "->", conn.RemoteAddr())
// stream multiplex
var muxer generic.Mux
switch config.SmuxVer {
case 1:
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
mux, err := smux.Server(conn, smuxConfig)
if err != nil {
log.Println(err)
return
}
defer mux.Close()
muxer = mux
case 2:
smuxConfig := smuxv2.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.MaxStreamBuffer = config.StreamBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
mux, err := smuxv2.Server(conn, smuxConfig)
if err != nil {
log.Println(err)
return
}
defer mux.Close()
muxer = mux
default:
panic("incorrect smux version")
}
for {
stream, err := mux.AcceptStream()
stream, err := muxer.Accept()
if err != nil {
log.Println(err)
return
}
go func(p1 *smux.Stream) {
go func(p1 io.ReadWriteCloser) {
var p2 net.Conn
var err error
if !isUnix {
@@ -76,7 +102,7 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
}
}
func handleClient(p1 *smux.Stream, p2 net.Conn, quiet bool) {
func handleClient(p1 io.ReadWriteCloser, p2 net.Conn, quiet bool) {
logln := func(v ...interface{}) {
if !quiet {
log.Println(v...)
@@ -86,15 +112,32 @@ func handleClient(p1 *smux.Stream, p2 net.Conn, quiet bool) {
defer p1.Close()
defer p2.Close()
logln("stream opened", "in:", fmt.Sprint(p1.RemoteAddr(), "(", p1.ID(), ")"), "out:", p2.RemoteAddr())
defer logln("stream closed", "in:", fmt.Sprint(p1.RemoteAddr(), "(", p1.ID(), ")"), "out:", p2.RemoteAddr())
if s1, ok := p1.(generic.Stream); ok {
logln("stream opened", "in:", fmt.Sprint(s1.RemoteAddr(), "(", s1.ID(), ")"), "out:", p2.RemoteAddr())
defer logln("stream closed", "in:", fmt.Sprint(s1.RemoteAddr(), "(", s1.ID(), ")"), "out:", p2.RemoteAddr())
}
// start tunnel & wait for tunnel termination
streamCopy := func(dst io.Writer, src io.ReadCloser) chan struct{} {
die := make(chan struct{})
go func() {
buf := xmitBuf.Get().([]byte)
generic.CopyBuffer(dst, src, buf)
if _, err := generic.CopyBuffer(dst, src, buf); err != nil {
if s1, ok := p1.(generic.Stream); ok {
// verbose error handling
cause := err
if e, ok := err.(interface{ Cause() error }); ok {
cause = e.Cause()
}
switch cause {
case smux.ErrInvalidProtocol:
log.Println("smux version:1", err, "in:", fmt.Sprint(s1.RemoteAddr(), "(", s1.ID(), ")"), "out:", p2.RemoteAddr())
case smuxv2.ErrInvalidProtocol:
log.Println("smux version:2", err, "in:", fmt.Sprint(s1.RemoteAddr(), "(", s1.ID(), ")"), "out:", p2.RemoteAddr())
}
}
}
xmitBuf.Put(buf)
close(die)
}()
@@ -219,11 +262,21 @@ func main() {
Value: 4194304, // socket buffer size in bytes
Usage: "per-socket buffer in bytes",
},
cli.IntFlag{
Name: "smuxver",
Value: 1,
Usage: "specify smux version, available 1,2",
},
cli.IntFlag{
Name: "smuxbuf",
Value: 4194304,
Usage: "the overall de-mux buffer in bytes",
},
cli.IntFlag{
Name: "streambuf",
Value: 2097152,
Usage: "per stream receive buffer in bytes, smux v2+",
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
@@ -283,6 +336,8 @@ func main() {
config.NoCongestion = c.Int("nc")
config.SockBuf = c.Int("sockbuf")
config.SmuxBuf = c.Int("smuxbuf")
config.StreamBuf = c.Int("streambuf")
config.SmuxVer = c.Int("smuxver")
config.KeepAlive = c.Int("keepalive")
config.Log = c.String("log")
config.SnmpLog = c.String("snmplog")
@@ -317,8 +372,35 @@ func main() {
}
log.Println("version:", VERSION)
log.Println("smux version:", config.SmuxVer)
log.Println("listening on:", config.Listen)
log.Println("target:", config.Target)
log.Println("encryption:", config.Crypt)
log.Println("nodelay parameters:", config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
log.Println("sndwnd:", config.SndWnd, "rcvwnd:", config.RcvWnd)
log.Println("compression:", !config.NoComp)
log.Println("mtu:", config.MTU)
log.Println("datashard:", config.DataShard, "parityshard:", config.ParityShard)
log.Println("acknodelay:", config.AckNodelay)
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("smuxbuf:", config.SmuxBuf)
log.Println("streambuf:", config.StreamBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("pprof:", config.Pprof)
log.Println("quiet:", config.Quiet)
log.Println("tcp:", config.TCP)
// parameters check
if config.SmuxVer > maxSmuxVer {
log.Fatal("unsupported smux version:", config.SmuxVer)
}
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
log.Println("key derivation done")
var block kcp.BlockCrypt
switch config.Crypt {
case "sm4":
@@ -350,61 +432,64 @@ func main() {
block, _ = kcp.NewAESBlockCrypt(pass)
}
lis, err := listen(&config, block)
checkError(err)
log.Println("listening on:", lis.Addr())
log.Println("target:", config.Target)
log.Println("encryption:", config.Crypt)
log.Println("nodelay parameters:", config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
log.Println("sndwnd:", config.SndWnd, "rcvwnd:", config.RcvWnd)
log.Println("compression:", !config.NoComp)
log.Println("mtu:", config.MTU)
log.Println("datashard:", config.DataShard, "parityshard:", config.ParityShard)
log.Println("acknodelay:", config.AckNodelay)
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("smuxbuf:", config.SmuxBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("pprof:", config.Pprof)
log.Println("quiet:", config.Quiet)
log.Println("tcp:", config.TCP)
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)
}
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
if config.Pprof {
go http.ListenAndServe(":6060", nil)
}
for {
if conn, err := lis.AcceptKCP(); err == nil {
log.Println("remote address:", conn.RemoteAddr())
conn.SetStreamMode(true)
conn.SetWriteDelay(false)
conn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
conn.SetMtu(config.MTU)
conn.SetWindowSize(config.SndWnd, config.RcvWnd)
conn.SetACKNoDelay(config.AckNodelay)
// main loop
var wg sync.WaitGroup
loop := func(lis *kcp.Listener) {
defer wg.Done()
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)
}
if config.NoComp {
go handleMux(conn, &config)
for {
if conn, err := lis.AcceptKCP(); err == nil {
log.Println("remote address:", conn.RemoteAddr())
conn.SetStreamMode(true)
conn.SetWriteDelay(false)
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 {
go handleMux(conn, &config)
} else {
go handleMux(generic.NewCompStream(conn), &config)
}
} else {
go handleMux(generic.NewCompStream(conn), &config)
log.Printf("%+v", err)
}
} else {
log.Printf("%+v", err)
}
}
if config.TCP { // tcp dual stack
if conn, err := tcpraw.Listen("tcp", config.Listen); err == nil {
lis, err := kcp.ServeConn(block, config.DataShard, config.ParityShard, conn)
checkError(err)
wg.Add(1)
go loop(lis)
} else {
log.Println(err)
}
}
// udp stack
lis, err := kcp.ListenWithOptions(config.Listen, block, config.DataShard, config.ParityShard)
checkError(err)
wg.Add(1)
go loop(lis)
wg.Wait()
return nil
}
myApp.Run(os.Args)
}