Compare commits

..
269 Commits
Author SHA1 Message Date
xtaci a1fa76173a upgrade to kcp-go@v5.5.14 2020-07-01 18:17:12 +08:00
xtaci 912a97993e upgrade to smux@v1.5.14 2020-05-20 23:13:35 +08:00
TexotandGitHub 706274829f Add iptables to docker image (#786) 2020-04-24 09:48:13 +08:00
xtaci 4358f5600f update Dockerfile 2020-04-10 21:49:24 +08:00
xtaci 7cf99098cf upd to v5.5.11 2020-03-22 22:02:19 +08:00
xtaci 720050cc39 upd deps 2020-03-22 21:48:55 +08:00
xtaci e99088b8d2 upd go.mod 2020-03-21 14:11:03 +08:00
xtaci 4b574ecbc1 a bugfix in kcp-go, upgrade to kcp-go/v5@v5.5.9 2020-03-09 21:26:41 +08:00
xtaci 8115fe5db9 upd deps to kcp-go 2020-02-25 11:00:58 +08:00
xtaci 0dabb34467 update travis.yml 2020-02-24 10:58:17 +08:00
xtaci c290f0b008 upd deps 2020-02-23 12:02:09 +08:00
xtaci 01e7b9f4c2 upd deps to smux to@v1.5.12 2020-02-20 19:24:20 +08:00
xtaci 0da917322c upgrade to kcp-go@v5.5.6 2020-02-09 14:54:49 +00:00
xtaci 23cd29a88e update deps to kcp-go to v5.5.5 2020-02-01 17:26:23 +08:00
xtaciandGitHub 3c54e12586 Update README.md 2020-01-21 20:08:16 +08:00
xtaci c71120e7d4 upd deps 2020-01-16 22:27:05 +08:00
xtaci ee29dc4fb1 upgrade deps 2020-01-16 22:16:39 +08:00
xtaciandGitHub 77dc451e83 Update README.md 2020-01-05 11:26:55 +08:00
xtaci 8c2d39753e upgrade to kcp-go@v5.5.3 2020-01-05 00:03:29 +08:00
xtaci 3790c74ca8 upgrade to kcp-go@v5.5.2 2020-01-04 23:48:27 +08:00
xtaci b07931c582 upgrade to kcp-go@5.5.0 2020-01-04 17:04:55 +08:00
xtaci d374f93447 upgrade kcp-go@v5.4.26 2020-01-03 19:51:28 +08:00
xtaci c8fa2a287f update to kcp-go@v5.4.25 2020-01-03 16:04:07 +08:00
xtaci eefaf5afac upgrade to kcp-go/v5@v5.4.23 2020-01-03 15:51:06 +08:00
xtaciandGitHub 3b5b4ac729 Update README.md 2020-01-02 13:13:36 +08:00
xtaciandGitHub b983528f33 Update README.md 2020-01-01 12:16:55 +08:00
xtaci 0f4131b7ae use go.mod based kcp-go 2019-12-31 22:45:36 +08:00
xtaci 0c315300a3 add an example systemd service 2019-12-31 15:09:22 +08:00
xtaci 7490778bbb upgrade to smux@v1.5.7 2019-12-29 18:39:24 +08:00
xtaci fc57c98098 rawcopy leads mistakes in smux in v2 2019-12-29 18:31:26 +08:00
xtaci 34bc48fd64 Squashed commit of the following:
commit 58d2c9d3468aa1c04f8cb60f0680186b6330804c
Author: xtaci <daniel820313@gmail.com>
Date:   Thu Dec 26 17:40:36 2019 +0800

    combine smux v1 & v2
2019-12-26 17:45:07 +08:00
xtaciandGitHub 56b45e84f7 Add files via upload 2019-12-20 10:26:12 +08:00
xtaci 98f93118cf smux@v1.4.8 & smux/v2@v2.0.18 2019-12-19 16:42:46 +08:00
xtaci dca5b2da39 upgrade deps to smux 2019-12-19 16:25:37 +08:00
xtaciandGitHub 5bd9b7e92b Update README.md 2019-12-19 15:15:46 +08:00
xtaci f3cccbb51c fix closing scheme 2019-12-19 14:52:45 +08:00
xtaci 4f88883837 fix termination sequence 2019-12-19 14:44:27 +08:00
xtaci 8a03eb1568 eliminate extra 1 goroutine per connection 2019-12-19 14:12:44 +08:00
xtaci 9e0d6f8ce8 upgrade to kcp-go@v5.4.20 2019-12-19 11:23:18 +08:00
xtaci de73ed90a5 add comments to rawCopy 2019-12-18 21:23:00 +08:00
xtaci 90ea4baa06 fallback on windows 2019-12-18 19:59:54 +08:00
xtaci c8c084a087 adjusts to 4k buf per mux 2019-12-18 16:42:24 +08:00
xtaci 5ad2b958a6 fix locking scheme 2019-12-18 16:26:46 +08:00
xtaci 361ba7600d fix error 2019-12-18 15:50:09 +08:00
xtaci 61e830c4e8 write controlled reading based on RawConn to buffer per stream 2019-12-18 15:42:48 +08:00
xtaci 216c7aaf6d upgrade smux to v1.4.6 & v2.0.16 2019-11-26 23:01:47 +08:00
xtaci 876e17ab18 upgrade to smux/v2@v2.0.15 2019-11-26 22:52:27 +08:00
xtaci 166dbca282 upgrade to github.com/xtaci/smux@v1.4.5 github.com/xtaci/smux/v2@v2.0.14, optimize Copy to use io.WriteTo 2019-11-26 22:18:57 +08:00
xtaci 24ff7caecb shrink per-direction buffer to 4k 2019-11-12 15:07:45 +08:00
xtaci 99abd12302 upgrade to smux@v2.0.13 2019-11-12 14:27:57 +08:00
xtaci 4a49552392 force GO111MODULE to on while compiling 2019-11-10 11:27:22 +08:00
xtaci 556de3055b upgrade to kcp-go@v5.4.19 2019-11-07 13:33:06 +08:00
xtaci 9d84f40720 upgrade to kcp-go@v5.4.18 2019-11-05 19:29:37 +08:00
xtaci f70791fc61 upgrade to kcp-go@v5.4.17 2019-11-05 14:47:40 +08:00
xtaci 8f2fcb7026 upgrade to kcp-go@v5.4.16 2019-11-04 16:12:37 +08:00
xtaci 2eec01d9c0 upgrade to kcp-go@v5.4.15 2019-11-04 12:37:57 +08:00
xtaci 047895f088 upgrade to kcp-go@v5.4.14 2019-11-02 00:46:42 +08:00
xtaciandGitHub b93460fb27 Delete wechat_donate.jpg 2019-11-01 15:42:18 +08:00
xtaciandGitHub 8ab062621e Update README.md 2019-11-01 15:41:53 +08:00
xtaci c380abfc75 upgrade to kcp-go@v5.4.13 2019-10-30 15:06:31 +00:00
xtaciandGitHub 029af29881 Update README.md 2019-10-26 21:46:23 +08:00
xtaciandGitHub b2720342c4 Update README.md 2019-09-28 10:47:45 +08:00
xtaciandGitHub b51ef20d30 Update README.md 2019-09-27 17:20:41 +08:00
xtaciandGitHub a95a000cad Update ISSUE_TEMPLATE 2019-09-27 12:06:21 +08:00
xtaciandGitHub c251f2c3b4 Update ISSUE_TEMPLATE 2019-09-27 12:05:27 +08:00
xtaciandGitHub ffb7f8aeaf Update README.md 2019-09-27 12:02:51 +08:00
xtaciandGitHub 265dd7eb1d Update README.md 2019-09-27 11:55:41 +08:00
xtaciandGitHub c21ba84b05 Update README.md 2019-09-27 11:41:14 +08:00
xtaci 7d06c5f2d7 upgrade to kcp-go@5.4.11 2019-09-26 11:14:12 +08:00
xtaci 7e648ff260 upgrade to kcp-go@5.4.10 2019-09-24 13:28:31 +08:00
xtaci 00db8d26ec upgrade to kcp-go@5.4.9 2019-09-23 22:02:38 +08:00
xtaci f45e756fca upgrade to kcp-go@5.4.8 2019-09-23 21:32:37 +08:00
xtaci 3530c325ba upgrade smux@v2.0.10 -> smux@v2.0.11 2019-09-22 21:59:51 +08:00
xtaci 6d6114bf26 update example json for smux v2 2019-09-22 20:51:39 +08:00
xtaci cda9de7d8d go mod tidy 2019-09-22 18:41:19 +08:00
xtaci 9004bf3170 update Dockerfile to support GO111MODULE 2019-09-22 18:06:09 +08:00
xtaci 903cb9f9f1 update .travis.yml 2019-09-22 17:45:40 +08:00
xtaci 6c46285010 upd to kcp-go@5.4.7 2019-09-22 17:42:01 +08:00
xtaci 1b72bf39d8 verbose logging on smux establishment 2019-09-22 16:41:23 +08:00
xtaci 112870d870 1->2 2019-09-22 16:31:02 +08:00
xtaci a859f419f6 verbose error handling for smux protocol 2019-09-22 14:47:38 +08:00
xtaci fa728236d4 only output protocol error in streamCopy 2019-09-22 14:40:14 +08:00
xtaci ade7ee06a0 stream copy print high-level error 2019-09-22 13:47:11 +08:00
xtaci 30cca4d7db half default streambuf to 2097152 bytes 2019-09-22 12:43:54 +08:00
xtaci 0f18b17a8a fix spelling 2019-09-22 12:32:07 +08:00
xtaci 1b756aeb3d adjust sequence of startup log 2019-09-22 11:12:55 +08:00
xtaci a69b0a90ed fix generic.Stream interface type error 2019-09-22 11:03:16 +08:00
xtaci 8778495915 upd deps smuxv2 2019-09-22 10:54:30 +08:00
xtaci 13deb22077 upd deps 2019-09-22 00:18:30 +08:00
xtaci 1635649aa5 upd deps 2019-09-22 00:02:21 +08:00
xtaci 3425d6288b upd deps 2019-09-21 23:56:05 +08:00
xtaci fe3227db22 update smux deps 2019-09-21 23:43:22 +08:00
xtaci 2684e47946 upd default value for streambuf 2019-09-21 22:30:26 +08:00
xtaci fcb6a5e141 add -smuxver to support smux version 2 2019-09-21 20:59:41 +08:00
xtaci ff9a67e931 upgrade kcp-go to v5.4.5 2019-09-10 22:14:24 +08:00
xtaci f288fe9ea6 upd deps 2019-09-10 20:57:21 +08:00
xtaci 7a42a51643 remove obsolete file 2019-09-06 14:18:02 +08:00
xtaci bd4051bd02 make server listen dual stack on tcp & udp if -tcp is specified 2019-09-06 14:15:18 +08:00
xtaci bab23e05b0 upd deps 2019-09-05 13:54:25 +08:00
xtaciandGitHub 4200cc7ef6 Update README.md 2019-08-13 18:14:24 +08:00
xtaci d9df85de52 upd deps 2019-08-08 12:53:24 +00:00
xtaci 379ce89334 upd deps 2019-08-08 09:33:05 +00:00
xtaci 34aaf35425 upd deps 2019-07-25 16:30:34 +08:00
xtaci 375d7bff86 support unix domain socket 2019-07-23 09:13:37 +00:00
xtaci 4e9d289d7a fix 2019-07-23 09:00:16 +00:00
xtaci b5f98ed351 support unix domain socket 2019-07-23 08:57:58 +00:00
xtaci 4cc3e083d8 Merge branch 'master' of https://github.com/xtaci/kcptun 2019-07-23 06:57:19 +00:00
xtaci adae541dd9 upd deps 2019-07-23 06:56:25 +00:00
xtaci 0734e23cf3 fix build issue 2019-07-23 11:08:45 +08:00
xtaci 6a8b0f70e7 upd deps 2019-07-22 11:13:27 +00:00
xtaci f8454de6b6 upd deps 2019-07-18 05:46:46 +00:00
xtaci e97e49498e upd deps 2019-07-17 07:47:41 +00:00
xtaci 9f2ff06ec8 upd deps 2019-07-16 08:47:36 +00:00
xtaci 6715764c4f upd deps 2019-07-15 13:57:07 +08:00
xtaci 62f2ffe2d8 Merge branch 'master' of https://github.com/xtaci/kcptun 2019-07-14 10:29:56 +00:00
xtaci 90b9f85617 upd 2019-07-14 10:28:59 +00:00
xtaci e619848985 upd 2019-07-14 12:17:40 +08:00
xtaci 7f93fb5858 upd deps 2019-07-13 07:22:04 +00:00
xtaci 7b8a4646fc upd deps 2019-07-13 05:01:55 +00:00
xtaci b5487cd0ce upd deps 2019-07-12 16:38:16 +00:00
xtaci acfe430810 upd deps 2019-07-12 16:16:29 +00:00
xtaci 9285b162b7 upd deps 2019-07-12 16:02:00 +00:00
xtaci 8d13f9be89 upd deps 2019-07-12 15:22:09 +00:00
xtaci 4ba9028985 upd deps 2019-07-12 06:25:06 +00:00
xtaci b4473a5413 print address on compressed connection 2019-07-11 15:24:54 +00:00
xtaci 3b01e69ba2 upd deps 2019-07-11 13:47:45 +00:00
xtaci 76b658917a add example config json file 2019-07-11 13:38:47 +00:00
xtaci b260423213 upd deps 2019-07-11 10:17:15 +00:00
xtaci 72fbf47844 upd deps 2019-07-11 08:01:44 +00:00
xtaci 8daf4edd0a upd deps 2019-07-11 04:30:12 +00:00
xtaci c8d917f400 upd desp 2019-07-10 05:38:28 +00:00
xtaci db88c47847 upd deps 2019-07-09 08:22:09 +00:00
xtaci 32ecbcdc34 upd deps 2019-07-09 07:45:25 +00:00
xtaci 3f8089807e upd 2019-07-08 13:22:39 +00:00
xtaci bdd293f180 upd 2019-07-08 12:45:33 +00:00
xtaci bd4a02a193 upd deps 2019-07-08 09:54:37 +00:00
xtaci bb6bf9985c simplify dial/listen 2019-07-08 07:13:28 +00:00
xtaci 3923bba92c upd deps 2019-07-08 06:33:51 +00:00
xtaci d6f97d1f4a upd deps 2019-07-05 08:11:38 +00:00
xtaci 255bb85640 upd 2019-07-04 23:06:02 +08:00
xtaci d5104ec4f1 upd script 2019-07-04 07:01:02 +00:00
xtaci addeb3b2df upd deps 2019-07-04 06:58:29 +00:00
xtaci 2feb1129f2 upd deps 2019-07-04 06:37:00 +00:00
xtaci efff54a699 upd build-release.sh 2019-07-04 05:19:43 +00:00
xtaci 6a84007ab0 fix dockerfile 2019-07-04 12:38:36 +08:00
xtaci 468cafff85 fix version 2019-07-03 14:08:10 +00:00
xtaci 002827cbaa add comment 2019-07-03 13:36:58 +00:00
xtaci 3260e4d346 Squashed commit of the following:
commit f3022926ae0c0d176088c299f40df47b472b7a52
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 13:18:04 2019 +0000

    enable tcp option

commit e8be0df1d071a2cab0c2c3bc573af0fd836d852e
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 13:01:22 2019 +0000

    fix compile for i386

commit 03d15811558f6aedc9d58b4eeef17b563186ac4b
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 12:35:02 2019 +0000

    upd build-release.sh and simplify platformd-depedent dial/listen

commit b8240d92ea453b397a5662c19c5ffebf3356af78
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 09:49:01 2019 +0000

    simplify listening

commit e2e87b6f8dcabbd91d521f02baa00443c0ad1df3
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 09:41:43 2019 +0000

    simplify dialing
2019-07-03 13:19:16 +00:00
xtaci 60bee85c51 Squashed commit of the following:
commit e8be0df1d071a2cab0c2c3bc573af0fd836d852e
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 13:01:22 2019 +0000

    fix compile for i386

commit 03d15811558f6aedc9d58b4eeef17b563186ac4b
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 12:35:02 2019 +0000

    upd build-release.sh and simplify platformd-depedent dial/listen

commit b8240d92ea453b397a5662c19c5ffebf3356af78
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 09:49:01 2019 +0000

    simplify listening

commit e2e87b6f8dcabbd91d521f02baa00443c0ad1df3
Author: xtaci <daniel820313@gmail.com>
Date:   Wed Jul 3 09:41:43 2019 +0000

    simplify dialing
2019-07-03 13:02:23 +00:00
xtaci 3a649e369c upd travis 2019-07-02 07:51:58 +00:00
xtaci 7cc7454c7c upd 2019-07-02 07:48:32 +00:00
xtaci 9ba6c75eff upd deps 2019-07-02 07:38:51 +00:00
xtaci 1a28b61d45 upd README.md 2019-07-01 12:19:15 +00:00
xtaci 5bf748b8b5 Revert "support -tcp", keep on tcp branch
This reverts commit 770f5c00da.
2019-06-27 21:49:44 +00:00
xtaci 04602bfb9f upd deps 2019-06-27 21:15:40 +00:00
xtaci 9dee7cb401 upd dep 2019-06-27 20:27:17 +00:00
xtaci 7e53f045d2 upd 2019-06-27 20:04:06 +00:00
xtaci 951521a0a6 upd deps 2019-06-27 16:16:58 +00:00
xtaci d0b4365909 upd 2019-06-27 15:44:30 +00:00
xtaci 51192afeba upds deps 2019-06-27 15:33:13 +00:00
xtaciandGitHub 1ab630df33 Update README.md 2019-06-27 15:17:24 +08:00
xtaciandGitHub 18113ed797 Update README.md 2019-06-27 15:13:11 +08:00
xtaci 770f5c00da support -tcp 2019-06-27 15:10:00 +08:00
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
27 changed files with 983 additions and 373 deletions
+16 -14
View File
@@ -1,27 +1,29 @@
问问题前先搜索ISSUE,并搞清楚下面的问题:
1. 检查 ```-key xxx``` 至少三遍, ***保证***两边一致。
2. 保证```-nocomp, -datashard, -parityshard, -key, -crypt```两边一致。
2. 保证```-nocomp, -datashard, -parityshard, -key, -crypt, -smuxver```两边一致。
3. 是否在服务器端,正确设定了转发的目标服务器地址 ***--target***。
4. 如果第3条不确定,尝试在服务器上telnet target port试试
5. 防火墙是否关闭了UDP通信
6. 两端的版本是否一致
7. 是不是最新版本
8. 两端分别是什么操作系统
9. 两端的输出日志是什么
4. 是否在客户端,正确的连接到了 client的监听端口
5. 如果第3条不确定,尝试在服务器上telnet target port试试
6. 防火墙是否关闭了UDP通信,或者设置了UDP的最大发包速率
7. 两端的版本是否一致
8. 是不是最新版本
9. 两端分别是什么操作系统
10. 两端的输出日志是什么?
Before firing issue, make sure you figured out the following common questions.
PLEASE DO SEARCH FIRST.
1. Check your ```-key xxx``` for at least 3 times, ***MAKE SURE*** both sides share the same secret.
2. ```-nocomp, -datashard, -parityshard, -key, -crypt``` ***must be the same*** on both side.
2. ```-nocomp, -datashard, -parityshard, -key, -crypt, -smuxver``` ***must be the same*** on both side.
3. Did you correctly set the ***-target*** on the server side?
4. ***MAKE SURE*** ```telnet target port``` on your server successful(don't ask me why couldn't).
5. Does your ***firewall allows UDP*** communications? (including your ISP Cable-Modem)
6. Are you using the **same version** for both client & server
7. Are you using the **latest release**?
8. Which **OS** do you use?
9. Which end for this issue related to, **client or server**?
4. Did you correctly connected to the listening port on client side?
5. ***MAKE SURE*** ```telnet target port``` on your server successful(don't ask me why couldn't).
6. Does your ***firewall allows UDP*** communications? (including your ISP Cable-Modem)
7. Are you using the **same version** for both client & server
8. Are you using the **latest release**?
9. Which **OS** do you use?
10. Which end for this issue related to, **client or server**?
+2
View File
@@ -24,3 +24,5 @@ _testmain.go
*.prof
client/client
server/server
build/*
.DS_Store
+5 -5
View File
@@ -1,16 +1,16 @@
language: go
go:
- 1.9
- 1.13.x
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
install:
- go get github.com/xtaci/kcptun/client
- go get github.com/xtaci/kcptun/server
- env GO111MODULE=on go get github.com/xtaci/kcptun/client
- env GO111MODULE=on go get github.com/xtaci/kcptun/server
before_script:
script:
- cd $HOME/gopath/src/github.com/xtaci/kcptun/client
- $HOME/gopath/bin/goveralls -service=travis-ci
- env GO111MODULE=on $HOME/gopath/bin/goveralls -service=travis-ci
- cd $HOME/gopath/src/github.com/xtaci/kcptun/server
- $HOME/gopath/bin/goveralls -service=travis-ci
- env GO111MODULE=on $HOME/gopath/bin/goveralls -service=travis-ci
- exit 0
+5 -3
View File
@@ -1,11 +1,13 @@
FROM golang:alpine as builder
FROM golang:1.14.2-alpine3.11 as builder
MAINTAINER xtaci <daniel820313@gmail.com>
ENV GO111MODULE=on
RUN apk update && \
apk upgrade && \
apk add git
apk add git gcc libc-dev linux-headers
RUN go get -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" github.com/xtaci/kcptun/client && go get -ldflags "-X main.VERSION=$(date -u +%Y%m%d) -s -w" github.com/xtaci/kcptun/server
FROM alpine:3.6
FROM alpine:3.11
RUN apk add --no-cache iptables
COPY --from=builder /go/bin /bin
EXPOSE 29900/udp
EXPOSE 12948
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+166 -77
View File
@@ -1,58 +1,93 @@
# <img src="logo.png" alt="kcptun" height="54px" />
[![Release][13]][14] [![Powered][17]][18] [![MIT licensed][11]][12] [![Build Status][3]][4] [![Go Report Card][5]][6] [![Downloads][15]][16] [![Docker][1]][2]
[![Release][13]][14] [![Powered][17]][18] [![MIT licensed][11]][12] [![Build Status][3]][4] [![Go Report Card][5]][6] [![Downloads][15]][16] [![Docker][1]][2]
[1]: https://images.microbadger.com/badges/image/xtaci/kcptun.svg
[2]: https://microbadger.com/images/xtaci/kcptun
[1]: https://img.shields.io/docker/pulls/xtaci/kcptun
[2]: https://hub.docker.com/r/xtaci/kcptun
[3]: https://travis-ci.org/xtaci/kcptun.svg?branch=master
[4]: https://travis-ci.org/xtaci/kcptun
[5]: https://goreportcard.com/badge/github.com/xtaci/kcptun
[6]: https://goreportcard.com/report/github.com/xtaci/kcptun
[7]: https://img.shields.io/badge/license-MIT-blue.svg
[8]: https://raw.githubusercontent.com/xtaci/kcptun/master/LICENSE.md
[11]: https://img.shields.io/badge/license-MIT-blue.svg
[11]: https://img.shields.io/github/license/xtaci/kcptun
[12]: LICENSE.md
[13]: https://img.shields.io/github/release/xtaci/kcptun.svg
[13]: https://img.shields.io/github/v/release/xtaci/kcptun?color=orange
[14]: https://github.com/xtaci/kcptun/releases/latest
[15]: https://img.shields.io/github/downloads/xtaci/kcptun/total.svg?maxAge=1800
[15]: https://img.shields.io/github/downloads/xtaci/kcptun/total.svg?maxAge=1800&color=orange
[16]: https://github.com/xtaci/kcptun/releases
[17]: https://img.shields.io/badge/KCP-Powered-blue.svg
[18]: https://github.com/skywind3000/kcp
<img src="kcptun.png" alt="kcptun" height="300px"/>
> *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. kcptun won't publish anything on any social media.*
> *Disclaimer: kcptun maintains a single website — [github.com/xtaci/kcptun](https://github.com/xtaci/kcptun). Any websites other than [github.com/xtaci/kcptun](https://github.com/xtaci/kcptun) are not endorsed by xtaci.*
### Requirements
| Target | Minimum | Recommended |
| --- | --- | --- |
| System | aix darwin dragonfly freebsd linux netbsd openbsd solaris windows | linux |
| Memory | >20MB | >32MB |
| CPU | ANY | amd64 with AES-NI & AVX2 |
> *KCP communication group: 364933586 (QQ group number), KCP integration, tuning, network transmission and related technical discussions.*
### QuickStart
Download precompiled [Releases](https://github.com/xtaci/kcptun/releases).
Increase the number of open files on your server, as:
`ulimit -n 65535`, or write it in `~/.bashrc`.
Suggested `sysctl.conf` parameters for better handling of UDP packets:
```
KCP Client: ./client_darwin_amd64 -r "KCP_SERVER_IP:4000" -l ":8388" -mode fast2
KCP Server: ./server_linux_amd64 -t "TARGET_IP:8388" -l ":4000" -mode fast2
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
```
The above commands will establish port forwarding for 8388/tcp as:
You can also increase the per-socket buffer by adding parameter(default 4MB):
```
-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)
Tunnels the original connection:
which tunnels the original connection:
> Application -> Target Server(8388/tcp)
### Install from source
### Build from source
```
$go get -u github.com/xtaci/kcptun/client
$go get -u github.com/xtaci/kcptun/server
$ git clone https://github.com/xtaci/kcptun.git
$ cd kcptun
$ ./build-release.sh
$ cd build
```
All precompiled releases are genereated from `build-release.sh` script.
### Performance
<img src="fast.png" alt="fast.com" height="256px" />
<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
@@ -75,7 +110,17 @@ All precompiled releases are genereated from `build-release.sh` script.
> *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.
For versions >= v20190924, you can switch to smux version 2, smux v2 has options to limit per-stream memory usage, now set `-smuxver 2` to enable smux v2, and adjust `-streambuf` to limit per-stream memory usage, eg: `-streambuf 2097152` can limit per-stream memory usage to 2MB. By limiting stream buffer on the receiver side, a back-pressure will be conducted to the sender and limits reading, and finally prevent source from sending too much data to occupy every bits of buffer along the link. (Setting -smuxver **MUST** be **IDENTICAL** on both side, default is 1. )
#### Slow Devices
kcptun made use of **ReedSolomon-Codes** to recover lost packets, which requires massive amount of computation, a low-end ARM device cannot satisfy kcptun well. To unleash the full potential of kcptun, a multi-core x86 homeserver CPU like AMD Opteron is recommended.
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
@@ -86,27 +131,28 @@ All precompiled releases are genereated from `build-release.sh` script.
#### Usage
```
$ ./client_darwin_amd64 -h
➜ ~ ./client_linux_amd64 -h
NAME:
kcptun - client(with SMUX)
USAGE:
client_darwin_amd64 [global options] command [command options] [arguments...]
client_linux_amd64 [global options] command [command options] [arguments...]
VERSION:
20170120
20190924
COMMANDS:
help, h Shows a list of commands or help for one command
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--localaddr value, -l value local listen address (default: ":12948")
--remoteaddr value, -r value kcp server address (default: "vps:29900")
--key value pre-shared secret between client and server (default: "it's a secrect") [$KCPTUN_KEY]
--crypt value aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--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)
@@ -114,32 +160,39 @@ GLOBAL OPTIONS:
--parityshard value, --ps value set reed-solomon erasure coding - parityshard (default: 3)
--dscp value set DSCP(6bit) (default: 0)
--nocomp disable compression
--sockbuf value per-socket buffer in bytes (default: 4194304)
--smuxver value specify smux version, available 1,2 (default: 1)
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
--streambuf value per stream receive buffer in bytes, smux v2+ (default: 2097152)
--keepalive value seconds between heartbeats (default: 10)
--snmplog value collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
--snmpperiod value snmp collect period, in seconds (default: 60)
--log value specify a log file to output, default goes to stderr
--quiet to suppress the 'stream open/close' messages
--tcp to emulate a TCP connection(linux)
-c value config from json file, which will override the command from shell
--help, -h show help
--version, -v print the version
$ ./server_darwin_amd64 -h
➜ ~ ./server_linux_amd64 -h
NAME:
kcptun - server(with SMUX)
USAGE:
server_darwin_amd64 [global options] command [command options] [arguments...]
server_linux_amd64 [global options] command [command options] [arguments...]
VERSION:
20170120
20190924
COMMANDS:
help, h Shows a list of commands or help for one command
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--listen value, -l value kcp server listen address (default: ":29900")
--target value, -t value target server address (default: "127.0.0.1:12948")
--target value, -t value target server address, or path/to/unix_socket (default: "127.0.0.1:12948")
--key value pre-shared secret between client and server (default: "it's a secrect") [$KCPTUN_KEY]
--crypt value aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, none (default: "aes")
--mode value profiles: fast3, fast2, fast, normal (default: "fast")
--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)
@@ -147,9 +200,17 @@ GLOBAL OPTIONS:
--parityshard value, --ps value set reed-solomon erasure coding - parityshard (default: 3)
--dscp value set DSCP(6bit) (default: 0)
--nocomp disable compression
--sockbuf value per-socket buffer in bytes (default: 4194304)
--smuxver value specify smux version, available 1,2 (default: 1)
--smuxbuf value the overall de-mux buffer in bytes (default: 4194304)
--streambuf value per stream receive buffer in bytes, smux v2+ (default: 2097152)
--keepalive value seconds between heartbeats (default: 10)
--snmplog value collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
--snmpperiod value snmp collect period, in seconds (default: 60)
--pprof start profiling server on :6060
--log value specify a log file to output, default goes to stderr
--quiet to suppress the 'stream open/close' messages
--tcp to emulate a TCP connection(linux)
-c value config from json file, which will override the command from shell
--help, -h show help
--version, -v print the version
@@ -157,11 +218,11 @@ GLOBAL OPTIONS:
#### Forward Error Correction
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.
In coding theory, the [ReedSolomon code](https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction) belongs to the class of non-binary cyclic error-correcting codes. The ReedSolomon code is based on univariate polynomials over finite fields.
It is able to detect and correct multiple symbol errors. By adding t check symbols to the data, a ReedSolomon code can detect any combination of up to t erroneous symbols, or correct up to ⌊t/2⌋ symbols. As an erasure code, it can correct up to t known erasures, or it can detect and correct combinations of errors and erasures. Furthermore, ReedSolomon codes are suitable as multiple-burst bit-error correcting codes, since a sequence of b + 1 consecutive bit errors can affect at most two symbols of size b. The choice of t is up to the designer of the code, and may be selected within wide limits.
![reed-solomon](rs.png)
![FED](FEC.png)
Setting parameters of RS-Code with ```-datashard m -parityshard n``` on **BOTH** KCP Client & KCP Server **MUST** be **IDENTICAL**.
@@ -173,39 +234,68 @@ DiffServ uses a 6-bit differentiated services code point (DSCP) in the 8-bit dif
setting each side with ```-dscp value```, Here are some [Commonly used DSCP values](https://en.wikipedia.org/wiki/Differentiated_services#Commonly_used_DSCP_values).
#### Security
#### Cryptanalysis
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 .
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.
`-crypt` and `-key` must be the same on both KCP Client & KCP Server.
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).
NOTICE: ```-crypt xor``` is also insecure, do not use this unless you know what you are doing.
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:
```
BenchmarkAES128-4 200000 11182 ns/op
BenchmarkAES192-4 200000 12699 ns/op
BenchmarkAES256-4 100000 13757 ns/op
BenchmarkTEA-4 50000 26441 ns/op
BenchmarkSimpleXOR-4 3000000 441 ns/op
BenchmarkBlowfish-4 30000 48036 ns/op
BenchmarkNone-4 20000000 106 ns/op
BenchmarkCast5-4 20000 60222 ns/op
BenchmarkTripleDES-4 2000 878759 ns/op
BenchmarkTwofish-4 20000 68501 ns/op
BenchmarkXTEA-4 20000 77417 ns/op
BenchmarkSalsa20-4 300000 4998 ns/op
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
```
Benchmark result from openssl
```
$ 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
```
The encrytion performance in kcptun is as fast as in openssl library(if not faster).
#### Memory Control
Routers, mobile devices are sensitive to memory consumption; by setting GOGC environment(eg: GOGC=20) will lower memory consumption.
Routers, mobile devices are susceptible to memory consumption; by setting GOGC environment(eg: GOGC=20) will make the garbage collector to recycle faster.
Reference: https://blog.golang.org/go15gc
Primary memory allocation are done from a global buffer pool *xmit.Buf*, in kcp-go, when we need to allocate some bytes, we can get from that pool, and a *fixed-capacity* 1500 bytes(mtuLimit) will be returned, the *rx queue*, *tx queue* and *fec queue* all receive bytes from there, and they will return the bytes to the pool after using to prevent *unnecessary zer0ing* of bytes.
The pool mechanism maintained a *high watermark* for slice objects, these *in-flight* objects from the pool will survive from the perodical garbage collection, meanwhile the pool kept the ability to return the memory to runtime if in idle, `-sndwnd`,`-rcvwnd`,`-ds`, `-ps`, these parameters affect this *high watermark*, the larger the value, the bigger the memory consumption will be.
`-smuxbuf` also affects the maximum memory consumption, this parameter maintains a subtle balance between *concurrency* and *resource*, you can increase this value(default 4MB) to boost concurrency if you have many clients to serve and you get a powerful server at the same time, and also you can decrease this value to serve only 1 or 2 clients and hope this program can run under some embeded SoC system with limited memory and only you can access. (Notice that the `-smuxbuf` value is not proprotional to concurrency, you need to test.)
#### Compression
kcptun has builtin snappy algorithms for compressing streams:
@@ -219,36 +309,37 @@ kcptun has builtin snappy algorithms for compressing streams:
> Reference: http://google.github.io/snappy/
Compression may save bandwidth for **PLAINTEXT** data, such as HTTP data.
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.
Compression is enabled by default, you can disable it by setting ```-nocomp``` on **BOTH** KCP Client & KCP Server **MUST** be **IDENTICAL**.
#### SNMP
```go
// Snmp defines network statistics indicator
type Snmp struct {
BytesSent uint64 // raw bytes sent
BytesReceived uint64
MaxConn uint64
ActiveOpens uint64
PassiveOpens uint64
CurrEstab uint64 // count of connections for now
InErrs uint64 // udp read errors
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 from kcp
InSegs uint64
OutSegs uint64
InBytes uint64 // udp bytes received
OutBytes uint64 // udp bytes sent
RetransSegs uint64
FastRetransSegs uint64
EarlyRetransSegs uint64
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
FECSegs uint64 // FEC segments received
FECParityShards uint64 // FEC segments received
FECShortShards uint64 // number of data shards that's not enough for recovery
}
```
@@ -273,6 +364,7 @@ The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
1. -nocomp
1. -datashard
1. -parityshard
1. -smuxver
### References
@@ -291,10 +383,7 @@ The parameters below **MUST** be **IDENTICAL** on **BOTH** side:
1. http://http2.github.io/ -- What is HTTP/2?
1. http://www.lartc.org/ -- Linux Advanced Routing & Traffic Control
1. https://en.wikipedia.org/wiki/Noisy-channel_coding_theorem -- Noisy channel coding theorem
1. https://play.google.com/store/apps/details?id=com.k17game.k3 -- Battle Zone - Earth 2048, an online strategy game using kcp.
1. https://zhuanlan.zhihu.com/p/53849089 -- kcptun开发小记
### Donate via Ethereum(ETH)
Address: 0x2e4b43ab3d0983da282592571eef61ae5e60f726 , Or scan here:
<img src="0x2e4b43ab3d0983da282592571eef61ae5e60f726.png" alt="kcptun" height="100px" />
(注意:我没有任何社交网站的账号,请小心骗子。)
+139
View File
@@ -0,0 +1,139 @@
#!/bin/bash
BUILD_DIR=$(dirname "$0")/build
mkdir -p $BUILD_DIR
cd $BUILD_DIR
sum="sha1sum"
if [ "$GO111MODULE" != "on" ]; then
echo "GO111MODULE is off"
else
echo "GO111MODULE is on"
fi
echo "Prerequisites for cross-compiling were written in build-release.sh"
# required library for cross-compiling
# sudo apt-get install -y automake autogen build-essential ca-certificates gcc-5-arm-linux-gnueabi g++-5-arm-linux-gnueabi libc6-dev-armel-cross gcc-5-arm-linux-gnueabihf g++-5-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-5-aarch64-linux-gnu g++-5-aarch64-linux-gnu libc6-dev-arm64-cross gcc-5-mips-linux-gnu g++-5-mips-linux-gnu libc6-dev-mips-cross gcc-5-mipsel-linux-gnu g++-5-mipsel-linux-gnu libc6-dev-mipsel-cross gcc-5-mips64-linux-gnuabi64 g++-5-mips64-linux-gnuabi64 libc6-dev-mips64-cross gcc-5-mips64el-linux-gnuabi64 g++-5-mips64el-linux-gnuabi64 libc6-dev-mips64el-cross gcc-5-multilib g++-5-multilib gcc-mingw-w64 g++-mingw-w64 clang llvm-dev libtool libxml2-dev uuid-dev libssl-dev swig openjdk-8-jdk pkg-config patch make xz-utils cpio wget zip unzip p7zip git mercurial bzr texinfo help2man --no-install-recommends
# if error message:
# /usr/include/linux/errno.h:1:23: fatal error: asm/errno.h: No such file or directory
# try:
# ln -s /usr/include/asm-generic /usr/include/asm
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
if hash upx 2>/dev/null; then
UPX=true
fi
VERSION=`date -u +%Y%m%d`
LDFLAGS="-X main.VERSION=$VERSION -s -w"
LDFLAGS_LINUX='-X main.VERSION='$VERSION' -s -w -linkmode "external" -extldflags "-static"'
LDFLAGS_LINUX32='-X main.VERSION='$VERSION' -s -w -linkmode "external" -extldflags "-static -m32 -L/usr/lib32"'
echo "-ldflag for linux/amd64:" $LDFLAGS_LINUX
echo "-ldflag for linux/386:" $LDFLAGS_LINUX32
echo "-ldflag for other:" $LDFLAGS
echo "=== Building ==="
# 386
OSES=(linux windows)
for os in ${OSES[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
if [ "$os" == "linux" ];then
CC=gcc-5 CGO_ENABLED=1 GOOS=$os GOARCH=386 CGO_CFLAGS="-m32 -L/usr/lib32" CGO_CXXFLAGS="-m32 -L/usr/lib32" go build -ldflags "$LDFLAGS_LINUX32" -o client_${os}_386${suffix} github.com/xtaci/kcptun/client
CC=gcc-5 CGO_ENABLED=1 GOOS=$os GOARCH=386 CGO_CFLAGS="-m32 -L/usr/lib32" CGO_CXXFLAGS="-m32 -L/usr/lib32" go build -ldflags "$LDFLAGS_LINUX32" -o server_${os}_386${suffix} github.com/xtaci/kcptun/server
else
CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -o client_${os}_386${suffix} github.com/xtaci/kcptun/client
CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -o server_${os}_386${suffix} github.com/xtaci/kcptun/server
fi
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
# AMD64
OSES=(linux darwin windows freebsd)
for os in ${OSES[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
if [ "$os" == "linux" ];then
CC=gcc-5 CGO_ENABLED=1 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS_LINUX" -o client_${os}_amd64${suffix} github.com/xtaci/kcptun/client
CC=gcc-5 CGO_ENABLED=1 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS_LINUX" -o server_${os}_amd64${suffix} github.com/xtaci/kcptun/server
else
CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -o client_${os}_amd64${suffix} github.com/xtaci/kcptun/client
CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -o server_${os}_amd64${suffix} github.com/xtaci/kcptun/server
fi
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
# ARM-5
#CC=arm-linux-gnueabi-gcc-5 GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CGO_CFLAGS="-march=armv5" CGO_CXXFLAGS="-march=armv5" go install std
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CGO_CFLAGS="-march=armv5" CGO_CXXFLAGS="-march=armv5" go build -ldflags "$LDFLAGS_LINUX" -o client_linux_arm5 github.com/xtaci/kcptun/client
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CGO_CFLAGS="-march=armv5" CGO_CXXFLAGS="-march=armv5" go build -ldflags "$LDFLAGS_LINUX" -o server_linux_arm5 github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm5 server_linux_arm5;fi
tar -zcf kcptun-linux-arm5-$VERSION.tar.gz client_linux_arm5 server_linux_arm5
$sum kcptun-linux-arm5-$VERSION.tar.gz
# ARM-6
#CC=arm-linux-gnueabi-gcc-5 GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 CGO_CFLAGS="-march=armv6" CGO_CXXFLAGS="-march=armv6" go install std
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 CGO_CFLAGS="-march=armv6" CGO_CXXFLAGS="-march=armv6" go build -ldflags "$LDFLAGS_LINUX" -o client_linux_arm6 github.com/xtaci/kcptun/client
CC=arm-linux-gnueabi-gcc-5 CXX=arm-linux-gnueabi-g++-5 GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=1 CGO_CFLAGS="-march=armv6" CGO_CXXFLAGS="-march=armv6" go build -ldflags "$LDFLAGS_LINUX" -o server_linux_arm6 github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm6 server_linux_arm6;fi
tar -zcf kcptun-linux-arm6-$VERSION.tar.gz client_linux_arm6 server_linux_arm6
$sum kcptun-linux-arm6-$VERSION.tar.gz
# ARM-7
ARMS=(7)
#CC=arm-linux-gnueabihf-gcc-5 GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a" CGO_CXXFLAGS="-march=armv7-a" go install std
CC=arm-linux-gnueabihf-gcc-5 CXX=arm-linux-gnueabihf-g++-5 GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a -fPIC" CGO_CXXFLAGS="-march=armv7-a -fPIC" go build -ldflags "$LDFLAGS_LINUX" -o client_linux_arm7 github.com/xtaci/kcptun/client
CC=arm-linux-gnueabihf-gcc-5 CXX=arm-linux-gnueabihf-g++-5 GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="-march=armv7-a -fPIC" CGO_CXXFLAGS="-march=armv7-a -fPIC" go build -ldflags "$LDFLAGS_LINUX" -o server_linux_arm7 github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm7 server_linux_arm7;fi
tar -zcf kcptun-linux-arm7-$VERSION.tar.gz client_linux_arm7 server_linux_arm7
$sum kcptun-linux-arm7-$VERSION.tar.gz
# ARM64
CC=aarch64-linux-gnu-gcc-5 CXX=aarch64-linux-gnu-g++-5 GOOS=linux GOARCH=arm64 CGO_ENABLED=1 go build -ldflags "$LDFLAGS_LINUX" -o client_linux_arm64 github.com/xtaci/kcptun/client
CC=aarch64-linux-gnu-gcc-5 CXX=aarch64-linux-gnu-g++-5 GOOS=linux GOARCH=arm64 CGO_ENABLED=1 go build -ldflags "$LDFLAGS_LINUX" -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
CC=mipsel-linux-gnu-gcc-5 CXX=mipsel-linux-gnu-g++-5 GOOS=linux GOARCH=mipsle CGO_ENABLED=1 GOMIPS=softfloat go build -ldflags "$LDFLAGS_LINUX" -o client_linux_mipsle github.com/xtaci/kcptun/client
CC=mipsel-linux-gnu-gcc-5 CXX=mipsel-linux-gnu-g++-5 GOOS=linux GOARCH=mipsle CGO_ENABLED=1 GOMIPS=softfloat go build -ldflags "$LDFLAGS_LINUX" -o server_linux_mipsle github.com/xtaci/kcptun/server
#MIPS32
CC=mips-linux-gnu-gcc-5 CXX=mips-linux-gnu-g++-5 GOOS=linux GOARCH=mips CGO_ENABLED=1 GOMIPS=softfloat go build -ldflags "$LDFLAGS_LINUX" -o client_linux_mips github.com/xtaci/kcptun/client
CC=mips-linux-gnu-gcc-5 CXX=mips-linux-gnu-g++-5 GOOS=linux GOARCH=mips CGO_ENABLED=1 GOMIPS=softfloat go build -ldflags "$LDFLAGS_LINUX" -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
echo "=== Building Completed ==="
+48 -20
View File
@@ -1,6 +1,14 @@
#!/bin/bash
BUILD_DIR=$(dirname "$0")/build
mkdir -p $BUILD_DIR
cd $BUILD_DIR
sum="sha1sum"
export GO111MODULE=on
echo "Setting GO111MODULE to" $GO111MODULE
if ! hash sha1sum 2>/dev/null; then
if ! hash shasum 2>/dev/null; then
echo "I can't see 'sha1sum' or 'shasum'"
@@ -19,21 +27,34 @@ VERSION=`date -u +%Y%m%d`
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS=""
# AMD64
OSES=(linux darwin windows freebsd)
ARCHS=(amd64 386)
for os in ${OSES[@]}; do
for arch in ${ARCHS[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_${arch}${suffix} github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_${arch}${suffix} github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_${os}_${arch}${suffix} server_${os}_${arch}${suffix};fi
tar -zcf kcptun-${os}-${arch}-$VERSION.tar.gz client_${os}_${arch}${suffix} server_${os}_${arch}${suffix}
$sum kcptun-${os}-${arch}-$VERSION.tar.gz
done
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_amd64${suffix} github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=$os GOARCH=amd64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_amd64${suffix} github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_${os}_amd64${suffix} server_${os}_amd64${suffix};fi
tar -zcf kcptun-${os}-amd64-$VERSION.tar.gz client_${os}_amd64${suffix} server_${os}_amd64${suffix}
$sum kcptun-${os}-amd64-$VERSION.tar.gz
done
# 386
OSES=(linux windows)
for os in ${OSES[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_${os}_386${suffix} github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=$os GOARCH=386 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_${os}_386${suffix} github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_${os}_386${suffix} server_${os}_386${suffix};fi
tar -zcf kcptun-${os}-386-$VERSION.tar.gz client_${os}_386${suffix} server_${os}_386${suffix}
$sum kcptun-${os}-386-$VERSION.tar.gz
done
# ARM
@@ -41,16 +62,23 @@ ARMS=(5 6 7)
for v in ${ARMS[@]}; do
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm$v github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=$v go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm$v github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm$v server_linux_arm$v;fi
tar -zcf kcptun-linux-arm$v-$VERSION.tar.gz client_linux_arm$v server_linux_arm$v
$sum kcptun-linux-arm$v-$VERSION.tar.gz
done
if $UPX; then upx -9 client_linux_arm* server_linux_arm*;fi
tar -zcf kcptun-linux-arm-$VERSION.tar.gz client_linux_arm* server_linux_arm*
$sum kcptun-linux-arm-$VERSION.tar.gz
# ARM64
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_arm64 github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_arm64 github.com/xtaci/kcptun/server
if $UPX; then upx -9 client_linux_arm64 server_linux_arm64*;fi
tar -zcf kcptun-linux-arm64-$VERSION.tar.gz client_linux_arm64 server_linux_arm64
$sum kcptun-linux-arm64-$VERSION.tar.gz
#MIPS32LE
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mipsle github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=mipsle go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_mipsle github.com/xtaci/kcptun/server
env CGO_ENABLED=0 GOOS=linux GOARCH=mips go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o client_linux_mips github.com/xtaci/kcptun/client
env CGO_ENABLED=0 GOOS=linux GOARCH=mips go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o server_linux_mips github.com/xtaci/kcptun/server
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
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+4
View File
@@ -28,11 +28,15 @@ type Config struct {
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxVer int `json:"smuxver"`
SmuxBuf int `json:"smuxbuf"`
StreamBuf int `json:"streambuf"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
Quiet bool `json:"quiet"`
TCP bool `json:"tcp"`
}
func parseJSONConfig(config *Config, path string) error {
+18
View File
@@ -0,0 +1,18 @@
package main
import (
"github.com/pkg/errors"
kcp "github.com/xtaci/kcp-go/v5"
"github.com/xtaci/tcpraw"
)
func dial(config *Config, block kcp.BlockCrypt) (*kcp.UDPSession, error) {
if config.TCP {
conn, err := tcpraw.Dial("tcp", config.RemoteAddr)
if err != nil {
return nil, errors.Wrap(err, "tcpraw.Dial()")
}
return kcp.NewConn(config.RemoteAddr, block, config.DataShard, config.ParityShard, conn)
}
return kcp.DialWithOptions(config.RemoteAddr, block, config.DataShard, config.ParityShard)
}
+114 -117
View File
@@ -2,79 +2,68 @@ package main
import (
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"log"
"math/rand"
"net"
"os"
"sync"
"time"
"golang.org/x/crypto/pbkdf2"
"github.com/golang/snappy"
"github.com/pkg/errors"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
kcp "github.com/xtaci/kcp-go/v5"
"github.com/xtaci/kcptun/generic"
"github.com/xtaci/smux"
)
var (
// VERSION is injected by buildflags
VERSION = "SELFBUILD"
const (
// SALT is use for pbkdf2 key expansion
SALT = "kcp-go"
// maximum supported smux version
maxSmuxVer = 2
// stream copy buffer size
bufSize = 4096
)
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
}
func handleClient(sess *smux.Session, p1 io.ReadWriteCloser, quiet bool) {
if !quiet {
log.Println("stream opened")
defer log.Println("stream closed")
// handleClient aggregates connection p1 on mux with 'writeLock'
func handleClient(session *smux.Session, p1 net.Conn, quiet bool) {
logln := func(v ...interface{}) {
if !quiet {
log.Println(v...)
}
}
defer p1.Close()
p2, err := sess.OpenStream()
p2, err := session.OpenStream()
if err != nil {
logln(err)
return
}
defer p2.Close()
// tunnel setup
var wg sync.WaitGroup
wg.Add(2)
go func() { io.Copy(p1, p2); wg.Done() }()
go func() { io.Copy(p2, p1); wg.Done() }()
wg.Wait()
logln("stream opened", "in:", p1.RemoteAddr(), "out:", fmt.Sprint(p2.RemoteAddr(), "(", p2.ID(), ")"))
defer logln("stream closed", "in:", p1.RemoteAddr(), "out:", fmt.Sprint(p2.RemoteAddr(), "(", p2.ID(), ")"))
// start tunnel & wait for tunnel termination
streamCopy := func(dst io.Writer, src io.ReadCloser) {
if _, err := generic.Copy(dst, src); err != nil {
// report protocol error
if err == smux.ErrInvalidProtocol {
log.Println("smux", err, "in:", p1.RemoteAddr(), "out:", fmt.Sprint(p2.RemoteAddr(), "(", p2.ID(), ")"))
}
}
p1.Close()
p2.Close()
}
go streamCopy(p1, p2)
streamCopy(p2, p1)
}
func checkError(err error) {
@@ -90,6 +79,7 @@ func main() {
// add more log flags for debugging
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
myApp := cli.NewApp()
myApp.Name = "kcptun"
myApp.Usage = "client(with SMUX)"
@@ -196,14 +186,29 @@ 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: "smuxver",
Value: 1,
Usage: "specify smux version, available 1,2",
},
cli.IntFlag{
Name: "smuxbuf",
Value: 4194304,
Usage: "the overall de-mux buffer in bytes",
},
cli.IntFlag{
Name: "streambuf",
Value: 2097152,
Usage: "per stream receive buffer in bytes, smux v2+",
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Usage: "seconds between heartbeats",
},
cli.StringFlag{
Name: "snmplog",
@@ -224,6 +229,10 @@ func main() {
Name: "quiet",
Usage: "to suppress the 'stream open/close' messages",
},
cli.BoolFlag{
Name: "tcp",
Usage: "to emulate a TCP connection(linux)",
},
cli.StringFlag{
Name: "c",
Value: "", // when the value is not empty, the config path must exists
@@ -253,11 +262,15 @@ func main() {
config.Resend = c.Int("resend")
config.NoCongestion = c.Int("nc")
config.SockBuf = c.Int("sockbuf")
config.SmuxBuf = c.Int("smuxbuf")
config.StreamBuf = c.Int("streambuf")
config.SmuxVer = c.Int("smuxver")
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")
config.TCP = c.Bool("tcp")
if c.String("c") != "" {
err := parseJSONConfig(&config, c.String("c"))
@@ -289,7 +302,37 @@ func main() {
listener, err := net.ListenTCP("tcp", addr)
checkError(err)
log.Println("smux version:", config.SmuxVer)
log.Println("listening on:", listener.Addr())
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("streambuf:", config.StreamBuf)
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)
log.Println("tcp:", config.TCP)
// parameters check
if config.SmuxVer > maxSmuxVer {
log.Fatal("unsupported smux version:", config.SmuxVer)
}
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
log.Println("key derivation done")
var block kcp.BlockCrypt
switch config.Crypt {
case "sm4":
@@ -321,36 +364,13 @@ func main() {
block, _ = kcp.NewAESBlockCrypt(pass)
}
log.Println("listening on:", listener.Addr())
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("keepalive:", config.KeepAlive)
log.Println("conn:", config.Conn)
log.Println("autoexpire:", config.AutoExpire)
log.Println("scavengettl:", config.ScavengeTTL)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("quiet:", config.Quiet)
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SockBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
createConn := func() (*smux.Session, error) {
kcpconn, err := kcp.DialWithOptions(config.RemoteAddr, block, config.DataShard, config.ParityShard)
kcpconn, err := dial(&config, block)
if err != nil {
return nil, errors.Wrap(err, "createConn()")
return nil, errors.Wrap(err, "dial()")
}
kcpconn.SetStreamMode(true)
kcpconn.SetWriteDelay(true)
kcpconn.SetWriteDelay(false)
kcpconn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
kcpconn.SetWindowSize(config.SndWnd, config.RcvWnd)
kcpconn.SetMtu(config.MTU)
@@ -365,18 +385,27 @@ func main() {
if err := kcpconn.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
log.Println("smux version:", config.SmuxVer, "on connection:", kcpconn.LocalAddr(), "->", kcpconn.RemoteAddr())
smuxConfig := smux.DefaultConfig()
smuxConfig.Version = config.SmuxVer
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.MaxStreamBuffer = config.StreamBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
if err := smux.VerifyConfig(smuxConfig); err != nil {
log.Fatalf("%+v", err)
}
// stream multiplex
var session *smux.Session
if config.NoComp {
session, err = smux.Client(kcpconn, smuxConfig)
} else {
session, err = smux.Client(newCompStream(kcpconn), smuxConfig)
session, err = smux.Client(generic.NewCompStream(kcpconn), smuxConfig)
}
if err != nil {
return nil, errors.Wrap(err, "createConn()")
}
log.Println("connection:", kcpconn.LocalAddr(), "->", kcpconn.RemoteAddr())
return session, nil
}
@@ -405,14 +434,13 @@ func main() {
chScavenger := make(chan *smux.Session, 128)
go scavenger(chScavenger, config.ScavengeTTL)
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
rr := uint16(0)
for {
p1, err := listener.AcceptTCP()
if err != nil {
log.Fatalln(err)
log.Fatalf("%+v", err)
}
checkError(err)
idx := rr % numconn
// do auto expiration && reconnection
@@ -442,16 +470,16 @@ func scavenger(ch chan *smux.Session, ttl int) {
select {
case sess := <-ch:
sessionList = append(sessionList, scavengeSession{sess, time.Now()})
log.Println("session marked as expired")
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")
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")
log.Println("session reached scavenge ttl", s.session.RemoteAddr())
s.session.Close()
} else {
newList = append(newList, sessionList[k])
@@ -461,34 +489,3 @@ func scavenger(ch chan *smux.Session, ttl int) {
}
}
}
func snmpLogger(path string, interval int) {
if path == "" || interval == 0 {
return
}
ticker := time.NewTicker(time.Duration(interval) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
f, err := os.OpenFile(time.Now().Format(path), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Println(err)
return
}
w := csv.NewWriter(f)
// write header in empty file
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
log.Println(err)
}
}
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
log.Println(err)
}
kcp.DefaultSnmp.Reset()
w.Flush()
f.Close()
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"os/signal"
"syscall"
kcp "github.com/xtaci/kcp-go"
kcp "github.com/xtaci/kcp-go/v5"
)
func init() {
+16
View File
@@ -0,0 +1,16 @@
Description=kcptun
Wants=network.target
After=syslog.target network-online.target
[Service]
Type=simple
Environment=GOGC=20
ExecStart=/home/user/client_linux_amd64 -c /home/user/local.json
Restart=on-failure
RestartSec=10
KillMode=process
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
+27
View File
@@ -0,0 +1,27 @@
{
"localaddr": ":2000",
"remoteaddr": "11.22.33.44:2000",
"key": "PASSWORD",
"crypt": "aes-128",
"mode": "fast3",
"mtu": 1400,
"sndwnd": 128,
"rcvwnd": 1024,
"datashard": 10,
"parityshard": 3,
"dscp": 46,
"nocomp": true,
"acknodelay": false,
"nodelay": 1,
"interval": 40,
"resend": 2,
"nc": 1,
"sockbuf": 16777217,
"smuxver": 1,
"smuxbuf": 16777217,
"streambuf": 2097152,
"keepalive": 10,
"autoexpire": 1800,
"quiet": false,
"tcp": false
}
+27
View File
@@ -0,0 +1,27 @@
{
"listen": ":2000",
"target": "127.0.0.1:9999",
"key": "PASSWORD",
"crypt": "aes-128",
"mode": "fast3",
"mtu": 1400,
"sndwnd": 2048,
"rcvwnd": 2048,
"datashard": 10,
"parityshard": 3,
"dscp": 46,
"nocomp": true,
"acknodelay": false,
"nodelay": 1,
"interval": 40,
"resend": 2,
"nc": 1,
"sockbuf": 16777217,
"smuxver": 1,
"smuxbuf": 16777217,
"streambuf": 2097152,
"keepalive": 10,
"pprof":false,
"quiet":false,
"tcp":false
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+62
View File
@@ -0,0 +1,62 @@
package generic
import (
"net"
"time"
"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 (c *CompStream) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
func (c *CompStream) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
func (c *CompStream) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
func (c *CompStream) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
func (c *CompStream) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}
func NewCompStream(conn net.Conn) *CompStream {
c := new(CompStream)
c.conn = conn
c.w = snappy.NewBufferedWriter(conn)
c.r = snappy.NewReader(conn)
return c
}
+24
View File
@@ -0,0 +1,24 @@
package generic
import (
"io"
)
const bufSize = 4096
// Memory optimized io.Copy function specified for this library
func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(io.WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(io.ReaderFrom); ok {
return rt.ReadFrom(src)
}
// fallback to standard io.CopyBuffer
buf := make([]byte, bufSize)
return io.CopyBuffer(dst, src, buf)
}
+46
View File
@@ -0,0 +1,46 @@
package generic
import (
"encoding/csv"
"fmt"
"log"
"os"
"path/filepath"
"time"
kcp "github.com/xtaci/kcp-go/v5"
)
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()
}
}
}
+22
View File
@@ -0,0 +1,22 @@
module github.com/xtaci/kcptun
require (
github.com/coreos/go-iptables v0.4.2 // indirect
github.com/golang/snappy v0.0.1
github.com/google/gopacket v1.1.17 // indirect
github.com/klauspost/cpuid v1.2.3 // indirect
github.com/pkg/errors v0.9.1
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
github.com/tjfoc/gmsm v1.3.0 // indirect
github.com/urfave/cli v1.21.0
github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
github.com/xtaci/kcp-go/v5 v5.5.14
github.com/xtaci/smux v1.5.14
github.com/xtaci/tcpraw v1.2.25
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df
golang.org/x/net v0.0.0-20200320220750-118fecf932d8 // indirect
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae // indirect
)
go 1.14
+66
View File
@@ -0,0 +1,66 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/coreos/go-iptables v0.4.2 h1:KH0EwId05JwWIfb96gWvkiT2cbuOu8ygqUaB+yPAwIg=
github.com/coreos/go-iptables v0.4.2/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us=
github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY=
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/templexxx/cpu v0.0.1 h1:hY4WdLOgKdc8y13EYklu9OUTXik80BkxHoWvTO6MQQY=
github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/templexxx/xorsimd v0.4.1 h1:iUZcywbOYDRAZUasAs2eSCUW8eobuZDy0I9FJiORkVg=
github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo=
github.com/tjfoc/gmsm v1.0.1 h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU=
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
github.com/tjfoc/gmsm v1.3.0 h1:i7c6Za/IlgBvnGxYpfD7L3TGuaS+v6oGcgq+J9/ecEA=
github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE=
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/kcp-go/v5 v5.5.11 h1:wYvoREAp6bG3sYwtxhY1QelbB/1fNggCtkt2DwqFj2M=
github.com/xtaci/kcp-go/v5 v5.5.11/go.mod h1:Oyw+zrBrO58urX1AaWV+2RynthEKcs+qrRAh0Q8YpdU=
github.com/xtaci/kcp-go/v5 v5.5.14-0.20200701100455-43d2c47d8ac1 h1:bnQj12vKzlMDxNGzFTj7ZDgXXpUpEQsX9mF/s7hD68o=
github.com/xtaci/kcp-go/v5 v5.5.14-0.20200701100455-43d2c47d8ac1/go.mod h1:H0T/EJ+lPNytnFYsKLH0JHUtiwZjG3KXlTM6c+Q4YUo=
github.com/xtaci/kcp-go/v5 v5.5.14 h1:YODIwvTyZmOTj3SduJeIcQPxthDoHllMm8YIBlK44Ik=
github.com/xtaci/kcp-go/v5 v5.5.14/go.mod h1:H0T/EJ+lPNytnFYsKLH0JHUtiwZjG3KXlTM6c+Q4YUo=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/xtaci/smux v1.5.14 h1:1j+zJYDZRv9FHaWqCJfH5RPizIm0fSzJIFbfVn8zsfg=
github.com/xtaci/smux v1.5.14/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
github.com/xtaci/tcpraw v1.2.25 h1:VDlqo0op17JeXBM6e2G9ocCNLOJcw9mZbobMbJjo0vk=
github.com/xtaci/tcpraw v1.2.25/go.mod h1:dKyZ2V75s0cZ7cbgJYdxPvms7af0joIeOyx1GgJQbLk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df h1:lDWgvUvNnaTnNBc/dwOty86cFeKoKWbwy2wQj0gIxbU=
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200320220750-118fecf932d8 h1:1+zQlQqEEhUeStBTi653GZAnAuivZq/2hz+Iz+OP7rg=
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae h1:3tcmuaB7wwSZtelmiv479UjUB+vviwABz7a133ZwOKQ=
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 55 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

+4
View File
@@ -25,12 +25,16 @@ type Config struct {
Resend int `json:"resend"`
NoCongestion int `json:"nc"`
SockBuf int `json:"sockbuf"`
SmuxBuf int `json:"smuxbuf"`
StreamBuf int `json:"streambuf"`
SmuxVer int `json:"smuxver"`
KeepAlive int `json:"keepalive"`
Log string `json:"log"`
SnmpLog string `json:"snmplog"`
SnmpPeriod int `json:"snmpperiod"`
Pprof bool `json:"pprof"`
Quiet bool `json:"quiet"`
TCP bool `json:"tcp"`
}
func parseJSONConfig(config *Config, path string) error {
+170 -135
View File
@@ -2,7 +2,6 @@ package main
import (
"crypto/sha1"
"encoding/csv"
"fmt"
"io"
"log"
@@ -16,52 +15,39 @@ import (
"golang.org/x/crypto/pbkdf2"
"github.com/golang/snappy"
"github.com/urfave/cli"
kcp "github.com/xtaci/kcp-go"
kcp "github.com/xtaci/kcp-go/v5"
"github.com/xtaci/kcptun/generic"
"github.com/xtaci/smux"
"github.com/xtaci/tcpraw"
)
var (
// VERSION is injected by buildflags
VERSION = "SELFBUILD"
const (
// SALT is use for pbkdf2 key expansion
SALT = "kcp-go"
// maximum supported smux version
maxSmuxVer = 2
// stream copy buffer size
bufSize = 4096
)
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) {
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
}
// VERSION is injected by buildflags
var VERSION = "SELFBUILD"
// handle multiplex-ed connection
func handleMux(conn io.ReadWriteCloser, config *Config) {
func handleMux(conn net.Conn, config *Config) {
// check if target is unix domain socket
var isUnix bool
if _, _, err := net.SplitHostPort(config.Target); err != nil {
isUnix = true
}
log.Println("smux version:", config.SmuxVer, "on connection:", conn.LocalAddr(), "->", conn.RemoteAddr())
// stream multiplex
smuxConfig := smux.DefaultConfig()
smuxConfig.MaxReceiveBuffer = config.SockBuf
smuxConfig.Version = config.SmuxVer
smuxConfig.MaxReceiveBuffer = config.SmuxBuf
smuxConfig.MaxStreamBuffer = config.StreamBuf
smuxConfig.KeepAliveInterval = time.Duration(config.KeepAlive) * time.Second
mux, err := smux.Server(conn, smuxConfig)
@@ -70,36 +56,59 @@ func handleMux(conn io.ReadWriteCloser, config *Config) {
return
}
defer mux.Close()
for {
p1, err := mux.AcceptStream()
stream, err := mux.AcceptStream()
if err != nil {
log.Println(err)
return
}
p2, err := net.DialTimeout("tcp", config.Target, 5*time.Second)
if err != nil {
p1.Close()
log.Println(err)
continue
}
go handleClient(p1, p2, config.Quiet)
go func(p1 *smux.Stream) {
var p2 net.Conn
var err error
if !isUnix {
p2, err = net.Dial("tcp", config.Target)
} else {
p2, err = net.Dial("unix", config.Target)
}
if err != nil {
log.Println(err)
p1.Close()
return
}
handleClient(p1, p2, config.Quiet)
}(stream)
}
}
func handleClient(p1, p2 io.ReadWriteCloser, quiet bool) {
if !quiet {
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()
// tunnel setup
var wg sync.WaitGroup
wg.Add(2)
go func() { io.Copy(p1, p2); wg.Done() }()
go func() { io.Copy(p2, p1); wg.Done() }()
wg.Wait()
logln("stream opened", "in:", fmt.Sprint(p1.RemoteAddr(), "(", p1.ID(), ")"), "out:", p2.RemoteAddr())
defer logln("stream closed", "in:", fmt.Sprint(p1.RemoteAddr(), "(", p1.ID(), ")"), "out:", p2.RemoteAddr())
// start tunnel & wait for tunnel termination
streamCopy := func(dst io.Writer, src io.ReadCloser) {
if _, err := generic.Copy(dst, src); err != nil {
if err == smux.ErrInvalidProtocol {
log.Println("smux", err, "in:", fmt.Sprint(p1.RemoteAddr(), "(", p1.ID(), ")"), "out:", p2.RemoteAddr())
}
}
p1.Close()
p2.Close()
}
go streamCopy(p2, p1)
streamCopy(p1, p2)
}
func checkError(err error) {
@@ -115,6 +124,7 @@ func main() {
// add more log flags for debugging
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
myApp := cli.NewApp()
myApp.Name = "kcptun"
myApp.Usage = "server(with SMUX)"
@@ -128,7 +138,7 @@ func main() {
cli.StringFlag{
Name: "target, t",
Value: "127.0.0.1:12948",
Usage: "target server address",
Usage: "target server address, or path/to/unix_socket",
},
cli.StringFlag{
Name: "key",
@@ -206,14 +216,29 @@ 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: "smuxver",
Value: 1,
Usage: "specify smux version, available 1,2",
},
cli.IntFlag{
Name: "smuxbuf",
Value: 4194304,
Usage: "the overall de-mux buffer in bytes",
},
cli.IntFlag{
Name: "streambuf",
Value: 2097152,
Usage: "per stream receive buffer in bytes, smux v2+",
},
cli.IntFlag{
Name: "keepalive",
Value: 10, // nat keepalive interval in seconds
Usage: "seconds between heartbeats",
},
cli.StringFlag{
Name: "snmplog",
@@ -238,6 +263,10 @@ func main() {
Name: "quiet",
Usage: "to suppress the 'stream open/close' messages",
},
cli.BoolFlag{
Name: "tcp",
Usage: "to emulate a TCP connection(linux)",
},
cli.StringFlag{
Name: "c",
Value: "", // when the value is not empty, the config path must exists
@@ -264,12 +293,16 @@ func main() {
config.Resend = c.Int("resend")
config.NoCongestion = c.Int("nc")
config.SockBuf = c.Int("sockbuf")
config.SmuxBuf = c.Int("smuxbuf")
config.StreamBuf = c.Int("streambuf")
config.SmuxVer = c.Int("smuxver")
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")
config.TCP = c.Bool("tcp")
if c.String("c") != "" {
//Now only support json config file
@@ -297,7 +330,35 @@ func main() {
}
log.Println("version:", VERSION)
log.Println("smux version:", config.SmuxVer)
log.Println("listening on:", config.Listen)
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("streambuf:", config.StreamBuf)
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)
log.Println("tcp:", config.TCP)
// parameters check
if config.SmuxVer > maxSmuxVer {
log.Fatal("unsupported smux version:", config.SmuxVer)
}
log.Println("initiating key derivation")
pass := pbkdf2.Key([]byte(config.Key), []byte(SALT), 4096, 32, sha1.New)
log.Println("key derivation done")
var block kcp.BlockCrypt
switch config.Crypt {
case "sm4":
@@ -329,90 +390,64 @@ func main() {
block, _ = kcp.NewAESBlockCrypt(pass)
}
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("keepalive:", config.KeepAlive)
log.Println("snmplog:", config.SnmpLog)
log.Println("snmpperiod:", config.SnmpPeriod)
log.Println("pprof:", config.Pprof)
log.Println("quiet:", config.Quiet)
if err := lis.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
}
if err := lis.SetReadBuffer(config.SockBuf); err != nil {
log.Println("SetReadBuffer:", err)
}
if err := lis.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
go snmpLogger(config.SnmpLog, config.SnmpPeriod)
go generic.SnmpLogger(config.SnmpLog, config.SnmpPeriod)
if config.Pprof {
go http.ListenAndServe(":6060", nil)
}
for {
if conn, err := lis.AcceptKCP(); err == nil {
log.Println("remote address:", conn.RemoteAddr())
conn.SetStreamMode(true)
conn.SetWriteDelay(true)
conn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
conn.SetMtu(config.MTU)
conn.SetWindowSize(config.SndWnd, config.RcvWnd)
conn.SetACKNoDelay(config.AckNodelay)
// main loop
var wg sync.WaitGroup
loop := func(lis *kcp.Listener) {
defer wg.Done()
if err := lis.SetDSCP(config.DSCP); err != nil {
log.Println("SetDSCP:", err)
}
if err := lis.SetReadBuffer(config.SockBuf); err != nil {
log.Println("SetReadBuffer:", err)
}
if err := lis.SetWriteBuffer(config.SockBuf); err != nil {
log.Println("SetWriteBuffer:", err)
}
if config.NoComp {
go handleMux(conn, &config)
for {
if conn, err := lis.AcceptKCP(); err == nil {
log.Println("remote address:", conn.RemoteAddr())
conn.SetStreamMode(true)
conn.SetWriteDelay(false)
conn.SetNoDelay(config.NoDelay, config.Interval, config.Resend, config.NoCongestion)
conn.SetMtu(config.MTU)
conn.SetWindowSize(config.SndWnd, config.RcvWnd)
conn.SetACKNoDelay(config.AckNodelay)
if config.NoComp {
go handleMux(conn, &config)
} else {
go handleMux(generic.NewCompStream(conn), &config)
}
} else {
go handleMux(newCompStream(conn), &config)
log.Printf("%+v", err)
}
} else {
log.Printf("%+v", err)
}
}
if config.TCP { // tcp dual stack
if conn, err := tcpraw.Listen("tcp", config.Listen); err == nil {
lis, err := kcp.ServeConn(block, config.DataShard, config.ParityShard, conn)
checkError(err)
wg.Add(1)
go loop(lis)
} else {
log.Println(err)
}
}
// udp stack
lis, err := kcp.ListenWithOptions(config.Listen, block, config.DataShard, config.ParityShard)
checkError(err)
wg.Add(1)
go loop(lis)
wg.Wait()
return nil
}
myApp.Run(os.Args)
}
func snmpLogger(path string, interval int) {
if path == "" || interval == 0 {
return
}
ticker := time.NewTicker(time.Duration(interval) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
f, err := os.OpenFile(time.Now().Format(path), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Println(err)
return
}
w := csv.NewWriter(f)
// write header in empty file
if stat, err := f.Stat(); err == nil && stat.Size() == 0 {
if err := w.Write(append([]string{"Unix"}, kcp.DefaultSnmp.Header()...)); err != nil {
log.Println(err)
}
}
if err := w.Write(append([]string{fmt.Sprint(time.Now().Unix())}, kcp.DefaultSnmp.ToSlice()...)); err != nil {
log.Println(err)
}
kcp.DefaultSnmp.Reset()
w.Flush()
f.Close()
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"os/signal"
"syscall"
kcp "github.com/xtaci/kcp-go"
kcp "github.com/xtaci/kcp-go/v5"
)
func init() {