mirror of
https://github.com/xtaci/kcptun.git
synced 2024-04-21 12:32:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60569b85fa | ||
|
|
273ca4febc | ||
|
|
d129f92842 | ||
|
|
75e83adfba | ||
|
|
3f6134be00 | ||
|
|
2ea87c9c22 | ||
|
|
0bf2b94d92 | ||
|
|
3e81672992 | ||
|
|
4052db212c | ||
|
|
68c1eb3c9e | ||
|
|
d1fe0565c6 | ||
|
|
ff83995830 | ||
|
|
288318b08a | ||
|
|
55e69c323d | ||
|
|
53ef93e08d | ||
|
|
7183a9ecd6 | ||
|
|
8252405714 | ||
|
|
ede800b0fd | ||
|
|
a43b688990 | ||
|
|
283f61068b | ||
|
|
e0b8ed5dad | ||
|
|
a8d76aed7f | ||
|
|
97cc1c0393 | ||
|
|
3becd2e925 | ||
|
|
aba4957096 | ||
|
|
b58104c7b9 |
+1
-1
@@ -5,7 +5,7 @@ RUN apk update && \
|
||||
apk add git
|
||||
RUN go get -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" github.com/xtaci/kcptun/client && go get -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" github.com/xtaci/kcptun/server
|
||||
|
||||
FROM alpine:3.6
|
||||
FROM alpine:3.9
|
||||
COPY --from=builder /go/bin /bin
|
||||
EXPOSE 29900/udp
|
||||
EXPOSE 12948
|
||||
|
||||
@@ -69,7 +69,11 @@ All precompiled releases are genereated from `build-release.sh` script.
|
||||
|
||||
### Performance
|
||||
|
||||
<img src="fast.png" alt="fast.com" height="256px" />
|
||||
<img src="fast.png" alt="fast.com" height="256px" />
|
||||
|
||||
<img src="bw.png" alt="bandwidth usage graph" height="256px" />
|
||||
|
||||
> Practical bandwidth graph with parameters: -mode fast3 -ds 10 -ps 3
|
||||
|
||||
### Basic Tuning Guide
|
||||
|
||||
@@ -97,6 +101,11 @@ All precompiled releases are genereated from `build-release.sh` script.
|
||||
Since streams are multiplexed into a single physical channel, head of line blocking may appear under certain circumstances, by
|
||||
increasing `-smuxbuf` to a larger value (default 4MB) may mitigate this problem, obviously this will costs more memory.
|
||||
|
||||
#### Slow Devices
|
||||
|
||||
kcptun made use of **ReedSolomon-Codes** to recover lost packets, which requires massive amount of computation, a low-end ARM device cannot satisfy kcptun well. To unleash the full potential of kcptun, a multi-core x86 homeserver CPU like AMD Opteron is recommended.
|
||||
If you insist on running under some ARM routers, you'd better turn off `FEC` and use `salsa20` as the encryption method.
|
||||
|
||||
### Expert Tuning Guide
|
||||
|
||||
#### Overview
|
||||
@@ -106,15 +115,15 @@ increasing `-smuxbuf` to a larger value (default 4MB) may mitigate this problem,
|
||||
#### Usage
|
||||
|
||||
```
|
||||
$ ./client_darwin_amd64 -h
|
||||
xtaci@gw:~$ ./client_linux_amd64 -h
|
||||
NAME:
|
||||
kcptun - client(with SMUX)
|
||||
|
||||
USAGE:
|
||||
client_darwin_amd64 [global options] command [command options] [arguments...]
|
||||
client_linux_amd64 [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
20180922
|
||||
20190409
|
||||
|
||||
COMMANDS:
|
||||
help, h Shows a list of commands or help for one command
|
||||
@@ -135,8 +144,9 @@ GLOBAL OPTIONS:
|
||||
--parityshard value, --ps value set reed-solomon erasure coding - parityshard (default: 3)
|
||||
--dscp value set DSCP(6bit) (default: 0)
|
||||
--nocomp disable compression
|
||||
--sockbuf value (default: 4194304)
|
||||
--keepalive value (default: 10)
|
||||
--sockbuf value per-socket buffer in bytes (default: 4194304)
|
||||
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
|
||||
--keepalive value seconds between heartbeats (default: 10)
|
||||
--snmplog value collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
|
||||
--snmpperiod value snmp collect period, in seconds (default: 60)
|
||||
--log value specify a log file to output, default goes to stderr
|
||||
@@ -144,16 +154,16 @@ GLOBAL OPTIONS:
|
||||
-c value config from json file, which will override the command from shell
|
||||
--help, -h show help
|
||||
--version, -v print the version
|
||||
|
||||
$ ./server_darwin_amd64 -h
|
||||
|
||||
xtaci@gw:~$ ./server_linux_amd64 -h
|
||||
NAME:
|
||||
kcptun - server(with SMUX)
|
||||
|
||||
USAGE:
|
||||
server_darwin_amd64 [global options] command [command options] [arguments...]
|
||||
server_linux_amd64 [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
20180922
|
||||
20190409
|
||||
|
||||
COMMANDS:
|
||||
help, h Shows a list of commands or help for one command
|
||||
@@ -171,8 +181,9 @@ GLOBAL OPTIONS:
|
||||
--parityshard value, --ps value set reed-solomon erasure coding - parityshard (default: 3)
|
||||
--dscp value set DSCP(6bit) (default: 0)
|
||||
--nocomp disable compression
|
||||
--sockbuf value (default: 4194304)
|
||||
--keepalive value (default: 10)
|
||||
--sockbuf value per-socket buffer in bytes (default: 4194304)
|
||||
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
|
||||
--keepalive value seconds between heartbeats (default: 10)
|
||||
--snmplog value collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
|
||||
--snmpperiod value snmp collect period, in seconds (default: 60)
|
||||
--pprof start profiling server on :6060
|
||||
@@ -252,11 +263,17 @@ aes-128-cfb 847216.79k 850770.86k 853712.05k 859912.39k 854565.80k
|
||||
The encrytion performance in kcptun is as fast as in openssl library(if not faster).
|
||||
|
||||
|
||||
#### Memory Usage Control
|
||||
#### Memory Control
|
||||
|
||||
Routers, mobile devices are susceptible to memory consumption; by setting GOGC environment(eg: GOGC=20) will make the garbage collector to recycle faster.
|
||||
Reference: https://blog.golang.org/go15gc
|
||||
|
||||
Primary memory allocation are done from a global buffer pool *xmit.Buf*, in kcp-go, when we need to allocate some bytes, we can get from that pool, and a *fixed-capacity* 1500 bytes(mtuLimit) will be returned, the *rx queue*, *tx queue* and *fec queue* all receive bytes from there, and they will return the bytes to the pool after using to prevent *unnecessary zer0ing* of bytes.
|
||||
The pool mechanism maintained a *high watermark* for slice objects, these *in-flight* objects from the pool will survive from the perodical garbage collection, meanwhile the pool kept the ability to return the memory to runtime if in idle, `-sndwnd`,`-rcvwnd`,`-ds`, `-ps`, these parameters affect this *high watermark*, the larger the value, the bigger the memory consumption will be.
|
||||
|
||||
`-smuxbuf` also affects the maximum memory consumption, this parameter maintains a subtle balance between *concurrency* and *resource*, you can increase this value(default 4MB) to boost concurrency if you have many clients to serve and you get a powerful server at the same time, and also you can decrease this value to serve only 1 or 2 clients and hope this program can run under some embeded SoC system with limited memory and only you can access. (Notice that the `-smuxbuf` value is not proprotional to concurrency, you need to test.)
|
||||
|
||||
|
||||
#### Compression
|
||||
|
||||
kcptun has builtin snappy algorithms for compressing streams:
|
||||
|
||||
+38
-16
@@ -1,6 +1,8 @@
|
||||
#!/bin/bash
|
||||
sum="sha1sum"
|
||||
|
||||
echo "If you need reproducible build, export GO111MODULE=on first"
|
||||
|
||||
if ! hash sha1sum 2>/dev/null; then
|
||||
if ! hash shasum 2>/dev/null; then
|
||||
echo "I can't see 'sha1sum' or 'shasum'"
|
||||
@@ -19,21 +21,34 @@ VERSION=`date -u +%Y%m%d`
|
||||
LDFLAGS="-X main.VERSION=$VERSION -s -w"
|
||||
GCFLAGS=""
|
||||
|
||||
# AMD64
|
||||
OSES=(linux darwin windows freebsd)
|
||||
ARCHS=(amd64 386)
|
||||
for os in ${OSES[@]}; do
|
||||
for arch in ${ARCHS[@]}; do
|
||||
suffix=""
|
||||
if [ "$os" == "windows" ]
|
||||
then
|
||||
suffix=".exe"
|
||||
fi
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_${arch}${suffix} github.com/xtaci/kcptun/client
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_${arch}${suffix} github.com/xtaci/kcptun/server
|
||||
if $UPX; then upx -9 client_${os}_${arch}${suffix} server_${os}_${arch}${suffix};fi
|
||||
tar -zcf kcptun-${os}-${arch}-$VERSION.tar.gz client_${os}_${arch}${suffix} server_${os}_${arch}${suffix}
|
||||
$sum kcptun-${os}-${arch}-$VERSION.tar.gz
|
||||
done
|
||||
suffix=""
|
||||
if [ "$os" == "windows" ]
|
||||
then
|
||||
suffix=".exe"
|
||||
fi
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_amd64${suffix} github.com/xtaci/kcptun/client
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_amd64${suffix} github.com/xtaci/kcptun/server
|
||||
if $UPX; then upx -9 client_${os}_amd64${suffix} server_${os}_amd64${suffix};fi
|
||||
tar -zcf kcptun-${os}-amd64-$VERSION.tar.gz client_${os}_amd64${suffix} server_${os}_amd64${suffix}
|
||||
$sum kcptun-${os}-amd64-$VERSION.tar.gz
|
||||
done
|
||||
|
||||
# 386
|
||||
OSES=(linux windows)
|
||||
for os in ${OSES[@]}; do
|
||||
suffix=""
|
||||
if [ "$os" == "windows" ]
|
||||
then
|
||||
suffix=".exe"
|
||||
fi
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_386${suffix} github.com/xtaci/kcptun/client
|
||||
env CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_386${suffix} github.com/xtaci/kcptun/server
|
||||
if $UPX; then upx -9 client_${os}_386${suffix} server_${os}_386${suffix};fi
|
||||
tar -zcf kcptun-${os}-386-$VERSION.tar.gz client_${os}_386${suffix} server_${os}_386${suffix}
|
||||
$sum kcptun-${os}-386-$VERSION.tar.gz
|
||||
done
|
||||
|
||||
# ARM
|
||||
@@ -41,10 +56,17 @@ ARMS=(5 6 7)
|
||||
for v in ${ARMS[@]}; do
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm$v github.com/xtaci/kcptun/client
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm$v github.com/xtaci/kcptun/server
|
||||
if $UPX; then upx -9 client_linux_arm$v server_linux_arm$v;fi
|
||||
tar -zcf kcptun-linux-arm$v-$VERSION.tar.gz client_linux_arm$v server_linux_arm$v
|
||||
$sum kcptun-linux-arm$v-$VERSION.tar.gz
|
||||
done
|
||||
if $UPX; then upx -9 client_linux_arm* server_linux_arm*;fi
|
||||
tar -zcf kcptun-linux-arm-$VERSION.tar.gz client_linux_arm* server_linux_arm*
|
||||
$sum kcptun-linux-arm-$VERSION.tar.gz
|
||||
|
||||
# ARM64
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm64 github.com/xtaci/kcptun/client
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm64 github.com/xtaci/kcptun/server
|
||||
if $UPX; then upx -9 client_linux_arm64 server_linux_arm64*;fi
|
||||
tar -zcf kcptun-linux-arm64-$VERSION.tar.gz client_linux_arm64 server_linux_arm64
|
||||
$sum kcptun-linux-arm64-$VERSION.tar.gz
|
||||
|
||||
#MIPS32LE
|
||||
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mipsle github.com/xtaci/kcptun/client
|
||||
|
||||
+26
-17
@@ -9,6 +9,7 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
@@ -22,12 +23,14 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
// VERSION is injected by buildflags
|
||||
VERSION = "SELFBUILD"
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
SALT = "kcp-go"
|
||||
)
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
const SALT = "kcp-go"
|
||||
|
||||
// VERSION is injected by buildflags
|
||||
var VERSION = "SELFBUILD"
|
||||
|
||||
// A pool for stream copying
|
||||
var xmitBuf sync.Pool
|
||||
|
||||
type compStream struct {
|
||||
conn net.Conn
|
||||
@@ -70,19 +73,21 @@ func handleClient(sess *smux.Session, p1 io.ReadWriteCloser, quiet bool) {
|
||||
}
|
||||
defer p2.Close()
|
||||
|
||||
// start tunnel
|
||||
p1die := make(chan struct{})
|
||||
buf1 := make([]byte, 65535)
|
||||
go func() { io.CopyBuffer(p1, p2, buf1); close(p1die) }()
|
||||
// start tunnel & wait for tunnel termination
|
||||
streamCopy := func(dst io.Writer, src io.Reader) chan struct{} {
|
||||
die := make(chan struct{})
|
||||
go func() {
|
||||
buf := xmitBuf.Get().([]byte)
|
||||
io.CopyBuffer(dst, src, buf)
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}()
|
||||
return die
|
||||
}
|
||||
|
||||
p2die := make(chan struct{})
|
||||
buf2 := make([]byte, 65535)
|
||||
go func() { io.CopyBuffer(p2, p1, buf2); close(p2die) }()
|
||||
|
||||
// wait for tunnel termination
|
||||
select {
|
||||
case <-p1die:
|
||||
case <-p2die:
|
||||
case <-streamCopy(p1, p2):
|
||||
case <-streamCopy(p2, p1):
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +104,10 @@ func main() {
|
||||
// add more log flags for debugging
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
xmitBuf.New = func() interface{} {
|
||||
return make([]byte, 65535)
|
||||
}
|
||||
|
||||
myApp := cli.NewApp()
|
||||
myApp.Name = "kcptun"
|
||||
myApp.Usage = "client(with SMUX)"
|
||||
|
||||
@@ -2,16 +2,16 @@ module github.com/xtaci/kcptun
|
||||
|
||||
require (
|
||||
github.com/golang/snappy v0.0.1
|
||||
github.com/klauspost/cpuid v1.2.0 // indirect
|
||||
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.1 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
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.1.3+incompatible
|
||||
github.com/xtaci/smux v1.1.2
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576
|
||||
golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87 // indirect
|
||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc // indirect
|
||||
github.com/xtaci/kcp-go v5.2.5+incompatible
|
||||
github.com/xtaci/smux v1.2.9
|
||||
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd
|
||||
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 // indirect
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect
|
||||
)
|
||||
|
||||
@@ -2,6 +2,8 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
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/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
@@ -21,18 +23,69 @@ github.com/xtaci/kcp-go v5.1.2+incompatible h1:UafCgw2Yk3QOf8MRm8jYEWJt1l4J61BgL
|
||||
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/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=
|
||||
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/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/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/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
+37
-25
@@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
@@ -23,12 +24,14 @@ import (
|
||||
"github.com/xtaci/smux"
|
||||
)
|
||||
|
||||
var (
|
||||
// VERSION is injected by buildflags
|
||||
VERSION = "SELFBUILD"
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
SALT = "kcp-go"
|
||||
)
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
const SALT = "kcp-go"
|
||||
|
||||
// VERSION is injected by buildflags
|
||||
var VERSION = "SELFBUILD"
|
||||
|
||||
// A pool for stream copying
|
||||
var xmitBuf sync.Pool
|
||||
|
||||
type compStream struct {
|
||||
conn net.Conn
|
||||
@@ -72,18 +75,21 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
|
||||
}
|
||||
defer mux.Close()
|
||||
for {
|
||||
p1, err := mux.AcceptStream()
|
||||
stream, err := mux.AcceptStream()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
p2, err := net.DialTimeout("tcp", config.Target, 5*time.Second)
|
||||
if err != nil {
|
||||
p1.Close()
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
go handleClient(p1, p2, config.Quiet)
|
||||
|
||||
go func(p1 *smux.Stream) {
|
||||
p2, err := net.Dial("tcp", config.Target)
|
||||
if err != nil {
|
||||
p1.Close()
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
handleClient(p1, p2, config.Quiet)
|
||||
}(stream)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,19 +101,21 @@ func handleClient(p1, p2 io.ReadWriteCloser, quiet bool) {
|
||||
defer p1.Close()
|
||||
defer p2.Close()
|
||||
|
||||
// start tunnel
|
||||
p1die := make(chan struct{})
|
||||
buf1 := make([]byte, 65535)
|
||||
go func() { io.CopyBuffer(p1, p2, buf1); close(p1die) }()
|
||||
// start tunnel & wait for tunnel termination
|
||||
streamCopy := func(dst io.Writer, src io.Reader) chan struct{} {
|
||||
die := make(chan struct{})
|
||||
go func() {
|
||||
buf := xmitBuf.Get().([]byte)
|
||||
io.CopyBuffer(dst, src, buf)
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}()
|
||||
return die
|
||||
}
|
||||
|
||||
p2die := make(chan struct{})
|
||||
buf2 := make([]byte, 65535)
|
||||
go func() { io.CopyBuffer(p2, p1, buf2); close(p2die) }()
|
||||
|
||||
// wait for tunnel termination
|
||||
select {
|
||||
case <-p1die:
|
||||
case <-p2die:
|
||||
case <-streamCopy(p1, p2):
|
||||
case <-streamCopy(p2, p1):
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +132,10 @@ func main() {
|
||||
// add more log flags for debugging
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
xmitBuf.New = func() interface{} {
|
||||
return make([]byte, 65535)
|
||||
}
|
||||
|
||||
myApp := cli.NewApp()
|
||||
myApp.Name = "kcptun"
|
||||
myApp.Usage = "server(with SMUX)"
|
||||
|
||||
Reference in New Issue
Block a user