Compare commits

..

228 Commits

Author SHA1 Message Date
sijie.sun
cca105e91d add chinese help message 2024-08-08 08:05:42 +08:00
sijie.sun
3e52490d1b update dep and bump version 2024-08-07 23:48:03 +08:00
sijie.sun
d1293276ce use tun2
meh/rust-tun has bug on windows and may stuck on large traffic.
2024-08-07 15:58:23 +08:00
sijie.sun
4a5e426730 fix android route and peer conn disconn bug
1. android correctly add route
2. use mock nic ctx to consume packets
2024-08-06 22:19:30 +08:00
sijie.sun
fdc2755291 fix set dev name not work on windows 2024-08-05 11:47:43 +08:00
sijie.sun
b4fbcd8d80 use random ip from dns record instead of only first one 2024-08-04 23:42:33 +08:00
sijie.sun
2415cb211e run on v7 need rustc < 1.78 2024-08-04 11:07:24 +08:00
sijie.sun
5e51784803 support unicode hostname 2024-08-04 11:07:24 +08:00
Sijie.Sun
5f0d71b0fe check trigger user for docker action (#219) 2024-08-04 00:37:58 +08:00
sijie.sun
71d41f0a70 introduce docker image updater 2024-08-04 00:28:34 +08:00
sijie.sun
78f2804bad bump version to v1.2.0 2024-08-03 15:39:04 +08:00
sijie.sun
0da09ec605 add network whitelist for public relay node 2024-08-03 15:39:04 +08:00
sijie.sun
02b5b5f3c7 use better artifect name 2024-08-03 13:11:44 +08:00
sijie.sun
4a0adaa3f8 fix listener stop accept after failure 2024-08-03 13:11:44 +08:00
sijie.sun
d5bc15cf7a fix session_task and session mismatch 2024-08-03 13:11:44 +08:00
Sijie.Sun
4fea3a60d6 update last_updated of peer info to local now (#211)
time between peers may not be synced, using peer last_updated time may cause peer info being cleared incorrectly
2024-08-02 00:48:31 +08:00
Sijie.Sun
7a2bc52ae0 fix network to network without masquerade (#207) 2024-08-01 01:27:23 +08:00
RiceCake
debc165326 delete bloated registry items (#200)
* delete bloated registry items

---------

Co-authored-by: 荣耀的捍卫者 <1250839773@qq.com>
2024-07-30 00:01:20 +08:00
RiceCake
d5eef25ad1 fix two tray (#193)
Co-authored-by: 荣耀的捍卫者 <1250839773@qq.com>
2024-07-27 23:57:04 +08:00
Sijie.Sun
5451b52daa allow set routes manually and disable propagated routes (#191) 2024-07-24 22:45:55 +08:00
Sijie.Sun
fc9812dd54 fix crash on old version android (<= 9) (#183)
* fix crash on old version android (<= 9)
* fix listener select
2024-07-19 23:55:11 +08:00
Sijie.Sun
8858492fb4 fix vpn close when getting new subnet route (#179) 2024-07-18 08:48:45 +08:00
Sijie.Sun
5987528f59 optimize android gui (#174)
make chips input more friendly
2024-07-15 22:55:10 +08:00
Sijie.Sun
a03fc04b1b set route correctly in android (#172) 2024-07-15 00:57:19 +08:00
Sijie.Sun
858ade2eee Android Support (#166)
1. Add vpnservice tauri plugin for android.
2. add workflow for android.
3. Easytier Core support android, allow set tun fd.
2024-07-15 00:03:55 +08:00
Sijie.Sun
4938e3ed2b migrate to tauri2 (#159)
migrate gui to tauri2
2024-07-08 23:18:10 +08:00
Sijie.Sun
537f6ecf78 fix smoltcp tcp proxy (#157)
1. allow smoltcp proxy with dhcp ip
2. fix smoltcp not work without no tun.
2024-07-07 22:08:50 +08:00
Sijie.Sun
24143cbf1c add verbose cli mode; add list foreign network (#156) 2024-07-07 16:51:20 +08:00
Sijie.Sun
513e4cacc9 add more debug info for route (#155)
1. use info log for sync_route_info
2. allow dump route info with cli tool.
3. dump route info every 60s
2024-07-07 15:40:46 +08:00
Sijie.Sun
7cfa850d4c GUI: support change log level when running (#153) 2024-07-06 17:18:13 +08:00
Sijie.Sun
571d4a6e8f fix bug in dhcp (#152)
1. fix dhcp not retry if tun device init failed.
2. forbid dhcp use default ip when no peer.
2024-07-06 14:22:11 +08:00
yylt
0f39bfcefa support change tun interface name (#151) 2024-07-03 15:41:12 +08:00
Sijie.Sun
34f832bbad make tun dependency optional (#142)
* remove log crates
* remove udp/raw of smoltcp
* make tun as optional dependancy, compile for freebsd works
2024-06-11 09:09:32 +08:00
Sijie.Sun
8aa57ebc22 support no tun mode (#141) 2024-06-10 10:27:24 +08:00
Sijie.Sun
fede35cca4 correctly handle ip fragment for udp/icmp proxy (#137)
icmp/udp proxy do not rely on kernel net stack, but currently not handle ip fragmentation correctly.

this patch add ip resembler to merge fragmented ip packet for udp/icmp proxy
2024-06-09 22:59:50 +08:00
sijie.sun
b2100b78d3 fix boringtun version 2024-06-05 21:42:40 +08:00
Sijie.Sun
70ad81f7bd only upx on linux (#134) 2024-06-05 21:00:30 +08:00
Sijie.Sun
b43c078152 fix udp proxy not work when being exit node (#133) 2024-06-05 08:08:55 +08:00
Sijie.Sun
6e77e6b5e7 support start on reboot (#132)
* move launcher to eastier lib
* support auto start after reboot
2024-06-04 23:06:10 +08:00
Sijie.Sun
f9e6264f31 fix upx and udp conn counter (#131)
* fix upx in workflow
* fix udp conn counter
2024-06-04 18:50:30 +08:00
Sijie.Sun
df17a7bb68 bugfix before release 11x (#130)
* use correct i18n hook

* fix peer rpc panic

make sure server use correct transact id

* fix dhcp

recreate tun device after ip changed

* use upx correctly

* compile arm & armv7

* prepare to release v1.1.0
2024-06-03 23:07:44 +08:00
Sijie.Sun
c1b725e64e websocket support bind addr (#129) 2024-06-02 21:48:16 +08:00
Sijie.Sun
360691276c support win7 and reduce win mem usage (#128) 2024-06-02 14:07:21 +08:00
Sijie.Sun
f1e9864d08 make release bin smaller (#127) 2024-06-02 09:15:40 +08:00
Sijie.Sun
abf9d23d52 improve hole punching and stun test (#124)
* implement new stun test algorithm, do test faster and provide more info
* support punching for symmetric
2024-06-02 07:20:57 +08:00
Sijie.Sun
bdbb1f02d6 Update Cargo.lock (#122) 2024-05-22 00:36:16 +08:00
Sijie.Sun
f64f58e2ae support exit node (#121)
support exit node, proxy all traffic via one of node
NOTE: this patch has not implemented automatically route management.
2024-05-18 20:32:42 +08:00
Sijie.Sun
6efbb5cb3d minor fixed (#120)
1. fix mtu, always set by ourselves and use smaller value
2. wireguard connector should return tunnel after receive packet
2024-05-18 18:04:06 +08:00
m1m1sha
0ead308392 Feat/pseudo dhcp (#109)
*  feat: pseudo dhcp
2024-05-17 23:16:56 +08:00
Sijie.Sun
bad6a5946a fix run with config, update readme (#118) 2024-05-17 22:00:11 +08:00
Sijie.Sun
7532a7c1b2 command line improvement (#115)
make -l easy to use:
-l wg wss
-l wg:12345
-l 12345

make -r use random port
2024-05-16 20:16:09 +08:00
Sijie.Sun
f665de9b18 allow peer rpc split packet, so tunnel mtu can be small (#116) 2024-05-16 08:18:35 +08:00
m1m1sha
58d2ec475c 🐞 fix: cmd error with gbk (#114)
* 🐞 fix: cmd error with gbk
* 🎈 perf: try gbk only on windows
2024-05-15 20:50:11 +08:00
Sijie.Sun
d5bf041834 some minor fix (#113)
1. fix ospf route panic if no ipv4 assigned.
2. should refetch global peer latency map every 60s
3. remove regex dep because it's too large and unnecessary.
2024-05-15 09:21:20 +08:00
Sijie.Sun
4e9b07f83b Merge pull request #108 from EasyTier/latency_first 2024-05-13 22:30:50 +08:00
sijie.sun
fc4e3782bd tune command line args 2024-05-13 22:13:31 +08:00
sijie.sun
3e6b1ac384 use path with least cost if hop count is same 2024-05-13 21:18:52 +08:00
sijie.sun
29365c39ed use latency from peer center for route 2024-05-13 21:18:34 +08:00
sijie.sun
09ebed157e fix peer center for latency report 2024-05-13 20:30:25 +08:00
sijie.sun
72f86025bd support custom cost calculate func when generating route table 2024-05-13 20:30:25 +08:00
sijie.sun
51aa23b635 add ttl for packet 2024-05-13 20:30:25 +08:00
m1m1sha
43e076ef18 🐞 fix: same tun name 2024-05-13 16:11:37 +08:00
sijie.sun
29d8d4ba87 correctly handle listener add fail 2024-05-11 23:29:55 +08:00
sijie.sun
1b1d76de99 introduce websocket tunnel 2024-05-11 23:29:55 +08:00
m1m1sha
a5637003ad Perf/optimize details (#106)
* 🎈 perf: details
* 🎈 perf: optimize Style
2024-05-11 16:26:44 +08:00
Sijie.Sun
65ac991d1c (Tyr) fix flashing console window on windows (#105)
add requireAdmin in app manist
2024-05-11 12:02:15 +08:00
sijie.sun
0926820849 fix workflow status check for matrix build 2024-05-11 00:39:35 +08:00
sijie.sun
518b6e277a networkList should not be empty after first start 2024-05-11 00:39:35 +08:00
Sijie.Sun
2deb867678 move shared codes in workflows to script (#103) 2024-05-10 22:56:00 +08:00
Sijie.Sun
e023c05440 Merge pull request #102 from EasyTier/fix-gui-workflow
rename workflow job name for gui
2024-05-10 22:39:23 +08:00
m1m1sha
486286e497 🐎 ci: change trigger
change the triggering mechanism to skip jobs upon detecting changes
2024-05-10 22:25:37 +08:00
Sijie.Sun
72701c9eb3 start tcp proxy after tun device created (#94)
on win 10, tcp proxy listener created before tun device may not accept
conn from tun dev.
2024-05-10 21:40:50 +08:00
Sijie.Sun
b1153378c9 fix icmp proxy on MacOS (#101)
1. MacOS doesn't fill length field in ip header when recving from raw
socket
2. Fix udp & icmp subnet proxy not work when no p2p connection.
2024-05-10 21:40:29 +08:00
sijie.sun
ab0404bf6e rename job and artifect name for easytier-gui workflow 2024-05-10 20:40:49 +08:00
m1m1sha
2a728482fa 🐎 ci: modify action on paths and split the steps (#96)
* 🐎 ci: modify action on paths and split the steps
2024-05-10 17:44:16 +08:00
m1m1sha
bee9565225 Merge pull request #100 from m1m1sha/perf/ts-type
Perf/ts type
2024-05-10 15:25:29 +08:00
m1m1sha
e07f760def 🎈 perf: simplify format 2024-05-10 11:56:18 +08:00
m1m1sha
24e2f41260 Merge branch 'EasyTier:main' into perf/ts-type 2024-05-10 00:16:39 +08:00
Yumin Wu
4da7f4ec20 fix AllowIps and Address fields for WireGuard client (#99)
- add Wireguard client cidr into AllowIps
- change subnet number to 32 in Address field
2024-05-09 22:01:55 +08:00
Sijie.Sun
7d3b8e42fe move reconn task join into select! (#88)
if join_next stuck, may miss global event and cause panic
2024-05-09 18:51:58 +08:00
Sijie.Sun
68c077820f Merge pull request #97 from wuyumin/yumin-dev 2024-05-09 18:26:34 +08:00
Yumin Wu
b4ebe7a481 update .gitignore 2024-05-09 17:56:00 +08:00
Yumin Wu
b1f8c5c175 update release profile 2024-05-09 17:18:20 +08:00
Yumin Wu
469187d0bb temporary version(v1.0.0 is already published) 2024-05-09 15:20:49 +08:00
Yumin Wu
770ab4a01b command friendly tips 2024-05-09 15:06:32 +08:00
Yumin Wu
e4146c3f92 release reduce size 2024-05-09 15:04:27 +08:00
Yumin Wu
8e841bf5b5 fixed version 2024-05-09 15:02:28 +08:00
Sijie.Sun
076f6cd965 Merge pull request #93 from wuyumin/yumin-dev
update  files for compiler
2024-05-08 22:29:45 +08:00
Yumin Wu
801104ca69 add target 2024-05-08 21:52:59 +08:00
Yumin Wu
5d5d8b122a rename config for IDE 2024-05-08 21:51:37 +08:00
Yumin Wu
4387d49a42 update Cargo.lock 2024-05-08 21:50:38 +08:00
Sijie.Sun
2d394acc47 Merge pull request #90 from m1m1sha/feat/custom-hostname
Feat/custom hostname
2024-05-08 21:44:01 +08:00
Sijie.Sun
e1e10b24e6 Merge pull request #92 from wuyumin/main 2024-05-08 21:07:56 +08:00
m1m1sha
52fef9fd4f 🎈 perf: 主机名提示显示本机主机名 2024-05-08 21:02:14 +08:00
m1m1sha
e6ad308cd5 ↩ revert: 兼容性 2024-05-08 20:49:33 +08:00
m1m1sha
bf6b46ec8e 🎈 perf: func 2024-05-08 19:09:39 +08:00
m1m1sha
da0777293f 🎈 perf: ts type 2024-05-08 18:58:17 +08:00
Yumin Wu
4ca840239a wireguard client keepalive 2024-05-08 17:40:43 +08:00
m1m1sha
30ccfab288 🐞 fix: hostname empty 2024-05-08 16:18:09 +08:00
m1m1sha
bde5b7f6ea 🎈 perf: get hostname 2024-05-08 16:06:11 +08:00
m1m1sha
6448955e05 🌈 style: 去除表格抖动 2024-05-08 14:48:23 +08:00
m1m1sha
0498b55d39 feat: custom hostname 2024-05-08 14:47:22 +08:00
Sijie.Sun
c3df9ea7fa Merge pull request #84 from m1m1sha/perf/gui-front-perf
Optimize the GUI front-end project structure
2024-05-08 00:25:20 +08:00
m1m1sha
6f437bf4c3 Merge branch 'perf/gui-front-perf' of https://github.com/m1m1sha/easytier into perf/gui-front-perf 2024-05-07 23:59:25 +08:00
m1m1sha
74f01e9800 🐳 chore: eslint config 2024-05-07 23:50:01 +08:00
m1m1sha
5cbe59219d 🐳 chore: 修改工作区配置
move the gui workspace configuration from the main workspace to the gui workspace to avoid issues such as plugin warnings
2024-05-07 23:49:17 +08:00
m1m1sha
1db1fbc03b 🐳 chore: vsc recommendations 2024-05-07 23:48:10 +08:00
m1m1sha
836a90e4d7 🌈 style: 清理依赖 2024-05-07 23:48:10 +08:00
m1m1sha
bc64b05e18 🐳 chore: vsc workspace 2024-05-07 23:48:00 +08:00
m1m1sha
1170f758c1 🌈 style: eslint lint 2024-05-07 23:47:42 +08:00
m1m1sha
0b3ff3ced3 🐳 chore: eslint 2024-05-07 23:47:21 +08:00
m1m1sha
060b11578f 🐳 chore: 增加依赖 2024-05-07 23:42:52 +08:00
m1m1sha
d4d352a36f 🐳 chore: pnpm lock 2024-05-07 23:39:38 +08:00
m1m1sha
c768e1d13b 🐞 fix: 全局作用域中异步加载语言 2024-05-07 23:39:38 +08:00
m1m1sha
5605d239ce 🐳 chore: eslint config and script
`eslint` 只忽略 `tauri` 文件目录
增加 `eslint` 自动修复命令
2024-05-07 23:39:38 +08:00
m1m1sha
831ede7d35 🌈 style: lint 2024-05-07 23:39:38 +08:00
m1m1sha
97e8cbb9ed 🐞 fix: 不可使用顶级 await 2024-05-07 23:39:38 +08:00
m1m1sha
705c34623c 🐳 chore: eslint 命令行忽略文件
由于未知原因导致 eslint 配置项中 ignores 未生效,暂时使用命令行代替
2024-05-07 23:39:38 +08:00
m1m1sha
42f933dfc3 🐞 fix: i18n 读写 key 不一致 2024-05-07 23:39:38 +08:00
m1m1sha
d2f89bb0ac 🐳 chore: eslint config 2024-05-07 23:39:38 +08:00
m1m1sha
114208081f 🐳 chore: 修改工作区配置
move the gui workspace configuration from the main workspace to the gui workspace to avoid issues such as plugin warnings
2024-05-07 23:39:38 +08:00
m1m1sha
bd484eb7fe 🐳 chore: vsc recommendations 2024-05-07 23:39:38 +08:00
m1m1sha
d44b63d45f 🌈 style: 清理依赖 2024-05-07 23:39:38 +08:00
m1m1sha
307a0c7b3c 🐳 chore: vsc workspace 2024-05-07 23:39:38 +08:00
m1m1sha
c66939249f 🌈 style: eslint lint 2024-05-07 23:39:38 +08:00
m1m1sha
6f75dd72b9 🐳 chore: eslint 2024-05-07 23:39:38 +08:00
m1m1sha
e6408f2582 🎈 perf: 修改多语言图标 2024-05-07 23:39:38 +08:00
m1m1sha
934cfce1b0 🐞 fix: 可能使用不存在的语言 2024-05-07 23:39:38 +08:00
m1m1sha
76292a8377 🎈 perf: 移除无用tsconfig 2024-05-07 23:39:38 +08:00
m1m1sha
20c509da77 🎈 perf: 拆分main 2024-05-07 23:39:38 +08:00
m1m1sha
584d924433 🎈 perf: 更新引入 2024-05-07 23:39:38 +08:00
m1m1sha
740d2938f5 🎈 perf: 使用路径路由 2024-05-07 23:39:38 +08:00
m1m1sha
7314309750 🎈 perf: 拆分composable 2024-05-07 23:39:38 +08:00
m1m1sha
af3e1634d1 🎈 perf: 拆分store 2024-05-07 23:39:38 +08:00
m1m1sha
376d533527 🎈 perf: 拆分i18n 2024-05-07 23:39:38 +08:00
m1m1sha
f583fea5e4 🎈 perf: 拆分type 2024-05-07 23:39:38 +08:00
m1m1sha
14a391d4fc 🐳 chore: 增加依赖 2024-05-07 23:39:38 +08:00
Sijie.Sun
14df3d3075 mips support wireguard (#87) 2024-05-07 23:14:29 +08:00
m1m1sha
0fa7895301 🐳 chore: pnpm lock update 2024-05-07 23:10:33 +08:00
m1m1sha
b9c4cd25a6 Merge branch 'perf/gui-front-perf' of https://github.com/m1m1sha/easytier into perf/gui-front-perf 2024-05-07 23:09:53 +08:00
m1m1sha
ecdf9f34ea 🐳 chore: pnpm lock 2024-05-07 23:04:06 +08:00
m1m1sha
5b14fc05d2 🐞 fix: 全局作用域中异步加载语言 2024-05-07 23:01:23 +08:00
m1m1sha
6089813da5 🐳 chore: eslint config and script
`eslint` 只忽略 `tauri` 文件目录
增加 `eslint` 自动修复命令
2024-05-07 23:01:06 +08:00
m1m1sha
189a073f05 🌈 style: lint 2024-05-07 23:01:06 +08:00
m1m1sha
a6b8f2023c 🐞 fix: 不可使用顶级 await 2024-05-07 23:01:06 +08:00
m1m1sha
9c390230f5 🐳 chore: eslint 命令行忽略文件
由于未知原因导致 eslint 配置项中 ignores 未生效,暂时使用命令行代替
2024-05-07 23:01:06 +08:00
m1m1sha
36436b597f 🐞 fix: i18n 读写 key 不一致 2024-05-07 23:01:06 +08:00
m1m1sha
f0c7b3a9bf 🐳 chore: eslint config 2024-05-07 23:01:06 +08:00
m1m1sha
cbbd8a2b8c 🐳 chore: 修改工作区配置
move the gui workspace configuration from the main workspace to the gui workspace to avoid issues such as plugin warnings
2024-05-07 22:58:42 +08:00
m1m1sha
3f44f48814 🐳 chore: vsc recommendations 2024-05-07 22:58:42 +08:00
m1m1sha
1a1549cdc7 🌈 style: 清理依赖 2024-05-07 22:58:42 +08:00
m1m1sha
eafff8439c 🐳 chore: vsc workspace 2024-05-07 22:57:56 +08:00
m1m1sha
c37fc13404 🌈 style: eslint lint 2024-05-07 22:57:56 +08:00
m1m1sha
8b94b3cab0 🐳 chore: eslint 2024-05-07 22:57:56 +08:00
m1m1sha
37f01f2898 🎈 perf: 修改多语言图标 2024-05-07 22:57:56 +08:00
m1m1sha
cd3387357b 🐞 fix: 可能使用不存在的语言 2024-05-07 22:57:56 +08:00
m1m1sha
59ccb38db2 🎈 perf: 移除无用tsconfig 2024-05-07 22:57:56 +08:00
m1m1sha
39fcbf91d5 🎈 perf: 拆分main 2024-05-07 22:57:56 +08:00
m1m1sha
e3c82dbbc8 🎈 perf: 更新引入 2024-05-07 22:57:56 +08:00
m1m1sha
be67330c24 🎈 perf: 使用路径路由 2024-05-07 22:57:56 +08:00
m1m1sha
795b8ec1d0 🎈 perf: 拆分composable 2024-05-07 22:57:56 +08:00
m1m1sha
856cd33f26 🎈 perf: 拆分store 2024-05-07 22:57:56 +08:00
m1m1sha
0b30bdf4a0 🎈 perf: 拆分i18n 2024-05-07 22:57:56 +08:00
m1m1sha
11a3f786cb 🎈 perf: 拆分type 2024-05-07 22:57:56 +08:00
m1m1sha
0b389afd22 🐳 chore: 增加依赖 2024-05-07 22:57:56 +08:00
m1m1sha
1280e1dde2 replace yarn with pnpm (#85)
* 🐳 chore: replace yarn with pnpm
2024-05-07 22:40:09 +08:00
m1m1sha
d10917d47d 🐞 fix: 全局作用域中异步加载语言 2024-05-07 15:24:51 +08:00
m1m1sha
fb2a6d9b17 🐳 chore: eslint config and script
`eslint` 只忽略 `tauri` 文件目录
增加 `eslint` 自动修复命令
2024-05-07 14:33:26 +08:00
m1m1sha
a8c4b1feac 🌈 style: lint 2024-05-07 14:30:40 +08:00
m1m1sha
c0dc9a493d 🐞 fix: 不可使用顶级 await 2024-05-07 13:43:08 +08:00
m1m1sha
83baf2fdc7 🐳 chore: eslint 命令行忽略文件
由于未知原因导致 eslint 配置项中 ignores 未生效,暂时使用命令行代替
2024-05-07 10:46:58 +08:00
m1m1sha
8188585edd 🐞 fix: i18n 读写 key 不一致 2024-05-07 10:40:12 +08:00
m1m1sha
e9a625ec5f 🐳 chore: eslint config 2024-05-07 10:39:06 +08:00
Sijie.Sun
8440eb842b fix bugs and improve user experiance (#86)
* correctly set mtu, and allow set mtu manually

* communicate between enc and non-enc should not panic

* allow loading cfg from file

* allow change file log level dynamically
2024-05-07 00:38:05 +08:00
m1m1sha
2e57599f41 🐳 chore: 修改工作区配置
move the gui workspace configuration from the main workspace to the gui workspace to avoid issues such as plugin warnings
2024-05-06 14:26:32 +08:00
m1m1sha
3abdca31f2 🐳 chore: vsc recommendations 2024-05-06 13:06:42 +08:00
m1m1sha
8d1e99da05 🌈 style: 清理依赖 2024-05-06 12:59:03 +08:00
m1m1sha
f72033e7f6 🐳 chore: vsc workspace 2024-05-06 12:52:12 +08:00
m1m1sha
57dce76363 🌈 style: eslint lint 2024-05-06 11:08:51 +08:00
m1m1sha
6c00ed4276 🐳 chore: eslint 2024-05-06 10:49:53 +08:00
m1m1sha
9e5bdf74bc 🎈 perf: 修改多语言图标 2024-05-06 09:49:59 +08:00
m1m1sha
893fba4adf 🐞 fix: 可能使用不存在的语言 2024-05-06 09:05:40 +08:00
m1m1sha
e7092bfcf6 🎈 perf: 移除无用tsconfig 2024-05-05 23:14:52 +08:00
m1m1sha
26c59d3507 🎈 perf: 拆分main 2024-05-05 23:14:37 +08:00
m1m1sha
c6660986c4 🎈 perf: 更新引入 2024-05-05 23:14:22 +08:00
m1m1sha
26d1482131 🎈 perf: 使用路径路由 2024-05-05 23:13:39 +08:00
m1m1sha
9dd44038bc 🎈 perf: 拆分composable 2024-05-05 23:12:54 +08:00
m1m1sha
06a0957734 🎈 perf: 拆分store 2024-05-05 23:12:19 +08:00
m1m1sha
6428f23dce 🎈 perf: 拆分i18n 2024-05-05 23:12:02 +08:00
m1m1sha
8604724ff7 🎈 perf: 拆分type 2024-05-05 23:11:00 +08:00
m1m1sha
fda056528b 🐳 chore: 增加依赖 2024-05-05 23:10:42 +08:00
Sijie.Sun
e5b537267e bug fix and improve (#81)
1. fix manual connector do not retry if dns resolve failed.
2. allow not creating tun device if no virtual ipv4 is assigned.
2024-05-05 16:18:05 +08:00
m1m1sha
638013a93d 🎈 perf: hidden cmd windows (#79)
* 🎈 perf: hidden cmd window, use CREATE_NO_WINDOW flag when exec shell cmd.
2024-05-05 15:33:05 +08:00
m1m1sha
064a009cb4 🐞 fix: Unable to correctly locate protoc in PATH 2024-05-05 13:02:12 +08:00
m1m1sha
0af32526f7 🐞 fix: 修复nightly错误 (https://github.com/KKRainbow/EasyTier/issues/74) (#75)
* 🐞 fix: 修复 1.80 nightly 编译错误错误

TODO: need fork boringtun and publish to crates.io before publishing easytier 

issues: https://github.com/KKRainbow/EasyTier/issues/74
2024-05-05 11:46:10 +08:00
Sijie.Sun
714667fdce Update rust.yml (#76)
fix [PR from fork cannot use github secret directly](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow)
2024-05-05 11:06:39 +08:00
Sijie.Sun
3a5332e31d use mimalloc for mips/mipsel (#71) 2024-05-04 00:26:57 +08:00
Sijie.Sun
61d5e38cc9 Update README.md (#70) 2024-05-03 21:50:48 +08:00
Sijie.Sun
3763c959db Merge pull request #68 from KKRainbow/mips
Add mips / mipsel support

- mips do not support wireguard.
- mips use aes-gcm crates instead of ring crates for encryption
2024-05-03 17:28:10 +08:00
sijie.sun
873851e6d0 mips 2024-05-03 17:09:46 +08:00
Sijie.Sun
ebbed97ed5 bump version in Carto.toml to v1.0.0 (#67) 2024-05-03 07:57:05 +08:00
sijie.sun
1be6db661e bump version in Carto.toml to v1.0.0 2024-05-02 23:28:38 +08:00
Sijie.Sun
d8446778cc update readme (#65)
add picture of gui
2024-04-29 21:50:58 +08:00
Sijie.Sun
70dee329d1 fix crash bugs (#64) 2024-04-29 21:02:05 +08:00
Sijie.Sun
6595c2837e fix win multi network (#63) 2024-04-28 23:21:58 +08:00
sijie.sun
577cef131b fix wireguard deadlock 2024-04-28 22:24:24 +08:00
sijie.sun
b3717d974b ipv6 set v6 only when bind 2024-04-28 22:24:24 +08:00
sijie.sun
d8033a77b9 support use ipv6 2024-04-28 22:24:24 +08:00
sijie.sun
3a965efab2 allow tunnel listener alloc port after listen 2024-04-28 22:24:24 +08:00
sijie.sun
a3e85a1270 tunnel support ipv6 2024-04-28 22:24:24 +08:00
Sijie.Sun
66b3241be7 fix handshake dead lock, clean old code (#61)
* fix handshake dead lock
* remove old code
2024-04-27 16:27:42 +08:00
Sijie.Sun
fcc73159b3 support encryption (#60) 2024-04-27 13:44:59 +08:00
Sijie.Sun
69651ae3fd Perf improve (#59)
* improve perf

* fix forward
2024-04-26 23:02:07 +08:00
Sijie.Sun
096af6aa45 fix tun device on mac (#58) 2024-04-26 21:19:47 +08:00
Sijie.Sun
57c9f11371 adapt tun device to zerocopy (#57) 2024-04-25 23:25:37 +08:00
Sijie.Sun
3467890270 zero copy tunnel (#55)
make tunnel zero copy, for better performance. remove most of the locks in io path.
introduce quic tunnel
prepare for encryption
2024-04-24 23:12:46 +08:00
Sijie.Sun
39021d7b1b fix gui minor-bugs (#54)
1. cannot persist locale setting.
2. set forcus after show from tray icon
2024-04-21 10:00:01 +08:00
Sijie.Sun
0ddcda1b31 introduce gui based on tauri (#52) 2024-04-14 23:29:34 +08:00
Sijie.Sun
50e14798d6 fix ring tunnel cannot close (#51) 2024-04-07 11:35:22 +08:00
Sijie.Sun
727ef37ae4 add client gui for easytier (#50) 2024-04-06 22:44:30 +08:00
Sijie.Sun
4eb7efe5fc use workspace, prepare for config server and gui (#48) 2024-04-04 10:33:53 +08:00
Sijie.Sun
bb4ae71869 bump easytier version to 0.1.2 (#45) 2024-04-03 23:14:23 +08:00
Sijie.Sun
892b06dfd3 some wg & cli & README improve (#47)
1. fix vpn client cannot access local node
2. fix wg client config no allowedip field
3. some cli & README improve
2024-04-03 22:22:44 +08:00
Sijie.Sun
e4be86cf92 allow specify bind dev for tunnels. also fix bugs #46)
1. fix wireguard / udp tunnel stack overflow on win.
2. custom panic handler to save panic stack.
3. fix iface filter on windows and linux.
4. add scheme black list to direct connector
2024-04-03 21:46:52 +08:00
Sijie.Sun
25a7603990 Add WireGuard Client to Readme (#44)
* Add README for Wireguard Client

* add default protocol flag

* wireguard connector support bind device
2024-03-31 21:10:59 +08:00
Sijie.Sun
05cabb2651 Support wireguard vpn portal (#43)
* support wireguard vpn portal
  user can use wireguard client to access easytier network

* add vpn portal cli

* clean logs

* avoid ospf msg too large
2024-03-30 22:15:14 +08:00
Sijie.Sun
90110aa587 add wireguard tunnel (#42)
peers can connect with each other using wireguard protocol.
2024-03-28 10:01:25 +08:00
Sijie.Sun
ce889e990e some minor bug fixs (#41)
* fix joinset leak; 

* fix udp packet format

* fix trace log panic

* avoid waiting after listener accept
2024-03-24 22:21:47 +08:00
314 changed files with 39619 additions and 8555 deletions

View File

@@ -1,7 +0,0 @@
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static"]
[target.'cfg(all(windows, target_env = "msvc"))']
rustflags = ["-C", "target-feature=+crt-static"]

77
.cargo/config.toml Normal file
View File

@@ -0,0 +1,77 @@
[target.x86_64-unknown-linux-musl]
linker = "rust-lld"
rustflags = ["-C", "linker-flavor=ld.lld"]
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static"]
[target.'cfg(all(windows, target_env = "msvc"))']
rustflags = ["-C", "target-feature=+crt-static"]
[target.mipsel-unknown-linux-musl]
linker = "mipsel-linux-muslsf-gcc"
rustflags = [
"-C",
"target-feature=+crt-static",
"-L",
"./musl_gcc/mipsel-linux-muslsf-cross/mipsel-linux-muslsf/lib",
"-L",
"./musl_gcc/mipsel-linux-muslsf-cross/lib/gcc/mipsel-linux-muslsf/11.2.1",
"-l",
"atomic",
"-l",
"ctz",
]
[target.mips-unknown-linux-musl]
linker = "mips-linux-muslsf-gcc"
rustflags = [
"-C",
"target-feature=+crt-static",
"-L",
"./musl_gcc/mips-linux-muslsf-cross/mips-linux-muslsf/lib",
"-L",
"./musl_gcc/mips-linux-muslsf-cross/lib/gcc/mips-linux-muslsf/11.2.1",
"-l",
"atomic",
"-l",
"ctz",
]
[target.armv7-unknown-linux-musleabihf]
linker = "armv7l-linux-musleabihf-gcc"
rustflags = ["-C", "target-feature=+crt-static"]
[target.armv7-unknown-linux-musleabi]
linker = "armv7m-linux-musleabi-gcc"
rustflags = ["-C", "target-feature=+crt-static"]
[target.arm-unknown-linux-musleabihf]
linker = "arm-linux-musleabihf-gcc"
rustflags = [
"-C",
"target-feature=+crt-static",
"-L",
"./musl_gcc/arm-linux-musleabihf-cross/arm-linux-musleabihf/lib",
"-L",
"./musl_gcc/arm-linux-musleabihf-cross/lib/gcc/arm-linux-musleabihf/11.2.1",
"-l",
"atomic",
]
[target.arm-unknown-linux-musleabi]
linker = "arm-linux-musleabi-gcc"
rustflags = [
"-C",
"target-feature=+crt-static",
"-L",
"./musl_gcc/arm-linux-musleabi-cross/arm-linux-musleabi/lib",
"-L",
"./musl_gcc/arm-linux-musleabi-cross/lib/gcc/arm-linux-musleabi/11.2.1",
"-l",
"atomic",
]

35
.github/workflows/Dockerfile vendored Normal file
View File

@@ -0,0 +1,35 @@
FROM alpine:latest AS builder
ARG TARGETPLATFORM
COPY . /tmp/artifacts
RUN mkdir -p /tmp/output; \
cd /tmp/artifacts; \
ARTIFACT_ARCH=""; \
if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
ARTIFACT_ARCH="x86_64"; \
elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
ARTIFACT_ARCH="aarch64"; \
else \
echo "Unsupported architecture: $TARGETARCH"; \
exit 1; \
fi; \
cp /tmp/artifacts/easytier-linux-${ARTIFACT_ARCH}/* /tmp/output;
FROM alpine:latest
WORKDIR /app
COPY --from=builder --chmod=755 /tmp/output/* /usr/local/bin
# tcp
EXPOSE 11010/tcp
# udp
EXPOSE 11010/udp
# wg
EXPOSE 11011/udp
# ws
EXPOSE 11011/tcp
# wss
EXPOSE 11012/tcp
ENTRYPOINT ["easytier-core"]

174
.github/workflows/core.yml vendored Normal file
View File

@@ -0,0 +1,174 @@
name: EasyTier Core
on:
push:
branches: ["develop", "main"]
pull_request:
branches: ["develop", "main"]
env:
CARGO_TERM_COLOR: always
defaults:
run:
# necessary for windows
shell: bash
jobs:
pre_job:
# continue-on-error: true # Uncomment once integration is finished
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
# All of these options are optional, so you can remove them if you are happy with the defaults
concurrent_skipping: 'never'
skip_after_successful_duplicate: 'true'
paths: '["Cargo.toml", "Cargo.lock", "easytier/**", ".github/workflows/core.yml", ".github/workflows/install_rust.sh"]'
build:
strategy:
fail-fast: false
matrix:
include:
- TARGET: aarch64-unknown-linux-musl
OS: ubuntu-latest
ARTIFACT_NAME: linux-aarch64
- TARGET: x86_64-unknown-linux-musl
OS: ubuntu-latest
ARTIFACT_NAME: linux-x86_64
- TARGET: mips-unknown-linux-musl
OS: ubuntu-latest
ARTIFACT_NAME: linux-mips
- TARGET: mipsel-unknown-linux-musl
OS: ubuntu-latest
ARTIFACT_NAME: linux-mipsel
- TARGET: armv7-unknown-linux-musleabihf # raspberry pi 2-3-4, not tested
OS: ubuntu-latest
ARTIFACT_NAME: linux-armv7hf
- TARGET: armv7-unknown-linux-musleabi # raspberry pi 2-3-4, not tested
OS: ubuntu-latest
ARTIFACT_NAME: linux-armv7
- TARGET: arm-unknown-linux-musleabihf # raspberry pi 0-1, not tested
OS: ubuntu-latest
ARTIFACT_NAME: linux-armhf
- TARGET: arm-unknown-linux-musleabi # raspberry pi 0-1, not tested
OS: ubuntu-latest
ARTIFACT_NAME: linux-arm
- TARGET: x86_64-apple-darwin
OS: macos-latest
ARTIFACT_NAME: macos-x86_64
- TARGET: aarch64-apple-darwin
OS: macos-latest
ARTIFACT_NAME: macos-aarch64
- TARGET: x86_64-pc-windows-msvc
OS: windows-latest
ARTIFACT_NAME: windows-x86_64
runs-on: ${{ matrix.OS }}
env:
NAME: easytier
TARGET: ${{ matrix.TARGET }}
OS: ${{ matrix.OS }}
OSS_BUCKET: ${{ secrets.ALIYUN_OSS_BUCKET }}
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version: 21
- name: Cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install rust target
run: bash ./.github/workflows/install_rust.sh
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build Core & Cli
run: |
if [[ $OS =~ ^ubuntu.*$ && $TARGET =~ ^mips.*$ ]]; then
cargo +nightly build -r --verbose --target $TARGET -Z build-std=std,panic_abort --no-default-features --features mips
else
cargo build --release --verbose --target $TARGET
fi
- name: Install UPX
if: ${{ matrix.OS != 'macos-latest' }}
uses: crazy-max/ghaction-upx@v3
with:
version: latest
install-only: true
- name: Compress
run: |
mkdir -p ./artifacts/objects/
# windows is the only OS using a different convention for executable file name
if [[ $OS =~ ^windows.*$ ]]; then
SUFFIX=.exe
cp easytier/third_party/Packet.dll ./artifacts/objects/
cp easytier/third_party/wintun.dll ./artifacts/objects/
fi
if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then
TAG=$GITHUB_REF_NAME
else
TAG=$GITHUB_SHA
fi
if [[ $OS =~ ^ubuntu.*$ ]]; then
upx --lzma --best ./target/$TARGET/release/easytier-core"$SUFFIX"
upx --lzma --best ./target/$TARGET/release/easytier-cli"$SUFFIX"
fi
mv ./target/$TARGET/release/easytier-core"$SUFFIX" ./artifacts/objects/
mv ./target/$TARGET/release/easytier-cli"$SUFFIX" ./artifacts/objects/
mv ./artifacts/objects/* ./artifacts/
rm -rf ./artifacts/objects/
- name: Archive artifact
uses: actions/upload-artifact@v4
with:
name: easytier-${{ matrix.ARTIFACT_NAME }}
path: |
./artifacts/*
- name: Upload OSS
if: ${{ env.OSS_BUCKET != '' }}
uses: Menci/upload-to-oss@main
with:
access-key-id: ${{ secrets.ALIYUN_OSS_ACCESS_ID }}
access-key-secret: ${{ secrets.ALIYUN_OSS_ACCESS_KEY }}
endpoint: ${{ secrets.ALIYUN_OSS_ENDPOINT }}
bucket: ${{ secrets.ALIYUN_OSS_BUCKET }}
local-path: ./artifacts/
remote-path: /easytier-releases/${{ github.sha }}/
no-delete-remote-files: true
retry: 5
core-result:
if: needs.pre_job.outputs.should_skip != 'true' && always()
runs-on: ubuntu-latest
needs:
- pre_job
- build
steps:
- name: Mark result as failed
if: needs.build.result != 'success'
run: exit 1

61
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: EasyTier Docker
on:
workflow_dispatch:
inputs:
run_id:
description: 'The run id of EasyTier-Core Action in EasyTier repo'
type: number
default: 10228239965
required: true
image_tag:
description: 'Tag for this image build'
type: string
default: 'v1.2.0'
required: true
mark_latest:
description: 'Mark this image as latest'
type: boolean
default: false
required: true
jobs:
docker:
if: contains('["KKRainbow"]', github.actor)
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Download artifact
id: download-artifact
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{secrets.GITHUB_TOKEN}}
run_id: ${{ inputs.run_id }}
repo: EasyTier/EasyTier
path: docker_context
- name: List files
run: |
ls -l -R .
-
name: Build and push
uses: docker/build-push-action@v6
with:
context: ./docker_context
platforms: linux/amd64,linux/arm64
push: true
file: .github/workflows/Dockerfile
tags: easytier/easytier:${{ inputs.image_tag }}${{ inputs.mark_latest && ',easytier/easytier:latest' || '' }},

212
.github/workflows/gui.yml vendored Normal file
View File

@@ -0,0 +1,212 @@
name: EasyTier GUI
on:
push:
branches: ["develop", "main"]
pull_request:
branches: ["develop", "main"]
env:
CARGO_TERM_COLOR: always
defaults:
run:
# necessary for windows
shell: bash
jobs:
pre_job:
# continue-on-error: true # Uncomment once integration is finished
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
# All of these options are optional, so you can remove them if you are happy with the defaults
concurrent_skipping: 'never'
skip_after_successful_duplicate: 'true'
paths: '["Cargo.toml", "Cargo.lock", "easytier/**", "easytier-gui/**", ".github/workflows/gui.yml", ".github/workflows/install_rust.sh"]'
build-gui:
strategy:
fail-fast: false
matrix:
include:
- TARGET: aarch64-unknown-linux-musl
OS: ubuntu-latest
GUI_TARGET: aarch64-unknown-linux-gnu
ARTIFACT_NAME: linux-aarch64
- TARGET: x86_64-unknown-linux-musl
OS: ubuntu-latest
GUI_TARGET: x86_64-unknown-linux-gnu
ARTIFACT_NAME: linux-x86_64
- TARGET: x86_64-apple-darwin
OS: macos-latest
GUI_TARGET: x86_64-apple-darwin
ARTIFACT_NAME: macos-x86_64
- TARGET: aarch64-apple-darwin
OS: macos-latest
GUI_TARGET: aarch64-apple-darwin
ARTIFACT_NAME: macos-aarch64
- TARGET: x86_64-pc-windows-msvc
OS: windows-latest
GUI_TARGET: x86_64-pc-windows-msvc
ARTIFACT_NAME: windows-x86_64
runs-on: ${{ matrix.OS }}
env:
NAME: easytier
TARGET: ${{ matrix.TARGET }}
OS: ${{ matrix.OS }}
GUI_TARGET: ${{ matrix.GUI_TARGET }}
OSS_BUCKET: ${{ secrets.ALIYUN_OSS_BUCKET }}
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version: 21
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install frontend dependencies
run: |
(cd easytier-gui; pnpm install)
(cd tauri-plugin-vpnservice; pnpm install; pnpm build)
- name: Cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install rust target
run: bash ./.github/workflows/install_rust.sh
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install GUI cross compile (aarch64 only)
if: ${{ matrix.TARGET == 'aarch64-unknown-linux-musl' }}
run: |
# see https://tauri.app/v1/guides/building/linux/
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted" | sudo tee /etc/apt/sources.list
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy universe" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates universe" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security main restricted" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security universe" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=amd64] http://security.ubuntu.com/ubuntu/ jammy-security multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy main restricted" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy universe" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates universe" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security universe" | sudo tee -a /etc/apt/sources.list
echo "deb [arch=armhf,arm64] http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse" | sudo tee -a /etc/apt/sources.list
sudo dpkg --add-architecture arm64
sudo apt-get update && sudo apt-get upgrade -y
sudo apt install gcc-aarch64-linux-gnu
sudo apt install libwebkit2gtk-4.1-dev:arm64
sudo apt install libssl-dev:arm64
echo "PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu/" >> "$GITHUB_ENV"
echo "PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig/" >> "$GITHUB_ENV"
- name: Build GUI
if: ${{ matrix.GUI_TARGET != '' }}
uses: tauri-apps/tauri-action@v0
with:
projectPath: ./easytier-gui
# https://tauri.app/v1/guides/building/linux/#cross-compiling-tauri-applications-for-arm-based-devices
args: --verbose --target ${{ matrix.GUI_TARGET }} ${{ matrix.OS == 'ubuntu-latest' && contains(matrix.TARGET, 'aarch64') && '--bundles deb' || '' }}
- name: Compress
run: |
mkdir -p ./artifacts/objects/
if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then
TAG=$GITHUB_REF_NAME
else
TAG=$GITHUB_SHA
fi
# copy gui bundle, gui is built without specific target
if [[ $OS =~ ^windows.*$ ]]; then
mv ./target/$GUI_TARGET/release/bundle/nsis/*.exe ./artifacts/objects/
elif [[ $OS =~ ^macos.*$ ]]; then
mv ./target/$GUI_TARGET/release/bundle/dmg/*.dmg ./artifacts/objects/
elif [[ $OS =~ ^ubuntu.*$ && ! $TARGET =~ ^mips.*$ ]]; then
mv ./target/$GUI_TARGET/release/bundle/deb/*.deb ./artifacts/objects/
if [[ $GUI_TARGET =~ ^x86_64.*$ ]]; then
# currently only x86 appimage is supported
mv ./target/$GUI_TARGET/release/bundle/appimage/*.AppImage ./artifacts/objects/
fi
fi
mv ./artifacts/objects/* ./artifacts/
rm -rf ./artifacts/objects/
- name: Archive artifact
uses: actions/upload-artifact@v4
with:
name: easytier-gui-${{ matrix.ARTIFACT_NAME }}
path: |
./artifacts/*
- name: Upload OSS
if: ${{ env.OSS_BUCKET != '' }}
uses: Menci/upload-to-oss@main
with:
access-key-id: ${{ secrets.ALIYUN_OSS_ACCESS_ID }}
access-key-secret: ${{ secrets.ALIYUN_OSS_ACCESS_KEY }}
endpoint: ${{ secrets.ALIYUN_OSS_ENDPOINT }}
bucket: ${{ secrets.ALIYUN_OSS_BUCKET }}
local-path: ./artifacts/
remote-path: /easytier-releases/${{ github.sha }}/gui
no-delete-remote-files: true
retry: 5
gui-result:
if: needs.pre_job.outputs.should_skip != 'true' && always()
runs-on: ubuntu-latest
needs:
- pre_job
- build-gui
steps:
- name: Mark result as failed
if: needs.build-gui.result != 'success'
run: exit 1

80
.github/workflows/install_rust.sh vendored Normal file
View File

@@ -0,0 +1,80 @@
#!/usr/bin/env bash
# env needed:
# - TARGET
# - GUI_TARGET
# - OS
# dependencies are only needed on ubuntu as that's the only place where
# we make cross-compilation
if [[ $OS =~ ^ubuntu.*$ ]]; then
sudo apt-get update && sudo apt-get install -qq crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools libappindicator3-dev
# for easytier-gui
if [[ $GUI_TARGET != '' && $GUI_TARGET =~ ^x86_64.*$ ]]; then
sudo apt install -qq libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libgtk-3-dev \
librsvg2-dev \
libxdo-dev \
libssl-dev \
patchelf
fi
# curl -s musl.cc | grep mipsel
case $TARGET in
mipsel-unknown-linux-musl)
MUSL_URI=mipsel-linux-muslsf
;;
mips-unknown-linux-musl)
MUSL_URI=mips-linux-muslsf
;;
aarch64-unknown-linux-musl)
MUSL_URI=aarch64-linux-musl
;;
armv7-unknown-linux-musleabihf)
MUSL_URI=armv7l-linux-musleabihf
;;
armv7-unknown-linux-musleabi)
MUSL_URI=armv7m-linux-musleabi
;;
arm-unknown-linux-musleabihf)
MUSL_URI=arm-linux-musleabihf
;;
arm-unknown-linux-musleabi)
MUSL_URI=arm-linux-musleabi
;;
esac
if [ -n "$MUSL_URI" ]; then
mkdir -p ./musl_gcc
wget -c https://musl.cc/${MUSL_URI}-cross.tgz -P ./musl_gcc/
tar zxf ./musl_gcc/${MUSL_URI}-cross.tgz -C ./musl_gcc/
sudo ln -s $(pwd)/musl_gcc/${MUSL_URI}-cross/bin/*gcc /usr/bin/
fi
fi
# see https://github.com/rust-lang/rustup/issues/3709
rustup set auto-self-update disable
rustup install 1.77
rustup default 1.77
# mips/mipsel cannot add target from rustup, need compile by ourselves
if [[ $OS =~ ^ubuntu.*$ && $TARGET =~ ^mips.*$ ]]; then
cd "$PWD/musl_gcc/${MUSL_URI}-cross/lib/gcc/${MUSL_URI}/11.2.1" || exit 255
# for panic-abort
cp libgcc_eh.a libunwind.a
# for mimalloc
ar x libgcc.a _ctzsi2.o _clz.o _bswapsi2.o
ar rcs libctz.a _ctzsi2.o _clz.o _bswapsi2.o
rustup toolchain install nightly-x86_64-unknown-linux-gnu
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
else
rustup target add $TARGET
if [[ $GUI_TARGET != '' ]]; then
rustup target add $GUI_TARGET
fi
fi

165
.github/workflows/mobile.yml vendored Normal file
View File

@@ -0,0 +1,165 @@
name: EasyTier Mobile
on:
push:
branches: ["develop", "main"]
pull_request:
branches: ["develop", "main"]
env:
CARGO_TERM_COLOR: always
defaults:
run:
# necessary for windows
shell: bash
jobs:
pre_job:
# continue-on-error: true # Uncomment once integration is finished
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
# All of these options are optional, so you can remove them if you are happy with the defaults
concurrent_skipping: 'never'
skip_after_successful_duplicate: 'true'
paths: '["Cargo.toml", "Cargo.lock", "easytier/**", "easytier-gui/**", "tauri-plugin-vpnservice/**", ".github/workflows/mobile.yml", ".github/workflows/install_rust.sh"]'
build-mobile:
strategy:
fail-fast: false
matrix:
include:
- TARGET: android
OS: ubuntu-latest
ARTIFACT_NAME: android
runs-on: ${{ matrix.OS }}
env:
NAME: easytier
TARGET: ${{ matrix.TARGET }}
OS: ${{ matrix.OS }}
OSS_BUCKET: ${{ secrets.ALIYUN_OSS_BUCKET }}
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v4
with:
distribution: 'oracle'
java-version: '20'
- name: Setup Android SDK
uses: android-actions/setup-android@v3
with:
cmdline-tools-version: 11076708
packages: 'build-tools;34.0.0 ndk;26.0.10792818 tools platform-tools platforms;android-34 '
- name: Setup Android Environment
run: |
echo "$ANDROID_HOME/platform-tools" >> $GITHUB_PATH
echo "$ANDROID_HOME/ndk/26.0.10792818/toolchains/llvm/prebuilt/linux-x86_64/bin" >> $GITHUB_PATH
echo "NDK_HOME=$ANDROID_HOME/ndk/26.0.10792818/" > $GITHUB_ENV
- uses: actions/setup-node@v4
with:
node-version: 21
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install frontend dependencies
run: |
(cd easytier-gui; pnpm install)
(cd tauri-plugin-vpnservice; pnpm install; pnpm build)
- name: Cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install rust target
run: |
bash ./.github/workflows/install_rust.sh
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android
rustup target add x86_64-linux-android
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Build Android
run: |
cd easytier-gui
pnpm tauri android build
- name: Compress
run: |
mkdir -p ./artifacts/objects/
mv easytier-gui/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk ./artifacts/objects/
if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then
TAG=$GITHUB_REF_NAME
else
TAG=$GITHUB_SHA
fi
mv ./artifacts/objects/* ./artifacts
rm -rf ./artifacts/objects/
- name: Archive artifact
uses: actions/upload-artifact@v4
with:
name: easytier-gui-${{ matrix.ARTIFACT_NAME }}
path: |
./artifacts/*
- name: Upload OSS
if: ${{ env.OSS_BUCKET != '' }}
uses: Menci/upload-to-oss@main
with:
access-key-id: ${{ secrets.ALIYUN_OSS_ACCESS_ID }}
access-key-secret: ${{ secrets.ALIYUN_OSS_ACCESS_KEY }}
endpoint: ${{ secrets.ALIYUN_OSS_ENDPOINT }}
bucket: ${{ secrets.ALIYUN_OSS_BUCKET }}
local-path: ./artifacts/
remote-path: /easytier-releases/${{ github.sha }}/mobile
no-delete-remote-files: true
retry: 5
mobile-result:
if: needs.pre_job.outputs.should_skip != 'true' && always()
runs-on: ubuntu-latest
needs:
- pre_job
- build-mobile
steps:
- name: Mark result as failed
if: needs.build-mobile.result != 'success'
run: exit 1

View File

@@ -1,151 +0,0 @@
name: Rust
on:
push:
branches: [ "develop", "main" ]
pull_request:
branches: [ "develop", "main" ]
env:
CARGO_TERM_COLOR: always
defaults:
run:
# necessary for windows
shell: bash
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- TARGET: aarch64-unknown-linux-musl
OS: ubuntu-latest
- TARGET: x86_64-unknown-linux-musl
OS: ubuntu-latest
- TARGET: x86_64-apple-darwin
OS: macos-latest
- TARGET: aarch64-apple-darwin
OS: macos-latest
- TARGET: x86_64-pc-windows-msvc
OS: windows-latest
runs-on: ${{ matrix.OS }}
env:
NAME: easytier
TARGET: ${{ matrix.TARGET }}
OS: ${{ matrix.OS }}
steps:
- uses: actions/checkout@v3
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Cargo cache
uses: actions/cache@v4.0.0
with:
path: |
~/.cargo
./target
key: build-cargo-registry-${{matrix.TARGET}}
- name: Install rust target
run: |
# dependencies are only needed on ubuntu as that's the only place where
# we make cross-compilation
if [[ $OS =~ ^ubuntu.*$ ]]; then
sudo apt-get update && sudo apt-get install -qq crossbuild-essential-arm64 crossbuild-essential-armhf musl-tools
# curl -s musl.cc | grep mipsel
case $TARGET in
mipsel-unknown-linux-musl)
MUSL_URI=mipsel-linux-musl-cross
;;
aarch64-unknown-linux-musl)
MUSL_URI=aarch64-linux-musl-cross
;;
armv7-unknown-linux-musleabihf)
MUSL_URI=armv7l-linux-musleabihf-cross
;;
arm-unknown-linux-musleabihf)
MUSL_URI=arm-linux-musleabihf-cross
;;
mips-unknown-linux-musl)
MUSL_URI=mips-linux-musl-cross
;;
esac
if [ -n "$MUSL_URI" ]; then
mkdir -p ./musl_gcc
wget -c https://musl.cc/$MUSL_URI.tgz -P ./musl_gcc/
tar zxf ./musl_gcc/$MUSL_URI.tgz -C ./musl_gcc/
sudo ln -s $(pwd)/musl_gcc/$MUSL_URI/bin/*gcc /usr/bin/
fi
fi
# see https://github.com/rust-lang/rustup/issues/3709
rustup set auto-self-update disable
rustup install 1.75
rustup default 1.75
rustup target add $TARGET
- name: Run build
run: cargo build --release --verbose --target $TARGET
- name: Compress
run: |
mkdir -p ./artifacts/objects/
# windows is the only OS using a different convention for executable file name
if [[ $OS =~ ^windows.*$ ]]; then
SUFFIX=.exe
cp third_party/Packet.dll ./artifacts/objects/
cp third_party/wintun.dll ./artifacts/objects/
fi
if [[ $GITHUB_REF_TYPE =~ ^tag$ ]]; then
TAG=$GITHUB_REF_NAME
else
TAG=$GITHUB_SHA
fi
mv ./target/$TARGET/release/easytier-core"$SUFFIX" ./artifacts/objects/
mv ./target/$TARGET/release/easytier-cli"$SUFFIX" ./artifacts/objects/
tar -cvf ./artifacts/$NAME-$TARGET-$TAG.tar -C ./artifacts/objects/ .
rm -rf ./artifacts/objects/
- name: Archive artifact
uses: actions/upload-artifact@v4
with:
name: easytier-${{ matrix.OS }}-${{ matrix.TARGET }}
path: |
./artifacts/*
- name: Upload OSS
uses: Menci/upload-to-oss@main
with:
access-key-id: ${{ secrets.ALIYUN_OSS_ACCESS_ID }}
access-key-secret: ${{ secrets.ALIYUN_OSS_ACCESS_KEY }}
endpoint: ${{ secrets.ALIYUN_OSS_ENDPOINT }}
bucket: ${{ secrets.ALIYUN_OSS_BUCKET }}
local-path: ./artifacts/
remote-path: /easytier-releases/${{ github.sha }}/
no-delete-remote-files: true
retry: 5
increment: true
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup tools for test
run: sudo apt install bridge-utils
- name: Setup system for test
run: |
sudo sysctl net.bridge.bridge-nf-call-iptables=0
sudo sysctl net.bridge.bridge-nf-call-ip6tables=0
- name: Cargo cache
uses: actions/cache@v4.0.0
with:
path: |
~/.cargo
./target
key: build-cargo-registry-test
- name: Run tests
run: sudo -E env "PATH=$PATH" cargo test --verbose

67
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
name: EasyTier Test
on:
push:
branches: ["develop", "main"]
pull_request:
branches: ["develop", "main"]
env:
CARGO_TERM_COLOR: always
defaults:
run:
# necessary for windows
shell: bash
jobs:
pre_job:
# continue-on-error: true # Uncomment once integration is finished
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v5
with:
# All of these options are optional, so you can remove them if you are happy with the defaults
concurrent_skipping: 'never'
skip_after_successful_duplicate: 'true'
paths: '["Cargo.toml", "Cargo.lock", "easytier/**", ".github/workflows/test.yml"]'
test:
runs-on: ubuntu-latest
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v3
- name: Setup protoc
uses: arduino/setup-protoc@v2
with:
# GitHub repo token to use to avoid rate limiter
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup tools for test
run: sudo apt install bridge-utils
- name: Setup system for test
run: |
sudo sysctl net.bridge.bridge-nf-call-iptables=0
sudo sysctl net.bridge.bridge-nf-call-ip6tables=0
sudo sysctl net.ipv6.conf.lo.disable_ipv6=0
sudo ip addr add 2001:db8::2/64 dev lo
- name: Cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo
./target
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
- name: Run tests
run: |
sudo -E env "PATH=$PATH" cargo test --no-default-features --features=full --verbose
sudo chown -R $USER:$USER ./target
sudo chown -R $USER:$USER ~/.cargo

13
.gitignore vendored
View File

@@ -4,10 +4,6 @@ debug/
target/
target-*/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
@@ -24,3 +20,12 @@ flamegraph.svg
root-target
nohup.out
.DS_Store
components.d.ts
musl_gcc
# log
easytier-panic.log

7595
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,144 +1,13 @@
[package]
name = "easytier"
description = "A full meshed p2p VPN, connecting all your devices in one network with one command."
homepage = "https://github.com/KKRainbow/EasyTier"
repository = "https://github.com/KKRainbow/EasyTier"
version = "0.1.1"
edition = "2021"
authors = ["kkrainbow"]
keywords = ["vpn", "p2p", "network", "easytier"]
categories = ["network-programming", "command-line-utilities"]
rust-version = "1.75"
license-file = "LICENSE"
readme = "README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "easytier-core"
path = "src/easytier-core.rs"
[[bin]]
name = "easytier-cli"
path = "src/easytier-cli.rs"
test = false
[dependencies]
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3", features = [
"env-filter",
"local-time",
"time",
] }
tracing-appender = "0.2.3"
log = "0.4"
thiserror = "1.0"
auto_impl = "1.1.0"
crossbeam = "0.8.4"
time = "0.3"
toml = "0.8.12"
chrono = "0.4.35"
gethostname = "0.4.3"
futures = "0.3"
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1"
tokio-util = { version = "0.7.9", features = ["codec", "net"] }
async-stream = "0.3.5"
async-trait = "0.1.74"
dashmap = "5.5.3"
timedmap = "1.0.1"
# for tap device
tun = { version = "0.6.1", features = ["async"] }
# for net ns
nix = { version = "0.27", features = ["sched", "socket", "ioctl"] }
uuid = { version = "1.5.0", features = [
"v4",
"fast-rng",
"macro-diagnostics",
"serde",
] }
# for ring tunnel
crossbeam-queue = "0.3"
once_cell = "1.18.0"
# for packet
rkyv = { "version" = "0.7.42", features = [
"validation",
"archive_le",
"strict",
"copy_unsafe",
"arbitrary_enum_discriminant",
] }
postcard = { "version" = "1.0.8", features = ["alloc"] }
# for rpc
tonic = "0.10"
prost = "0.12"
anyhow = "1.0"
tarpc = { version = "0.32", features = ["tokio1", "serde1"] }
url = { version = "2.5", features = ["serde"] }
# for tun packet
byteorder = "1.5.0"
# for proxy
cidr = "0.2.2"
socket2 = "0.5.5"
# for hole punching
stun_codec = "0.3.4"
bytecodec = "0.4.15"
rand = "0.8.5"
serde = { version = "1.0", features = ["derive"] }
pnet = { version = "0.34.0", features = ["serde"] }
public-ip = { version = "0.2", features = ["default"] }
clap = { version = "4.4.8", features = ["unicode", "derive", "wrap_help"] }
async-recursion = "1.0.5"
network-interface = "1.1.1"
# for ospf route
pathfinding = "4.9.1"
# for cli
tabled = "0.15.*"
humansize = "2.1.3"
[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.52", features = [
"Win32_Networking_WinSock",
"Win32_NetworkManagement_IpHelper",
"Win32_Foundation",
"Win32_System_IO",
] }
[build-dependencies]
tonic-build = "0.10"
[target.'cfg(windows)'.build-dependencies]
reqwest = { version = "0.11", features = ["blocking"] }
zip = "0.6.6"
[dev-dependencies]
serial_test = "3.0.0"
[workspace]
resolver = "2"
members = ["easytier", "easytier-gui/src-tauri"]
default-members = ["easytier"]
[profile.dev]
panic = "abort"
panic = "unwind"
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
strip = true

87
EasyTier.code-workspace Normal file
View File

@@ -0,0 +1,87 @@
{
"folders": [
{
"path": "."
},
{
"path": "easytier-gui"
},
{
"path": "easytier"
}
],
"settings": {
"eslint.experimental.useFlatConfig": true,
"prettier.enable": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
"eslint.rules.customizations": [
{
"rule": "style/*",
"severity": "off"
},
{
"rule": "style/eol-last",
"severity": "error"
},
{
"rule": "format/*",
"severity": "off"
},
{
"rule": "*-indent",
"severity": "off"
},
{
"rule": "*-spacing",
"severity": "off"
},
{
"rule": "*-spaces",
"severity": "off"
},
{
"rule": "*-order",
"severity": "off"
},
{
"rule": "*-dangle",
"severity": "off"
},
{
"rule": "*-newline",
"severity": "off"
},
{
"rule": "*quotes",
"severity": "off"
},
{
"rule": "*semi",
"severity": "off"
}
],
"eslint.validate": [
"code-workspace",
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml",
"toml",
"gql",
"graphql"
],
"i18n-ally.localesPaths": [
"easytier-gui/locales"
]
}
}

119
README.md
View File

@@ -1,17 +1,27 @@
# EasyTier
[![GitHub](https://img.shields.io/github/license/KKRainbow/EasyTier)](https://github.com/KKRainbow/EasyTier/blob/main/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/KKRainbow/EasyTier)](https://github.com/KKRainbow/EasyTier/commits/main)
[![GitHub issues](https://img.shields.io/github/issues/KKRainbow/EasyTier)](https://github.com/KKRainbow/EasyTier/issues)
[![GitHub actions](https://github.com/KKRainbow/EasyTier/actions/workflows/rust.yml/badge.svg)](https://github.com/KKRainbow/EasyTier/actions/)
[![GitHub](https://img.shields.io/github/license/EasyTier/EasyTier)](https://github.com/EasyTier/EasyTier/blob/main/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/EasyTier/EasyTier)](https://github.com/EasyTier/EasyTier/commits/main)
[![GitHub issues](https://img.shields.io/github/issues/EasyTier/EasyTier)](https://github.com/EasyTier/EasyTier/issues)
[![GitHub Core Actions](https://github.com/EasyTier/EasyTier/actions/workflows/core.yml/badge.svg)](https://github.com/EasyTier/EasyTier/actions/workflows/core.yml)
[![GitHub GUI Actions](https://github.com/EasyTier/EasyTier/actions/workflows/gui.yml/badge.svg)](https://github.com/EasyTier/EasyTier/actions/workflows/gui.yml)
[简体中文](/README_CN.md) | [English](/README.md)
EasyTier is a simple, plug-and-play, decentralized VPN networking solution implemented with the Rust language and Tokio framework.
**Please visit the [EasyTier Official Website](https://www.easytier.top/en/) to view the full documentation.**
EasyTier is a simple, safe and decentralized VPN networking solution implemented with the Rust language and Tokio framework.
<p align="center">
<img src="assets/image-5.png" width="300">
<img src="assets/image-4.png" width="300">
</p>
## Features
- **Decentralized**: No need to rely on centralized services, nodes are equal and independent.
- **Safe**: Use WireGuard protocol to encrypt data.
- **High Performance**: Full-link zero-copy, with performance comparable to mainstream networking software.
- **Cross-platform**: Supports MacOS/Linux/Windows, will support IOS and Android in the future. The executable file is statically linked, making deployment simple.
- **Networking without public IP**: Supports networking using shared public nodes, refer to [Configuration Guide](#Networking-without-public-IP)
- **NAT traversal**: Supports UDP-based NAT traversal, able to establish stable connections even in complex network environments.
@@ -19,13 +29,15 @@
- **Smart Routing**: Selects links based on traffic to reduce latency and increase throughput.
- **TCP Support**: Provides reliable data transmission through concurrent TCP links when UDP is limited, optimizing performance.
- **High Availability**: Supports multi-path and switches to healthy paths when high packet loss or network errors are detected.
- **IPv6 Support**: Supports networking using IPv6.
- **Multiple Protocol Types**: Supports communication between nodes using protocols such as WebSocket and QUIC.
## Installation
1. **Download the precompiled binary file**
Visit the [GitHub Release page](https://github.com/KKRainbow/EasyTier/releases) to download the binary file suitable for your operating system.
Visit the [GitHub Release page](https://github.com/EasyTier/EasyTier/releases) to download the binary file suitable for your operating system. Release includes both command-line programs and GUI programs in the compressed package.
2. **Install via crates.io**
```sh
@@ -34,10 +46,12 @@
3. **Install from source code**
```sh
cargo install --git https://github.com/KKRainbow/EasyTier.git
cargo install --git https://github.com/EasyTier/EasyTier.git
```
## Quick Start
> The following text only describes the use of the command-line tool; the GUI program can be configured by referring to the following concepts.
Make sure EasyTier is installed according to the [Installation Guide](#Installation), and both easytier-core and easytier-cli commands are available.
@@ -66,7 +80,7 @@
```
Successful execution of the command will print the following.
![alt text](assets/image-2.png)
![alt text](/assets/image-2.png)
2. Execute on Node B
```sh
@@ -84,11 +98,11 @@
```sh
easytier-cli peer
```
![alt text](assets/image.png)
![alt text](/assets/image.png)
```sh
easytier-cli route
```
![alt text](assets/image-1.png)
![alt text](/assets/image-1.png)
---
@@ -138,7 +152,7 @@
```sh
easytier-cli route
```
![alt text](assets/image-3.png)
![alt text](/assets/image-3.png)
2. Test whether Node A can access nodes under the proxied subnet
@@ -157,17 +171,79 @@
Taking two nodes as an example, Node A executes:
```sh
sudo easytier-core -i 10.144.144.1 --network-name abc --network-secret abc -e 'tcp://easytier.public.kkrainbow.top:11010'
sudo easytier-core -i 10.144.144.1 --network-name abc --network-secret abc -e tcp://easytier.public.kkrainbow.top:11010
```
Node B executes
```sh
sudo easytier-core --ipv4 10.144.144.2 --network-name abc --network-secret abc -e 'tcp://easytier.public.kkrainbow.top:11010'
sudo easytier-core --ipv4 10.144.144.2 --network-name abc --network-secret abc -e tcp://easytier.public.kkrainbow.top:11010
```
After the command is successfully executed, Node A can access Node B through the virtual IP 10.144.144.2.
### Use EasyTier with WireGuard Client
EasyTier can be used as a WireGuard server to allow any device with WireGuard client installed to access the EasyTier network. For platforms currently unsupported by EasyTier (such as iOS, Android, etc.), this method can be used to connect to the EasyTier network.
Assuming the network topology is as follows:
```mermaid
flowchart LR
ios[[iPhone \n WireGuard Installed]]
subgraph Node A IP 22.1.1.1
nodea[EasyTier\n10.144.144.1]
end
subgraph Node B
nodeb[EasyTier\n10.144.144.2]
end
id1[[10.1.1.0/24]]
ios <-.-> nodea <--> nodeb <-.-> id1
```
To enable an iPhone to access the EasyTier network through Node A, the following configuration can be applied:
Include the --vpn-portal parameter in the easytier-core command on Node A to specify the port that the WireGuard service listens on and the subnet used by the WireGuard network.
```
# The following parameters mean: listen on port 0.0.0.0:11013, and use the 10.14.14.0/24 subnet for WireGuard
sudo easytier-core --ipv4 10.144.144.1 --vpn-portal wg://0.0.0.0:11013/10.14.14.0/24
```
After successfully starting easytier-core, use easytier-cli to obtain the WireGuard client configuration.
```
$> easytier-cli vpn-portal
portal_name: wireguard
############### client_config_start ###############
[Interface]
PrivateKey = 9VDvlaIC9XHUvRuE06hD2CEDrtGF+0lDthgr9SZfIho=
Address = 10.14.14.0/32 # should assign an ip from this cidr manually
[Peer]
PublicKey = zhrZQg4QdPZs8CajT3r4fmzcNsWpBL9ImQCUsnlXyGM=
AllowedIPs = 10.144.144.0/24,10.14.14.0/24
Endpoint = 0.0.0.0:11013 # should be the public ip(or domain) of the vpn server
PersistentKeepalive = 25
############### client_config_end ###############
connected_clients:
[]
```
Before using the Client Config, you need to modify the Interface Address and Peer Endpoint to the client's IP and the IP of the EasyTier node, respectively. Import the configuration file into the WireGuard client to access the EasyTier network.
# Self-Hosted Public Server
Each node can act as a relay node for other users' networks. Simply start EasyTier without any parameters.
### Configurations
@@ -183,20 +259,27 @@
# Community and Contribution
We welcome and encourage community contributions! If you want to get involved, please submit a [GitHub PR](https://github.com/KKRainbow/EasyTier/pulls). Detailed contribution guidelines can be found in [CONTRIBUTING.md](https://github.com/KKRainbow/EasyTier/blob/main/CONTRIBUTING.md).
We welcome and encourage community contributions! If you want to get involved, please submit a [GitHub PR](https://github.com/EasyTier/EasyTier/pulls). Detailed contribution guidelines can be found in [CONTRIBUTING.md](https://github.com/EasyTier/EasyTier/blob/main/CONTRIBUTING.md).
# Related Projects and Resources
- [ZeroTier](https://www.zerotier.com/): A global virtual network for connecting devices.
- [TailScale](https://tailscale.com/): A VPN solution aimed at simplifying network configuration.
- [vpncloud](https://github.com/dswd/vpncloud): A P2P Mesh VPN
- [Candy](https://github.com/lanthora/candy): A reliable, low-latency, and anti-censorship virtual private network
# License
EasyTier is released under the [Apache License 2.0](https://github.com/KKRainbow/EasyTier/blob/main/LICENSE).
EasyTier is released under the [Apache License 2.0](https://github.com/EasyTier/EasyTier/blob/main/LICENSE).
# Contact
- Ask questions or report problems: [GitHub Issues](https://github.com/KKRainbow/EasyTier/issues)
- Discussion and exchange: [GitHub Discussions](https://github.com/KKRainbow/EasyTier/discussions)
- QQ Group: 949700262
- Ask questions or report problems: [GitHub Issues](https://github.com/EasyTier/EasyTier/issues)
- Discussion and exchange: [GitHub Discussions](https://github.com/EasyTier/EasyTier/discussions)
- Telegramhttps://t.me/easytier
- QQ Group: 949700262
# Sponsor
<img src="assets/image-8.png" width="300">
<img src="assets/image-9.png" width="300">

View File

@@ -1,17 +1,27 @@
# EasyTier
[![GitHub](https://img.shields.io/github/license/KKRainbow/EasyTier)](https://github.com/KKRainbow/EasyTier/blob/main/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/KKRainbow/EasyTier)](https://github.com/KKRainbow/EasyTier/commits/main)
[![GitHub issues](https://img.shields.io/github/issues/KKRainbow/EasyTier)](https://github.com/KKRainbow/EasyTier/issues)
[![GitHub actions](https://github.com/KKRainbow/EasyTier/actions/workflows/rust.yml/badge.svg)](https://github.com/KKRainbow/EasyTier/actions/)
[![GitHub](https://img.shields.io/github/license/EasyTier/EasyTier)](https://github.com/EasyTier/EasyTier/blob/main/LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/EasyTier/EasyTier)](https://github.com/EasyTier/EasyTier/commits/main)
[![GitHub issues](https://img.shields.io/github/issues/EasyTier/EasyTier)](https://github.com/EasyTier/EasyTier/issues)
[![GitHub Core Actions](https://github.com/EasyTier/EasyTier/actions/workflows/core.yml/badge.svg)](https://github.com/EasyTier/EasyTier/actions/workflows/core.yml)
[![GitHub GUI Actions](https://github.com/EasyTier/EasyTier/actions/workflows/gui.yml/badge.svg)](https://github.com/EasyTier/EasyTier/actions/workflows/gui.yml)
[简体中文](/README_CN.md) | [English](/README.md)
一个简单、即插即用、去中心化的内网穿透 VPN 组网方案,使用 Rust 语言和 Tokio 框架实现。
**请访问 [EasyTier 官网](https://www.easytier.top/) 以查看完整的文档。**
一个简单、安全、去中心化的内网穿透 VPN 组网方案,使用 Rust 语言和 Tokio 框架实现。
<p align="center">
<img src="assets/image-6.png" width="300">
<img src="assets/image-7.png" width="300">
</p>
## 特点
- **去中心化**:无需依赖中心化服务,节点平等且独立。
- **安全**:支持利用 WireGuard 加密通信,也支持 AES-GCM 加密保护中转流量。
- **高性能**:全链路零拷贝,性能与主流组网软件相当。
- **跨平台**:支持 MacOS/Linux/Windows未来将支持 IOS 和 Android。可执行文件静态链接部署简单。
- **无公网 IP 组网**:支持利用共享的公网节点组网,可参考 [配置指南](#无公网IP组网)
- **NAT 穿透**:支持基于 UDP 的 NAT 穿透,即使在复杂的网络环境下也能建立稳定的连接。
@@ -19,12 +29,14 @@
- **智能路由**:根据流量智能选择链路,减少延迟,提高吞吐量。
- **TCP 支持**:在 UDP 受限的情况下,通过并发 TCP 链接提供可靠的数据传输,优化性能。
- **高可用性**:支持多路径和在检测到高丢包率或网络错误时切换到健康路径。
- **IPV6 支持**:支持利用 IPV6 组网。
- **多协议类型**: 支持使用 WebSocket、QUIC 等协议进行节点间通信。
## 安装
1. **下载预编译的二进制文件**
访问 [GitHub Release 页面](https://github.com/KKRainbow/EasyTier/releases) 下载适用于您操作系统的二进制文件。
访问 [GitHub Release 页面](https://github.com/EasyTier/EasyTier/releases) 下载适用于您操作系统的二进制文件。Release 压缩包中同时包含命令行程序和图形界面程序。
2. **通过 crates.io 安装**
```sh
@@ -34,11 +46,13 @@
3. **通过源码安装**
```sh
cargo install --git https://github.com/KKRainbow/EasyTier.git
cargo install --git https://github.com/EasyTier/EasyTier.git
```
## 快速开始
> 下文仅描述命令行工具的使用,图形界面程序可参考下述概念自行配置。
确保已按照 [安装指南](#安装) 安装 EasyTier并且 easytier-core 和 easytier-cli 两个命令都已经可用。
### 双节点组网
@@ -66,7 +80,7 @@ nodea <-----> nodeb
```
命令执行成功会有如下打印。
![alt text](assets/image-2.png)
![alt text](/assets/image-2.png)
2. 在节点 B 执行
```sh
@@ -84,11 +98,11 @@ nodea <-----> nodeb
```sh
easytier-cli peer
```
![alt text](assets/image.png)
![alt text](/assets/image.png)
```sh
easytier-cli route
```
![alt text](assets/image-1.png)
![alt text](/assets/image-1.png)
---
@@ -138,7 +152,7 @@ sudo easytier-core --ipv4 10.144.144.2 -n 10.1.1.0/24
```sh
easytier-cli route
```
![alt text](assets/image-3.png)
![alt text](/assets/image-3.png)
2. 测试节点 A 是否可访问被代理子网下的节点
@@ -157,19 +171,84 @@ EasyTier 支持共享公网节点进行组网。目前已部署共享的公网
以双节点为例,节点 A 执行:
```sh
sudo easytier-core -i 10.144.144.1 --network-name abc --network-secret abc -e 'tcp://easytier.public.kkrainbow.top:11010'
sudo easytier-core -i 10.144.144.1 --network-name abc --network-secret abc -e tcp://easytier.public.kkrainbow.top:11010
```
节点 B 执行
```sh
sudo easytier-core --ipv4 10.144.144.2 --network-name abc --network-secret abc -e 'tcp://easytier.public.kkrainbow.top:11010'
sudo easytier-core --ipv4 10.144.144.2 --network-name abc --network-secret abc -e tcp://easytier.public.kkrainbow.top:11010
```
命令执行成功后,节点 A 即可通过虚拟 IP 10.144.144.2 访问节点 B。
---
### 使用 WireGuard 客户端接入
EasyTier 可以用作 WireGuard 服务端,让任意安装了 WireGuard 客户端的设备访问 EasyTier 网络。对于目前 EasyTier 不支持的平台 (如 iOS、Android 等),可以使用这种方式接入 EasyTier 网络。
假设网络拓扑如下:
```mermaid
flowchart LR
ios[[iPhone \n 安装 WireGuard]]
subgraph 节点 A IP 22.1.1.1
nodea[EasyTier\n10.144.144.1]
end
subgraph 节点 B
nodeb[EasyTier\n10.144.144.2]
end
id1[[10.1.1.0/24]]
ios <-.-> nodea <--> nodeb <-.-> id1
```
我们需要 iPhone 通过节点 A 访问 EasyTier 网络,则可进行如下配置:
在节点 A 的 easytier-core 命令中,加入 --vpn-portal 参数,指定 WireGuard 服务监听的端口,以及 WireGuard 网络使用的网段。
```
# 以下参数的含义为: 监听 0.0.0.0:11013 端口WireGuard 使用 10.14.14.0/24 网段
sudo easytier-core --ipv4 10.144.144.1 --vpn-portal wg://0.0.0.0:11013/10.14.14.0/24
```
easytier-core 启动成功后,使用 easytier-cli 获取 WireGuard Client 的配置。
```
$> easytier-cli vpn-portal
portal_name: wireguard
############### client_config_start ###############
[Interface]
PrivateKey = 9VDvlaIC9XHUvRuE06hD2CEDrtGF+0lDthgr9SZfIho=
Address = 10.14.14.0/32 # should assign an ip from this cidr manually
[Peer]
PublicKey = zhrZQg4QdPZs8CajT3r4fmzcNsWpBL9ImQCUsnlXyGM=
AllowedIPs = 10.144.144.0/24,10.14.14.0/24
Endpoint = 0.0.0.0:11013 # should be the public ip(or domain) of the vpn server
PersistentKeepalive = 25
############### client_config_end ###############
connected_clients:
[]
```
使用 Client Config 前,需要将 Interface Address 和 Peer Endpoint 分别修改为客户端的 IP 和 EasyTier 节点的 IP。将配置文件导入 WireGuard 客户端,即可访问 EasyTier 网络。
---
### 自建公共中转服务器
每个节点都可作为其他用户网络的中转节点。不带任何参数直接启动 EasyTier 即可。
### 其他配置
可使用 ``easytier-core --help`` 查看全部配置项
@@ -178,26 +257,33 @@ sudo easytier-core --ipv4 10.144.144.2 --network-name abc --network-secret abc -
# 路线图
- [ ] 完善文档和用户指南。
- [ ] 支持加密、TCP 打洞等特性。
- [ ] 支持 TCP 打洞等特性。
- [ ] 支持 Android、IOS 等移动平台。
- [ ] 支持 Web 配置管理。
# 社区和贡献
我们欢迎并鼓励社区贡献!如果你想参与进来,请提交 [GitHub PR](https://github.com/KKRainbow/EasyTier/pulls)。详细的贡献指南可以在 [CONTRIBUTING.md](https://github.com/KKRainbow/EasyTier/blob/main/CONTRIBUTING.md) 中找到。
我们欢迎并鼓励社区贡献!如果你想参与进来,请提交 [GitHub PR](https://github.com/EasyTier/EasyTier/pulls)。详细的贡献指南可以在 [CONTRIBUTING.md](https://github.com/EasyTier/EasyTier/blob/main/CONTRIBUTING.md) 中找到。
# 相关项目和资源
- [ZeroTier](https://www.zerotier.com/): 一个全球虚拟网络,用于连接设备。
- [TailScale](https://tailscale.com/): 一个旨在简化网络配置的 VPN 解决方案。
- [vpncloud](https://github.com/dswd/vpncloud): 一个 P2P Mesh VPN
- [Candy](https://github.com/lanthora/candy): 可靠、低延迟、抗审查的虚拟专用网络
# 许可证
EasyTier 根据 [Apache License 2.0](https://github.com/KKRainbow/EasyTier/blob/main/LICENSE) 许可证发布。
EasyTier 根据 [Apache License 2.0](https://github.com/EasyTier/EasyTier/blob/main/LICENSE) 许可证发布。
# 联系方式
- 提问或报告问题:[GitHub Issues](https://github.com/KKRainbow/EasyTier/issues)
- 讨论和交流:[GitHub Discussions](https://github.com/KKRainbow/EasyTier/discussions)
- QQ 群: 949700262
- 提问或报告问题:[GitHub Issues](https://github.com/EasyTier/EasyTier/issues)
- 讨论和交流:[GitHub Discussions](https://github.com/EasyTier/EasyTier/discussions)
- QQ 群: 949700262
- Telegramhttps://t.me/easytier
# 赞助
<img src="assets/image-8.png" width="300">
<img src="assets/image-9.png" width="300">

BIN
assets/image-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
assets/image-5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
assets/image-6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
assets/image-7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
assets/image-8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
assets/image-9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

27
easytier-gui/.gitignore vendored Normal file
View File

@@ -0,0 +1,27 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
vite.config.ts.timestamp*

2
easytier-gui/.npmrc Normal file
View File

@@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false

7
easytier-gui/.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"vue.volar",
"lokalise.i18n-ally"
]
}

5
easytier-gui/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"i18n-ally.localesPaths": [
"locales"
]
}

46
easytier-gui/README.md Normal file
View File

@@ -0,0 +1,46 @@
# GUI for EasyTier
this is a GUI implementation for EasyTier, based on Tauri2.
## Compile
### Install prerequisites
```
apt install npm
npm install -g pnpm
```
### For Desktop (Win/Mac/Linux)
```
pnpm install
pnpm tauri build
```
### For Android
Need to install android SDK / emulator / NDK / Java (easy with android studio)
```
# For ArchLinux
sudo pacman -Sy sdkmanager
sudo sdkmanager --install platform-tools platforms\;android-34 ndk\;r26 build-tools
export PATH=/opt/android-sdk/platform-tools:$PATH
export ANDROID_HOME=/opt/android-sdk/
export NDK_HOME=/opt/android-sdk/ndk/26.0.10792818/
rustup target add aarch64-linux-android
install java 20
```
Java version depend on gradle version specified in (easytier-gui\src-tauri\gen\android\build.gradle.kts)
See [Gradle compatibility matrix](https://docs.gradle.org/current/userguide/compatibility.html) for detail .
```
pnpm install
pnpm tauri android init
pnpm tauri android build
```

View File

@@ -0,0 +1,12 @@
// @ts-check
import antfu from '@antfu/eslint-config'
export default antfu({
formatters: true,
rules: {
'style/eol-last': ['error', 'always'],
},
ignores: [
'src-tauri/**',
],
})

14
easytier-gui/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri + Vue + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@@ -0,0 +1,77 @@
network: 网络
networking_method: 网络方式
public_server: 公共服务器
manual: 手动
standalone: 独立
virtual_ipv4: 虚拟IPv4地址
virtual_ipv4_dhcp: DHCP
network_name: 网络名称
network_secret: 网络密码
public_server_url: 公共服务器地址
peer_urls: 对等节点地址
proxy_cidrs: 子网代理CIDR
enable_vpn_portal: 启用VPN门户
vpn_portal_listen_port: 监听端口
vpn_portal_client_network: 客户端子网
advanced_settings: 高级设置
basic_settings: 基础设置
listener_urls: 监听地址
rpc_port: RPC端口
config_network: 配置网络
running: 运行中
error_msg: 错误信息
detail: 详情
add_new_network: 添加新网络
del_cur_network: 删除当前网络
select_network: 选择网络
network_instances: 网络实例
instance_id: 实例ID
network_infos: 网络信息
parse_network_config: 解析网络配置
retain_network_instance: 保留网络实例
collect_network_infos: 收集网络信息
settings: 设置
exchange_language: Switch to English
logging: 日志
logging_level_info: 信息
logging_level_debug: 调试
logging_level_warn: 警告
logging_level_trace: 跟踪
logging_level_off: 关闭
logging_open_dir: 打开日志目录
logging_copy_dir: 复制日志路径
disable_auto_launch: 关闭开机自启
enable_auto_launch: 开启开机自启
exit: 退出
chips_placeholder: 例如: {0}, 按回车添加
hostname_placeholder: '留空默认为主机名: {0}'
off_text: 点击关闭
on_text: 点击开启
show_config: 显示配置
close: 关闭
my_node_info: 当前节点信息
peer_count: 已连接
upload: 上传
download: 下载
show_vpn_portal_config: 显示VPN门户配置
vpn_portal_config: VPN门户配置
show_event_log: 显示事件日志
event_log: 事件日志
peer_info: 节点信息
hostname: 主机名
route_cost: 路由
latency: 延迟
upload_bytes: 上传
download_bytes: 下载
loss_rate: 丢包率
run_network: 运行网络
stop_network: 停止网络
network_running: 运行中
network_stopped: 已停止
dhcp_experimental_warning: 实验性警告使用DHCP时如果组网环境中发生IP冲突将自动更改IP。
tray:
show: 显示 / 隐藏
exit: 退出

View File

@@ -0,0 +1,77 @@
network: Network
networking_method: Networking Method
public_server: Public Server
manual: Manual
standalone: Standalone
virtual_ipv4: Virtual IPv4
virtual_ipv4_dhcp: DHCP
network_name: Network Name
network_secret: Network Secret
public_server_url: Public Server URL
peer_urls: Peer URLs
proxy_cidrs: Subnet Proxy CIDRs
enable_vpn_portal: Enable VPN Portal
vpn_portal_listen_port: VPN Portal Listen Port
vpn_portal_client_network: Client Sub Network
advanced_settings: Advanced Settings
basic_settings: Basic Settings
listener_urls: Listener URLs
rpc_port: RPC Port
config_network: Config Network
running: Running
error_msg: Error Message
detail: Detail
add_new_network: New Network
del_cur_network: Delete Current Network
select_network: Select Network
network_instances: Network Instances
instance_id: Instance ID
network_infos: Network Infos
parse_network_config: Parse Network Config
retain_network_instance: Retain Network Instance
collect_network_infos: Collect Network Infos
settings: Settings
exchange_language: 切换中文
logging: Logging
logging_level_info: Info
logging_level_debug: Debug
logging_level_warn: Warn
logging_level_trace: Trace
logging_level_off: Off
logging_open_dir: Open Log Directory
logging_copy_dir: Copy Log Path
disable_auto_launch: Disable Launch on Reboot
enable_auto_launch: Enable Launch on Reboot
exit: Exit
chips_placeholder: 'e.g: {0}, press Enter to add'
hostname_placeholder: 'Leave blank and default to host name: {0}'
off_text: Press to disable
on_text: Press to enable
show_config: Show Config
close: Close
my_node_info: My Node Info
peer_count: Connected
upload: Upload
download: Download
show_vpn_portal_config: Show VPN Portal Config
vpn_portal_config: VPN Portal Config
show_event_log: Show Event Log
event_log: Event Log
peer_info: Peer Info
route_cost: Route Cost
hostname: Hostname
latency: Latency
upload_bytes: Upload
download_bytes: Download
loss_rate: Loss Rate
run_network: Run Network
stop_network: Stop Network
network_running: running
network_stopped: stopped
dhcp_experimental_warning: Experimental warning! if there is an IP conflict in the network when using DHCP, the IP will be automatically changed.
tray:
show: Show / Hide
exit: Exit

58
easytier-gui/package.json Normal file
View File

@@ -0,0 +1,58 @@
{
"name": "easytier-gui",
"type": "module",
"version": "1.2.1",
"private": true,
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"tauri": "tauri",
"lint": "eslint . --ignore-pattern src-tauri",
"lint:fix": "eslint . --ignore-pattern src-tauri --fix"
},
"dependencies": {
"@primevue/themes": "^4.0.4",
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.0",
"@tauri-apps/plugin-os": "2.0.0-rc.0",
"@tauri-apps/plugin-process": "2.0.0-rc.0",
"@tauri-apps/plugin-shell": "2.0.0-rc.0",
"aura": "link:@primevue/themes/aura",
"pinia": "^2.2.1",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
"primevue": "^4.0.4",
"tauri-plugin-vpnservice-api": "link:../tauri-plugin-vpnservice",
"vue": "^3.4.36",
"vue-i18n": "^9.13.1",
"vue-router": "^4.4.3"
},
"devDependencies": {
"@antfu/eslint-config": "^2.24.1",
"@intlify/unplugin-vue-i18n": "^4.0.0",
"@primevue/auto-import-resolver": "^4.0.4",
"@tauri-apps/api": "2.0.0-rc.0",
"@tauri-apps/cli": "2.0.0-rc.1",
"@types/node": "^20.14.14",
"@types/uuid": "^9.0.8",
"@vitejs/plugin-vue": "^5.1.2",
"@vue-macros/volar": "^0.19.1",
"autoprefixer": "^10.4.20",
"eslint": "^9.8.0",
"eslint-plugin-format": "^0.1.2",
"postcss": "^8.4.41",
"tailwindcss": "^3.4.7",
"typescript": "^5.5.4",
"unplugin-auto-import": "^0.17.8",
"unplugin-vue-components": "^0.27.3",
"unplugin-vue-macros": "^2.11.4",
"unplugin-vue-markdown": "^0.26.2",
"unplugin-vue-router": "^0.8.8",
"uuid": "^9.0.1",
"vite": "^5.3.5",
"vite-plugin-vue-devtools": "^7.3.7",
"vite-plugin-vue-layouts": "^0.11.0",
"vue-i18n": "^9.13.1",
"vue-tsc": "^2.0.29"
}
}

6714
easytier-gui/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -0,0 +1,4 @@
[build]
target = "x86_64-unknown-linux-gnu"
[target]

7
easytier-gui/src-tauri/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target/
# Generated by Tauri
# will have schema files for capabilities auto-completion
/gen/schemas

View File

@@ -0,0 +1,51 @@
[package]
name = "easytier-gui"
version = "1.2.1"
description = "EasyTier GUI"
authors = ["you"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.0.0-rc", features = [] }
[dependencies]
tauri = { version = "2.0.0-rc", features = [
"tray-icon",
"image-png",
"image-ico",
] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
easytier = { path = "../../easytier" }
tokio = { version = "1", features = ["full"] }
anyhow = "1.0"
chrono = { version = "0.4.37", features = ["serde"] }
once_cell = "1.18.0"
dashmap = "6.0"
privilege = "0.3"
gethostname = "0.5"
auto-launch = "0.5.0"
dunce = "1.0.4"
tauri-plugin-shell = "2.0.0-rc"
tauri-plugin-process = "2.0.0-rc"
tauri-plugin-clipboard-manager = "2.0.0-rc"
tauri-plugin-positioner = { version = "2.0.0-rc", features = ["tray-icon"] }
tauri-plugin-vpnservice = { path = "../../tauri-plugin-vpnservice" }
tauri-plugin-os = "2.0.0-rc"
[features]
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
custom-protocol = ["tauri/custom-protocol"]

View File

@@ -0,0 +1,34 @@
fn main() {
if !cfg!(debug_assertions) && cfg!(target_os = "windows") {
let mut windows = tauri_build::WindowsAttributes::new();
windows = windows.app_manifest(
r#"
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
"#,
);
tauri_build::try_build(tauri_build::Attributes::new().windows_attributes(windows))
.expect("failed to run build script");
} else {
tauri_build::build();
}
}

View File

@@ -0,0 +1,49 @@
{
"identifier": "migrated",
"description": "permissions that were migrated from v1",
"local": true,
"windows": [
"main"
],
"permissions": [
"core:path:default",
"core:event:default",
"core:window:default",
"core:window:allow-is-visible",
"core:window:allow-show",
"core:window:allow-hide",
"core:window:allow-set-focus",
"core:app:default",
"core:resources:default",
"core:menu:default",
"core:tray:default",
"shell:allow-open",
"process:allow-exit",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text",
"shell:default",
"process:default",
"clipboard-manager:default",
"core:tray:default",
"core:tray:allow-new",
"core:tray:allow-set-menu",
"core:tray:allow-set-title",
"core:tray:allow-remove-by-id",
"core:tray:allow-get-by-id",
"core:tray:allow-set-icon",
"core:tray:allow-set-icon-as-template",
"core:tray:allow-set-show-menu-on-left-click",
"core:tray:allow-set-tooltip",
"vpnservice:allow-ping",
"vpnservice:allow-prepare-vpn",
"vpnservice:allow-start-vpn",
"vpnservice:allow-stop-vpn",
"vpnservice:allow-register-listener",
"os:default",
"os:allow-os-type",
"os:allow-arch",
"os:allow-hostname",
"os:allow-platform",
"os:allow-locale"
]
}

View File

@@ -0,0 +1,12 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

View File

@@ -0,0 +1,19 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
build
/captures
.externalNativeBuild
.cxx
local.properties
key.properties
/.tauri
/tauri.settings.gradle

View File

@@ -0,0 +1,6 @@
/src/main/java/com/kkrainbow/easytier/generated
/src/main/jniLibs/**/*.so
/src/main/assets/tauri.conf.json
/tauri.build.gradle.kts
/proguard-tauri.pro
/tauri.properties

View File

@@ -0,0 +1,85 @@
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("rust")
}
val tauriProperties = Properties().apply {
val propFile = file("tauri.properties")
if (propFile.exists()) {
propFile.inputStream().use { load(it) }
}
}
android {
compileSdk = 34
namespace = "com.kkrainbow.easytier"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "false"
applicationId = "com.kkrainbow.easytier"
minSdk = 24
targetSdk = 34
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
signingConfigs {
create("release") {
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
}
}
getByName("release") {
isMinifyEnabled = true
proguardFiles(
*fileTree(".") { include("**/*.pro") }
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
.toList().toTypedArray()
)
signingConfig = signingConfigs.getByName("release")
}
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
buildConfig = true
}
}
rust {
rootDirRel = "../../../"
}
dependencies {
implementation("androidx.webkit:webkit:1.6.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.8.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
}
apply(from = "tauri.build.gradle.kts")

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.easytier_gui"
android:usesCleartextTraffic="${usesCleartextTraffic}">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:launchMode="singleTask"
android:label="@string/main_activity_title"
android:name=".MainActivity"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<service
android:name="com.plugin.vpnservice.TauriVpnService"
android:enabled="true"
android:exported="false"
android:label="@string/main_activity_title"
android:permission="android.permission.BIND_VPN_SERVICE"
android:foregroundServiceType="specialUse">
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
</service>
</application>
</manifest>

View File

@@ -0,0 +1,3 @@
package com.kkrainbow.easytier
class MainActivity : TauriActivity()

View File

@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.easytier_gui" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

View File

@@ -0,0 +1,4 @@
<resources>
<string name="app_name">easytier-gui</string>
<string name="main_activity_title">easytier-gui</string>
</resources>

View File

@@ -0,0 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.easytier_gui" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
<cache-path name="my_cache_images" path="." />
</paths>

View File

@@ -0,0 +1,22 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.3.2")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21")
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
tasks.register("clean").configure {
delete("build")
}

View File

@@ -0,0 +1,23 @@
plugins {
`kotlin-dsl`
}
gradlePlugin {
plugins {
create("pluginsForCoolKids") {
id = "rust"
implementationClass = "RustPlugin"
}
}
}
repositories {
google()
mavenCentral()
}
dependencies {
compileOnly(gradleApi())
implementation("com.android.tools.build:gradle:8.3.2")
}

View File

@@ -0,0 +1,52 @@
import java.io.File
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
open class BuildTask : DefaultTask() {
@Input
var rootDirRel: String? = null
@Input
var target: String? = null
@Input
var release: Boolean? = null
@TaskAction
fun assemble() {
val executable = """pnpm""";
try {
runTauriCli(executable)
} catch (e: Exception) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
runTauriCli("$executable.cmd")
} else {
throw e;
}
}
}
fun runTauriCli(executable: String) {
val rootDirRel = rootDirRel ?: throw GradleException("rootDirRel cannot be null")
val target = target ?: throw GradleException("target cannot be null")
val release = release ?: throw GradleException("release cannot be null")
val args = listOf("tauri", "android", "android-studio-script");
project.exec {
workingDir(File(project.projectDir, rootDirRel))
executable(executable)
args(args)
if (project.logger.isEnabled(LogLevel.DEBUG)) {
args("-vv")
} else if (project.logger.isEnabled(LogLevel.INFO)) {
args("-v")
}
if (release) {
args("--release")
}
args(listOf("--target", target))
}.assertNormalExitValue()
}
}

View File

@@ -0,0 +1,85 @@
import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.get
const val TASK_GROUP = "rust"
open class Config {
lateinit var rootDirRel: String
}
open class RustPlugin : Plugin<Project> {
private lateinit var config: Config
override fun apply(project: Project) = with(project) {
config = extensions.create("rust", Config::class.java)
val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64");
val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList
val defaultArchList = listOf("arm64", "arm", "x86", "x86_64");
val archList = (findProperty("archList") as? String)?.split(',') ?: defaultArchList
val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf("aarch64", "armv7", "i686", "x86_64")
extensions.configure<ApplicationExtension> {
@Suppress("UnstableApiUsage")
flavorDimensions.add("abi")
productFlavors {
create("universal") {
dimension = "abi"
ndk {
abiFilters += abiList
}
}
defaultArchList.forEachIndexed { index, arch ->
create(arch) {
dimension = "abi"
ndk {
abiFilters.add(defaultAbiList[index])
}
}
}
}
}
afterEvaluate {
for (profile in listOf("debug", "release")) {
val profileCapitalized = profile.replaceFirstChar { it.uppercase() }
val buildTask = tasks.maybeCreate(
"rustBuildUniversal$profileCapitalized",
DefaultTask::class.java
).apply {
group = TASK_GROUP
description = "Build dynamic library in $profile mode for all targets"
}
tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask)
for (targetPair in targetsList.withIndex()) {
val targetName = targetPair.value
val targetArch = archList[targetPair.index]
val targetArchCapitalized = targetArch.replaceFirstChar { it.uppercase() }
val targetBuildTask = project.tasks.maybeCreate(
"rustBuild$targetArchCapitalized$profileCapitalized",
BuildTask::class.java
).apply {
group = TASK_GROUP
description = "Build dynamic library in $profile mode for $targetArch"
rootDirRel = config.rootDirRel
target = targetName
release = profile == "release"
}
buildTask.dependsOn(targetBuildTask)
tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn(
targetBuildTask
)
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonFinalResIds=false

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Tue May 10 19:22:52 CST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

185
easytier-gui/src-tauri/gen/android/gradlew vendored Executable file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1,4 @@
storePassword=EasyTier
keyPassword=EasyTier
keyAlias=upload
storeFile=upload-keystore.jks

View File

@@ -0,0 +1,3 @@
include ':app'
apply from: 'tauri.settings.gradle'

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More