Compare commits

..
189 Commits
Author SHA1 Message Date
xtaciandGitHub 68b36fbf74 Update README.md 2016-10-01 09:49:36 +08:00
xtaci 9b08423b3e upd README 2016-09-27 12:36:23 +08:00
xtaci 35522d30cb upd README 2016-09-23 12:42:14 +08:00
xtaci e8e3e5a894 add -log option to redirect log , see issue #199 2016-09-22 15:20:42 +08:00
xtaci 9c95df026b lint 2016-09-20 16:16:36 +08:00
xtaci 09aea3056a block-waiting for a connection after the client has been started 2016-09-19 10:40:59 +08:00
xtaci 0788aa8260 Revert "Revert "do not panic when network is temporarily unavailable""
This reverts commit 2f479b788c.
2016-09-19 10:31:21 +08:00
xtaci 2f479b788c Revert "do not panic when network is temporarily unavailable"
This reverts commit f3f78460a4.
2016-09-18 21:00:28 +08:00
xtaci f3f78460a4 do not panic when network is temporarily unavailable 2016-09-18 20:51:35 +08:00
xtaci 3127b2d19f lint 2016-09-06 16:29:36 +08:00
xtaci 3db63cdff6 add a max ttl for session in scavenger 2016-09-03 14:32:35 +08:00
xtaci 5154cf81de api change of smux 2016-09-02 23:18:29 +08:00
xtaci cc80029b1e adjust params 2016-09-02 17:29:55 +08:00
xtaci 23d6624745 upd 2016-09-02 17:05:44 +08:00
xtaci f38f7a8ac5 scavenge only 2016-09-02 10:55:22 +08:00
xtaci e913f96f7e Merge branch 'smux' 2016-09-02 10:54:00 +08:00
xtaci 5d0d8bd74d upd 2016-09-02 10:42:23 +08:00
xtaci 4010c83e8f upd 2016-09-01 15:02:21 +08:00
xtaci 76351dff2b upd 2016-09-01 12:59:08 +08:00
xtaci 7a5807cbf5 Revert "explict close session"
This reverts commit cb0f299263.
2016-08-31 23:24:30 +08:00
xtaci 6b26c75ea5 upd 2016-08-31 21:48:43 +08:00
xtaci 0873f349c3 upd 2016-08-31 21:46:14 +08:00
xtaci 281f8675a3 upd 2016-08-31 21:33:52 +08:00
xtaci 65512e9296 upd 2016-08-31 21:31:05 +08:00
xtaci 3ea858ed90 upd 2016-08-31 21:29:27 +08:00
xtaci 5f23781fc0 scavenger 2016-08-31 21:27:19 +08:00
xtaci 2b3573f4ea Merge branch 'master' into smux 2016-08-31 18:10:48 +08:00
xtaci cb0f299263 explict close session 2016-08-31 18:07:24 +08:00
xtaci f64bc908ee upd 2016-08-31 16:30:51 +08:00
xtaci 43c6a674ef upd 2016-08-31 15:28:43 +08:00
xtaci 1a48680a55 upd 2016-08-31 15:23:31 +08:00
xtaci dbdb5293b4 branch smux 2016-08-31 11:39:56 +08:00
xtaci 94070bfcbe should continue 2016-08-30 15:34:19 +08:00
xtaciandGitHub 398a0bf9fc Merge pull request #166 from jannson/master
add support for json configuration
2016-08-30 14:56:33 +08:00
janson ff54a2dc92 better for parseJsonConfig 2016-08-30 14:44:55 +08:00
janson 747eba0ee1 add usage and check error for json config 2016-08-30 14:24:08 +08:00
janson f057cbc7f4 add support for json configuration (server side) 2016-08-30 13:50:37 +08:00
janson a83ae4bf15 add support for json configuration 2016-08-30 13:39:08 +08:00
xtaci 4d062090a7 bugfix 2016-08-30 11:17:15 +08:00
xtaci 27f76582e1 structured configuration 2016-08-29 16:06:38 +08:00
xtaci b023b542e8 handle errors gracefully 2016-08-28 10:37:09 +08:00
xtaci 9a3be067bf upd 2016-08-27 21:52:42 +08:00
xtaci 8705bd7670 upd 2016-08-27 09:17:16 +08:00
xtaci b4e5181a2f optimize retry strategy 2016-08-27 09:00:35 +08:00
xtaci 94f61b5945 upd param 2016-08-26 13:04:38 +08:00
xtaci efc0b99d21 Revert "replace yamux with muxado"
This reverts commit 3803993529.
2016-08-26 11:35:13 +08:00
xtaci 3803993529 replace yamux with muxado 2016-08-26 10:58:43 +08:00
xtaci d23ff7c351 upd 2016-08-25 20:34:33 +08:00
xtaci f383ee31a5 add autoexpire option 2016-08-25 20:33:04 +08:00
xtaci d399f220f0 remove a line 2016-08-25 20:04:34 +08:00
xtaci 59a1bbc7b8 SetFinalizer to session 2016-08-25 18:22:20 +08:00
xtaci 3b656e101f better api 2016-08-25 11:46:17 +08:00
xtaci aec364eb72 set tcp socket buffer 2016-08-24 12:27:33 +08:00
xtaci e26ab6729f spelling 2016-08-22 14:46:57 +08:00
xtaci 583fe3ba24 simple layer 2016-08-21 19:09:08 +08:00
xtaci 7fd6442284 refer to my fork 2016-08-20 21:15:05 +08:00
xtaci 81f4643830 Revert "refer to fork"
This reverts commit 744a6407e7.
2016-08-20 20:49:44 +08:00
xtaci 744a6407e7 refer to fork 2016-08-20 20:23:04 +08:00
xtaci 2cf5292ac1 revert yamux config 2016-08-20 18:37:52 +08:00
xtaci b3a8b631b4 upd README 2016-08-20 16:48:10 +08:00
xtaci 1167419210 add salsa20, xtea crypto 2016-08-20 15:02:25 +08:00
xtaci 56f9f0d01a Merge branch 'master' of https://github.com/xtaci/kcptun 2016-08-20 13:39:01 +08:00
xtaci 96888f1cac pisces 2016-08-20 13:35:27 +08:00
xtaciandGitHub e752d70c79 Update README.en.md 2016-08-20 10:47:59 +08:00
xtaciandGitHub a882b94e5b Update README.md 2016-08-20 10:46:34 +08:00
xtaciandGitHub 790a6d5352 Update README.en.md 2016-08-19 21:21:03 +08:00
xtaciandGitHub 603c2db5ab Update README.md 2016-08-19 21:20:15 +08:00
xtaci 581df3a34d update README.md 2016-08-19 15:00:25 +08:00
xtaci 6113d2b497 update README.md 2016-08-19 14:27:13 +08:00
xtaci d3b8a4d71d keep compatiability 2016-08-19 13:17:02 +08:00
xtaci 1f0a4a2c2f change default settings 2016-08-19 12:31:51 +08:00
xtaci 75923fb08f adjust -help 2016-08-19 12:22:36 +08:00
xtaci 0243422885 add supports for blowfish, cast5, 3des 2016-08-19 11:15:13 +08:00
xtaci 6374cb0d36 Merge branch 'master' of https://github.com/xtaci/kcptun 2016-08-18 23:44:25 +08:00
xtaci 0aedc21c50 Revert "change default resend from 2 -> 3"
This reverts commit 003617186b.
2016-08-18 23:40:51 +08:00
xtaciandGitHub 727887517f Update README.en.md 2016-08-18 10:56:46 +08:00
xtaciandGitHub 7b81b24e8d Update README.md 2016-08-18 10:55:55 +08:00
xtaci ba22434379 experimental Bounds Checking Elimination 2016-08-18 09:51:17 +08:00
xtaci 003617186b change default resend from 2 -> 3 2016-08-17 21:07:27 +08:00
xtaciandGitHub b9ce27cb3e Update README.en.md 2016-08-17 11:33:53 +08:00
xtaciandGitHub c93a199823 Update README.md 2016-08-17 11:32:58 +08:00
xtaci bb34894947 upd issue 2016-08-17 11:26:35 +08:00
xtaci f743a075c5 upd 2016-08-17 11:22:09 +08:00
xtaci a04c959c9c add aes-128 aes-192 cipher 2016-08-16 16:46:27 +08:00
xtaci 4a79d26d35 upd README.md 2016-08-16 10:31:37 +08:00
xtaci 8104d18959 Revert "add manual GC support"
This reverts commit ae699f498c.
2016-08-15 21:34:43 +08:00
xtaci ae699f498c add manual GC support 2016-08-15 20:28:15 +08:00
xtaci dbdd79f1d6 upd 2016-08-15 14:04:45 +08:00
xtaciandGitHub 51bdedb1b3 Update README.md 2016-08-15 14:03:48 +08:00
xtaci 8ea071fa03 upd README 2016-08-15 10:23:47 +08:00
xtaciandGitHub f74201a410 Update ISSUE_TEMPLATE 2016-08-14 18:34:32 +08:00
xtaci 96622bcfc0 add issue template 2016-08-12 10:27:17 +08:00
xtaciandGitHub 29328b375a Update README.md 2016-08-11 21:02:21 +08:00
xtaciandGitHub db7f1def1b Update README.en.md 2016-08-11 20:50:48 +08:00
xtaciandGitHub 628e723167 Update README.md 2016-08-11 20:48:48 +08:00
xtaci ff393ccacb revert part of the PR 2016-08-11 14:47:43 +08:00
xtaciandGitHub 1bb61dbcfc Merge pull request #113 from buaazp/yamux-optimize
*: some optimizes for yamux cache and config
2016-08-11 14:38:05 +08:00
招牌疯子 0b1598d09f *: yamux optimizes for cache and config
and debug log flags when selfbuild.
2016-08-11 14:23:44 +08:00
xtaci 0552bebe46 upd 2016-08-11 13:29:01 +08:00
xtaci d158e6df3f set stream max windows size to sockbuff 2016-08-11 13:20:03 +08:00
xtaciandGitHub cf7bca5cb7 Update README.md 2016-08-11 10:05:05 +08:00
xtaciandGitHub 99a2b60c7d Update README.md 2016-08-11 10:04:25 +08:00
xtaciandGitHub 4a5024b361 Update README.md 2016-08-11 10:04:02 +08:00
xtaciandGitHub 12bd3853d5 Update README.en.md 2016-08-10 10:31:05 +08:00
xtaciandGitHub 7992b87889 Update README.md 2016-08-10 10:30:17 +08:00
xtaciandGitHub cfcc2e0676 Update README.en.md 2016-08-09 15:52:45 +08:00
xtaciandGitHub 1e870f02af Update README.md 2016-08-09 14:08:22 +08:00
xtaci bf2abf14e7 change default socket buffer to 4MB(macOS default limit) 2016-08-08 10:50:46 +08:00
xtaci 2df3e6c438 optimize API 2016-08-08 10:41:42 +08:00
xtaciandGitHub ba4c93c3f5 Update README.md 2016-08-07 21:00:52 +08:00
xtaciandGitHub bc22f46065 Merge pull request #97 from buaazp/master
optmize cli flags for accept callback
2016-08-07 19:45:01 +08:00
招牌疯子 3fc15de95d optmize cli flags for accept callback
And use custom kcp package name for godef.
2016-08-07 14:09:58 +08:00
xtaci 6f9449bb10 rename api 2016-08-06 11:21:20 +08:00
xtaci c6cbfd307e change ping -> keepalive for nat keep-alive 2016-08-06 10:19:13 +08:00
xtaci d68792cb1a add hidden parameters -- ping 2016-08-05 22:46:11 +08:00
xtaci 117edce137 upd kcp-go api 2016-08-05 17:06:57 +08:00
xtaciandGitHub 990a5f7f87 Update README.md 2016-08-02 14:24:42 +08:00
xtaciandGitHub 19d7d74d59 Add files via upload 2016-08-01 12:44:41 +08:00
xtaci 31afe325ad Merge branch 'master' of https://github.com/xtaci/kcptun 2016-07-29 10:17:33 +08:00
xtaci ab7519c2d6 remove one unnecessary line 2016-07-29 10:17:14 +08:00
xtaciandGitHub d6da2e1ead Update README.en.md 2016-07-27 13:51:13 +08:00
xtaciandGitHub 4d5a3dd791 Update README.md 2016-07-27 13:49:01 +08:00
xtaciandGitHub 4a46d696b6 Update README.md 2016-07-27 13:41:31 +08:00
xtaciandGitHub 33d50dcd45 Update README.en.md 2016-07-26 23:26:23 +08:00
xtaciandGitHub 2b3f6dbabe Update README.md 2016-07-26 23:25:15 +08:00
xtaciandGitHub 448717fa1c Update README.md 2016-07-26 21:40:17 +08:00
xtaciandGitHub 887fba3381 Update README.md 2016-07-26 21:33:52 +08:00
xtaciandGitHub fb62d45df8 Update README.en.md 2016-07-26 16:10:29 +08:00
xtaciandGitHub cd1e2b4ff7 Update README.md 2016-07-26 16:09:08 +08:00
xtaci 5ee659dd41 improve network latency by introducing stream mode 2016-07-25 20:14:12 +08:00
xtaciandGitHub 1a596f55f4 Update README.en.md 2016-07-24 16:18:28 +08:00
xtaciandGitHub 889a904dca Update README.md 2016-07-24 16:18:09 +08:00
xtaciandGitHub 172dcf6481 Update README.en.md 2016-07-24 16:16:34 +08:00
xtaciandGitHub ff92c70b40 Add files via upload 2016-07-24 16:15:22 +08:00
xtaciandGitHub af1d28ae5a Update README.md 2016-07-24 16:09:06 +08:00
xtaciandGitHub 4a7d143c69 Update README.en.md 2016-07-24 16:04:58 +08:00
xtaciandGitHub 7ff69f16d5 Update README.md 2016-07-24 16:03:48 +08:00
xtaciandGitHub 7eb037c4dd Update README.md 2016-07-24 16:00:53 +08:00
xtaciandGitHub a87f6af812 Add files via upload 2016-07-24 15:58:35 +08:00
xtaciandGitHub 7574f9bfd3 Update README.md 2016-07-24 09:23:47 +08:00
xtaci d5b5cf683b update Dockerfile 2016-07-23 11:30:37 +08:00
xtaci fded353b68 update Dockerfile 2016-07-23 11:23:18 +08:00
xtaci 832dbed064 Merge branch 'master' of https://github.com/xtaci/kcptun 2016-07-23 11:18:48 +08:00
xtaci 4b660fa02c update 2016-07-23 11:18:29 +08:00
xtaciandGitHub 59e6ebee05 Update README.md 2016-07-23 11:10:55 +08:00
xtaciandGitHub c1a895426d Update README.md 2016-07-23 10:49:21 +08:00
xtaci ebdcc9ae8a Merge branch 'master' of https://github.com/xtaci/kcptun 2016-07-22 21:41:24 +08:00
xtaci 2c076f7a34 update Dockerfile to alpine 2016-07-22 21:25:29 +08:00
Daniel FuandGitHub a1a0fbd060 Update README.md 2016-07-21 20:25:43 +08:00
Daniel FuandGitHub bc4214e4a8 Update README.md 2016-07-21 12:27:00 +08:00
Daniel FuandGitHub 61e6dfe87b Update README.md 2016-07-21 12:26:00 +08:00
Daniel FuandGitHub 4448a2658d Add files via upload 2016-07-20 14:53:01 +08:00
Daniel FuandGitHub c9a312f12b Update README.md 2016-07-18 11:04:47 +08:00
Daniel FuandGitHub 2bb48495d3 Update README.md 2016-07-18 11:03:30 +08:00
Daniel FuandGitHub 06f0a6f80b Update README.md 2016-07-18 11:01:21 +08:00
Daniel FuandGitHub ea895ad824 Update README.md 2016-07-18 10:52:37 +08:00
Daniel FuandGitHub a72bf0c9b5 Update README.md 2016-07-18 10:32:22 +08:00
xtaci 2b83dbda07 hide acknodelay parameters 2016-07-16 22:57:03 +08:00
xtaci c35ef339af fix urfave deprecated action signature 2016-07-14 10:01:35 +08:00
xtaci c96d4b534e Merge branch 'master' of https://github.com/xtaci/kcptun 2016-07-12 12:35:54 +08:00
xtaci 6216049c14 force CGO_ENABLED=0 2016-07-12 12:35:23 +08:00
Daniel FuandGitHub 0d98020e59 Update README.md 2016-07-12 11:32:42 +08:00
Daniel FuandGitHub 14ea6f8a71 Update README.md 2016-07-11 17:23:00 +08:00
Daniel FuandGitHub 214669eaf9 Update README.md 2016-07-11 17:15:15 +08:00
Daniel FuandGitHub 48d2cad6ac Update README.en.md 2016-07-11 17:14:04 +08:00
Daniel FuandGitHub 67cd5a4e22 Update README.md 2016-07-11 17:06:34 +08:00
Daniel FuandGitHub f49392c95e Update README.md 2016-07-11 17:03:18 +08:00
Daniel FuandGitHub 4c9370a252 Update README.en.md 2016-07-07 11:07:42 +08:00
Daniel FuandGitHub ef3cf3d982 Update README.en.md 2016-07-07 11:03:49 +08:00
Daniel FuandGitHub 8e5f405336 Update README.md 2016-07-07 10:52:50 +08:00
Daniel FuandGitHub 2aa6887860 Update README.md 2016-07-07 10:37:27 +08:00
Daniel FuandGitHub 9d13ec9350 Update README.md 2016-07-06 21:31:55 +08:00
Daniel FuandGitHub ef9d08567f Update README.md 2016-07-06 21:26:30 +08:00
Daniel FuandGitHub 66ebcf2773 Update README.md 2016-07-06 21:18:52 +08:00
Daniel FuandGitHub 67a08b43ed Update README.md 2016-07-06 21:15:36 +08:00
Daniel FuandGitHub 46ce8a2e51 Update README.md 2016-07-06 21:12:34 +08:00
Daniel FuandGitHub fd6a6e4a64 Update README.md 2016-07-06 19:18:55 +08:00
Daniel FuandGitHub 1de3c1fa8a Update README.md 2016-07-05 22:31:08 +08:00
Daniel FuandGitHub cc821b6eaf Update README.en.md 2016-07-05 22:30:25 +08:00
xtaci 6f8ce90c23 add english readme 2016-07-05 22:25:36 +08:00
Daniel FuandGitHub 32be3e836b Update README.md 2016-07-05 21:46:37 +08:00
Daniel FuandGitHub 664a79e488 Update README.md 2016-07-05 14:12:33 +08:00
Daniel FuandGitHub 74d874b0db Update README.md 2016-07-04 11:37:58 +08:00
Daniel FuandGitHub 58874784f3 Add files via upload 2016-07-04 11:36:24 +08:00
Daniel FuandGitHub f92bae1d03 Update README.md 2016-07-04 11:35:35 +08:00
Daniel FuandGitHub a1aa89ea1c Update README.md 2016-07-02 17:04:35 +08:00
Daniel FuandGitHub 52c75f68ba Update README.md 2016-07-02 11:11:35 +08:00
Daniel FuandGitHub 57fce73ca6 Update README.md 2016-07-02 09:52:18 +08:00
xtaci 13e980cdff lint 2016-06-30 14:45:26 +08:00
19 changed files with 514 additions and 533 deletions
-14
View File
@@ -1,15 +1,3 @@
问问题前先搜索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.
@@ -23,5 +11,3 @@ 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**?
+1 -3
View File
@@ -1,8 +1,6 @@
language: go
go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.6
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 B

