Compare commits

..
47 Commits
Author SHA1 Message Date
xtaci 46831490b2 add a shortname for parityshard & datashard 2017-01-17 23:37:52 +08:00
xtaciandGitHub 2f11f135a8 Update README.md 2017-01-16 15:57:39 +08:00
xtaciandGitHub ce4af6237b Update README.md 2017-01-12 23:09:30 +08:00
xtaci e3ef794c64 Revert "Update README.md"
This reverts commit a981e32abe.
2017-01-12 23:08:17 +08:00
xtaci 6e529de8d2 Revert "Update README.md"
This reverts commit f5ac595e0c.
2017-01-12 23:08:16 +08:00
xtaci 831824ab79 Revert "Update README.md"
This reverts commit f84c47a491.
2017-01-12 23:08:15 +08:00
xtaci 13c451735b Revert "Update README.en.md"
This reverts commit 6b249273f5.
2017-01-12 23:08:15 +08:00
xtaci ba2da70222 Revert "Update README.md"
This reverts commit ca8be8cea4.
2017-01-12 23:08:14 +08:00
xtaci 1609b180cf Revert "Update README.md"
This reverts commit 511d49e3f5.
2017-01-12 23:08:13 +08:00
xtaci 4adcf45fb2 Revert "Update README.md"
This reverts commit 1b11a849ae.
2017-01-12 23:08:12 +08:00
xtaci d24deceff7 Revert "Update README.md"
This reverts commit 56a9b3b5e5.
2017-01-12 23:08:11 +08:00
xtaciandGitHub 56a9b3b5e5 Update README.md 2017-01-12 22:57:59 +08:00
xtaciandGitHub 1b11a849ae Update README.md 2017-01-12 22:49:58 +08:00
xtaciandGitHub 511d49e3f5 Update README.md 2017-01-12 22:45:00 +08:00
xtaciandGitHub ca8be8cea4 Update README.md 2017-01-12 22:13:33 +08:00
xtaciandGitHub 6b249273f5 Update README.en.md 2017-01-12 22:11:15 +08:00
xtaciandGitHub f84c47a491 Update README.md 2017-01-12 22:10:43 +08:00
xtaciandGitHub f5ac595e0c Update README.md 2017-01-12 22:08:28 +08:00
xtaciandGitHub a981e32abe Update README.md 2017-01-12 22:07:10 +08:00
xtaciandGitHub aed33d45ae Update README.md 2017-01-12 11:33:08 +08:00
xtaciandGitHub 53328dce08 Update README.md 2017-01-11 13:12:29 +08:00
xtaci 17be438477 switch back to golang offical snappy lib 2017-01-11 12:50:33 +08:00
xtaci c7db48ae11 upd 2017-01-03 12:51:21 +08:00
xtaci de389a8500 upd issue template 2017-01-03 11:01:15 +08:00
xtaci f7474faf19 adjust default rcvwnd from 1024 to 512 2016-12-27 13:34:46 +08:00
xtaci 61e69d9d5b add snmp reset 2016-12-21 10:52:12 +08:00
xtaci 11cdc2038c add unix timestamp to snmp records 2016-12-20 23:01:47 +08:00
xtaci 1908dc391e upd 2016-12-20 22:16:34 +08:00
xtaci 51e6b381bf upd 2016-12-20 22:16:10 +08:00
xtaci 3531726339 add -snmplog & -snmpperiod options to collect SNMP into file 2016-12-20 22:13:00 +08:00
xtaci 53f814ec9f handle AcceptTCP error 2016-12-17 13:13:59 +08:00
xtaci 375640d183 Merge branch 'master' of https://github.com/xtaci/kcptun 2016-12-07 20:14:34 +08:00
xtaci ae2ba18b08 async stream open 2016-12-07 20:14:09 +08:00
xtaciandGitHub 717df77668 Update README.md 2016-12-05 14:06:44 +08:00
xtaci b61a2c240c upd 2016-12-02 17:02:41 +08:00
xtaci bfe3524d74 Merge branch 'master' of https://github.com/xtaci/kcptun 2016-12-02 16:24:44 +08:00
xtaci 8b3b38eeef add compile target mipsle 2016-12-02 16:23:53 +08:00
xtaciandGitHub 754b4a7186 Update README.md 2016-11-18 13:50:09 +08:00
xtaci 229a4a8783 Merge branch 'master' of https://github.com/xtaci/kcptun 2016-11-10 20:36:39 +08:00
xtaci 052f0a5397 optimized xor doesn't need -B flag for bce 2016-11-10 20:35:33 +08:00
xtaciandGitHub 8e74cf410c Update README.en.md 2016-11-04 10:56:03 +08:00
xtaciandGitHub 206df4b69f Update README.md 2016-11-04 10:55:36 +08:00
xtaciandGitHub 4ccc922059 Update README.md 2016-11-01 13:47:57 +08:00
xtaciandGitHub 1e88951c54 Update README.md 2016-11-01 13:41:49 +08:00
xtaciandGitHub 6540e3e90a Update README.en.md 2016-11-01 13:38:47 +08:00
xtaciandGitHub 9ac03a973b Update README.md 2016-11-01 13:34:51 +08:00
xtaciandGitHub f911127426 Add files via upload 2016-11-01 13:31:48 +08:00
9 changed files with 187 additions and 41 deletions
+14
View File
@@ -1,3 +1,15 @@
问问题前先搜索ISSUE,并搞清楚下面的问题:
1. 检查 ```-key xxx``` 至少三遍, ***保证***两边一致。
2. 保证```-nocomp, -datashard, -parityshard, -key, -crypt```两边一致。
3. 是否在服务器端,正确设定了转发的目标服务器地址 ***--target***。
4. 如果第3条不确定,尝试在服务器上telnet target port试试。
5. 防火墙是否关闭了UDP通信。
6. 两端的版本是否一致?
7. 是不是最新版本?
8. 两端分别是什么操作系统?
9. 两端的输出日志是什么?
Before firing issue, make sure you figured out the following common questions.
PLEASE DO SEARCH FIRST.
@@ -11,3 +23,5 @@ PLEASE DO SEARCH FIRST.
7. Are you using the **latest release**?
8. Which **OS** do you use?
9. Which end for this issue related to, **client or server**?
+5 -2
View File
@@ -30,8 +30,8 @@ A tool for converting tcp stream into kcp+udp stream, :zap: ***[download address
### *QuickStart* :lollipop:
Client, server, respectively, download the corresponding platform binary compression package, and extract, through the following command to start port forwarding.
```
Server: ./server_linux_amd64 -t "SERVER_IP:8388" -l ":4000"
Client: ./client_darwin_amd64 -r "SERVER_IP:4000" -l ":8388"
Server: ./server_linux_amd64 -t "SERVER_IP:8388" -l ":4000" -mode fast2
Client: ./client_darwin_amd64 -r "SERVER_IP:4000" -l ":8388" -mode fast2
```
The above command can establish 8388/tcp port forwarding (through 4000/udp port).
@@ -109,6 +109,9 @@ GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
```
#### *Parameters by Layers* :lollipop:
<p align="left"><img src="layeredparams.png" alt="params" height="450px"/></p>
### *Applications* :lollipop:
1. Real-time gaming.
+35 -18
View File
@@ -1,5 +1,5 @@
<p align="center"><img src="logo.png" alt="kcptun" height="60px" /></p>
<p align="center"><em>也许是世界上最快的UDP传输工具</em></p>
<p align="center"><em>A Simple UDP Tunnel Based On KCP</em></p>
-
@@ -26,16 +26,24 @@
<p align="center"><img src="kcptun.png" alt="kcptun" height="200px"/></p>
<p align="center"><a href="https://github.com/xtaci/kcptun/releases/latest">立即安装</a></p>
<p align="center"><em>支持macOS/Linux/Windows/FreeBSD/ARM/Raspberry Pi/OpenWrt</em></p>
<p align="right"><a href="https://github.com/xtaci/kcptun/blob/master/README.en.md">ENG</a></p>
<p align="right"><a href="https://github.com/xtaci/kcptun/blob/master/README.en.md">ENGLISH VERSION</a></p>
-
### 手动编译
```
$go get -u github.com/xtaci/kcptun/client
$go get -u github.com/xtaci/kcptun/server
```
注意: 如果出现错误提示,请确保依赖库能正确访问到。
Release中的所有二进制版本,是通过 `build-release.sh` 脚本生成并优化。
### 快速设定
客户端、服务器分别**下载**对应平台的二进制压缩包,并**解压**,通过下面的命令**启动**端口转发。
```
服务器: ./server_linux_amd64 -t "服务器IP地址:8388" -l ":4000"
客户端: ./client_darwin_amd64 -r "服务器IP地址:4000" -l ":8388"
服务器: ./server_linux_amd64 -t "服务器IP地址:8388" -l ":4000" -mode fast2
客户端: ./client_darwin_amd64 -r "服务器IP地址:4000" -l ":8388" -mode fast2
```
以上命令可以实现8388/tcp端口的转发(通过4000/udp端口)。
@@ -114,6 +122,19 @@ GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
```
#### 分层参数图
<p align="left"><img src="layeredparams.png" alt="params" height="450px"/></p>
**两端参数必须一致的有**:
* datashard --前向纠错
* parityshard --前向纠错
* nocomp --压缩
* key --密钥
* crypt --加密算法
其余为两边可独立设定的参数
### 内置模式
@@ -121,7 +142,7 @@ GLOBAL OPTIONS:
*fast3 > fast2 >* **[fast]** *> normal > default*
有效载荷比:
*default > normal >* **[fast]** *> fast2 > fast3*
中间mode参数比较均衡,总之就是越快,包重传越激进。
中间-mode参数比较均衡,总之就是越快,包重传越激进。
更高级的 **手动档** 需要理解KCP协议,并通过 **隐藏参数** 调整,例如:
```
-mode manual -nodelay 1 -resend 2 -nc 1 -interval 20
@@ -131,6 +152,8 @@ GLOBAL OPTIONS:
* 搭配2. fast2 + FEC(10,3)
* 搭配3. fast2 + FEC(0,0)
默认profile参考: https://github.com/xtaci/kcptun/blob/master/client/main.go#L248
### 前向纠错
前向纠错采用Reed Solomon纠删码, 它的基本原理如下: 给定n个数据块d1, d2,…, dn,n和一个正整数m, RS根据n个数据块生成m个校验块, c1, c2,…, cm。 对于任意的n和m, 从n个原始数据块和m 个校验块中任取n块就能解码出原始数据, 即RS最多**容忍m个数据块或者校验块同时丢失**。
@@ -144,21 +167,10 @@ GLOBAL OPTIONS:
注意:为了发挥FEC最佳效果,设置 parityshard/(parity+datashard) > packet loss,比如5/(5+5) > 30%
### 窗口调整
**两端参数必须一致的有**:
* datashard --前向纠错
* parityshard --前向纠错
* nocomp --压缩
* key --密钥
* crypt --加密算法
其余为两边可独立设定的参数
**简易窗口自我调优方法**
> 第一步:同时在两端逐步增大client rcvwnd和server sndwnd;
> 第二步:尝试下载,观察如果带宽利用率(服务器+客户端两端都要观察)接近物理带宽则停止,否则跳转到第一步。
> 第二步:尝试下载,观察如果带宽利用率(服务器+客户端两端都要观察)到达预期则停止,否则跳转到第一步。
**注意:产生大量重传时,一定是窗口偏大了**
@@ -213,6 +225,8 @@ DSCP差分服务代码点(Differentiated Services Code Point),IETF于1998
> Reference: http://google.github.io/snappy/
压缩对于非加密,非压缩的数据能降低传输数据量,比如点对点的HTTP数据转发。
通过参数 ```-nocomp``` 在两端同时设定以关闭压缩。
> 提示: 关闭压缩可能会降低延迟。
@@ -316,7 +330,9 @@ type Snmp struct {
> 郑H立, 南东风, Li, 七七, 凌君, 昶,LesMiserables, KyOn, 噼里啪啦, 继斌, 小苍辛苦, **Ken**,
> 乔槁, 佳晨, 猪肉佬, lcx, 昊文, 冰峰, 凡, alex, **海豹叔叔**, 奥姐, 张冰, 司成,
> 武子, **慎**Alex43211**Coxxs**,荣,NeroNg,吴骁,定一
> 武子, **慎**Alex43211**Coxxs**,荣,NeroNg,吴骁,定一,我不是林JPatrick, 超, 陈,windfarer, 宇,
> 今晶,斌,晓东,最后一缕阳光,亮,Ethan,一心不乱,allenm,冬卯,GELATO,用户1Butterfly,光子曲面,
> 丞佳,捉鱼,TalonBiny,李勇,***阿彪******rinex20***Fabre,路过发光体,池子,kk
好人一生平安!
@@ -326,6 +342,7 @@ type Snmp struct {
2. https://github.com/EasyPi/openwrt-kcptun
3. https://github.com/kuoruan/luci-app-kcptun
4. https://github.com/dfdragon/kcptun_gclient
5. https://github.com/dfdragon/kcptun_xclient
### 参考资料
+13 -1
View File
@@ -12,7 +12,7 @@ fi
VERSION=`date -u +%Y%m%d`
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS="-B"
GCFLAGS=""
OSES=(linux darwin windows freebsd)
ARCHS=(amd64 386)
@@ -40,3 +40,15 @@ 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*
$MD5 kcptun-linux-arm-$VERSION.tar.gz
#MIPS32LE
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mipsle github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_mipsle github.com/xtaci/kcptun/server
env CGO_ENABLED=0 GOOS=linux GOARCH=mips go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mips github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=mips go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_mips github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_mips* server_linux_mips*;fi
tar -zcf kcptun-linux-mipsle-$VERSION.tar.gz client_linux_mipsle server_linux_mipsle
tar -zcf kcptun-linux-mips-$VERSION.tar.gz client_linux_mips server_linux_mips
$MD5 kcptun-linux-mipsle-$VERSION.tar.gz
$MD5 kcptun-linux-mips-$VERSION.tar.gz
+2
View File
@@ -29,6 +29,8 @@ type Config struct {
SockBuf int `json:"sockbuf"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
}
func parseJSONConfig(config *Config, path string) error {
+64 -17
View File
@@ -2,6 +2,8 @@ package main
import (
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"log"
"math/rand"
@@ -11,7 +13,7 @@ import (
"golang.org/x/crypto/pbkdf2"
"github.com/klauspost/compress/snappy"
"github.com/golang/snappy"
"github.com/pkg/errors"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
@@ -53,7 +55,12 @@ func newCompStream(conn net.Conn) *compStream {
return c
}
func handleClient(p1, p2 io.ReadWriteCloser) {
func handleClient(sess *smux.Session, p1 io.ReadWriteCloser) {
p2, err := sess.OpenStream()
if err != nil {
return
}
log.Println("stream opened")
defer log.Println("stream closed")
defer p1.Close()
@@ -139,16 +146,16 @@ func main() {
},
cli.IntFlag{
Name: "rcvwnd",
Value: 1024,
Value: 512,
Usage: "set receive window size(num of packets)",
},
cli.IntFlag{
Name: "datashard",
Name: "datashard,ds",
Value: 10,
Usage: "set reed-solomon erasure coding - datashard",
},
cli.IntFlag{
Name: "parityshard",
Name: "parityshard,ps",
Value: 3,
Usage: "set reed-solomon erasure coding - parityshard",
},
@@ -196,6 +203,16 @@ func main() {
Value: 10, // nat keepalive interval in seconds
Hidden: true,
},
cli.StringFlag{
Name: "snmplog",
Value: "",
Usage: "collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log",
},
cli.IntFlag{
Name: "snmpperiod",
Value: 60,
Usage: "snmp collect period, in seconds",
},
cli.StringFlag{
Name: "log",
Value: "",
@@ -231,6 +248,8 @@ func main() {
config.SockBuf = c.Int("sockbuf")
config.KeepAlive = c.Int("keepalive")
config.Log = c.String("log")
config.SnmpLog = c.String("snmplog")
config.SnmpPeriod = c.Int("snmpperiod")
if c.String("c") != "" {
err := parseJSONConfig(&config, c.String("c"))
@@ -306,6 +325,8 @@ func main() {
log.Println("keepalive:", config.KeepAlive)
log.Println("conn:", config.Conn)
log.Println("autoexpire:", config.AutoExpire)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SockBuf
@@ -371,9 +392,13 @@ func main() {
chScavenger := make(chan *smux.Session, 128)
go scavenger(chScavenger)
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
rr := uint16(0)
for {
p1, err := listener.AcceptTCP()
if err != nil {
log.Fatalln(err)
}
if err := p1.SetReadBuffer(config.SockBuf); err != nil {
log.Println("TCP SetReadBuffer:", err)
}
@@ -383,23 +408,14 @@ func main() {
checkError(err)
idx := rr % numconn
OPEN_P2:
// do auto expiration
if config.AutoExpire > 0 && time.Now().After(muxes[idx].ttl) {
// do auto expiration && reconnection
if muxes[idx].session.IsClosed() || (config.AutoExpire > 0 && time.Now().After(muxes[idx].ttl)) {
chScavenger <- muxes[idx].session
muxes[idx].session = waitConn()
muxes[idx].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
}
// do session open
p2, err := muxes[idx].session.OpenStream()
if err != nil { // mux failure
chScavenger <- muxes[idx].session
muxes[idx].session = waitConn()
muxes[idx].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
goto OPEN_P2
}
go handleClient(p1, p2)
go handleClient(muxes[idx].session, p1)
rr++
}
}
@@ -438,3 +454,34 @@ func scavenger(ch chan *smux.Session) {
}
}
}
func snmpLogger(path string, interval int) {
if path == "" || interval == 0 {
return
}
ticker := time.NewTicker(time.Duration(interval) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
f, err := os.OpenFile(time.Now().Format(path), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Println(err)
return
}
w := csv.NewWriter(f)
// write header in empty file
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
log.Println(err)
}
}
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
log.Println(err)
}
kcp.DefaultSnmp.Reset()
w.Flush()
f.Close()
}
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

+2
View File
@@ -27,6 +27,8 @@ type Config struct {
SockBuf int `json:"sockbuf"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
}
func parseJSONConfig(config *Config, path string) error {
+52 -3
View File
@@ -2,6 +2,8 @@ package main
import (
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"log"
"math/rand"
@@ -11,7 +13,7 @@ import (
"golang.org/x/crypto/pbkdf2"
"github.com/klauspost/compress/snappy"
"github.com/golang/snappy"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/smux"
@@ -165,12 +167,12 @@ func main() {
Usage: "set receive window size(num of packets)",
},
cli.IntFlag{
Name: "datashard",
Name: "datashard,ds",
Value: 10,
Usage: "set reed-solomon erasure coding - datashard",
},
cli.IntFlag{
Name: "parityshard",
Name: "parityshard,ps",
Value: 3,
Usage: "set reed-solomon erasure coding - parityshard",
},
@@ -218,6 +220,16 @@ func main() {
Value: 10, // nat keepalive interval in seconds
Hidden: true,
},
cli.StringFlag{
Name: "snmplog",
Value: "",
Usage: "collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log",
},
cli.IntFlag{
Name: "snmpperiod",
Value: 60,
Usage: "snmp collect period, in seconds",
},
cli.StringFlag{
Name: "log",
Value: "",
@@ -251,6 +263,8 @@ func main() {
config.SockBuf = c.Int("sockbuf")
config.KeepAlive = c.Int("keepalive")
config.Log = c.String("log")
config.SnmpLog = c.String("snmplog")
config.SnmpPeriod = c.Int("snmpperiod")
if c.String("c") != "" {
//Now only support json config file
@@ -322,6 +336,8 @@ func main() {
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
if err := lis.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
@@ -332,6 +348,8 @@ func main() {
if err := lis.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
for {
if conn, err := lis.AcceptKCP(); err == nil {
log.Println("remote address:", conn.RemoteAddr())
@@ -354,3 +372,34 @@ func main() {
}
myApp.Run(os.Args)
}
func snmpLogger(path string, interval int) {
if path == "" || interval == 0 {
return
}
ticker := time.NewTicker(time.Duration(interval) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
f, err := os.OpenFile(time.Now().Format(path), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Println(err)
return
}
w := csv.NewWriter(f)
// write header in empty file
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
log.Println(err)
}
}
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
log.Println(err)
}
kcp.DefaultSnmp.Reset()
w.Flush()
f.Close()
}
}
}