mirror of
https://github.com/xtaci/kcptun.git
synced 2024-04-21 12:32:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23cd29a88e | ||
|
|
3c54e12586 | ||
|
|
c71120e7d4 | ||
|
|
ee29dc4fb1 | ||
|
|
77dc451e83 | ||
|
|
8c2d39753e | ||
|
|
3790c74ca8 | ||
|
|
b07931c582 | ||
|
|
d374f93447 | ||
|
|
c8fa2a287f | ||
|
|
eefaf5afac | ||
|
|
3b5b4ac729 | ||
|
|
b983528f33 | ||
|
|
0f4131b7ae | ||
|
|
0c315300a3 | ||
|
|
7490778bbb | ||
|
|
fc57c98098 | ||
|
|
34bc48fd64 | ||
|
|
56b45e84f7 | ||
|
|
98f93118cf | ||
|
|
dca5b2da39 | ||
|
|
5bd9b7e92b | ||
|
|
f3cccbb51c | ||
|
|
4f88883837 | ||
|
|
8a03eb1568 | ||
|
|
9e0d6f8ce8 | ||
|
|
de73ed90a5 | ||
|
|
90ea4baa06 | ||
|
|
c8c084a087 | ||
|
|
5ad2b958a6 | ||
|
|
361ba7600d | ||
|
|
61e830c4e8 | ||
|
|
216c7aaf6d | ||
|
|
876e17ab18 | ||
|
|
166dbca282 | ||
|
|
24ff7caecb | ||
|
|
99abd12302 | ||
|
|
4a49552392 | ||
|
|
556de3055b | ||
|
|
9d84f40720 | ||
|
|
f70791fc61 | ||
|
|
8f2fcb7026 | ||
|
|
2eec01d9c0 | ||
|
|
047895f088 | ||
|
|
b93460fb27 | ||
|
|
8ab062621e | ||
|
|
c380abfc75 | ||
|
|
029af29881 | ||
|
|
b2720342c4 | ||
|
|
b51ef20d30 | ||
|
|
a95a000cad | ||
|
|
c251f2c3b4 | ||
|
|
ffb7f8aeaf | ||
|
|
265dd7eb1d | ||
|
|
c21ba84b05 | ||
|
|
7d06c5f2d7 |
+16
-14
@@ -1,27 +1,29 @@
|
||||
问问题前先搜索ISSUE,并搞清楚下面的问题:
|
||||
|
||||
1. 检查 ```-key xxx``` 至少三遍, ***保证***两边一致。
|
||||
2. 保证```-nocomp, -datashard, -parityshard, -key, -crypt```两边一致。
|
||||
2. 保证```-nocomp, -datashard, -parityshard, -key, -crypt, -smuxver```两边一致。
|
||||
3. 是否在服务器端,正确设定了转发的目标服务器地址 ***--target***。
|
||||
4. 如果第3条不确定,尝试在服务器上telnet target port试试。
|
||||
5. 防火墙是否关闭了UDP通信。
|
||||
6. 两端的版本是否一致?
|
||||
7. 是不是最新版本?
|
||||
8. 两端分别是什么操作系统?
|
||||
9. 两端的输出日志是什么?
|
||||
4. 是否在客户端,正确的连接到了 client的监听端口。
|
||||
5. 如果第3条不确定,尝试在服务器上telnet target port试试。
|
||||
6. 防火墙是否关闭了UDP通信,或者设置了UDP的最大发包速率?
|
||||
7. 两端的版本是否一致?
|
||||
8. 是不是最新版本?
|
||||
9. 两端分别是什么操作系统?
|
||||
10. 两端的输出日志是什么?
|
||||
|
||||
Before firing issue, make sure you figured out the following common questions.
|
||||
|
||||
PLEASE DO SEARCH FIRST.
|
||||
|
||||
1. Check your ```-key xxx``` for at least 3 times, ***MAKE SURE*** both sides share the same secret.
|
||||
2. ```-nocomp, -datashard, -parityshard, -key, -crypt``` ***must be the same*** on both side.
|
||||
2. ```-nocomp, -datashard, -parityshard, -key, -crypt, -smuxver``` ***must be the same*** on both side.
|
||||
3. Did you correctly set the ***-target*** on the server side?
|
||||
4. ***MAKE SURE*** ```telnet target port``` on your server successful(don't ask me why couldn't).
|
||||
5. Does your ***firewall allows UDP*** communications? (including your ISP Cable-Modem)
|
||||
6. Are you using the **same version** for both client & server
|
||||
7. Are you using the **latest release**?
|
||||
8. Which **OS** do you use?
|
||||
9. Which end for this issue related to, **client or server**?
|
||||
4. Did you correctly connected to the listening port on client side?
|
||||
5. ***MAKE SURE*** ```telnet target port``` on your server successful(don't ask me why couldn't).
|
||||
6. Does your ***firewall allows UDP*** communications? (including your ISP Cable-Modem)
|
||||
7. Are you using the **same version** for both client & server
|
||||
8. Are you using the **latest release**?
|
||||
9. Which **OS** do you use?
|
||||
10. Which end for this issue related to, **client or server**?
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
# <img src="logo.png" alt="kcptun" height="54px" />
|
||||
|
||||
[![Release][13]][14] [![Powered][17]][18] [![MIT licensed][11]][12] [![Build Status][3]][4] [![Go Report Card][5]][6] [![Downloads][15]][16] [![Docker][1]][2]
|
||||
[![Release][13]][14] [![Powered][17]][18] [![MIT licensed][11]][12] [![Build Status][3]][4] [![Go Report Card][5]][6] [![Downloads][15]][16] [![Docker][1]][2]
|
||||
|
||||
[1]: https://images.microbadger.com/badges/image/xtaci/kcptun.svg
|
||||
[2]: https://microbadger.com/images/xtaci/kcptun
|
||||
[1]: https://img.shields.io/docker/pulls/xtaci/kcptun
|
||||
[2]: https://hub.docker.com/r/xtaci/kcptun
|
||||
[3]: https://travis-ci.org/xtaci/kcptun.svg?branch=master
|
||||
[4]: https://travis-ci.org/xtaci/kcptun
|
||||
[5]: https://goreportcard.com/badge/github.com/xtaci/kcptun
|
||||
[6]: https://goreportcard.com/report/github.com/xtaci/kcptun
|
||||
[7]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[8]: https://raw.githubusercontent.com/xtaci/kcptun/master/LICENSE.md
|
||||
[11]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[11]: https://img.shields.io/github/license/xtaci/kcptun
|
||||
[12]: LICENSE.md
|
||||
[13]: https://img.shields.io/github/release/xtaci/kcptun.svg
|
||||
[13]: https://img.shields.io/github/v/release/xtaci/kcptun?color=orange
|
||||
[14]: https://github.com/xtaci/kcptun/releases/latest
|
||||
[15]: https://img.shields.io/github/downloads/xtaci/kcptun/total.svg?maxAge=1800
|
||||
[15]: https://img.shields.io/github/downloads/xtaci/kcptun/total.svg?maxAge=1800&color=orange
|
||||
[16]: https://github.com/xtaci/kcptun/releases
|
||||
[17]: https://img.shields.io/badge/KCP-Powered-blue.svg
|
||||
[18]: https://github.com/skywind3000/kcp
|
||||
@@ -23,6 +21,15 @@
|
||||
|
||||
> *Disclaimer: kcptun maintains a single website — [github.com/xtaci/kcptun](https://github.com/xtaci/kcptun). Any websites other than [github.com/xtaci/kcptun](https://github.com/xtaci/kcptun) are not endorsed by xtaci.*
|
||||
|
||||
### Requirements
|
||||
|
||||
| Target | Minimum | Recommended |
|
||||
| --- | --- | --- |
|
||||
| System | aix darwin dragonfly freebsd linux netbsd openbsd solaris windows | linux |
|
||||
| Memory | >20MB | >32MB |
|
||||
| CPU | ANY | amd64 with AES-NI & AVX2 |
|
||||
|
||||
|
||||
### QuickStart
|
||||
|
||||
Increase the number of open files on your server, as:
|
||||
@@ -59,10 +66,13 @@ which tunnels the original connection:
|
||||
|
||||
> Application -> Target Server(8388/tcp)
|
||||
|
||||
### Install from source
|
||||
### Build from source
|
||||
|
||||
```
|
||||
$go get -u github.com/xtaci/kcptun/...
|
||||
$ git clone https://github.com/xtaci/kcptun.git
|
||||
$ cd kcptun
|
||||
$ ./build-release.sh
|
||||
$ cd build
|
||||
```
|
||||
|
||||
All precompiled releases are genereated from `build-release.sh` script.
|
||||
@@ -105,6 +115,8 @@ 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.
|
||||
|
||||
For versions >= v20190924, you can switch to smux version 2, smux v2 has options to limit per-stream memory usage, now set `-smuxver 2` to enable smux v2, and adjust `-streambuf` to limit per-stream memory usage, eg: `-streambuf 2097152` can limit per-stream memory usage to 2MB. By limiting stream buffer on the receiver side, a back-pressure will be conducted to the sender and limits reading, and finally prevent source from sending too much data to occupy every bits of buffer along the link. (Setting -smuxver **MUST** be **IDENTICAL** on both side, default is 1. )
|
||||
|
||||
#### 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.
|
||||
@@ -119,7 +131,7 @@ If you insist on running under some ARM routers, you'd better turn off `FEC` and
|
||||
#### Usage
|
||||
|
||||
```
|
||||
xtaci@gw:~$ ./client_linux_amd64 -h
|
||||
➜ ~ ./client_linux_amd64 -h
|
||||
NAME:
|
||||
kcptun - client(with SMUX)
|
||||
|
||||
@@ -127,10 +139,10 @@ USAGE:
|
||||
client_linux_amd64 [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
20190409
|
||||
20190924
|
||||
|
||||
COMMANDS:
|
||||
help, h Shows a list of commands or help for one command
|
||||
help, h Shows a list of commands or help for one command
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--localaddr value, -l value local listen address (default: ":12948")
|
||||
@@ -149,17 +161,20 @@ GLOBAL OPTIONS:
|
||||
--dscp value set DSCP(6bit) (default: 0)
|
||||
--nocomp disable compression
|
||||
--sockbuf value per-socket buffer in bytes (default: 4194304)
|
||||
--smuxver value specify smux version, available 1,2 (default: 1)
|
||||
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
|
||||
--streambuf value per stream receive buffer in bytes, smux v2+ (default: 2097152)
|
||||
--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
|
||||
--quiet to suppress the 'stream open/close' messages
|
||||
--tcp to emulate a TCP connection(linux)
|
||||
-c value config from json file, which will override the command from shell
|
||||
--help, -h show help
|
||||
--version, -v print the version
|
||||
|
||||
xtaci@gw:~$ ./server_linux_amd64 -h
|
||||
➜ ~ ./server_linux_amd64 -h
|
||||
NAME:
|
||||
kcptun - server(with SMUX)
|
||||
|
||||
@@ -167,14 +182,14 @@ USAGE:
|
||||
server_linux_amd64 [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
20190409
|
||||
20190924
|
||||
|
||||
COMMANDS:
|
||||
help, h Shows a list of commands or help for one command
|
||||
help, h Shows a list of commands or help for one command
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
--listen value, -l value kcp server listen address (default: ":29900")
|
||||
--target value, -t value target server address (default: "127.0.0.1:12948")
|
||||
--target value, -t value target server address, or path/to/unix_socket (default: "127.0.0.1:12948")
|
||||
--key value pre-shared secret between client and server (default: "it's a secrect") [$KCPTUN_KEY]
|
||||
--crypt value aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none (default: "aes")
|
||||
--mode value profiles: fast3, fast2, fast, normal, manual (default: "fast")
|
||||
@@ -186,13 +201,16 @@ GLOBAL OPTIONS:
|
||||
--dscp value set DSCP(6bit) (default: 0)
|
||||
--nocomp disable compression
|
||||
--sockbuf value per-socket buffer in bytes (default: 4194304)
|
||||
--smuxver value specify smux version, available 1,2 (default: 1)
|
||||
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
|
||||
--streambuf value per stream receive buffer in bytes, smux v2+ (default: 2097152)
|
||||
--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
|
||||
--log value specify a log file to output, default goes to stderr
|
||||
--quiet to suppress the 'stream open/close' messages
|
||||
--tcp to emulate a TCP connection(linux)
|
||||
-c value config from json file, which will override the command from shell
|
||||
--help, -h show help
|
||||
--version, -v print the version
|
||||
@@ -346,6 +364,7 @@ The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
|
||||
1. -nocomp
|
||||
1. -datashard
|
||||
1. -parityshard
|
||||
1. -smuxver
|
||||
|
||||
### References
|
||||
|
||||
@@ -366,14 +385,5 @@ The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
|
||||
1. https://en.wikipedia.org/wiki/Noisy-channel_coding_theorem -- Noisy channel coding theorem
|
||||
1. https://zhuanlan.zhihu.com/p/53849089 -- kcptun开发小记
|
||||
|
||||
### Donate
|
||||
|
||||
via Ethereum(ETH): Address: 0x2e4b43ab3d0983da282592571eef61ae5e60f726 , Or scan here:
|
||||
|
||||
<img src="0x2e4b43ab3d0983da282592571eef61ae5e60f726.png" alt="kcptun" height="120px" />
|
||||
|
||||
via WeChat
|
||||
|
||||
<img src="wechat_donate.jpg" alt="kcptun" height="120px" />
|
||||
|
||||
(注意:我没有任何社交网站的账号,请小心骗子。)
|
||||
|
||||
+2
-5
@@ -6,11 +6,8 @@ cd $BUILD_DIR
|
||||
|
||||
sum="sha1sum"
|
||||
|
||||
if [ "$GO111MODULE" != "on" ]; then
|
||||
echo "GO111MODULE is off"
|
||||
else
|
||||
echo "GO111MODULE is on"
|
||||
fi
|
||||
export GO111MODULE=on
|
||||
echo "Setting GO111MODULE to" $GO111MODULE
|
||||
|
||||
if ! hash sha1sum 2>/dev/null; then
|
||||
if ! hash shasum 2>/dev/null; then
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
"github.com/xtaci/tcpraw"
|
||||
)
|
||||
|
||||
|
||||
+49
-88
@@ -8,39 +8,38 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli"
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
"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
|
||||
const (
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
SALT = "kcp-go"
|
||||
// maximum supported smux version
|
||||
maxSmuxVer = 2
|
||||
// stream copy buffer size
|
||||
bufSize = 4096
|
||||
)
|
||||
|
||||
// VERSION is injected by buildflags
|
||||
var VERSION = "SELFBUILD"
|
||||
|
||||
// A pool for stream copying
|
||||
var xmitBuf sync.Pool
|
||||
|
||||
func handleClient(mux generic.Mux, p1 net.Conn, quiet bool) {
|
||||
// handleClient aggregates connection p1 on mux with 'writeLock'
|
||||
func handleClient(session *smux.Session, p1 net.Conn, quiet bool) {
|
||||
logln := func(v ...interface{}) {
|
||||
if !quiet {
|
||||
log.Println(v...)
|
||||
}
|
||||
}
|
||||
defer p1.Close()
|
||||
p2, err := mux.Open()
|
||||
p2, err := session.OpenStream()
|
||||
if err != nil {
|
||||
logln(err)
|
||||
return
|
||||
@@ -48,42 +47,23 @@ func handleClient(mux generic.Mux, p1 net.Conn, quiet bool) {
|
||||
|
||||
defer p2.Close()
|
||||
|
||||
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(), ")"))
|
||||
}
|
||||
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(), ")"))
|
||||
|
||||
// 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)
|
||||
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(), ")"))
|
||||
}
|
||||
}
|
||||
streamCopy := func(dst io.Writer, src io.ReadCloser) {
|
||||
if _, err := generic.Copy(dst, src); err != nil {
|
||||
// report protocol error
|
||||
if err == smux.ErrInvalidProtocol {
|
||||
log.Println("smux", err, "in:", p1.RemoteAddr(), "out:", fmt.Sprint(p2.RemoteAddr(), "(", p2.ID(), ")"))
|
||||
}
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}()
|
||||
return die
|
||||
}
|
||||
p1.Close()
|
||||
p2.Close()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-streamCopy(p1, p2):
|
||||
case <-streamCopy(p2, p1):
|
||||
}
|
||||
go streamCopy(p1, p2)
|
||||
streamCopy(p2, p1)
|
||||
}
|
||||
|
||||
func checkError(err error) {
|
||||
@@ -99,9 +79,6 @@ func main() {
|
||||
// add more log flags for debugging
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
xmitBuf.New = func() interface{} {
|
||||
return make([]byte, 32768)
|
||||
}
|
||||
|
||||
myApp := cli.NewApp()
|
||||
myApp.Name = "kcptun"
|
||||
@@ -387,7 +364,7 @@ func main() {
|
||||
block, _ = kcp.NewAESBlockCrypt(pass)
|
||||
}
|
||||
|
||||
createConn := func() (generic.Mux, error) {
|
||||
createConn := func() (*smux.Session, error) {
|
||||
kcpconn, err := dial(&config, block)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "dial()")
|
||||
@@ -409,47 +386,31 @@ func main() {
|
||||
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
|
||||
smuxConfig := smux.DefaultConfig()
|
||||
smuxConfig.Version = config.SmuxVer
|
||||
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
|
||||
smuxConfig.MaxStreamBuffer = config.StreamBuf
|
||||
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)
|
||||
}
|
||||
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 := smux.VerifyConfig(smuxConfig); err != nil {
|
||||
log.Fatalf("%+v", err)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// wait until a connection is ready
|
||||
waitConn := func() generic.Mux {
|
||||
waitConn := func() *smux.Session {
|
||||
for {
|
||||
if session, err := createConn(); err == nil {
|
||||
return session
|
||||
@@ -462,7 +423,7 @@ func main() {
|
||||
|
||||
numconn := uint16(config.Conn)
|
||||
muxes := make([]struct {
|
||||
session generic.Mux
|
||||
session *smux.Session
|
||||
ttl time.Time
|
||||
}, numconn)
|
||||
|
||||
@@ -471,7 +432,7 @@ func main() {
|
||||
muxes[k].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
|
||||
}
|
||||
|
||||
chScavenger := make(chan generic.Mux, 128)
|
||||
chScavenger := make(chan *smux.Session, 128)
|
||||
go scavenger(chScavenger, config.ScavengeTTL)
|
||||
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
|
||||
rr := uint16(0)
|
||||
@@ -497,11 +458,11 @@ func main() {
|
||||
}
|
||||
|
||||
type scavengeSession struct {
|
||||
session generic.Mux
|
||||
session *smux.Session
|
||||
ts time.Time
|
||||
}
|
||||
|
||||
func scavenger(ch chan generic.Mux, ttl int) {
|
||||
func scavenger(ch chan *smux.Session, ttl int) {
|
||||
ticker := time.NewTicker(time.Second)
|
||||
defer ticker.Stop()
|
||||
var sessionList []scavengeSession
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
Description=kcptun
|
||||
|
||||
Wants=network.target
|
||||
After=syslog.target network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment=GOGC=20
|
||||
ExecStart=/home/user/client_linux_amd64 -c /home/user/local.json
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
KillMode=process
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
+18
-30
@@ -1,36 +1,24 @@
|
||||
package generic
|
||||
|
||||
import "io"
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// io.CopyBuffer has extra tests for interface like io.ReaderFrom and io.WriterTo
|
||||
// which is not efficient in memory management from tests
|
||||
func CopyBuffer(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) {
|
||||
if buf != nil && len(buf) == 0 {
|
||||
panic("empty buffer in copyBuffer")
|
||||
const bufSize = 4096
|
||||
|
||||
// Memory optimized io.Copy function specified for this library
|
||||
func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
// If the reader has a WriteTo method, use it to do the copy.
|
||||
// Avoids an allocation and a copy.
|
||||
if wt, ok := src.(io.WriterTo); ok {
|
||||
return wt.WriteTo(dst)
|
||||
}
|
||||
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
|
||||
if rt, ok := dst.(io.ReaderFrom); ok {
|
||||
return rt.ReadFrom(src)
|
||||
}
|
||||
|
||||
for {
|
||||
nr, er := src.Read(buf)
|
||||
if nr > 0 {
|
||||
nw, ew := dst.Write(buf[0:nr])
|
||||
if nw > 0 {
|
||||
written += int64(nw)
|
||||
}
|
||||
if ew != nil {
|
||||
err = ew
|
||||
break
|
||||
}
|
||||
if nr != nw {
|
||||
err = io.ErrShortWrite
|
||||
break
|
||||
}
|
||||
}
|
||||
if er != nil {
|
||||
if er != io.EOF {
|
||||
err = er
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return written, err
|
||||
// fallback to standard io.CopyBuffer
|
||||
buf := make([]byte, bufSize)
|
||||
return io.CopyBuffer(dst, src, buf)
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
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
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/xtaci/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
)
|
||||
|
||||
func SnmpLogger(path string, interval int) {
|
||||
|
||||
@@ -4,21 +4,12 @@ require (
|
||||
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
|
||||
github.com/klauspost/reedsolomon v1.9.2 // 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.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/kcp-go/v5 v5.5.5
|
||||
github.com/xtaci/smux v1.5.9
|
||||
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
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
||||
@@ -5,49 +5,65 @@ 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.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
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/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us=
|
||||
github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY=
|
||||
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/templexxx/cpu v0.0.1 h1:hY4WdLOgKdc8y13EYklu9OUTXik80BkxHoWvTO6MQQY=
|
||||
github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM=
|
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/templexxx/xorsimd v0.3.1 h1:K6aBXKOSPgs0Pz/VXDy0pQK/RlwvtI1Cf9sOm3dPDrU=
|
||||
github.com/templexxx/xorsimd v0.3.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo=
|
||||
github.com/templexxx/xorsimd v0.4.1 h1:iUZcywbOYDRAZUasAs2eSCUW8eobuZDy0I9FJiORkVg=
|
||||
github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo=
|
||||
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.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/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/kcp-go/v5 v5.4.23 h1:fQG2rrEYWRKyq/PRtUZdBZ+RSr3S/3QQFuScA/KzjxU=
|
||||
github.com/xtaci/kcp-go/v5 v5.4.23/go.mod h1:kaRUj0x4HWAdtA32VaDNGGY8AZTRsFIOSCJQOWYcDc0=
|
||||
github.com/xtaci/kcp-go/v5 v5.4.25 h1:hD2bpx3R92TXvXoYGQ844heHekXNmXafnpKUE/uxGbc=
|
||||
github.com/xtaci/kcp-go/v5 v5.4.25/go.mod h1:kaRUj0x4HWAdtA32VaDNGGY8AZTRsFIOSCJQOWYcDc0=
|
||||
github.com/xtaci/kcp-go/v5 v5.4.26 h1:4NhV2D9c8IMUzhxI8eS0QVRR4MPqjhxoPGoh7Za3lQU=
|
||||
github.com/xtaci/kcp-go/v5 v5.4.26/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.0 h1:dEfJ6gid0SsGPMfvOxiF8SggVV+mtJ949ajOot+dMZg=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.0/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.2 h1:CzcoWZmYR1bAgk73D3ZUa3QVSwN8fgPbTglyqCGOFJM=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.2/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.3 h1:kBSV/WG8HOp/IC3GuSgqhTnrWnPq6O5t/tKwGn1mq7E=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.3/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.4 h1:LxBOkiy+NKBK80tfKF1uFMfQyMIRyyIjaLrvR9udkyk=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.4/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.5 h1:6wHtI6FyJVQ+PemXtCwhvVS6yu7sBQJWli6nOrg82qQ=
|
||||
github.com/xtaci/kcp-go/v5 v5.5.5/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
|
||||
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/smux v1.5.7 h1:fVOjux34i112nzp5BIF7yg4WvVKLj1pUMqEgSdiBho4=
|
||||
github.com/xtaci/smux v1.5.7/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
|
||||
github.com/xtaci/smux v1.5.8 h1:qyXDeYtjmAnSLqmptfgebpD1Wx1KPMF39POSfx0klDw=
|
||||
github.com/xtaci/smux v1.5.8/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
|
||||
github.com/xtaci/smux v1.5.9 h1:Sysv8NISQoULTQut7Cj4RIb3jVP/WMw5nYGgvSSTWKo=
|
||||
github.com/xtaci/smux v1.5.9/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
|
||||
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-20190909091759-094676da4a83 h1:mgAKeshyNqWKdENOnQsg+8dRTwZFIwFaO3HNl52sweA=
|
||||
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/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-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-20190910064555-bbd175535a8b h1:3S2h5FadpNr0zUUCVZjlKIEYF+KaX/OBplTGo89CYHI=
|
||||
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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=
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 55 KiB |
+33
-75
@@ -16,25 +16,24 @@ import (
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
"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
|
||||
const (
|
||||
// SALT is use for pbkdf2 key expansion
|
||||
SALT = "kcp-go"
|
||||
// maximum supported smux version
|
||||
maxSmuxVer = 2
|
||||
// stream copy buffer size
|
||||
bufSize = 4096
|
||||
)
|
||||
|
||||
// VERSION is injected by buildflags
|
||||
var VERSION = "SELFBUILD"
|
||||
|
||||
// A pool for stream copying
|
||||
var xmitBuf sync.Pool
|
||||
|
||||
// handle multiplex-ed connection
|
||||
func handleMux(conn net.Conn, config *Config) {
|
||||
// check if target is unix domain socket
|
||||
@@ -45,45 +44,27 @@ func handleMux(conn net.Conn, config *Config) {
|
||||
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
|
||||
smuxConfig := smux.DefaultConfig()
|
||||
smuxConfig.Version = config.SmuxVer
|
||||
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
|
||||
smuxConfig.MaxStreamBuffer = config.StreamBuf
|
||||
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")
|
||||
mux, err := smux.Server(conn, smuxConfig)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
defer mux.Close()
|
||||
|
||||
for {
|
||||
stream, err := muxer.Accept()
|
||||
stream, err := mux.AcceptStream()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
go func(p1 io.ReadWriteCloser) {
|
||||
go func(p1 *smux.Stream) {
|
||||
var p2 net.Conn
|
||||
var err error
|
||||
if !isUnix {
|
||||
@@ -102,7 +83,7 @@ func handleMux(conn net.Conn, config *Config) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleClient(p1 io.ReadWriteCloser, p2 net.Conn, quiet bool) {
|
||||
func handleClient(p1 *smux.Stream, p2 net.Conn, quiet bool) {
|
||||
logln := func(v ...interface{}) {
|
||||
if !quiet {
|
||||
log.Println(v...)
|
||||
@@ -112,42 +93,22 @@ func handleClient(p1 io.ReadWriteCloser, p2 net.Conn, quiet bool) {
|
||||
defer p1.Close()
|
||||
defer p2.Close()
|
||||
|
||||
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())
|
||||
}
|
||||
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())
|
||||
|
||||
// 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)
|
||||
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())
|
||||
}
|
||||
}
|
||||
streamCopy := func(dst io.Writer, src io.ReadCloser) {
|
||||
if _, err := generic.Copy(dst, src); err != nil {
|
||||
if err == smux.ErrInvalidProtocol {
|
||||
log.Println("smux", err, "in:", fmt.Sprint(p1.RemoteAddr(), "(", p1.ID(), ")"), "out:", p2.RemoteAddr())
|
||||
}
|
||||
xmitBuf.Put(buf)
|
||||
close(die)
|
||||
}()
|
||||
return die
|
||||
}
|
||||
p1.Close()
|
||||
p2.Close()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-streamCopy(p1, p2):
|
||||
case <-streamCopy(p2, p1):
|
||||
}
|
||||
go streamCopy(p2, p1)
|
||||
streamCopy(p1, p2)
|
||||
}
|
||||
|
||||
func checkError(err error) {
|
||||
@@ -163,9 +124,6 @@ func main() {
|
||||
// add more log flags for debugging
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
}
|
||||
xmitBuf.New = func() interface{} {
|
||||
return make([]byte, 32768)
|
||||
}
|
||||
|
||||
myApp := cli.NewApp()
|
||||
myApp.Name = "kcptun"
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
kcp "github.com/xtaci/kcp-go"
|
||||
kcp "github.com/xtaci/kcp-go/v5"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB |
Reference in New Issue
Block a user