Compare commits

..
227 Commits
Author SHA1 Message Date
xtaci bf635db2f9 upd deps 2019-06-11 15:32:03 +08:00
xtaci b31a9d01af change stream i/o log 2019-06-11 14:59:09 +08:00
xtaci 440e490204 upd deps 2019-06-11 14:22:28 +08:00
xtaci 45e58e6500 output endpoint address when stream opened 2019-06-11 14:07:17 +08:00
xtaci 7382d41489 do not reset the snmp values 2019-05-23 11:26:08 +08:00
xtaciandGitHub 22966661c4 Update README.md 2019-05-20 13:24:31 +08:00
xtaci a704f60ee3 remove one line 2019-05-16 21:35:24 +08:00
xtaci 0db71f7d0c upd readme 2019-05-16 13:10:03 +08:00
xtaci 76c88158c8 upd deps 2019-05-14 21:21:31 +08:00
xtaci af3185d2e9 log prints remoteaddr 2019-05-14 21:20:24 +08:00
xtaci 76f62b0dd1 smux 1.3.1 2019-05-14 14:07:53 +08:00
xtaci 9f5d2a278a smux v1.2.12 kcp-go v5.3.8 2019-05-14 11:29:45 +08:00
xtaci af88878dd9 kcp-go v5.3.7 2019-05-13 16:52:30 +08:00
xtaci ec9ace1de0 fix 2019-05-12 21:30:14 +08:00
xtaci e93a1908c1 upd 2019-05-12 20:34:42 +08:00
xtaci e7c6eb17d2 upd deps 2019-05-12 19:06:06 +08:00
jessandxtaci 26f6688da3 Added backers and sponsors on the README (#679) 2019-05-12 11:21:10 +08:00
xtaci dbaefc35a7 adjust bi-tun parameters 2019-05-11 18:13:48 +08:00
xtaci 5da363682e indie snmp.go 2019-05-10 21:47:23 +08:00
xtaci 116c1e7668 seperate compStream 2019-05-10 21:44:02 +08:00
xtaci 86cc46f437 a specific version of copy 2019-05-10 21:33:51 +08:00
xtaci e54a648576 half-close 2019-05-10 17:38:20 +08:00
xtaci 49f701be26 fix format 2019-05-10 15:27:04 +08:00
xtaci 6e0b2077ea add error output 2019-05-10 15:22:45 +08:00
xtaci 873351361a upd deps 2019-05-10 14:36:20 +08:00
xtaci f33e913f73 deps kcp-go to 5.3.2 2019-05-10 12:36:14 +08:00
xtaci 5c77ac3c60 upd deps 2019-04-28 14:56:10 +08:00
xtaci 5d015f0616 less memory usage 2019-04-28 14:53:40 +08:00
xtaci 2a9fb0b908 mv build-releash.sh to root dir 2019-04-28 14:35:33 +08:00
xtaciandGitHub 2f36a43223 Add files via upload (#671)
* Add files via upload

* Update README.md
2019-04-27 10:17:43 +08:00
xtaci 11681b5d73 deps 2019-04-24 23:14:17 +08:00
xtaci 4ab1085fe5 update deps 2019-04-24 13:42:52 +08:00
xtaci 60569b85fa upd deps 2019-04-23 21:10:39 +08:00
xtaci 273ca4febc upd deps 2019-04-23 21:08:03 +08:00
xtaci d129f92842 upd deps 2019-04-22 17:05:50 +08:00
xtaci 75e83adfba reuse buffer for io.copyBuffer 2019-04-22 14:10:12 +08:00
xtaciandGitHub 3f6134be00 Merge pull request #667 from imcotton/patch-1
upgrade alpine to v3.9 in docker image
2019-04-19 17:42:24 +08:00
Cotton HouandGitHub 2ea87c9c22 upgrade alpine to v3.9 in docker image 2019-04-19 17:04:06 +08:00
xtaci 0bf2b94d92 upd deps 2019-04-18 14:17:27 +08:00
xtaci 3e81672992 upd deps 2019-04-18 13:48:56 +08:00
xtaci 4052db212c dep 2019-04-18 12:21:27 +08:00
xtaci 68c1eb3c9e dep upd 2019-04-18 12:20:34 +08:00
xtaci d1fe0565c6 don't block Accept on Dial for new connections 2019-04-17 21:37:49 +08:00
xtaci ff83995830 remove i386 support for freebsd and darwin 2019-04-16 14:57:54 +08:00
xtaci 288318b08a upd dep 2019-04-16 11:58:00 +08:00
xtaci 55e69c323d upd mod 2019-04-16 11:54:05 +08:00
xtaci 53ef93e08d add ARM64 compile target 2019-04-16 11:20:47 +08:00
xtaciandGitHub 7183a9ecd6 Update README.md 2019-04-10 18:10:13 +08:00
xtaciandGitHub 8252405714 Update README.md 2019-04-09 12:37:19 +08:00
xtaciandGitHub ede800b0fd Update README.md 2019-04-09 12:10:47 +08:00
xtaci a43b688990 upd deps 2019-04-09 11:33:04 +08:00
xtaci 283f61068b upgrade deps 2019-04-07 22:10:47 +08:00
xtaci e0b8ed5dad fan in bi-directional tunnel 2019-04-07 14:51:10 +08:00
xtaciandGitHub a8d76aed7f Update README.md 2019-04-05 21:40:28 +08:00
xtaciandGitHub 97cc1c0393 Update README.md 2019-04-04 17:26:06 +08:00
xtaci 3becd2e925 compress img 2019-04-04 17:22:03 +08:00
xtaci aba4957096 add bw.png 2019-04-04 17:20:22 +08:00
xtaci b58104c7b9 update deps 2019-04-01 21:40:39 +08:00
xtaci ceb89917f9 allow access to -smuxbuf parameter for handling HOLB 2019-03-25 11:51:21 +08:00
xtaci d4392a37db upd 2019-03-22 02:23:40 +08:00
xtaci 7e733b20cb upd dep 2019-03-22 02:02:04 +08:00
xtaci 5dc5480d8e upd library 2019-03-22 01:02:17 +08:00
xtaci 7a0c3fd6cc upd library 2019-03-22 00:31:56 +08:00
xtaci 64069d2dbb avoid one bytes copying for each packet output 2019-03-21 23:49:24 +08:00
xtaciandGitHub e758833307 Update README.md 2019-03-06 15:31:07 +08:00
xtaci 3be37deaed export GO111MODULE=on in build-release.sh 2019-02-13 12:59:05 +08:00
xtaci 43882f89eb move build script to a new directory 2019-02-13 12:57:43 +08:00
xtaci 8e625bedf8 update deps 2019-02-13 00:55:58 +08:00
xtaci 456232eafd add support for GO111MODULE 2019-02-03 18:48:12 +08:00
xtaciandGitHub 04b55a1a90 Update README.md 2019-01-26 23:14:57 +08:00
xtaciandGitHub 6df0795aa7 Update README.md 2019-01-22 21:28:43 +08:00
xtaciandGitHub 3158204afd Update README.md 2019-01-15 16:27:17 +08:00
xtaciandGitHub e9b96e71b9 Update README.md 2019-01-15 14:48:18 +08:00
xtaciandGitHub b50f736bb7 Update README.md 2019-01-15 14:46:09 +08:00
xtaciandGitHub 43a662772b Update README.md 2019-01-04 19:10:54 +08:00
xtaciandGitHub f8ca7afa22 Update README.md 2018-12-26 23:26:56 +08:00
xtaciandGitHub baf532e1b1 Update README.md 2018-10-27 21:56:36 +08:00
xtaci c5cdc30250 add wechat_donate 2018-10-27 21:51:25 +08:00
xtaciandGitHub d0eafa4cce Merge pull request #625 from HaraldNordgren/master
Bump Travis versions
2018-10-20 12:23:51 +08:00
Harald Nordgren 3ac0c05756 Bump Travis versions 2018-10-19 21:48:36 +02:00
xtaciandGitHub 1bcb40d3fe Update README.md 2018-10-16 01:42:44 +08:00
xtaci 962f8c4a31 rm rs.png 2018-10-15 17:05:06 +08:00
xtaci cba4bbefd4 upd FEC.png 2018-10-15 17:01:47 +08:00
xtaci a3f60e5781 update FEC diagram 2018-10-15 16:59:44 +08:00
xtaciandGitHub e31a6cfca3 Update README.md 2018-10-08 13:53:57 +08:00
xtaciandGitHub 79deb2ab86 Update README.md 2018-10-05 23:36:52 +08:00
xtaciandGitHub 6cc274e01e Update README.md 2018-10-05 23:07:18 +08:00
xtaciandGitHub b0620ab7a2 Update README.md
elaborate crypto analysis
2018-10-05 22:55:54 +08:00
xtaciandGitHub b4e4d747e7 Update README.md 2018-10-04 23:52:33 +08:00
xtaciandGitHub f430afcd99 Update README.md 2018-09-29 18:28:17 +08:00
xtaciandGitHub 88e3c64aed Update README.md 2018-09-29 18:26:54 +08:00
xtaci 22893775cc increase copy buffer to 64k to maximize the frame size in smux 2018-09-29 17:56:09 +08:00
xtaci aae950de2d add usage to -sockbuf -keepalive 2018-09-28 21:35:05 +08:00
xtaci 43a68a68f5 reveal 2 parameters, -sockbuf -keepalive 2018-09-28 21:35:05 +08:00
xtaciandGitHub c0077c2043 Update README.md 2018-09-28 21:31:53 +08:00
xtaci adae725995 toggle writing method to nodelay for responsivness 2018-09-22 21:07:08 +08:00
xtaciandGitHub c59479c7c4 Update README.md 2018-09-20 19:16:27 +08:00
xtaci 561ee05818 make 'softfloat' for MIPS as the default when compiling 2018-09-17 16:12:58 +08:00
xtaci 65d8945050 hint before key stretching for low-end devices 2018-09-15 15:48:26 +08:00
xtaciandGitHub cdaff1bd72 Update README.md 2018-08-17 15:15:44 +08:00
xtaciandGitHub cb451a3a88 Update README.md 2018-08-16 17:12:18 +08:00
xtaci 8f8d762742 gofmt 2018-06-28 19:25:37 +08:00
xtaciandGitHub e3ab00cf5b Merge pull request #600 from mateomartin1998/master
snmplog: only format the log file name, not the whole path
2018-06-21 12:11:32 +08:00
mateomartin1998 42bf13fb7a snmplog: only format the log file name, not the whole path 2018-06-17 17:58:21 +08:00
xtaci 03f27ec53d Revert "passive tunnel termination"
This reverts commit bf1d0d6419.
2018-03-16 13:44:44 +08:00
xtaciandGitHub b2390a5dd3 Update README.md 2018-03-16 13:30:53 +08:00
xtaci bf1d0d6419 passive tunnel termination 2018-03-05 16:38:28 +08:00
xtaciandGitHub 834cc5d596 Update README.md 2017-12-03 21:59:22 +08:00
xtaciandGitHub 825ccca6ac Update README.md 2017-10-23 02:59:28 -05:00
xtaci 2845af3911 print quiet option 2017-10-21 19:34:26 +08:00
xtaciandGitHub 31a9d13871 Merge pull request #509 from jiangtiandao/master
reduce docker image size by using multi stage build
2017-10-21 19:16:01 +08:00
xtaci 43761f486c add '-quiet' option to suppress stream open/close messages 2017-10-21 19:11:14 +08:00
xtaci 030e39bf74 add encryption support for sm4 2017-10-09 22:58:44 +08:00
Rheinmetal e6a1d00758 reduce docker image size by using multi stage build 2017-09-23 10:26:17 +08:00
xtaci 9d5a5b9c0d upd travis 2017-09-04 11:06:21 +08:00
xtaci 4aaf974a0b add ethereum qrcode 2017-08-06 17:22:46 +08:00
xtaciandGitHub 1600d4d26f Update README.md 2017-08-02 19:26:33 +08:00
xtaciandGitHub c612e5e153 Update README.md 2017-07-30 18:48:11 +08:00
xtaciandGitHub 2fef48ce71 Update README.md 2017-07-30 18:47:19 +08:00
xtaciandGitHub 1d492accd6 Update README.md 2017-07-30 18:46:48 +08:00
xtaci d1beaf8383 update README.md 2017-07-02 00:14:39 +08:00
xtaciandGitHub ded53a9229 Update README.md 2017-05-20 19:35:17 +08:00
xtaciandGitHub 65751d535b Update README.md 2017-05-20 19:34:42 +08:00
xtaci 4b5f7c1405 add bitcoin donate 2017-05-20 18:48:05 +08:00
xtaciandGitHub 25bad3c03c Update README.md 2017-04-26 11:16:48 +08:00
xtaciandGitHub d2c4d04600 Update README.md 2017-04-26 11:07:24 +08:00
xtaci 0cb075b061 add a log for re-connecting 2017-04-08 10:38:51 +08:00
xtaciandGitHub ab7a8321a6 Update README.md 2017-03-29 21:08:16 +08:00
xtaci 6496672b61 Revert "use io.CopyBuffer instead of io.Copy for memory recycle"
This reverts commit ad8683d46c.
2017-03-28 15:34:23 +08:00
xtaci ae513e9af1 inject version in Dockerfile 2017-03-27 15:56:29 +08:00
xtaci 36763feca4 ignore sigpipe 2017-03-24 22:52:06 +08:00
xtaci acf7a01922 adjust parameters based on improvements in kcp-go 2017-03-21 22:29:05 +08:00
xtaciandGitHub ee01d61266 Update README.md 2017-03-20 12:57:48 +08:00
xtaciandGitHub fd7ed8532e Update README.md 2017-03-20 12:56:23 +08:00
xtaci ff9e3d699b add SetWriteDelay func 2017-03-18 13:07:34 +08:00
xtaci e667b74b35 remove pprof on client side to shrink binary size 2017-03-15 12:42:16 +08:00
xtaciandGitHub 9a162e7008 Update README.md 2017-03-14 12:36:51 +08:00
xtaciandGitHub bf4170ddff Update README.md 2017-03-13 23:31:47 +08:00
xtaciandGitHub 915db867bd Delete README-CN.md 2017-03-13 23:31:31 +08:00
xtaciandGitHub e32fa78db6 Update README-CN.md 2017-03-13 23:30:16 +08:00
xtaciandGitHub 12b8cdb366 Update README-CN.md 2017-03-13 23:29:24 +08:00
xtaciandGitHub 87120a019b Update README-CN.md 2017-03-13 14:09:20 +08:00
xtaciandGitHub 2ab1e3fb26 Update README.md 2017-03-13 14:08:37 +08:00
xtaci b3c4ec9483 update 2017-03-12 21:12:03 +08:00
xtaci 91335c3db6 listen to all 6060 2017-03-12 21:03:44 +08:00
xtaci 7df2c447db add -pprof option for debuging purpose 2017-03-12 20:53:53 +08:00
xtaci ad8683d46c use io.CopyBuffer instead of io.Copy for memory recycle 2017-03-11 13:20:28 +08:00
xtaci ca4800f298 remove hard limit for tcp socket buffer,let kernel autoscale 2017-03-10 12:53:14 +08:00
xtaci a25c9eb3a9 fix possible CLOSE_WAIT in client 2017-03-08 16:33:10 +08:00
xtaci a0e8b2592e use keepalive in smux alone directly 2017-03-07 20:33:52 +08:00
xtaci dc6b61ded3 remove a deprecated func 2017-03-07 10:49:06 +08:00
xtaci 298b4a0795 adjusta default parameters 2017-03-02 11:04:01 +08:00
xtaci 1334ce5a9a Revert "adjust defaults"
This reverts commit 6efb6008e5.
2017-03-02 00:08:34 +08:00
xtaci 6efb6008e5 adjust defaults 2017-03-01 16:27:33 +08:00
xtaci 53d4bbfe4c change default parameters 2017-03-01 11:06:20 +08:00
xtaciandGitHub 2f0783f81d Update README.md 2017-02-14 15:53:42 +08:00
xtaciandGitHub 64e141430e Update README.md 2017-02-14 13:00:03 +08:00
xtaci bf543cfd63 add scavengettl option 2017-02-12 12:26:34 +08:00
xtaciandGitHub 751fb5f8cd Update README-CN.md 2017-02-08 11:36:06 +08:00
xtaci e074076db5 do not quit when NIC is disabled 2017-02-06 16:45:03 +08:00
higher-syandxtaci 417c602cc5 Update build-release.sh again
是我想多了,请多多指教 😄
2017-02-04 14:04:39 +08:00
higher-syandxtaci 23e3782dc4 Update build-release.sh
Use sha1sum. But on sometimes it's shasum (e.g. macos),so......
2017-02-04 14:04:39 +08:00
higher-syandxtaci 532d9e56ce Update build-release.sh
change md5 to sha256
2017-02-04 14:04:39 +08:00
xtaciandGitHub 203a626528 Update README-CN.md 2017-01-26 22:00:11 +08:00
xtaciandGitHub 338bc5befc Update README-CN.md 2017-01-26 12:03:30 +08:00
xtaciandGitHub 4051938931 Update README.md 2017-01-24 21:54:56 +08:00
xtaciandGitHub c2489808cc Update README.md 2017-01-24 21:54:20 +08:00
xtaciandGitHub a9ea222f24 Update README-CN.md 2017-01-24 21:51:46 +08:00
xtaciandGitHub aa85dc9ada Update README-CN.md 2017-01-24 21:51:19 +08:00
xtaciandGitHub ec5cb958b7 Update README-CN.md 2017-01-24 21:50:43 +08:00
xtaciandGitHub 490c40eb44 Update README-CN.md 2017-01-24 21:47:39 +08:00
xtaciandGitHub 76e7818b45 Update README-CN.md 2017-01-24 21:46:31 +08:00
xtaciandGitHub f2363702bc Update README-CN.md 2017-01-24 21:45:25 +08:00
xtaciandGitHub beddab04fe Update README.md 2017-01-24 17:53:34 +08:00
xtaciandGitHub 12a39bebb8 Update README.md 2017-01-24 17:35:48 +08:00
xtaciandGitHub c0d6104594 Update README.md 2017-01-24 17:32:44 +08:00
xtaciandGitHub 2fe88a1c46 Update README.md 2017-01-24 17:32:10 +08:00
xtaciandGitHub 22c2314eee Update README.md 2017-01-24 17:28:53 +08:00
xtaciandGitHub e7ee96cb1c Update README.md 2017-01-24 17:24:36 +08:00
xtaciandGitHub a5f5d64fd9 Update README.md 2017-01-24 17:14:24 +08:00
xtaciandGitHub ac0d3aa954 Update README.md 2017-01-24 17:10:20 +08:00
xtaciandGitHub 16c8c2daa5 Update README.md 2017-01-24 17:07:12 +08:00
xtaciandGitHub 69b1ee3e30 Update README-CN.md 2017-01-24 14:18:34 +08:00
xtaciandGitHub 87ee41833b Update README-CN.md 2017-01-24 14:16:14 +08:00
xtaciandGitHub d3d2cd271d Update README-CN.md 2017-01-24 14:11:48 +08:00
xtaciandGitHub 1a2c3559a2 Update README-CN.md 2017-01-24 14:03:59 +08:00
xtaciandGitHub 844dc17ab7 Update README.md 2017-01-24 13:58:10 +08:00
xtaciandGitHub 7eee949682 Update README-CN.md 2017-01-24 13:57:09 +08:00
xtaci 06b63b6fdd upd 2017-01-24 13:55:47 +08:00
xtaciandGitHub 5f950feed8 Update README.md 2017-01-24 13:09:29 +08:00
xtaciandGitHub 8ee3fce2ff Add files via upload 2017-01-24 13:08:52 +08:00
xtaciandGitHub 190f82f064 Update README.md 2017-01-24 12:59:43 +08:00
xtaciandGitHub 534708138c Add files via upload 2017-01-24 12:58:43 +08:00
xtaciandGitHub e58e3e66d0 Add files via upload 2017-01-24 12:58:16 +08:00
xtaciandGitHub 3bee8ca6e9 Update README.md 2017-01-24 12:33:48 +08:00
xtaci cfabba001d update -mode usage 2017-01-24 12:29:19 +08:00
xtaciandGitHub d4b07015ab Update README.md 2017-01-24 12:23:15 +08:00
xtaciandGitHub f70beed964 Update README.md 2017-01-24 12:21:03 +08:00
xtaciandGitHub 0ba3cfb0a2 Update README.md 2017-01-24 11:36:55 +08:00
xtaciandGitHub ee8e1be581 Update README.md 2017-01-24 11:33:30 +08:00
xtaciandGitHub ae2e3be73d Update README.md 2017-01-24 11:25:22 +08:00
xtaciandGitHub 356bb7615e Update README.md 2017-01-24 11:23:48 +08:00
xtaciandGitHub b870c588ae Update README.md 2017-01-24 11:20:47 +08:00
xtaciandGitHub f31a5e6b61 Update README.md 2017-01-24 11:18:43 +08:00
xtaciandGitHub 3972a6faa1 Update README.md 2017-01-24 11:17:42 +08:00
xtaciandGitHub 20211352e7 Update README.md 2017-01-24 11:16:56 +08:00
xtaciandGitHub 608c598cbf Update README.md 2017-01-24 11:09:09 +08:00
xtaciandGitHub e26d19da09 Update README.md 2017-01-24 11:08:32 +08:00
xtaciandGitHub 9f63ea2362 Update README.md 2017-01-24 11:04:23 +08:00
xtaciandGitHub 81c9f91f44 Update README.md 2017-01-24 11:03:40 +08:00
xtaciandGitHub 8d8ee15381 Update README.md 2017-01-24 10:59:09 +08:00
xtaciandGitHub dc730d8501 Update README.md 2017-01-24 10:58:08 +08:00
xtaciandGitHub 8ae01cd92f Update README.md 2017-01-24 10:57:52 +08:00
xtaciandGitHub 3000a611cc Update README.md 2017-01-24 10:56:35 +08:00
xtaciandGitHub f09f1c9b2d Update README.md 2017-01-24 10:54:38 +08:00
xtaciandGitHub cc12ada5a7 Update README.md 2017-01-24 10:53:00 +08:00
xtaciandGitHub 074f4d54d5 Update README.md 2017-01-24 10:50:01 +08:00
xtaciandGitHub c4253493b4 Update README.md 2017-01-24 10:49:23 +08:00
xtaciandGitHub 7b4c8967d6 Update README.md 2017-01-24 10:45:12 +08:00
xtaciandGitHub a1befb4763 Update README.md 2017-01-24 10:33:00 +08:00
xtaciandGitHub 9b31b71cb5 Update README.md 2017-01-24 00:37:07 +08:00
xtaciandGitHub 0ffe2cd369 Update README.md 2017-01-24 00:30:26 +08:00
xtaciandGitHub 42535dff05 Update README.md 2017-01-23 23:22:09 +08:00
xtaciandGitHub 52a3e0f7ff Update README.md 2017-01-23 23:18:12 +08:00
xtaciandGitHub b643d63bad Update README.md 2017-01-23 23:13:28 +08:00
xtaciandGitHub b7f0cb8408 Update README.md 2017-01-23 23:04:42 +08:00
xtaci dc4d42007b init 2017-01-23 22:30:54 +08:00
27 changed files with 1280 additions and 737 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**?
+2
View File
@@ -24,3 +24,5 @@ _testmain.go
*.prof
client/client
server/server
build/*
.DS_Store
+3 -1
View File
@@ -1,6 +1,8 @@
language: go
go:
- 1.6
- 1.9.x
- 1.10.x
- 1.11.x
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

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

After

Width:  |  Height:  |  Size: 16 KiB

-240
View File
@@ -1,240 +0,0 @@
# <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 - kcptun client
USAGE:
client_darwin_amd64 [global options] command [command options] [arguments...]
VERSION:
20160819
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 for client and server (default: "it's a secrect") [$KCPTUN_KEY]
--crypt value aes, aes-128, aes-192, blowfish, cast5, 3des, tea, xor, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--conn value set num of UDP connections to server (default: 1)
--mtu value set maximum transmission unit of 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
--help, -h show help
--version, -v print the version
$ ./server_darwin_amd64 -h
NAME:
kcptun - kcptun server
USAGE:
server_darwin_amd64 [global options] command [command options] [arguments...]
VERSION:
20160819
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 for client and server (default: "it's a secrect") [$KCPTUN_KEY]
--crypt value aes, aes-128, aes-192, blowfish, cast5, 3des, tea, xor, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--mtu value set maximum transmission unit of 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
--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)
All donations to this project will be used on the R&D of [gonet/2](http://gonet2.github.io/).
### *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
+310 -187
View File
@@ -1,5 +1,7 @@
# <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]
# <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]
[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
@@ -16,173 +18,270 @@
[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
***[kcp-go](https://github.com/xtaci/kcp-go)协议测试小工具 :zap: [官方下载地址](https://github.com/xtaci/kcptun/releases/latest):zap:***
<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.*
### 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:
![kcptun](kcptun.png)
[English Readme](README.en.md)
### *快速设定* :lollipop:
```
服务器: ./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端口
net.core.rmem_max=26214400 // BDP - bandwidth delay product
net.core.rmem_default=26214400
net.core.wmem_max=26214400
net.core.wmem_default=26214400
net.core.netdev_max_backlog=2048 // proportional to -rcvwnd
```
### *速度对比* :lollipop:
<img src="fast.png" alt="fast.com" height="256px" />
* 测速网站: https://fast.com
* 接入: 100M ADSL
* WIFI: 5GHz TL-WDR3320
### *使用方法* :lollipop:
在Mac OS X El Capitan下的帮助输出:
You can also increase the per-socket buffer by adding parameter(default 4MB):
```
$ ./client_darwin_amd64 -h
-sockbuf 16777217
```
for **slow processors**, increasing this buffer is **CRITICAL** to receive packets properly.
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 fast3 -nocomp -autoexpire 900 -sockbuf 16777217 -dscp 46
KCP Server: ./server_linux_amd64 -t "TARGET_IP:8388" -l ":4000" -mode fast3 -nocomp -sockbuf 16777217 -dscp 46
```
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
<img src="fast.png" alt="fast.com" height="256px" />
![bandwidth](bw.png)
![flame](flame.png)
> Practical bandwidth graph with parameters: -mode fast3 -ds 10 -ps 3
### 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*
#### HOLB
Since streams are multiplexed into a single physical channel, head of line blocking may appear under certain circumstances, by
increasing `-smuxbuf` to a larger value (default 4MB) may mitigate this problem, obviously this will costs more memory.
#### Slow Devices
kcptun made use of **ReedSolomon-Codes** to recover lost packets, which requires massive amount of computation, a low-end ARM device cannot satisfy kcptun well. To unleash the full potential of kcptun, a multi-core x86 homeserver CPU like AMD Opteron is recommended.
If you insist on running under some ARM routers, you'd better turn off `FEC` and use `salsa20` as the encryption method.
### Expert Tuning Guide
#### Overview
<p align="left"><img src="layeredparams.png" alt="params" height="450px"/></p>
#### Usage
```
xtaci@gw:~$ ./client_linux_amd64 -h
NAME:
kcptun - kcptun client
kcptun - client(with SMUX)
USAGE:
client_darwin_amd64 [global options] command [command options] [arguments...]
client_linux_amd64 [global options] command [command options] [arguments...]
VERSION:
20160819
20190409
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 for client and server (default: "it's a secrect") [$KCPTUN_KEY]
--crypt value aes, aes-128, aes-192, blowfish, cast5, 3des, tea, xor, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--conn value set num of UDP connections to server (default: 1)
--mtu value set maximum transmission unit of 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
--help, -h show help
--version, -v print the version
$ ./server_darwin_amd64 -h
--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 per-socket buffer in bytes (default: 4194304)
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
--keepalive value seconds between heartbeats (default: 10)
--snmplog value collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
--snmpperiod value snmp collect period, in seconds (default: 60)
--log value specify a log file to output, default goes to stderr
--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
xtaci@gw:~$ ./server_linux_amd64 -h
NAME:
kcptun - kcptun server
kcptun - server(with SMUX)
USAGE:
server_darwin_amd64 [global options] command [command options] [arguments...]
server_linux_amd64 [global options] command [command options] [arguments...]
VERSION:
20160819
20190409
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 for client and server (default: "it's a secrect") [$KCPTUN_KEY]
--crypt value aes, aes-128, aes-192, blowfish, cast5, 3des, tea, xor, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--mtu value set maximum transmission unit of 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
--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, 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 per-socket buffer in bytes (default: 4194304)
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
--keepalive value seconds between heartbeats (default: 10)
--snmplog value collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
--snmpperiod value snmp collect period, in seconds (default: 60)
--pprof start profiling server on :6060
--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
```
### *参数调整* :lollipop:
***两端参数必须一致的有:***
* datashard
* parityshard
* nocomp
* key
* crypt
#### Forward Error Correction
其余为两边可独立设定的参数
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.
*简易自我调优方法*
> 第一步:同时在两端逐步增大client rcvwnd和server sndwnd;
> 第二步:尝试下载,观察如果带宽利用率(服务器+客户端两端都要观察)接近物理带宽则停止,否则跳转到第一步。
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.
***注意:产生大量重传时,一定是窗口偏大了***
![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:
*带宽计算公式*
```
在不丢包的情况下,有最大-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
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
```
### *安全* :lollipop:
无论你上层如何加密,如果```-crypt none```,那么协议头部都是***明文***的,建议至少采用```-crypt aes-128```加密。
Benchmark result from openssl
注意: ```-crypt xor``` 也是不安全的,除非你知道你在做什么。
### *内存控制* :lollipop:
路由器,手机等嵌入式设备通常对内存用量敏感,通过调节环境变量GOGC(例如GOGC=20)后启动client,可以降低内存使用。
参考:https://blog.golang.org/go15gc
### *流量控制* :lollipop:
***必要性: 针对流量敏感的服务器,做双保险。***
> 基本原则: SERVER的发送速率不能超过ADSL下行带宽,否则只会浪费您的服务器带宽。
在server通过linux tc,可以限制服务器发送带宽。
举例: 用linux tc限制server发送带宽为32mbit/s:
```
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:~#
$ 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
```
其中eth0为网卡,有些服务器为ens3,有些为p2p1,通过ifconfig查询修改。
The encrytion performance in kcptun is as fast as in openssl library(if not faster).
### *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),至于有没有用,完全取决于数据包经过的设备。
#### Memory Control
通过 ```-dscp ``` 参数指定dscp值,两端可分别设定。
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
### *前向纠错* :lollipop:
前向纠错采用Reed Solomon纠删码, 它的基本原理如下: 给定n个数据块d1, d2,…, dn,n和一个正整数m, RS根据n个数据块生成m个校验块, c1, c2,…, cm。 对于任意的n和m, 从n个原始数据块和m 个校验块中任取n块就能解码出原始数据, 即RS最多容忍m个数据块或者校验块同时丢失。
Primary memory allocation are done from a global buffer pool *xmit.Buf*, in kcp-go, when we need to allocate some bytes, we can get from that pool, and a *fixed-capacity* 1500 bytes(mtuLimit) will be returned, the *rx queue*, *tx queue* and *fec queue* all receive bytes from there, and they will return the bytes to the pool after using to prevent *unnecessary zer0ing* of bytes.
The pool mechanism maintained a *high watermark* for slice objects, these *in-flight* objects from the pool will survive from the perodical garbage collection, meanwhile the pool kept the ability to return the memory to runtime if in idle, `-sndwnd`,`-rcvwnd`,`-ds`, `-ps`, these parameters affect this *high watermark*, the larger the value, the bigger the memory consumption will be.
![reed-solomon](rs.png)
`-smuxbuf` also affects the maximum memory consumption, this parameter maintains a subtle balance between *concurrency* and *resource*, you can increase this value(default 4MB) to boost concurrency if you have many clients to serve and you get a powerful server at the same time, and also you can decrease this value to serve only 1 or 2 clients and hope this program can run under some embeded SoC system with limited memory and only you can access. (Notice that the `-smuxbuf` value is not proprotional to concurrency, you need to test.)
通过参数```-datashard 10 -parityshard 3``` 在两端同时设定。
### *Snappy数据流压缩* :lollipop:
#### Compression
kcptun has builtin snappy algorithms for compressing streams:
> 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,
@@ -192,83 +291,107 @@ DSCP差分服务代码点(Differentiated Services Code Point),IETF于1998
> Reference: http://google.github.io/snappy/
通过参数 ```-nocomp``` 在两端同时设定以关闭压缩。
> 提示: 关闭压缩可能会降低延迟。
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.
### *内置模式* :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。
Compression is enabled by default, you can disable it by setting ```-nocomp``` on **BOTH** KCP Client & KCP Server **MUST** be **IDENTICAL**.
#### SNMP
### *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
BytesSent uint64 // bytes sent from upper level
BytesReceived uint64 // bytes received to upper level
MaxConn uint64 // max number of connections ever reached
ActiveOpens uint64 // accumulated active open connections
PassiveOpens uint64 // accumulated passive open connections
CurrEstab uint64 // current number of established connections
InErrs uint64 // UDP read errors reported from net.PacketConn
InCsumErrors uint64 // checksum errors from CRC32
KCPInErrors uint64 // packet iput errors reported from KCP
InPkts uint64 // incoming packets count
OutPkts uint64 // outgoing packets count
InSegs uint64 // incoming KCP segments
OutSegs uint64 // outgoing KCP segments
InBytes uint64 // UDP bytes received
OutBytes uint64 // UDP bytes sent
RetransSegs uint64 // accmulated retransmited segments
FastRetransSegs uint64 // accmulated fast retransmitted segments
EarlyRetransSegs uint64 // accmulated early retransmitted segments
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
FECParityShards uint64 // FEC segments received
FECShortShards uint64 // number of data shards that's not enough for recovery
}
```
使用```kill -SIGUSR1 pid``` 可以在控制台打印出SNMP信息,通常用于精细调整***当前链路的有效载荷比***。
观察```RetransSegs,FastRetransSegs,LostSegs,OutSegs```这几者的数值比例,用于参考调整```-mode manual,fec```的参数。
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.
### *故障排除* :lollipop:
> Q: 客户端和服务器端***皆无*** ```stream opened```信息。
> A: 连接客户端程序的端口设置错误。
### Manual Control
> 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`
### *免责申明* :warning:
用户以各种方式使用本软件(包括但不限于修改使用、直接使用、通过第三方使用)的过程中,不得以任何方式利用本软件直接或间接从事违反中国法律、以及社会公德的行为。软件的使用者需对自身行为负责,因使用软件引发的一切纠纷,由使用者承担全部法律及连带责任。作者不承担任何法律及连带责任。
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.
对免责声明的解释、修改及更新权均属于作者本人所有。
### *捐赠* :dollar:
![donate](donate.png)
### Identical Parmeters
对该项目的捐款将用于[gonet/2](http://gonet2.github.io/)游戏服务器框架的研发。
The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
```特别感谢: 郑H立, 南D风, Li, 七q, 凌J,昶,Les*ables, Ky*n, 噼**啦, 等,名字已做特殊处理。```
1. -key
1. -crypt
1. -nocomp
1. -datashard
1. -parityshard
### 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/LARTC-zh_CN.GB2312.pdf -- Linux Advanced Routing & Traffic Control
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
### 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" />
(注意:我没有任何社交网站的账号,请小心骗子。)
## Contributors
This project exists thanks to all the people who contribute.
<a href="https://github.com/xtaci/kcptun/graphs/contributors"><img src="https://opencollective.com/kcptun/contributors.svg?width=890&button=false" /></a>
## Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/kcptun#backer)]
<a href="https://opencollective.com/kcptun#backers" target="_blank"><img src="https://opencollective.com/kcptun/backers.svg?width=890"></a>
## Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/kcptun#sponsor)]
+64 -21
View File
@@ -1,8 +1,19 @@
#!/bin/bash
MD5='md5sum'
unamestr=`uname`
if [[ "$unamestr" == 'Darwin' ]]; then
MD5='md5'
BUILD_DIR=$(dirname "$0")/build
mkdir -p $BUILD_DIR
cd $BUILD_DIR
sum="sha1sum"
echo "If you need reproducible build, export GO111MODULE=on first"
if ! hash sha1sum 2>/dev/null; then
if ! hash shasum 2>/dev/null; then
echo "I can't see 'sha1sum' or 'shasum'"
echo "Please install one of them!"
exit
fi
sum="shasum"
fi
UPX=false
@@ -12,23 +23,36 @@ fi
VERSION=`date -u +%Y%m%d`
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS="-B"
GCFLAGS=""
# AMD64
OSES=(linux darwin windows freebsd)
ARCHS=(amd64 386)
for os in ${OSES[@]}; do
for arch in ${ARCHS[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_${arch}${suffix} github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_${arch}${suffix} github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_${os}_${arch}${suffix} server_${os}_${arch}${suffix};fi
tar -zcf kcptun-${os}-${arch}-$VERSION.tar.gz client_${os}_${arch}${suffix} server_${os}_${arch}${suffix}
$MD5 kcptun-${os}-${arch}-$VERSION.tar.gz
done
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_amd64${suffix} github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_amd64${suffix} github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_${os}_amd64${suffix} server_${os}_amd64${suffix};fi
tar -zcf kcptun-${os}-amd64-$VERSION.tar.gz client_${os}_amd64${suffix} server_${os}_amd64${suffix}
$sum kcptun-${os}-amd64-$VERSION.tar.gz
done
# 386
OSES=(linux windows)
for os in ${OSES[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_386${suffix} github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_386${suffix} github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_${os}_386${suffix} server_${os}_386${suffix};fi
tar -zcf kcptun-${os}-386-$VERSION.tar.gz client_${os}_386${suffix} server_${os}_386${suffix}
$sum kcptun-${os}-386-$VERSION.tar.gz
done
# ARM
@@ -36,7 +60,26 @@ ARMS=(5 6 7)
for v in ${ARMS[@]}; do
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm$v github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm$v github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm$v server_linux_arm$v;fi
tar -zcf kcptun-linux-arm$v-$VERSION.tar.gz client_linux_arm$v server_linux_arm$v
$sum kcptun-linux-arm$v-$VERSION.tar.gz
done
if $UPX; then upx -9 client_linux_arm* server_linux_arm*;fi
tar -zcf kcptun-linux-arm-$VERSION.tar.gz client_linux_arm* server_linux_arm*
$MD5 kcptun-linux-arm-$VERSION.tar.gz
# ARM64
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm64 github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm64 github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm64 server_linux_arm64*;fi
tar -zcf kcptun-linux-arm64-$VERSION.tar.gz client_linux_arm64 server_linux_arm64
$sum kcptun-linux-arm64-$VERSION.tar.gz
#MIPS32LE
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mipsle github.com/xtaci/kcptun/client
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
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+47
View File
@@ -0,0 +1,47 @@
package main
import (
"encoding/json"
"os"
)
// Config for client
type Config struct {
LocalAddr string `json:"localaddr"`
RemoteAddr string `json:"remoteaddr"`
Key string `json:"key"`
Crypt string `json:"crypt"`
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"`
DataShard int `json:"datashard"`
ParityShard int `json:"parityshard"`
DSCP int `json:"dscp"`
NoComp bool `json:"nocomp"`
AckNodelay bool `json:"acknodelay"`
NoDelay int `json:"nodelay"`
Interval int `json:"interval"`
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxBuf int `json:"smuxbuf"`
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 {
file, err := os.Open(path) // For read access.
if err != nil {
return err
}
defer file.Close()
return json.NewDecoder(file).Decode(config)
}
+275 -148
View File
@@ -2,85 +2,72 @@ package main
import (
"crypto/sha1"
"fmt"
"io"
"log"
"math/rand"
"net"
"os"
"sync"
"time"
"golang.org/x/crypto/pbkdf2"
"github.com/golang/snappy"
"github.com/hashicorp/yamux"
"github.com/pkg/errors"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/kcptun/generic"
"github.com/xtaci/smux"
)
var (
// VERSION is injected by buildflags
VERSION = "SELFBUILD"
// SALT is use for pbkdf2 key expansion
SALT = "kcp-go"
)
// SALT is use for pbkdf2 key expansion
const SALT = "kcp-go"
type compStream struct {
conn net.Conn
w *snappy.Writer
r *snappy.Reader
}
// VERSION is injected by buildflags
var VERSION = "SELFBUILD"
func (c *compStream) Read(p []byte) (n int, err error) {
return c.r.Read(p)
}
// A pool for stream copying
var xmitBuf sync.Pool
func (c *compStream) Write(p []byte) (n int, err error) {
n, err = c.w.Write(p)
err = c.w.Flush()
return n, err
}
func (c *compStream) Close() error {
return c.conn.Close()
}
func newCompStream(conn net.Conn) *compStream {
c := new(compStream)
c.conn = conn
c.w = snappy.NewBufferedWriter(conn)
c.r = snappy.NewReader(conn)
return c
}
func handleClient(p1, p2 io.ReadWriteCloser) {
log.Println("stream opened")
defer log.Println("stream closed")
func handleClient(sess *smux.Session, p1 net.Conn, quiet bool) {
logln := func(v ...interface{}) {
if !quiet {
log.Println(v...)
}
}
defer p1.Close()
p2, err := sess.OpenStream()
if err != nil {
logln(err)
return
}
defer p2.Close()
// start tunnel
p1die := make(chan struct{})
go func() {
io.Copy(p1, p2)
close(p1die)
}()
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(), ")"))
p2die := make(chan struct{})
go func() {
io.Copy(p2, p1)
close(p2die)
}()
// start tunnel & wait for tunnel termination
streamCopy := func(dst io.Writer, src io.ReadCloser) chan struct{} {
die := make(chan struct{})
go func() {
buf := xmitBuf.Get().([]byte)
generic.CopyBuffer(dst, src, buf)
xmitBuf.Put(buf)
close(die)
}()
return die
}
// wait for tunnel termination
select {
case <-p1die:
case <-p2die:
case <-streamCopy(p1, p2):
case <-streamCopy(p2, p1):
}
}
func checkError(err error) {
if err != nil {
log.Println(err)
log.Printf("%+v\n", err)
os.Exit(-1)
}
}
@@ -91,9 +78,13 @@ 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"
myApp.Usage = "kcptun client"
myApp.Usage = "client(with SMUX)"
myApp.Version = VERSION
myApp.Flags = []cli.Flag{
cli.StringFlag{
@@ -109,28 +100,38 @@ func main() {
cli.StringFlag{
Name: "key",
Value: "it's a secrect",
Usage: "pre-shared secret for client and server",
Usage: "pre-shared secret between client and server",
EnvVar: "KCPTUN_KEY",
},
cli.StringFlag{
Name: "crypt",
Value: "aes",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, none",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none",
},
cli.StringFlag{
Name: "mode",
Value: "fast",
Usage: "profiles: fast3, fast2, fast, normal",
Usage: "profiles: fast3, fast2, fast, normal, manual",
},
cli.IntFlag{
Name: "conn",
Value: 1,
Usage: "set num of UDP connections to server",
},
cli.IntFlag{
Name: "autoexpire",
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,
Usage: "set maximum transmission unit of UDP packets",
Usage: "set maximum transmission unit for UDP packets",
},
cli.IntFlag{
Name: "sndwnd",
@@ -139,24 +140,19 @@ 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",
},
cli.BoolFlag{
Name: "acknodelay",
Usage: "flush ack immediately when a packet is received",
Hidden: true,
},
cli.IntFlag{
Name: "dscp",
Value: 0,
@@ -166,6 +162,11 @@ func main() {
Name: "nocomp",
Usage: "disable compression",
},
cli.BoolFlag{
Name: "acknodelay",
Usage: "flush ack immediately when a packet is received",
Hidden: true,
},
cli.IntFlag{
Name: "nodelay",
Value: 0,
@@ -173,7 +174,7 @@ func main() {
},
cli.IntFlag{
Name: "interval",
Value: 40,
Value: 50,
Hidden: true,
},
cli.IntFlag{
@@ -187,41 +188,111 @@ func main() {
Hidden: true,
},
cli.IntFlag{
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Hidden: true,
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Usage: "per-socket buffer in bytes",
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Hidden: true,
Name: "smuxbuf",
Value: 4194304,
Usage: "the overall de-mux buffer in bytes",
},
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.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
Usage: "config from json file, which will override the command from shell",
},
}
myApp.Action = func(c *cli.Context) error {
config := Config{}
config.LocalAddr = c.String("localaddr")
config.RemoteAddr = c.String("remoteaddr")
config.Key = c.String("key")
config.Crypt = c.String("crypt")
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")
config.DataShard = c.Int("datashard")
config.ParityShard = c.Int("parityshard")
config.DSCP = c.Int("dscp")
config.NoComp = c.Bool("nocomp")
config.AckNodelay = c.Bool("acknodelay")
config.NoDelay = c.Int("nodelay")
config.Interval = c.Int("interval")
config.Resend = c.Int("resend")
config.NoCongestion = c.Int("nc")
config.SockBuf = c.Int("sockbuf")
config.SmuxBuf = c.Int("smuxbuf")
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"))
checkError(err)
}
// log redirect
if config.Log != "" {
f, err := os.OpenFile(config.Log, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
checkError(err)
defer f.Close()
log.SetOutput(f)
}
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 "fast2":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 20, 2, 1
case "fast3":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 10, 2, 1
}
log.Println("version:", VERSION)
addr, err := net.ResolveTCPAddr("tcp", c.String("localaddr"))
addr, err := net.ResolveTCPAddr("tcp", config.LocalAddr)
checkError(err)
listener, err := net.ListenTCP("tcp", addr)
checkError(err)
// kcp server
nodelay, interval, resend, nc := c.Int("nodelay"), c.Int("interval"), c.Int("resend"), c.Int("nc")
switch c.String("mode") {
case "normal":
nodelay, interval, resend, nc = 0, 30, 2, 1
case "fast":
nodelay, interval, resend, nc = 0, 20, 2, 1
case "fast2":
nodelay, interval, resend, nc = 1, 20, 2, 1
case "fast3":
nodelay, interval, resend, nc = 1, 10, 2, 1
}
crypt := c.String("crypt")
pass := pbkdf2.Key([]byte(c.String("key")), []byte(SALT), 4096, 32, sha1.New)
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
var block kcp.BlockCrypt
switch c.String("crypt") {
switch config.Crypt {
case "sm4":
block, _ = kcp.NewSM4BlockCrypt(pass[:16])
case "tea":
block, _ = kcp.NewTEABlockCrypt(pass[:16])
case "xor":
@@ -245,91 +316,147 @@ func main() {
case "salsa20":
block, _ = kcp.NewSalsa20BlockCrypt(pass)
default:
crypt = "aes"
config.Crypt = "aes"
block, _ = kcp.NewAESBlockCrypt(pass)
}
remoteaddr := c.String("remoteaddr")
datashard, parityshard := c.Int("datashard"), c.Int("parityshard")
mtu, sndwnd, rcvwnd := c.Int("mtu"), c.Int("sndwnd"), c.Int("rcvwnd")
nocomp, acknodelay := c.Bool("nocomp"), c.Bool("acknodelay")
dscp, sockbuf, keepalive, conn := c.Int("dscp"), c.Int("sockbuf"), c.Int("keepalive"), c.Int("conn")
log.Println("listening on:", listener.Addr())
log.Println("encryption:", crypt)
log.Println("nodelay parameters:", nodelay, interval, resend, nc)
log.Println("remote address:", remoteaddr)
log.Println("sndwnd:", sndwnd, "rcvwnd:", rcvwnd)
log.Println("compression:", !nocomp)
log.Println("mtu:", mtu)
log.Println("datashard:", datashard, "parityshard:", parityshard)
log.Println("acknodelay:", acknodelay)
log.Println("dscp:", dscp)
log.Println("sockbuf:", sockbuf)
log.Println("keepalive:", keepalive)
log.Println("conn:", conn)
log.Println("encryption:", config.Crypt)
log.Println("nodelay parameters:", config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
log.Println("remote address:", config.RemoteAddr)
log.Println("sndwnd:", config.SndWnd, "rcvwnd:", config.RcvWnd)
log.Println("compression:", !config.NoComp)
log.Println("mtu:", config.MTU)
log.Println("datashard:", config.DataShard, "parityshard:", config.ParityShard)
log.Println("acknodelay:", config.AckNodelay)
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("smuxbuf:", config.SmuxBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("conn:", config.Conn)
log.Println("autoexpire:", config.AutoExpire)
log.Println("scavengettl:", config.ScavengeTTL)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("quiet:", config.Quiet)
config := &yamux.Config{
AcceptBacklog: 256,
EnableKeepAlive: true,
KeepAliveInterval: 30 * time.Second,
ConnectionWriteTimeout: 10 * time.Second,
MaxStreamWindowSize: uint32(sockbuf),
LogOutput: os.Stderr,
}
createConn := func() *yamux.Session {
kcpconn, err := kcp.DialWithOptions(remoteaddr, block, datashard, parityshard)
checkError(err)
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
createConn := func() (*smux.Session, error) {
kcpconn, err := kcp.DialWithOptions(config.RemoteAddr, block, config.DataShard, config.ParityShard)
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
kcpconn.SetStreamMode(true)
kcpconn.SetNoDelay(nodelay, interval, resend, nc)
kcpconn.SetWindowSize(sndwnd, rcvwnd)
kcpconn.SetMtu(mtu)
kcpconn.SetACKNoDelay(acknodelay)
kcpconn.SetKeepAlive(keepalive)
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)
if err := kcpconn.SetDSCP(dscp); err != nil {
if err := kcpconn.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
}
if err := kcpconn.SetReadBuffer(sockbuf); err != nil {
if err := kcpconn.SetReadBuffer(config.SockBuf); err != nil {
log.Println("SetReadBuffer:", err)
}
if err := kcpconn.SetWriteBuffer(sockbuf); err != nil {
if err := kcpconn.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
// stream multiplex
var session *yamux.Session
if nocomp {
session, err = yamux.Client(kcpconn, config)
var session *smux.Session
if config.NoComp {
session, err = smux.Client(kcpconn, smuxConfig)
} else {
session, err = yamux.Client(newCompStream(kcpconn), config)
session, err = smux.Client(generic.NewCompStream(kcpconn), smuxConfig)
}
checkError(err)
return session
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
log.Println("connection:", kcpconn.LocalAddr(), "->", kcpconn.RemoteAddr())
return session, nil
}
numconn := uint16(conn)
var muxes []*yamux.Session
for i := uint16(0); i < numconn; i++ {
muxes = append(muxes, createConn())
// wait until a connection is ready
waitConn := func() *smux.Session {
for {
if session, err := createConn(); err == nil {
return session
} else {
log.Println("re-connecting:", err)
time.Sleep(time.Second)
}
}
}
numconn := uint16(config.Conn)
muxes := make([]struct {
session *smux.Session
ttl time.Time
}, numconn)
for k := range muxes {
muxes[k].session = waitConn()
muxes[k].ttl = time.Now().Add(time.Duration(config.AutoExpire) * time.Second)
}
chScavenger := make(chan *smux.Session, 128)
go scavenger(chScavenger, config.ScavengeTTL)
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
rr := uint16(0)
for {
p1, err := listener.AcceptTCP()
checkError(err)
mux := muxes[rr%numconn]
p2, err := mux.Open()
if err != nil { // yamux failure
log.Println(err)
p1.Close()
muxes[rr%numconn] = createConn()
mux.Close()
continue
if err != nil {
log.Fatalf("%+v", err)
}
go handleClient(p1, p2)
idx := rr % numconn
// 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)
}
go handleClient(muxes[idx].session, p1, config.Quiet)
rr++
}
}
myApp.Run(os.Args)
}
type scavengeSession struct {
session *smux.Session
ts time.Time
}
func scavenger(ch chan *smux.Session, ttl int) {
ticker := time.NewTicker(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", sess.RemoteAddr())
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.RemoteAddr())
s.session.Close()
} else if ttl >= 0 && time.Since(s.ts) >= time.Duration(ttl)*time.Second {
log.Println("session reached scavenge ttl", s.session.RemoteAddr())
s.session.Close()
} else {
newList = append(newList, sessionList[k])
}
}
sessionList = newList
}
}
}
+1
View File
@@ -18,6 +18,7 @@ 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: 4.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+41
View File
@@ -0,0 +1,41 @@
package generic
import (
"net"
"github.com/golang/snappy"
"github.com/pkg/errors"
)
type CompStream struct {
conn net.Conn
w *snappy.Writer
r *snappy.Reader
}
func (c *CompStream) Read(p []byte) (n int, err error) {
return c.r.Read(p)
}
func (c *CompStream) Write(p []byte) (n int, err error) {
if _, err := c.w.Write(p); err != nil {
return 0, errors.WithStack(err)
}
if err := c.w.Flush(); err != nil {
return 0, errors.WithStack(err)
}
return len(p), err
}
func (c *CompStream) Close() error {
return c.conn.Close()
}
func NewCompStream(conn net.Conn) *CompStream {
c := new(CompStream)
c.conn = conn
c.w = snappy.NewBufferedWriter(conn)
c.r = snappy.NewReader(conn)
return c
}
+36
View File
@@ -0,0 +1,36 @@
package generic
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")
}
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
}
+46
View File
@@ -0,0 +1,46 @@
package generic
import (
"encoding/csv"
"fmt"
"log"
"os"
"path/filepath"
"time"
"github.com/xtaci/kcp-go"
)
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()
}
}
}
+19
View File
@@ -0,0 +1,19 @@
module github.com/xtaci/kcptun
require (
github.com/golang/snappy v0.0.1
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.20.0
github.com/xtaci/kcp-go v5.4.2+incompatible
github.com/xtaci/smux v1.3.3
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7 // indirect
)
+163
View File
@@ -0,0 +1,163 @@
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.1 h1:kYrT1MlR4JH6PqOpC+okdb9CDTcwEC/BqpzK4WFyXL8=
github.com/klauspost/reedsolomon v1.9.1/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/klauspost/reedsolomon v1.9.2 h1:E9CMS2Pqbv+C7tsrYad4YC9MfhnMVWhMRsTi7U0UB18=
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/tjfoc/gmsm v1.0.1 h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU=
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/xtaci/kcp-go v5.0.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.1+incompatible h1:A6zXUGblo98vosfEdaHcy0cTBZKY2dByJxICuaV+L5g=
github.com/xtaci/kcp-go v5.1.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.2+incompatible h1:UafCgw2Yk3QOf8MRm8jYEWJt1l4J61BgLpMsROkJQxo=
github.com/xtaci/kcp-go v5.1.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.3+incompatible h1:s96+ulBrZlxk4DPRPgEGPBV8o55kYKKFVivDwVgZNcA=
github.com/xtaci/kcp-go v5.1.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.1.4+incompatible h1:GHIUAicdHMKwTys8sx2ZnZbFaK8lvmwDniQlFa2BOo4=
github.com/xtaci/kcp-go v5.1.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.3+incompatible h1:LD/Go8xYxtcyvOvFzeo387BV3UNPcwJvMY+8H+JDhfk=
github.com/xtaci/kcp-go v5.2.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.4+incompatible h1:96bjdOFrUFfU4wYXqGwPJkEOdvnVwciGlAGOHEDpgy8=
github.com/xtaci/kcp-go v5.2.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.5+incompatible h1:9C3xCFYCw6HUMN1/DQhLlUcbx1DmFiLbpiNA/moLYPM=
github.com/xtaci/kcp-go v5.2.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.6+incompatible h1:WokjD7IJJopwivFVIleBjmuHYlhGTlR/JAhCsapl1dk=
github.com/xtaci/kcp-go v5.2.6+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.7+incompatible h1:NkJrwfMj3K6lRHfppR8H+oayahPS6GkGGF4BKiRAiFg=
github.com/xtaci/kcp-go v5.2.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.2.8+incompatible h1:WRlKHMAWdB08NEmWW0cpdEQcJsOYRdFwP7lA62AhpWo=
github.com/xtaci/kcp-go v5.2.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.2+incompatible h1:sWzdr6Wcs/ZlRY0U8PeeMgpmtimIutFNfrxgQTPoA9U=
github.com/xtaci/kcp-go v5.3.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.3+incompatible h1:zlvskph4pBYpt5C8Y22GO2EL3saYpE/2WSZRUEKZXbE=
github.com/xtaci/kcp-go v5.3.3+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.4+incompatible h1:vHlrCvUC4nDSGQQxbgzwwF35sup3mKAxr5Wj3Yzg4c4=
github.com/xtaci/kcp-go v5.3.4+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.5+incompatible h1:PD0cqKLJDAMKgX2qzWfK98fbcrVPYDEdstlY0SN0q20=
github.com/xtaci/kcp-go v5.3.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.6+incompatible h1:g3/sc8dtbFG6td3W7BTyJNr/5Sb0zMNBFgEtqnSuxmw=
github.com/xtaci/kcp-go v5.3.6+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.7+incompatible h1:iWiEoXj7BnFNR1XUPAQssR8DJGw9E7BE0l1rqFCAi3Y=
github.com/xtaci/kcp-go v5.3.7+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.8+incompatible h1:1f9hBNbkoMfLryf0P82GzrMkSkqBLUztOmmqKqh7XxM=
github.com/xtaci/kcp-go v5.3.8+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.3.9+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.1+incompatible h1:zRYDrtFx/DBNI2pngZNOYxEDvWyGN6zZlIB2QcXHL9M=
github.com/xtaci/kcp-go v5.4.1+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go v5.4.2+incompatible h1:srUoSnFj4dkRzo2b+yz1WENGB32vAv0iuMS8wjYmaEI=
github.com/xtaci/kcp-go v5.4.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/smux v1.1.1 h1:ZyIo9XHuHkAeENzHR8yGWC+6xUSCTeP2tPTRE8mnLvc=
github.com/xtaci/smux v1.1.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.1.2 h1:AeAzHKqvDeFEcicL9Q06LTjIVW2I55iooUbpDRGHth4=
github.com/xtaci/smux v1.1.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.2 h1:pF/P78jvAXNG3yddhxKYTXMmNLzxXxdGKKjUBvxF8lk=
github.com/xtaci/smux v1.2.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.3/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.4 h1:l+peIfF3MUC5OmA93nKlezj8Nhejjv76BvnTyQEB2RI=
github.com/xtaci/smux v1.2.4/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.5 h1:p5K13hQEKeMo/H0XwO7jNxuT2G4/guo7Z7blfxBWBpI=
github.com/xtaci/smux v1.2.5/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.6 h1:lcooP+CKdWf1IE0d35eJ4MuUt7+kA3hwtQN0uPdd5lo=
github.com/xtaci/smux v1.2.6/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.7 h1:h7m7UL5zNZRaqEAtFXReqAVuStI3Al85zvJSGxqDqF0=
github.com/xtaci/smux v1.2.7/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.8 h1:mNFGEdnACCih1aER/JF4JVJIcOl7Mkf5yrQNzdDY6jg=
github.com/xtaci/smux v1.2.8/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.9 h1:aLBpFdORtDMzFJnrktW5hhe6UScbiS9inicP01KWR7M=
github.com/xtaci/smux v1.2.9/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.10 h1:DQiH08XfO+33X7l5XOGV5urQHrgK8PRFWYxT/z9Hrnw=
github.com/xtaci/smux v1.2.10/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.11 h1:QI4M2HgkkpsVU3Bfcmyx10qURBEeHfKi7xDhGEORfu0=
github.com/xtaci/smux v1.2.11/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.2.12 h1:POGYLDuR61+XZlVzKUdI4fTLtJnyVba++XS4Q6T5e3M=
github.com/xtaci/smux v1.2.12/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.1 h1:qMkK+dTu8ozfYz13UaX5q9GRIx0Qwux3FvcjtKZmDF8=
github.com/xtaci/smux v1.3.1/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.2 h1:8NsGbxBW6oSaeLu5E6V8AmklZm6EhBz7BeCOU3Zdhwc=
github.com/xtaci/smux v1.3.2/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
github.com/xtaci/smux v1.3.3 h1:+vnzZHTLGHrj+LzUZEkKmvu4KkG7fj4jwMPqhawvErg=
github.com/xtaci/smux v1.3.3/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a h1:Igim7XhdOpBnWPuYJ70XcNpq8q3BCACtVgNfoJxOV7g=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af h1:6qGQw30u837TXZbCmLFR9AVA+RjJU1LIbvk0oIkDZGY=
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd h1:sMHc2rZHuzQmrbVoSpt9HgerkXPyIeCSO6k0zUMGfFk=
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 h1:rlLehGeYg6jfoyz/eDqDU1iRXLKfR42nnNh57ytKEWo=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87 h1:yh5/K199RObPR6zqVBYf+AyJuweAqx+fOe9s3cekn1Y=
golang.org/x/net v0.0.0-20190324223953-e3b2ff56ed87/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190328230028-74de082e2cca h1:hyA6yiAgbUwuWqtscNvWAI7U1CtlaD1KilQ6iudt1aI=
golang.org/x/net v0.0.0-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190415214537-1da14a5a36f2 h1:iC0Y6EDq+rhnAePxGvJs2kzUAYcwESqdcGRPzEUfzTU=
golang.org/x/net v0.0.0-20190415214537-1da14a5a36f2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 h1:HdqqaWmYAUI7/dmByKKEw+yxDksGSo+9GjkUc9Zp34E=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424024845-afe8014c977f h1:uALRiwYevCJtciRa4mKKFkrs5jY4F2OTf1D2sfi1swY=
golang.org/x/net v0.0.0-20190424024845-afe8014c977f/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6 h1:FP8hkuE6yUEaJnK7O2eTuejKWwW+Rhfj80dQ2JcKxCU=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00=
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190329044733-9eb1bfa1ce65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190415145633-3fd5a3612ccd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190416152802-12500544f89f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190424031103-cb2dda6eabdf/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190428024724-550556f78a90/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190509153222-73554e0f7805/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190511041617-99f201b6807e/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190513233021-7d589f28aaf4/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190610231749-f8d1dee965f7/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 33 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

+45
View File
@@ -0,0 +1,45 @@
package main
import (
"encoding/json"
"os"
)
// Config for server
type Config struct {
Listen string `json:"listen"`
Target string `json:"target"`
Key string `json:"key"`
Crypt string `json:"crypt"`
Mode string `json:"mode"`
MTU int `json:"mtu"`
SndWnd int `json:"sndwnd"`
RcvWnd int `json:"rcvwnd"`
DataShard int `json:"datashard"`
ParityShard int `json:"parityshard"`
DSCP int `json:"dscp"`
NoComp bool `json:"nocomp"`
AckNodelay bool `json:"acknodelay"`
NoDelay int `json:"nodelay"`
Interval int `json:"interval"`
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxBuf int `json:"smuxbuf"`
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 {
file, err := os.Open(path) // For read access.
if err != nil {
return err
}
defer file.Close()
return json.NewDecoder(file).Decode(config)
}
+208 -137
View File
@@ -2,104 +2,101 @@ package main
import (
"crypto/sha1"
"fmt"
"io"
"log"
"math/rand"
"net"
"net/http"
_ "net/http/pprof"
"os"
"sync"
"time"
"golang.org/x/crypto/pbkdf2"
"github.com/golang/snappy"
"github.com/hashicorp/yamux"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
"github.com/xtaci/kcptun/generic"
"github.com/xtaci/smux"
)
var (
// VERSION is injected by buildflags
VERSION = "SELFBUILD"
// SALT is use for pbkdf2 key expansion
SALT = "kcp-go"
)
// SALT is use for pbkdf2 key expansion
const SALT = "kcp-go"
type compStream struct {
conn net.Conn
w *snappy.Writer
r *snappy.Reader
}
// VERSION is injected by buildflags
var VERSION = "SELFBUILD"
func (c *compStream) Read(p []byte) (n int, err error) {
return c.r.Read(p)
}
func (c *compStream) Write(p []byte) (n int, err error) {
n, err = c.w.Write(p)
err = c.w.Flush()
return n, err
}
func (c *compStream) Close() error {
return c.conn.Close()
}
func newCompStream(conn net.Conn) *compStream {
c := new(compStream)
c.conn = conn
c.w = snappy.NewBufferedWriter(conn)
c.r = snappy.NewReader(conn)
return c
}
// A pool for stream copying
var xmitBuf sync.Pool
// handle multiplex-ed connection
func handleMux(conn io.ReadWriteCloser, target string, config *yamux.Config) {
func handleMux(conn io.ReadWriteCloser, config *Config) {
// stream multiplex
mux, err := yamux.Server(conn, config)
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
mux, err := smux.Server(conn, smuxConfig)
if err != nil {
log.Println(err)
return
}
defer mux.Close()
for {
p1, err := mux.Accept()
stream, err := mux.AcceptStream()
if err != nil {
log.Println(err)
return
}
p2, err := net.DialTimeout("tcp", target, 5*time.Second)
if err != nil {
log.Println(err)
return
}
go handleClient(p1, p2)
go func(p1 *smux.Stream) {
p2, err := net.Dial("tcp", config.Target)
if err != nil {
log.Println(err)
p1.Close()
return
}
handleClient(p1, p2, config.Quiet)
}(stream)
}
}
func handleClient(p1, p2 io.ReadWriteCloser) {
log.Println("stream opened")
defer log.Println("stream closed")
func handleClient(p1 *smux.Stream, p2 net.Conn, quiet bool) {
logln := func(v ...interface{}) {
if !quiet {
log.Println(v...)
}
}
defer p1.Close()
defer p2.Close()
// start tunnel
p1die := make(chan struct{})
go func() {
io.Copy(p1, p2)
close(p1die)
}()
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())
p2die := make(chan struct{})
go func() {
io.Copy(p2, p1)
close(p2die)
}()
// start tunnel & wait for tunnel termination
streamCopy := func(dst io.Writer, src io.ReadCloser) chan struct{} {
die := make(chan struct{})
go func() {
buf := xmitBuf.Get().([]byte)
generic.CopyBuffer(dst, src, buf)
xmitBuf.Put(buf)
close(die)
}()
return die
}
// wait for tunnel termination
select {
case <-p1die:
case <-p2die:
case <-streamCopy(p1, p2):
case <-streamCopy(p2, p1):
}
}
func checkError(err error) {
if err != nil {
log.Printf("%+v\n", err)
os.Exit(-1)
}
}
@@ -109,9 +106,13 @@ 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"
myApp.Usage = "kcptun server"
myApp.Usage = "server(with SMUX)"
myApp.Version = VERSION
myApp.Flags = []cli.Flag{
cli.StringFlag{
@@ -127,23 +128,23 @@ func main() {
cli.StringFlag{
Name: "key",
Value: "it's a secrect",
Usage: "pre-shared secret for client and server",
Usage: "pre-shared secret between client and server",
EnvVar: "KCPTUN_KEY",
},
cli.StringFlag{
Name: "crypt",
Value: "aes",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, none",
Usage: "aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none",
},
cli.StringFlag{
Name: "mode",
Value: "fast",
Usage: "profiles: fast3, fast2, fast, normal",
Usage: "profiles: fast3, fast2, fast, normal, manual",
},
cli.IntFlag{
Name: "mtu",
Value: 1350,
Usage: "set maximum transmission unit of UDP packets",
Usage: "set maximum transmission unit for UDP packets",
},
cli.IntFlag{
Name: "sndwnd",
@@ -156,20 +157,15 @@ 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",
},
cli.BoolFlag{
Name: "acknodelay",
Usage: "flush ack immediately when a packet is received",
Hidden: true,
},
cli.IntFlag{
Name: "dscp",
Value: 0,
@@ -179,6 +175,11 @@ func main() {
Name: "nocomp",
Usage: "disable compression",
},
cli.BoolFlag{
Name: "acknodelay",
Usage: "flush ack immediately when a packet is received",
Hidden: true,
},
cli.IntFlag{
Name: "nodelay",
Value: 0,
@@ -186,7 +187,7 @@ func main() {
},
cli.IntFlag{
Name: "interval",
Value: 40,
Value: 50,
Hidden: true,
},
cli.IntFlag{
@@ -200,34 +201,109 @@ func main() {
Hidden: true,
},
cli.IntFlag{
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Hidden: true,
Name: "sockbuf",
Value: 4194304, // socket buffer size in bytes
Usage: "per-socket buffer in bytes",
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Hidden: true,
Name: "smuxbuf",
Value: 4194304,
Usage: "the overall de-mux buffer in bytes",
},
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",
},
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
Usage: "config from json file, which will override the command from shell",
},
}
myApp.Action = func(c *cli.Context) error {
log.Println("version:", VERSION)
nodelay, interval, resend, nc := c.Int("nodelay"), c.Int("interval"), c.Int("resend"), c.Int("nc")
switch c.String("mode") {
case "normal":
nodelay, interval, resend, nc = 0, 30, 2, 1
case "fast":
nodelay, interval, resend, nc = 0, 20, 2, 1
case "fast2":
nodelay, interval, resend, nc = 1, 20, 2, 1
case "fast3":
nodelay, interval, resend, nc = 1, 10, 2, 1
config := Config{}
config.Listen = c.String("listen")
config.Target = c.String("target")
config.Key = c.String("key")
config.Crypt = c.String("crypt")
config.Mode = c.String("mode")
config.MTU = c.Int("mtu")
config.SndWnd = c.Int("sndwnd")
config.RcvWnd = c.Int("rcvwnd")
config.DataShard = c.Int("datashard")
config.ParityShard = c.Int("parityshard")
config.DSCP = c.Int("dscp")
config.NoComp = c.Bool("nocomp")
config.AckNodelay = c.Bool("acknodelay")
config.NoDelay = c.Int("nodelay")
config.Interval = c.Int("interval")
config.Resend = c.Int("resend")
config.NoCongestion = c.Int("nc")
config.SockBuf = c.Int("sockbuf")
config.SmuxBuf = c.Int("smuxbuf")
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
err := parseJSONConfig(&config, c.String("c"))
checkError(err)
}
crypt := c.String("crypt")
pass := pbkdf2.Key([]byte(c.String("key")), []byte(SALT), 4096, 32, sha1.New)
// log redirect
if config.Log != "" {
f, err := os.OpenFile(config.Log, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
checkError(err)
defer f.Close()
log.SetOutput(f)
}
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 "fast2":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 20, 2, 1
case "fast3":
config.NoDelay, config.Interval, config.Resend, config.NoCongestion = 1, 10, 2, 1
}
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 crypt {
switch config.Crypt {
case "sm4":
block, _ = kcp.NewSM4BlockCrypt(pass[:16])
case "tea":
block, _ = kcp.NewTEABlockCrypt(pass[:16])
case "xor":
@@ -251,67 +327,62 @@ func main() {
case "salsa20":
block, _ = kcp.NewSalsa20BlockCrypt(pass)
default:
crypt = "aes"
config.Crypt = "aes"
block, _ = kcp.NewAESBlockCrypt(pass)
}
datashard, parityshard := c.Int("datashard"), c.Int("parityshard")
lis, err := kcp.ListenWithOptions(c.String("listen"), block, datashard, parityshard)
if err != nil {
log.Fatal(err)
}
lis, err := kcp.ListenWithOptions(config.Listen, block, config.DataShard, config.ParityShard)
checkError(err)
log.Println("listening on:", lis.Addr())
log.Println("target:", config.Target)
log.Println("encryption:", config.Crypt)
log.Println("nodelay parameters:", config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
log.Println("sndwnd:", config.SndWnd, "rcvwnd:", config.RcvWnd)
log.Println("compression:", !config.NoComp)
log.Println("mtu:", config.MTU)
log.Println("datashard:", config.DataShard, "parityshard:", config.ParityShard)
log.Println("acknodelay:", config.AckNodelay)
log.Println("dscp:", config.DSCP)
log.Println("sockbuf:", config.SockBuf)
log.Println("smuxbuf:", config.SmuxBuf)
log.Println("keepalive:", config.KeepAlive)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("pprof:", config.Pprof)
log.Println("quiet:", config.Quiet)
mtu, sndwnd, rcvwnd := c.Int("mtu"), c.Int("sndwnd"), c.Int("rcvwnd")
nocomp, acknodelay := c.Bool("nocomp"), c.Bool("acknodelay")
dscp, sockbuf, keepalive := c.Int("dscp"), c.Int("sockbuf"), c.Int("keepalive")
target := c.String("target")
log.Println("listening on ", lis.Addr())
log.Println("encryption:", crypt)
log.Println("nodelay parameters:", nodelay, interval, resend, nc)
log.Println("sndwnd:", sndwnd, "rcvwnd:", rcvwnd)
log.Println("compression:", !nocomp)
log.Println("mtu:", mtu)
log.Println("datashard:", datashard, "parityshard:", parityshard)
log.Println("acknodelay:", acknodelay)
log.Println("dscp:", dscp)
log.Println("sockbuf:", sockbuf)
log.Println("keepalive:", keepalive)
if err := lis.SetDSCP(dscp); err != nil {
if err := lis.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
}
if err := lis.SetReadBuffer(sockbuf); err != nil {
if err := lis.SetReadBuffer(config.SockBuf); err != nil {
log.Println("SetReadBuffer:", err)
}
if err := lis.SetWriteBuffer(sockbuf); err != nil {
if err := lis.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
config := &yamux.Config{
AcceptBacklog: 256,
EnableKeepAlive: true,
KeepAliveInterval: 30 * time.Second,
ConnectionWriteTimeout: 10 * time.Second,
MaxStreamWindowSize: uint32(sockbuf),
LogOutput: os.Stderr,
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
if config.Pprof {
go http.ListenAndServe(":6060", nil)
}
for {
if conn, err := lis.Accept(); err == nil {
if conn, err := lis.AcceptKCP(); err == nil {
log.Println("remote address:", conn.RemoteAddr())
conn.SetStreamMode(true)
conn.SetNoDelay(nodelay, interval, resend, nc)
conn.SetMtu(mtu)
conn.SetWindowSize(sndwnd, rcvwnd)
conn.SetACKNoDelay(acknodelay)
conn.SetKeepAlive(keepalive)
conn.SetWriteDelay(false)
conn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
conn.SetMtu(config.MTU)
conn.SetWindowSize(config.SndWnd, config.RcvWnd)
conn.SetACKNoDelay(config.AckNodelay)
if nocomp {
go handleMux(conn, target, config)
if config.NoComp {
go handleMux(conn, &config)
} else {
go handleMux(newCompStream(conn), target, config)
go handleMux(generic.NewCompStream(conn), &config)
}
} else {
log.Println(err)
log.Printf("%+v", err)
}
}
}
+1
View File
@@ -18,6 +18,7 @@ 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: 34 KiB