+2 -5
View File
@@ -1,11 +1,8 @@
FROM golang:alpine as builder
FROM golang:alpine
MAINTAINER xtaci <daniel820313@gmail.com>
RUN apk update && \
apk upgrade && \
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
COPY --from=builder /go/bin /bin
RUN go get github.com/xtaci/kcptun/client && go get github.com/xtaci/kcptun/server
EXPOSE 29900/udp
EXPOSE 12948
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

+244
View File
@@ -0,0 +1,244 @@
# <img src="logo.png" alt="kcptun" height="60px" />
[![Release][13]][14] [![Powered][17]][18] [![MIT licensed][11]][12] [![Build Status][3]][4] [![Go Report Card][5]][6] [![Downloads][15]][16] [![Gitter][19]][20] [![Docker][1]][2]
[1]: https://images.microbadger.com/badges/image/xtaci/kcptun.svg
[2]: https://microbadger.com/images/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
[9]: https://img.shields.io/github/stars/xtaci/kcptun.svg
[10]: https://github.com/xtaci/kcptun/stargazers
[11]: https://img.shields.io/badge/license-MIT-blue.svg
[12]: LICENSE.md
[13]: https://img.shields.io/github/release/xtaci/kcptun.svg
[14]: https://github.com/xtaci/kcptun/releases/latest
[15]: https://img.shields.io/github/downloads/xtaci/kcptun/total.svg?maxAge=1800
[16]: https://github.com/xtaci/kcptun/releases
[17]: https://img.shields.io/badge/KCP-Powered-blue.svg
[18]: https://github.com/skywind3000/kcp
[19]: https://badges.gitter.im/xtaci/kcptun.svg
[20]: https://gitter.im/xtaci/kcptun?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
A tool for converting tcp stream into kcp+udp stream, :zap: ***[download address](https://github.com/xtaci/kcptun/releases/latest)***:zap:
![kcptun](kcptun.png)
***kcptun is based on [kcp-go](https://github.com/xtaci/kcp-go)***
### *QuickStart* :lollipop:
```
Server Side: ./server_linux_amd64 -t "127.0.0.1:1080" -l ":4000" -mode fast2 // forwarding to local port 1080
Client Side: ./client_darwin_amd64 -r "SERVERIP:4000" -l ":1080" -mode fast2 // listening on port 1080
```
### *Performance* :lollipop:
<img src="fast.png" alt="fast.com" height="256px" />
* Speed tested with: https://fast.com
* WAN Link Speed: 100M ADSL
* WIFI: 5GHz TL-WDR3320
### *Usage* :lollipop:
Help output under MacOS X:
```
$ ./client_darwin_amd64 -h
NAME:
kcptun - client(with SMUX)
USAGE:
client_darwin_amd64 [global options] command [command options] [arguments...]
VERSION:
20160922
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--localaddr value, -l value local listen address (default: ":12948")
--remoteaddr value, -r value kcp server address (default: "vps:29900")
--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, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--conn value set num of UDP connections to server (default: 1)
--autoexpire value set auto expiration time(in seconds) for a single UDP connection, 0 to disable (default: 0)
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 128)
--rcvwnd value set receive window size(num of packets) (default: 1024)
--datashard value set reed-solomon erasure coding - datashard (default: 10)
--parityshard value set reed-solomon erasure coding - parityshard (default: 3)
--dscp value set DSCP(6bit) (default: 0)
--nocomp disable compression
--log value specify a log file to output, default goes to stderr
-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
NAME:
kcptun - server(with SMUX)
USAGE:
server_darwin_amd64 [global options] command [command options] [arguments...]
VERSION:
20160922
COMMANDS:
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")
--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, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 1024)
--rcvwnd value set receive window size(num of packets) (default: 1024)
--datashard value set reed-solomon erasure coding - datashard (default: 10)
--parityshard value set reed-solomon erasure coding - parityshard (default: 3)
--dscp value set DSCP(6bit) (default: 0)
--nocomp disable compression
--log value specify a log file to output, default goes to stderr
-c value config from json file, which will override the command from shell
--help, -h show help
--version, -v print the version
```
### *Applications* :lollipop:
1. Real-time gaming.
2. Cross-ISP data exchange in PRC.
3. Other lossy network.
### *Parameters* :lollipop:
***Both sides must agree on the following parameters:***
* datashard
* parityshard
* nocomp
* key
* crypt
other parameters can be set independently.
*How to optimize*
> Step 1Increase client rcvwnd & server sndwnd simultaneously & gradually。
> Step 2Try download something and observer, if the bandwidth usage is close the limit then stop, otherwise goto step 1.
***NOTICE: if too much retranmission happens, it's quite possible the windows are too large***
### *Security* :lollipop:
No matter what encryption you are using for application layer, if you specify ```-crypt none``` to kcptun,
the header will be ***PLAINTEXT*** to everyone; I suggest ```-crypt aes-128``` for encryption at least .
NOTICE: ```-crypt xor``` is also insecure, do not use this unless you know what you are doing.
### *Memory Control* :lollipop:
Routers, mobile devices are sensitive to memory consumption; by setting GOGC environment(eg: GOGC=20) will lower memory consumption.
Reference: https://blog.golang.org/go15gc
### *Traffic Control* :lollipop:
***Intended audience : for those server's bandwidth is quite limited.***
Example: To limit outgoing bandwidth to 32mbit/s on server.
```
root@kcptun:~# cat tc.sh
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:1 htb rate 32mbit
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 10 fw flowid 1:1
iptables -t mangle -A POSTROUTING -o eth0 -j MARK --set-mark 10
root@kcptun:~#
```
### *DSCP* :lollipop:
Differentiated services or DiffServ is a computer networking architecture that specifies a simple, scalable and coarse-grained mechanism for classifying and managing network traffic and providing quality of service (QoS) on modern IP networks. DiffServ can, for example, be used to provide low-latency to critical network traffic such as voice or streaming media while providing simple best-effort service to non-critical services such as web traffic or file transfers.
DiffServ uses a 6-bit differentiated services code point (DSCP) in the 8-bit differentiated services field (DS field) in the IP header for packet classification purposes. The DS field and ECN field replace the outdated IPv4 TOS field.[1]
setting each side with ```-dscp value```.
### *Embeded Mode* :lollipop:
Latency:
*fast3 >* ***[fast2]*** *> fast > normal > default*
Payload Ratio:
*default > normal > fast >* ***[fast2]*** *> fast3*
Parameters in middle is balanced for latency & payload ratio, the faster you get the more wasteful you are.
Manual control is supported with hidden parameters, you must understand KCP protocol before doing this.
```
-mode manual -nodelay 1 -resend 2 -nc 1 -interval 20
```
I suggest fast2 for high-loss network, normal for low-loss network.
### *Forward Error Correction* :lollipop:
In coding theory, the ReedSolomon code belongs to the class of non-binary cyclic error-correcting codes. The ReedSolomon code is based on univariate polynomials over finite fields.
It is able to detect and correct multiple symbol errors. By adding t check symbols to the data, a ReedSolomon code can detect any combination of up to t erroneous symbols, or correct up to ⌊t/2⌋ symbols. As an erasure code, it can correct up to t known erasures, or it can detect and correct combinations of errors and erasures. Furthermore, ReedSolomon codes are suitable as multiple-burst bit-error correcting codes, since a sequence of b + 1 consecutive bit errors can affect at most two symbols of size b. The choice of t is up to the designer of the code, and may be selected within wide limits.
![reed-solomon](rs.png)
Setting parameters of RS-Code with ```-datashard 10 -parityshard 3```
### *Snappy Stream Compression* :lollipop:
> Snappy is a compression/decompression library. It does not aim for maximum
> compression, or compatibility with any other compression library; instead,
> it aims for very high speeds and reasonable compression. For instance,
> compared to the fastest mode of zlib, Snappy is an order of magnitude faster
> for most inputs, but the resulting compressed files are anywhere from 20% to
> 100% bigger.
> Reference: http://google.github.io/snappy/
disable compression by setting ```-nocomp``` on both side.
> Tips: Turning off compression may reduce latency.
### *SNMP* :lollipop:
```go
// Snmp defines network statistics indicator
type Snmp struct {
BytesSent uint64 // payload bytes sent
BytesReceived uint64
MaxConn uint64
ActiveOpens uint64
PassiveOpens uint64
CurrEstab uint64
InErrs uint64
InCsumErrors uint64 // checksum errors
InSegs uint64
OutSegs uint64
OutBytes uint64 // udp bytes sent
RetransSegs uint64
FastRetransSegs uint64
EarlyRetransSegs uint64
LostSegs uint64
RepeatSegs uint64
FECRecovered uint64
FECErrs uint64
FECSegs uint64 // fec segments received
}
```
Sending a signal by ```kill -SIGUSR1 pid``` will give SNMP information for KCPuseful for fine-grained adjustment.
Of which ```RetransSegs,FastRetransSegs,LostSegs,OutSegs``` is the most useful.
### *Donations* :dollar:
![donate](donate.png)
Best wishes to you all.
### *References* :paperclip:
1. https://github.com/skywind3000/kcp -- KCP - A Fast and Reliable ARQ Protocol.
2. https://github.com/klauspost/reedsolomon -- Reed-Solomon Erasure Coding in Go.
3. https://en.wikipedia.org/wiki/Differentiated_services -- DSCP.
4. http://google.github.io/snappy/ -- A fast compressor/decompressor.
5. https://www.backblaze.com/blog/reed-solomon/ -- Reed-Solomon Explained.
6. http://www.qualcomm.cn/products/raptorq -- RaptorQ Forward Error Correction Scheme for Object Delivery.
7. https://en.wikipedia.org/wiki/PBKDF2 -- Key stretching.
8. http://blog.appcanary.com/2016/encrypt-or-compress.html -- Should you encrypt or compress first?
9. https://github.com/hashicorp/yamux -- Connection multiplexing library.
10. https://tools.ietf.org/html/rfc6937 -- Proportional Rate Reduction for TCP.
11. https://tools.ietf.org/html/rfc5827 -- Early Retransmit for TCP and Stream Control Transmission Protocol (SCTP).
12. http://http2.github.io/ -- What is HTTP/2?
13. http://www.lartc.org/ -- Linux Advanced Routing & Traffic Control
+184 -259
View File
@@ -1,7 +1,5 @@
# <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]
# <img src="logo.png" alt="kcptun" height="60px" />
[![Release][13]][14] [![Powered][17]][18] [![MIT licensed][11]][12] [![Build Status][3]][4] [![Go Report Card][5]][6] [![Downloads][15]][16] [![Gitter][19]][20] [![Docker][1]][2]
[1]: https://images.microbadger.com/badges/image/xtaci/kcptun.svg
[2]: https://microbadger.com/images/xtaci/kcptun
[3]: https://travis-ci.org/xtaci/kcptun.svg?branch=master
@@ -18,93 +16,28 @@
[16]: https://github.com/xtaci/kcptun/releases
[17]: https://img.shields.io/badge/KCP-Powered-blue.svg
[18]: https://github.com/skywind3000/kcp
[19]: https://badges.gitter.im/xtaci/kcptun.svg
[20]: https://gitter.im/xtaci/kcptun?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
<img src="kcptun.png" alt="kcptun" height="300px"/>
> *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.*
> *KCP discussion QQ group: 364933586, KCP integration, tuning, network transmission and related technical discussions.*
### QuickStart
Increase the number of open files on your server, as:
`ulimit -n 65535`, or write it in `~/.bashrc`.
Suggested `sysctl.conf` parameters for better handling of UDP packets:
***[kcp-go](https://github.com/xtaci/kcp-go)协议测试小工具 :zap: [官方下载地址](https://github.com/xtaci/kcptun/releases/latest):zap:***
![kcptun](kcptun.png)
[English Readme](README.en.md)
### *快速设定* :lollipop:
```
net.core.rmem_max=26214400
net.core.rmem_default=26214400
net.core.wmem_max=26214400
net.core.wmem_default=26214400
net.core.netdev_max_backlog=2048
服务器: ./server_linux_amd64 -t "127.0.0.1:8388" -l ":4000" -mode fast2 // 转发到服务器的本地8388端口
客户端: ./client_darwin_amd64 -r "服务器IP地址:4000" -l ":8388" -mode fast2 // 监听客户端的本地8388端口
注: 服务器端需要有服务监听8388端口
```
You can also increase the per-socket buffer by adding parameter(default 4MB):
```
-sockbuf 16777217
```
increasing this would work for most of the old model CPUs.
Download a corresponding one from precompiled [Releases](https://github.com/xtaci/kcptun/releases).
```
KCP Client: ./client_darwin_amd64 -r "KCP_SERVER_IP:4000" -l ":8388" -mode fast2
KCP Server: ./server_linux_amd64 -t "TARGET_IP:8388" -l ":4000" -mode fast2
```
The above commands will establish port forwarding channel for 8388/tcp as:
> Application -> **KCP Client(8388/tcp) -> KCP Server(4000/udp)** -> Target Server(8388/tcp)
which tunnels the original connection:
> Application -> Target Server(8388/tcp)
### Install from source
```
$go get -u github.com/xtaci/kcptun/...
```
All precompiled releases are genereated from `build-release.sh` script.
### Performance
### *速度对比* :lollipop:
<img src="fast.png" alt="fast.com" height="256px" />
* 测速网站: https://fast.com
* 接入: 100M ADSL
* WIFI: 5GHz TL-WDR3320
### Basic Tuning Guide
#### Improving Thoughput
> **Q: I have a high speed network link, how to reach the maximum bandwidth?**
> **A:** Increase `-rcvwnd` on KCP Client and `-sndwnd` on KCP Server **simultaneously & gradually**, the mininum one decides the maximum transfer rate of the link, as `wnd * mtu / rtt`; Then try downloading something and to see if it meets your requirements.
(mtu is adjustable by `-mtu`)
#### Improving Latency
> **Q: I'm using kcptun for game, I don't want any lag happening.**
> **A:** Lag means packet loss for most of the time, lags can be improved by changing `-mode`.
> eg: `-mode fast3`
> Aggresiveness/Responsiveness on retransmission for embeded modes are:
> *fast3 > fast2 > fast > normal > default*
### Expert Tuning Guide
#### Overview
<p align="left"><img src="layeredparams.png" alt="params" height="450px"/></p>
#### Usage
### *使用方法* :lollipop:
在Mac OS X El Capitan下的帮助输出:
```
$ ./client_darwin_amd64 -h
NAME:
@@ -114,36 +47,30 @@ USAGE:
client_darwin_amd64 [global options] command [command options] [arguments...]
VERSION:
20180922
20160922
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--localaddr value, -l value local listen address (default: ":12948")
--remoteaddr value, -r value kcp server address (default: "vps:29900")
--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")
--conn value set num of UDP connections to server (default: 1)
--autoexpire value set auto expiration time(in seconds) for a single UDP connection, 0 to disable (default: 0)
--scavengettl value set how long an expired connection can live(in sec), -1 to disable (default: 600)
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 128)
--rcvwnd value set receive window size(num of packets) (default: 512)
--datashard value, --ds value set reed-solomon erasure coding - datashard (default: 10)
--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)
--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
-c value config from json file, which will override the command from shell
--help, -h show help
--version, -v print the version
--localaddr value, -l value local listen address (default: ":12948")
--remoteaddr value, -r value kcp server address (default: "vps:29900")
--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, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--conn value set num of UDP connections to server (default: 1)
--autoexpire value set auto expiration time(in seconds) for a single UDP connection, 0 to disable (default: 0)
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 128)
--rcvwnd value set receive window size(num of packets) (default: 1024)
--datashard value set reed-solomon erasure coding - datashard (default: 10)
--parityshard value set reed-solomon erasure coding - parityshard (default: 3)
--dscp value set DSCP(6bit) (default: 0)
--nocomp disable compression
--log value specify a log file to output, default goes to stderr
-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
NAME:
@@ -153,114 +80,115 @@ USAGE:
server_darwin_amd64 [global options] command [command options] [arguments...]
VERSION:
20180922
20160922
COMMANDS:
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")
--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")
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 1024)
--rcvwnd value set receive window size(num of packets) (default: 1024)
--datashard value, --ds value set reed-solomon erasure coding - datashard (default: 10)
--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)
--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
-c value config from json file, which will override the command from shell
--help, -h show help
--version, -v print the version
--listen value, -l value kcp server listen address (default: ":29900")
--target value, -t value target server address (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, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--mtu value set maximum transmission unit for UDP packets (default: 1350)
--sndwnd value set send window size(num of packets) (default: 1024)
--rcvwnd value set receive window size(num of packets) (default: 1024)
--datashard value set reed-solomon erasure coding - datashard (default: 10)
--parityshard value set reed-solomon erasure coding - parityshard (default: 3)
--dscp value set DSCP(6bit) (default: 0)
--nocomp disable compression
--log value specify a log file to output, default goes to stderr
-c value config from json file, which will override the command from shell
--help, -h show help
--version, -v print the version
```
#### Forward Error Correction
### *参数调整* :lollipop:
***两端参数必须一致的有:***
* datashard
* parityshard
* nocomp
* key
* crypt
In coding theory, the [ReedSolomon code](https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction) belongs to the class of non-binary cyclic error-correcting codes. The ReedSolomon code is based on univariate polynomials over finite fields.
其余为两边可独立设定的参数
It is able to detect and correct multiple symbol errors. By adding t check symbols to the data, a ReedSolomon code can detect any combination of up to t erroneous symbols, or correct up to ⌊t/2⌋ symbols. As an erasure code, it can correct up to t known erasures, or it can detect and correct combinations of errors and erasures. Furthermore, ReedSolomon codes are suitable as multiple-burst bit-error correcting codes, since a sequence of b + 1 consecutive bit errors can affect at most two symbols of size b. The choice of t is up to the designer of the code, and may be selected within wide limits.
*简易自我调优方法*
> 第一步:同时在两端逐步增大client rcvwnd和server sndwnd;
> 第二步:尝试下载,观察如果带宽利用率(服务器+客户端两端都要观察)接近物理带宽则停止,否则跳转到第一步。
![FED](FEC.png)
Setting parameters of RS-Code with ```-datashard m -parityshard n``` on **BOTH** KCP Client & KCP Server **MUST** be **IDENTICAL**.
#### DSCP
Differentiated services or DiffServ is a computer networking architecture that specifies a simple, scalable and coarse-grained mechanism for classifying and managing network traffic and providing quality of service (QoS) on modern IP networks. DiffServ can, for example, be used to provide low-latency to critical network traffic such as voice or streaming media while providing simple best-effort service to non-critical services such as web traffic or file transfers.
DiffServ uses a 6-bit differentiated services code point (DSCP) in the 8-bit differentiated services field (DS field) in the IP header for packet classification purposes. The DS field and ECN field replace the outdated IPv4 TOS field.
setting each side with ```-dscp value```, Here are some [Commonly used DSCP values](https://en.wikipedia.org/wiki/Differentiated_services#Commonly_used_DSCP_values).
#### Cryptanalysis
kcptun is shipped with builtin packet encryption powered by various block encryption algorithms and works in [Cipher Feedback Mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_(CFB)), for each packet to be sent, the encryption process will start from encrypting a [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) from the [system entropy](https://en.wikipedia.org/wiki//dev/random), so encryption to same plaintexts never leads to a same ciphertexts thereafter.
The contents of the packets are completely anonymous with encryption, including the headers(FEC,KCP), checksums and contents. Note that, no matter which encryption method you choose on you upper layer, if you disable encryption by specifying `-crypt none` to kcptun, the transmit will be insecure somehow, since the header is ***PLAINTEXT*** to everyone it would be susceptible to header tampering, such as jamming the *sliding window size*, *round-trip time*, *FEC property* and *checksums*. ```aes-128``` is suggested for minimal encryption since modern CPUs are shipped with [AES-NI](https://en.wikipedia.org/wiki/AES_instruction_set) instructions and performs even better than `salsa20`(check the table below).
Other possible attacks to kcptun includes: a) [traffic analysis](https://en.wikipedia.org/wiki/Traffic_analysis), dataflow on specific websites may have pattern while interchanging data, but this type of eavesdropping has been mitigated by adapting [smux](https://github.com/xtaci/smux) to mix data streams so as to introduce noises, perfect solution to this has not appeared yet, theroretically by shuffling/mixing messages on larger scale network may mitigate this problem. b) [replay attack](https://en.wikipedia.org/wiki/Replay_attack), since the asymmetrical encryption has not been introduced into kcptun for some reason, capturing the packets and replay them on a different machine is possible, (notice: hijacking the session and decrypting the contents is still *impossible*), so upper layers should contain a asymmetrical encryption system to guarantee the authenticity of each message(to process message exactly once), such as HTTPS/OpenSSL/LibreSSL, only by signing the requests with private keys can eliminate this type of attack.
Important:
1. `-crypt` and `-key` must be the same on both KCP Client & KCP Server.
2. `-crypt xor` is also insecure and vulnerable to [known-plaintext attack](https://en.wikipedia.org/wiki/Known-plaintext_attack), do not use this unless you know what you are doing. (*cryptanalysis note: any type of [counter mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)) is insecure in packet encryption due to the shorten of counter period and leads to iv/nonce collision*)
Benchmarks for crypto algorithms supported by kcptun:
***注意:产生大量重传时,一定是窗口偏大了***
*带宽计算公式*
```
BenchmarkSM4-4 50000 32087 ns/op 93.49 MB/s 0 B/op 0 allocs/op
BenchmarkAES128-4 500000 3274 ns/op 916.15 MB/s 0 B/op 0 allocs/op
BenchmarkAES192-4 500000 3587 ns/op 836.34 MB/s 0 B/op 0 allocs/op
BenchmarkAES256-4 300000 3828 ns/op 783.60 MB/s 0 B/op 0 allocs/op
BenchmarkTEA-4 100000 15359 ns/op 195.32 MB/s 0 B/op 0 allocs/op
BenchmarkXOR-4 20000000 90.2 ns/op 33249.02 MB/s 0 B/op 0 allocs/op
BenchmarkBlowfish-4 50000 26885 ns/op 111.58 MB/s 0 B/op 0 allocs/op
BenchmarkNone-4 30000000 45.8 ns/op 65557.11 MB/s 0 B/op 0 allocs/op
BenchmarkCast5-4 50000 34370 ns/op 87.29 MB/s 0 B/op 0 allocs/op
Benchmark3DES-4 10000 117893 ns/op 25.45 MB/s 0 B/op 0 allocs/op
BenchmarkTwofish-4 50000 33477 ns/op 89.61 MB/s 0 B/op 0 allocs/op
BenchmarkXTEA-4 30000 45825 ns/op 65.47 MB/s 0 B/op 0 allocs/op
BenchmarkSalsa20-4 500000 3282 ns/op 913.90 MB/s 0 B/op 0 allocs/op
在不丢包的情况下,有最大-rcvwnd 个数据包在网络上正在向你传输,以平均数据包大小avgsize计算,在任意时刻,有:
network_cap = rcvwnd*avgsize
数据流向你,这个值再除以ping值(rtt),等于最大带宽使用量。
max_bandwidth = network_cap/rtt = rcvwnd*avgsize/rtt
举例,设rcvwnd = 1024, avgsize = 1KB, rtt = 400ms,则:
max_bandwidth = 1024 * 1KB / 400ms = 2.5MB/s ~= 25Mbps
(注:以上计算不包括前向纠错的数据量)
前向纠错是最大带宽量的一个固定比例增加:
max_bandwidth_fec = max_bandwidth*(datashard+parityshard)/datashard
举例,设datashard = 10 , partiyshard = 3,则:
max_bandwidth_fec = max_bandwidth * (10 + 3) /10 = 1.3*max_bandwidth 1.3 * 25Mbps = 32.5Mbps
```
Benchmark result from openssl
### *安全* :lollipop:
无论你上层如何加密,如果```-crypt none```,那么协议头部都是***明文***的,建议至少采用```-crypt aes-128```加密。
注意: ```-crypt xor``` 也是不安全的,除非你知道你在做什么。
### *内存控制* :lollipop:
路由器,手机等嵌入式设备通常对内存用量敏感,通过调节环境变量GOGC(例如GOGC=20)后启动client,可以降低内存使用。
参考:https://blog.golang.org/go15gc
### *流量控制* :lollipop:
***必要性: 针对流量敏感的服务器,做双保险。***
> 基本原则: SERVER的发送速率不能超过ADSL下行带宽,否则只会浪费您的服务器带宽。
在server通过linux tc,可以限制服务器发送带宽。
举例: 用linux tc限制server发送带宽为32mbit/s:
```
$ openssl speed -evp aes-128-cfb
Doing aes-128-cfb for 3s on 16 size blocks: 157794127 aes-128-cfb's in 2.98s
Doing aes-128-cfb for 3s on 64 size blocks: 39614018 aes-128-cfb's in 2.98s
Doing aes-128-cfb for 3s on 256 size blocks: 9971090 aes-128-cfb's in 2.99s
Doing aes-128-cfb for 3s on 1024 size blocks: 2510877 aes-128-cfb's in 2.99s
Doing aes-128-cfb for 3s on 8192 size blocks: 310865 aes-128-cfb's in 2.98s
OpenSSL 1.0.2p 14 Aug 2018
built on: reproducible build, date unspecified
options:bn(64,64) rc4(ptr,int) des(idx,cisc,16,int) aes(partial) idea(int) blowfish(idx)
compiler: clang -I. -I.. -I../include -fPIC -fno-common -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-128-cfb 847216.79k 850770.86k 853712.05k 859912.39k 854565.80k
root@kcptun:~# cat tc.sh
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:1 htb rate 32mbit
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 10 fw flowid 1:1
iptables -t mangle -A POSTROUTING -o eth0 -j MARK --set-mark 10
root@kcptun:~#
```
The encrytion performance in kcptun is as fast as in openssl library(if not faster).
其中eth0为网卡,有些服务器为ens3,有些为p2p1,通过ifconfig查询修改。
#### Memory Usage Control
### *DSCP* :lollipop:
DSCP差分服务代码点(Differentiated Services Code Point),IETF于1998年12月发布了Diff-ServDifferentiated Service)的QoS分类标准。它在每个数据包IP头部的服务类别TOS标识字节中,利用已使用的6比特和未使用的2比特,通过编码值来区分优先级。
常用DSCP值可以参考[Wikipedia DSCP](https://en.wikipedia.org/wiki/Differentiated_services#Commonly_used_DSCP_values),至于有没有用,完全取决于数据包经过的设备。
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
通过 ```-dscp ``` 参数指定dscp值,两端可分别设定。
#### Compression
注意:设置dscp不一定会更好,需要尝试。
kcptun has builtin snappy algorithms for compressing streams:
### *前向纠错* :lollipop:
前向纠错采用Reed Solomon纠删码, 它的基本原理如下: 给定n个数据块d1, d2,…, dn,n和一个正整数m, RS根据n个数据块生成m个校验块, c1, c2,…, cm。 对于任意的n和m, 从n个原始数据块和m 个校验块中任取n块就能解码出原始数据, 即RS最多容忍m个数据块或者校验块同时丢失。
![reed-solomon](rs.png)
通过参数```-datashard 10 -parityshard 3``` 在两端同时设定。
### *Snappy数据流压缩* :lollipop:
> Snappy is a compression/decompression library. It does not aim for maximum
> compression, or compatibility with any other compression library; instead,
> it aims for very high speeds and reasonable compression. For instance,
@@ -270,86 +198,83 @@ kcptun has builtin snappy algorithms for compressing streams:
> Reference: http://google.github.io/snappy/
Compression may save bandwidth for **PLAINTEXT** data, it's quite useful for specific scenarios as cross-datacenter replications, by compressing the redologs in dbms or kafka-like message queues and then transfer the data streams across the continent can be much faster.
通过参数 ```-nocomp``` 在两端同时设定以关闭压缩。
> 提示: 关闭压缩可能会降低延迟。
Compression is enabled by default, you can disable it by setting ```-nocomp``` on **BOTH** KCP Client & KCP Server **MUST** be **IDENTICAL**.
#### SNMP
### *内置模式* :lollipop:
响应速度:
*fast3 >* ***[fast2]*** *> fast > normal > default*
有效载荷比:
*default > normal > fast >* ***[fast2]*** *> fast3*
中间mode参数比较均衡,总之就是越快越浪费带宽,推荐模式 ***fast2***
更高级的 ***手动档*** 需要理解KCP协议,并通过 ***隐藏参数*** 调整,例如:
```
-mode manual -nodelay 1 -resend 2 -nc 1 -interval 20
```
高丢包率的网络建议采用fast2, 低丢包率的网络,建议采用normal。
### *SNMP* :lollipop:
```go
// Snmp defines network statistics indicator
type Snmp struct {
BytesSent uint64 // raw bytes sent
BytesReceived uint64
MaxConn uint64
ActiveOpens uint64
PassiveOpens uint64
CurrEstab uint64 // count of connections for now
InErrs uint64 // udp read errors
InCsumErrors uint64 // checksum errors from CRC32
KCPInErrors uint64 // packet iput errors from kcp
InSegs uint64
OutSegs uint64
InBytes uint64 // udp bytes received
OutBytes uint64 // udp bytes sent
RetransSegs uint64
FastRetransSegs uint64
EarlyRetransSegs uint64
LostSegs uint64 // number of segs infered as lost
RepeatSegs uint64 // number of segs duplicated
FECRecovered uint64 // correct packets recovered from FEC
FECErrs uint64 // incorrect packets recovered from FEC
FECSegs uint64 // FEC segments received
FECShortShards uint64 // number of data shards that's not enough for recovery
BytesSent uint64 // payload bytes sent
BytesReceived uint64
MaxConn uint64
ActiveOpens uint64
PassiveOpens uint64
CurrEstab uint64
InErrs uint64
InCsumErrors uint64 // checksum errors
InSegs uint64
OutSegs uint64
OutBytes uint64 // udp bytes sent
RetransSegs uint64
FastRetransSegs uint64
EarlyRetransSegs uint64
LostSegs uint64
RepeatSegs uint64
FECRecovered uint64
FECErrs uint64
FECSegs uint64 // fec segments received
}
```
Sending a `SIGUSR1` signal to KCP Client or KCP Server will dump SNMP information to console, just like `/proc/net/snmp`. You can use this information to do fine-grained tuning.
使用```kill -SIGUSR1 pid``` 可以在控制台打印出SNMP信息,通常用于精细调整***当前链路的有效载荷比***。
观察```RetransSegs,FastRetransSegs,LostSegs,OutSegs```这几者的数值比例,用于参考调整```-mode manual,fec```的参数。
### Manual Control
### *故障排除* :lollipop:
> Q: 客户端和服务器端***皆无*** ```stream opened```信息。
> A: 连接客户端程序的端口设置错误。
https://github.com/skywind3000/kcp/blob/master/README.en.md#protocol-configuration
> Q: 客户端有 ```stream opened```信息,服务器端没有。
> A: 连接服务器的端口设置错误,或者被防火墙拦截。
`-mode manual -nodelay 1 -interval 20 -resend 2 -nc 1`
> Q: 客户端服务器***皆有*** ```stream opened```信息,但无法通信。
> A: 上层软件的设定错误。
Low-level KCP configuration can be altered by using manual mode like above, make sure you really **UNDERSTAND** what these means before doing **ANY** manual settings.
### *免责申明* :warning:
用户以各种方式使用本软件(包括但不限于修改使用、直接使用、通过第三方使用)的过程中,不得以任何方式利用本软件直接或间接从事违反中国法律、以及社会公德的行为。软件的使用者需对自身行为负责,因使用软件引发的一切纠纷,由使用者承担全部法律及连带责任。作者不承担任何法律及连带责任。
对免责声明的解释、修改及更新权均属于作者本人所有。
### Identical Parmeters
### *捐赠* :dollar:
![donate](donate.png)
The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
好人一生平安
1. -key
1. -crypt
1. -nocomp
1. -datashard
1. -parityshard
### References
```特别感谢: 郑H立, 南D风, Li, 七q, 凌J,昶,Les*ables, Ky*n, 噼**啦, *斌, 小苍**, Ken 等,名字已做特殊处理。```
### *参考资料* :paperclip:
1. https://github.com/skywind3000/kcp -- KCP - A Fast and Reliable ARQ Protocol.
1. https://github.com/xtaci/kcp-go/ -- A Production-Grade Reliable-UDP Library for golang
1. https://github.com/klauspost/reedsolomon -- Reed-Solomon Erasure Coding in Go.
1. https://en.wikipedia.org/wiki/Differentiated_services -- DSCP.
1. http://google.github.io/snappy/ -- A fast compressor/decompressor.
1. https://www.backblaze.com/blog/reed-solomon/ -- Reed-Solomon Explained.
1. http://www.qualcomm.cn/products/raptorq -- RaptorQ Forward Error Correction Scheme for Object Delivery.
1. https://en.wikipedia.org/wiki/PBKDF2 -- Key stretching.
1. http://blog.appcanary.com/2016/encrypt-or-compress.html -- Should you encrypt or compress first?
1. https://github.com/hashicorp/yamux -- Connection multiplexing library.
1. https://tools.ietf.org/html/rfc6937 -- Proportional Rate Reduction for TCP.
1. https://tools.ietf.org/html/rfc5827 -- Early Retransmit for TCP and Stream Control Transmission Protocol (SCTP).
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://play.google.com/store/apps/details?id=com.k17game.k3 -- Battle Zone - Earth 2048, an online strategy game using kcp.
### 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. https://github.com/klauspost/reedsolomon -- Reed-Solomon Erasure Coding in Go.
3. https://en.wikipedia.org/wiki/Differentiated_services -- DSCP.
4. http://google.github.io/snappy/ -- A fast compressor/decompressor.
5. https://www.backblaze.com/blog/reed-solomon/ -- Reed-Solomon Explained.
6. http://www.qualcomm.cn/products/raptorq -- RaptorQ Forward Error Correction Scheme for Object Delivery.
7. https://en.wikipedia.org/wiki/PBKDF2 -- Key stretching.
8. http://blog.appcanary.com/2016/encrypt-or-compress.html -- Should you encrypt or compress first?
9. https://github.com/hashicorp/yamux -- Connection multiplexing library.
10. https://tools.ietf.org/html/rfc6937 -- Proportional Rate Reduction for TCP.
11. https://tools.ietf.org/html/rfc5827 -- Early Retransmit for TCP and Stream Control Transmission Protocol (SCTP).
12. http://http2.github.io/ -- What is HTTP/2?
13. http://www.lartc.org/LARTC-zh_CN.GB2312.pdf -- Linux Advanced Routing & Traffic Control
+7 -24
View File
@@ -1,13 +1,8 @@
#!/bin/bash
sum="sha1sum"
if ! hash sha1sum 2>/dev/null; then
if ! hash shasum 2>/dev/null; then
echo "I can't see 'sha1sum' or 'shasum'"
echo "Please install one of them!"
exit
fi
sum="shasum"
MD5='md5sum'
unamestr=`uname`
if [[ "$unamestr" == 'Darwin' ]]; then
MD5='md5'
fi
UPX=false
@@ -17,7 +12,7 @@ fi
VERSION=`date -u +%Y%m%d`
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS=""
GCFLAGS="-B"
OSES=(linux darwin windows freebsd)
ARCHS=(amd64 386)
@@ -32,7 +27,7 @@ for os in ${OSES[@]}; do
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
$MD5 kcptun-${os}-${arch}-$VERSION.tar.gz
done
done
@@ -44,16 +39,4 @@ for v in ${ARMS[@]}; do
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
#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
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_mipsle github.com/xtaci/kcptun/server
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mips github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat 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
$sum kcptun-linux-mipsle-$VERSION.tar.gz
$sum kcptun-linux-mips-$VERSION.tar.gz
$MD5 kcptun-linux-arm-$VERSION.tar.gz
-4
View File
@@ -14,7 +14,6 @@ type Config struct {
Mode string `json:"mode"`
Conn int `json:"conn"`
AutoExpire int `json:"autoexpire"`
ScavengeTTL int `json:"scavengettl"`
MTU int `json:"mtu"`
SndWnd int `json:"sndwnd"`
RcvWnd int `json:"rcvwnd"`
@@ -30,9 +29,6 @@ type Config struct {
SockBuf int `json:"sockbuf"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
Quiet bool `json:"quiet"`
}
func parseJSONConfig(config *Config, path string) error {
+50 -117
View File
@@ -2,8 +2,6 @@ package main
import (
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"log"
"math/rand"
@@ -18,8 +16,6 @@ import (
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/smux"
"path/filepath"
)
var (
@@ -57,27 +53,18 @@ func newCompStream(conn net.Conn) *compStream {
return c
}
func handleClient(sess *smux.Session, p1 io.ReadWriteCloser, quiet bool) {
if !quiet {
log.Println("stream opened")
defer log.Println("stream closed")
}
func handleClient(p1, p2 io.ReadWriteCloser) {
log.Println("stream opened")
defer log.Println("stream closed")
defer p1.Close()
p2, err := sess.OpenStream()
if err != nil {
return
}
defer p2.Close()
// start tunnel
p1die := make(chan struct{})
buf1 := make([]byte, 65535)
go func() { io.CopyBuffer(p1, p2, buf1); close(p1die) }()
go func() { io.Copy(p1, p2); close(p1die) }()
p2die := make(chan struct{})
buf2 := make([]byte, 65535)
go func() { io.CopyBuffer(p2, p1, buf2); close(p2die) }()
go func() { io.Copy(p2, p1); close(p2die) }()
// wait for tunnel termination
select {
@@ -123,12 +110,12 @@ func main() {
cli.StringFlag{
Name: "crypt",
Value: "aes",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, none",
},
cli.StringFlag{
Name: "mode",
Value: "fast",
Usage: "profiles: fast3, fast2, fast, normal, manual",
Usage: "profiles: fast3, fast2, fast, normal",
},
cli.IntFlag{
Name: "conn",
@@ -140,11 +127,6 @@ func main() {
Value: 0,
Usage: "set auto expiration time(in seconds) for a single UDP connection, 0 to disable",
},
cli.IntFlag{
Name: "scavengettl",
Value: 600,
Usage: "set how long an expired connection can live(in sec), -1 to disable",
},
cli.IntFlag{
Name: "mtu",
Value: 1350,
@@ -157,16 +139,16 @@ func main() {
},
cli.IntFlag{
Name: "rcvwnd",
Value: 512,
Value: 1024,
Usage: "set receive window size(num of packets)",
},
cli.IntFlag{
Name: "datashard,ds",
Name: "datashard",
Value: 10,
Usage: "set reed-solomon erasure coding - datashard",
},
cli.IntFlag{
Name: "parityshard,ps",
Name: "parityshard",
Value: 3,
Usage: "set reed-solomon erasure coding - parityshard",
},
@@ -191,7 +173,7 @@ func main() {
},
cli.IntFlag{
Name: "interval",
Value: 50,
Value: 40,
Hidden: true,
},
cli.IntFlag{
@@ -205,34 +187,20 @@ func main() {
Hidden: true,
},
cli.IntFlag{
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Usage: "per-socket buffer in bytes",
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Hidden: true,
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Usage: "seconds between heartbeats",
},
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",
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Hidden: true,
},
cli.StringFlag{
Name: "log",
Value: "",
Usage: "specify a log file to output, default goes to stderr",
},
cli.BoolFlag{
Name: "quiet",
Usage: "to suppress the 'stream open/close' messages",
},
cli.StringFlag{
Name: "c",
Value: "", // when the value is not empty, the config path must exists
@@ -248,7 +216,6 @@ func main() {
config.Mode = c.String("mode")
config.Conn = c.Int("conn")
config.AutoExpire = c.Int("autoexpire")
config.ScavengeTTL = c.Int("scavengettl")
config.MTU = c.Int("mtu")
config.SndWnd = c.Int("sndwnd")
config.RcvWnd = c.Int("rcvwnd")
@@ -264,9 +231,6 @@ 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")
config.Quiet = c.Bool("quiet")
if c.String("c") != "" {
err := parseJSONConfig(&config, c.String("c"))
@@ -283,9 +247,9 @@ func main() {
switch config.Mode {
case "normal":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 40, 2, 1
case "fast":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 30, 2, 1
case "fast":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 20, 2, 1
case "fast2":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 20, 2, 1
case "fast3":
@@ -298,12 +262,9 @@ func main() {
listener, err := net.ListenTCP("tcp", addr)
checkError(err)
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
var block kcp.BlockCrypt
switch config.Crypt {
case "sm4":
block, _ = kcp.NewSM4BlockCrypt(pass[:16])
case "tea":
block, _ = kcp.NewTEABlockCrypt(pass[:16])
case "xor":
@@ -345,14 +306,9 @@ func main() {
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)
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SockBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
createConn := func() (*smux.Session, error) {
kcpconn, err := kcp.DialWithOptions(config.RemoteAddr, block, config.DataShard, config.ParityShard)
@@ -360,11 +316,11 @@ func main() {
return nil, errors.Wrap(err, "createConn()")
}
kcpconn.SetStreamMode(true)
kcpconn.SetWriteDelay(false)
kcpconn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
kcpconn.SetWindowSize(config.SndWnd, config.RcvWnd)
kcpconn.SetMtu(config.MTU)
kcpconn.SetACKNoDelay(config.AckNodelay)
kcpconn.SetKeepAlive(config.KeepAlive)
if err := kcpconn.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
@@ -386,7 +342,6 @@ func main() {
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
log.Println("connection:", kcpconn.LocalAddr(), "->", kcpconn.RemoteAddr())
return session, nil
}
@@ -396,7 +351,6 @@ func main() {
if session, err := createConn(); err == nil {
return session
} else {
log.Println("re-connecting:", err)
time.Sleep(time.Second)
}
}
@@ -409,30 +363,43 @@ func main() {
}, numconn)
for k := range muxes {
muxes[k].session = waitConn()
sess, err := createConn()
checkError(err)
muxes[k].session = sess
muxes[k].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
}
chScavenger := make(chan *smux.Session, 128)
go scavenger(chScavenger, config.ScavengeTTL)
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
go scavenger(chScavenger)
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)
}
if err := p1.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("TCP SetWriteBuffer:", err)
}
checkError(err)
idx := rr % numconn
// do auto expiration && reconnection
if muxes[idx].session.IsClosed() || (config.AutoExpire > 0 && time.Now().After(muxes[idx].ttl)) {
OPEN_P2:
// do auto expiration
if 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)
}
go handleClient(muxes[idx].session, p1, config.Quiet)
// 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)
rr++
}
}
@@ -441,27 +408,27 @@ func main() {
type scavengeSession struct {
session *smux.Session
ts time.Time
ttl time.Time
}
func scavenger(ch chan *smux.Session, ttl int) {
ticker := time.NewTicker(time.Second)
const (
maxScavengeTTL = 10 * time.Minute
)
func scavenger(ch chan *smux.Session) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
var sessionList []scavengeSession
for {
select {
case sess := <-ch:
sessionList = append(sessionList, scavengeSession{sess, time.Now()})
log.Println("session marked as expired")
case <-ticker.C:
var newList []scavengeSession
for k := range sessionList {
s := sessionList[k]
if s.session.NumStreams() == 0 || s.session.IsClosed() {
log.Println("session normally closed")
s.session.Close()
} else if ttl >= 0 && time.Since(s.ts) >= time.Duration(ttl)*time.Second {
log.Println("session reached scavenge ttl")
if s.session.NumStreams() == 0 || s.session.IsClosed() || time.Since(s.ttl) > maxScavengeTTL {
log.Println("session scavenged")
s.session.Close()
} else {
newList = append(newList, sessionList[k])
@@ -471,37 +438,3 @@ func scavenger(ch chan *smux.Session, ttl int) {
}
}
}
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:
// split path into dirname and filename
logdir, logfile := filepath.Split(path)
// only format logfile
f, err := os.OpenFile(logdir+time.Now().Format(logfile), 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()
}
}
}
-1
View File
@@ -18,7 +18,6 @@ func init() {
func sigHandler() {
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGUSR1)
signal.Ignore(syscall.SIGPIPE)
for {
switch <-ch {
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 20 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

-4
View File
@@ -27,10 +27,6 @@ type Config struct {
SockBuf int `json:"sockbuf"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
Pprof bool `json:"pprof"`
Quiet bool `json:"quiet"`
}
func parseJSONConfig(config *Config, path string) error {
+26 -101
View File
@@ -2,21 +2,15 @@ package main
import (
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"log"
"math/rand"
"net"
"net/http"
_ "net/http/pprof"
"os"
"time"
"golang.org/x/crypto/pbkdf2"
"path/filepath"
"github.com/golang/snappy"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
@@ -63,8 +57,6 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
// stream multiplex
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SockBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
mux, err := smux.Server(conn, smuxConfig)
if err != nil {
log.Println(err)
@@ -83,26 +75,28 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
log.Println(err)
continue
}
go handleClient(p1, p2, config.Quiet)
if err := p2.(*net.TCPConn).SetReadBuffer(config.SockBuf); err != nil {
log.Println("TCP SetReadBuffer:", err)
}
if err := p2.(*net.TCPConn).SetWriteBuffer(config.SockBuf); err != nil {
log.Println("TCP SetWriteBuffer:", err)
}
go handleClient(p1, p2)
}
}
func handleClient(p1, p2 io.ReadWriteCloser, quiet bool) {
if !quiet {
log.Println("stream opened")
defer log.Println("stream closed")
}
func handleClient(p1, p2 io.ReadWriteCloser) {
log.Println("stream opened")
defer log.Println("stream closed")
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) }()
go func() { io.Copy(p1, p2); close(p1die) }()
p2die := make(chan struct{})
buf2 := make([]byte, 65535)
go func() { io.CopyBuffer(p2, p1, buf2); close(p2die) }()
go func() { io.Copy(p2, p1); close(p2die) }()
// wait for tunnel termination
select {
@@ -148,12 +142,12 @@ func main() {
cli.StringFlag{
Name: "crypt",
Value: "aes",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, none",
},
cli.StringFlag{
Name: "mode",
Value: "fast",
Usage: "profiles: fast3, fast2, fast, normal, manual",
Usage: "profiles: fast3, fast2, fast, normal",
},
cli.IntFlag{
Name: "mtu",
@@ -171,12 +165,12 @@ func main() {
Usage: "set receive window size(num of packets)",
},
cli.IntFlag{
Name: "datashard,ds",
Name: "datashard",
Value: 10,
Usage: "set reed-solomon erasure coding - datashard",
},
cli.IntFlag{
Name: "parityshard,ps",
Name: "parityshard",
Value: 3,
Usage: "set reed-solomon erasure coding - parityshard",
},
@@ -201,7 +195,7 @@ func main() {
},
cli.IntFlag{
Name: "interval",
Value: 50,
Value: 40,
Hidden: true,
},
cli.IntFlag{
@@ -215,38 +209,20 @@ func main() {
Hidden: true,
},
cli.IntFlag{
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Usage: "per-socket buffer in bytes",
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Hidden: true,
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Usage: "seconds between heartbeats",
},
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.BoolFlag{
Name: "pprof",
Usage: "start profiling server on :6060",
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Hidden: true,
},
cli.StringFlag{
Name: "log",
Value: "",
Usage: "specify a log file to output, default goes to stderr",
},
cli.BoolFlag{
Name: "quiet",
Usage: "to suppress the 'stream open/close' messages",
},
cli.StringFlag{
Name: "c",
Value: "", // when the value is not empty, the config path must exists
@@ -275,10 +251,6 @@ 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")
config.Pprof = c.Bool("pprof")
config.Quiet = c.Bool("quiet")
if c.String("c") != "" {
//Now only support json config file
@@ -296,9 +268,9 @@ func main() {
switch config.Mode {
case "normal":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 40, 2, 1
case "fast":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 30, 2, 1
case "fast":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 0, 20, 2, 1
case "fast2":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 20, 2, 1
case "fast3":
@@ -306,12 +278,9 @@ func main() {
}
log.Println("version:", VERSION)
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
var block kcp.BlockCrypt
switch config.Crypt {
case "sm4":
block, _ = kcp.NewSM4BlockCrypt(pass[:16])
case "tea":
block, _ = kcp.NewTEABlockCrypt(pass[:16])
case "xor":
@@ -353,10 +322,6 @@ 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)
log.Println("pprof:", config.Pprof)
log.Println("quiet:", config.Quiet)
if err := lis.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
@@ -367,21 +332,15 @@ func main() {
if err := lis.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
go 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)
conn.SetKeepAlive(config.KeepAlive)
if config.NoComp {
go handleMux(conn, &config)
@@ -395,37 +354,3 @@ 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:
// split path into dirname and filename
logdir, logfile := filepath.Split(path)
// only format logfile
f, err := os.OpenFile(logdir+time.Now().Format(logfile), 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()
}
}
}
-1
View File
@@ -18,7 +18,6 @@ func init() {
func sigHandler() {
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGUSR1)
signal.Ignore(syscall.SIGPIPE)
for {
switch <-ch {
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB