Compare commits

...

272 Commits

Author SHA1 Message Date
8a72f6eec0 switch to libsodium aegis256 implementation 2020-06-09 21:13:21 +02:00
47d8790409 switch to miegl's mud fork 2020-06-09 21:04:34 +02:00
Adrien Gallouët
dafc7e8106 Rework command set
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-17 21:36:41 +00:00
Adrien Gallouët
3622f928ca Better explain why the connection fails
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-03 09:35:43 +00:00
Adrien Gallouët
18b8229a93 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-03 08:33:21 +00:00
Adrien Gallouët
1e62537ac3 Fix automake & meson
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-02 20:27:07 +00:00
Adrien Gallouët
6091853f46 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-02 20:10:18 +00:00
Adrien Gallouët
392a493c17 Add a command to list all tunnels
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-02 16:23:44 +00:00
Adrien Gallouët
b80f1b6ac1 The path command should only show the conf
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-04-02 13:48:17 +00:00
Adrien Gallouët
c86bbf8bb7 Show libsodium major.minor version
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-31 11:49:07 +00:00
Adrien Gallouët
c113724eb0 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-25 20:47:47 +00:00
Adrien Gallouët
b184ddedaa Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-25 10:33:47 +00:00
Adrien Gallouët
28a978f276 Fix the last fix :)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-25 07:32:34 +00:00
Adrien Gallouët
e0546ec46a Fix build on OpenBSD
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-24 17:41:58 +00:00
Adrien Gallouët
50f002b7f8 Add variable X to cross build a static binary
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-24 09:27:36 +00:00
Adrien Gallouët
42faaf816f Update mud: losslimit per path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-03-07 16:19:06 +00:00
Adrien Gallouët
eee6a22ccd Use strip -x
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-02-29 10:06:50 +00:00
Adrien Gallouët
ee2d7a2e07 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-02-29 09:57:46 +00:00
Adrien Gallouët
e5949b409f Handle cross stripped binary
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-02-29 09:34:58 +00:00
Adrien Gallouët
13703fb15f Allow to setup beat without [back]up
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-02-21 16:40:22 +00:00
Adrien Gallouët
7f30cdc5ee Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-02-05 14:01:13 +00:00
Adrien Gallouët
b2077f5cd4 Use mud_set_conf()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-16 17:48:02 +00:00
Adrien Gallouët
a9408e799d Show beat
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-11 15:04:55 +00:00
Adrien Gallouët
61c7b48e3f Add beat option in path command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-11 09:55:17 +00:00
Adrien Gallouët
4db90b42b6 Use mud based keepalive
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-11 09:12:47 +00:00
Adrien Gallouët
3df542b6d7 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-09 22:25:42 +00:00
Adrien Gallouët
4a0027e640 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-09 17:39:58 +00:00
Adrien Gallouët
296d80782a Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-08 14:38:28 +00:00
Adrien Gallouët
1c38034265 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-07 13:00:51 +00:00
Adrien Gallouët
0b26eb108d Add rate fixed|auto option
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-07 12:46:28 +00:00
Adrien Gallouët
ac167e74f5 Fix keepalive and use a small value for now
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-04 16:17:36 +00:00
Adrien Gallouët
203feba186 Update README.md about backup path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 16:26:21 +00:00
Adrien Gallouët
3b938df408 Happy New Year
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:57:16 +00:00
Adrien Gallouët
0ccb3de68d Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:39:10 +00:00
Adrien Gallouët
020b115171 Add keepalive
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:28:27 +00:00
Adrien Gallouët
53e7a7ba0a Resize and align buf
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:09:06 +00:00
Adrien Gallouët
1ae7775ce1 Cleanup Makefile
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-12-31 20:04:52 +00:00
Adrien Gallouët
c75f5d5620 Do not allow mtu manipulation anymore
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-12-31 19:34:20 +00:00
Adrien Gallouët
5f72198a96 Fix upload-artifact
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-12-10 14:54:49 +00:00
Adrien Gallouët
c01dbe3e4b Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-19 13:38:59 +00:00
Adrien Gallouët
6be944d7cb Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-19 12:00:07 +00:00
Adrien Gallouët
009d482fd1 Be careful with dirname()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-15 10:43:41 +00:00
Adrien Gallouët
b9aaab661f Probe run/tmp directory at runtime
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-14 19:19:23 +00:00
Adrien Gallouët
a4f63ecf40 Add rundir option for make
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-13 14:12:58 +00:00
Adrien Gallouët
0ceedaec10 Update Makefile
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-13 13:54:15 +00:00
Adrien Gallouët
34486c20b1 Update EXTRA_DIST
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-13 13:39:07 +00:00
Adrien Gallouët
b1fca4c1d2 301 to wikis
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-12 11:19:56 +00:00
Adrien Gallouët
5e0900c8ee Add option losslimit in the set command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-23 13:52:40 +00:00
Adrien Gallouët
8bd936929e Show bad behaviors with command show bad
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-15 14:15:21 +00:00
Adrien Gallouët
289d88f3a7 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-15 13:06:36 +00:00
Adrien Gallouët
1673110de1 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-08 08:53:38 +00:00
Adrien Gallouët
1ce919c1e5 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-08 07:31:11 +00:00
Adrien Gallouët
e19fcaa2b0 Show remote loss too
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-07 14:18:50 +00:00
Adrien Gallouët
104fb37075 Update submodules
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-05 15:21:40 +00:00
Adrien Gallouët
6787e90be7 Update .gitignore
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-05 15:17:48 +00:00
Adrien Gallouët
639853b665 Show loss in command path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-05 09:47:04 +00:00
Adrien Gallouët
57ea0d283d Bench with more time to improve accuracy
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-05 09:17:22 +00:00
Adrien Gallouët
0c82c06119 Show correct cipher
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-05 06:05:34 +00:00
Adrien Gallouët
65f636555b Do a simpler boring bench
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-04 17:10:10 +00:00
Adrien Gallouët
c93cef5491 Faster sigma
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-03 15:35:07 +00:00
Adrien Gallouët
1fed2813e5 Fix the unprobable s.v==1 case
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-03 15:10:37 +00:00
Adrien Gallouët
860651d02f Rework bench without using -lm
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-02 16:49:27 +00:00
Adrien Gallouët
fd7ddf7814 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-24 09:57:21 +00:00
Adrien Gallouët
7e7b52f9fd Try to limit pkt drops
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-19 14:00:00 +00:00
Adrien Gallouët
97784c43ac Revert "Try to use submodules"
This reverts commit bccc9945f4.
2019-09-17 17:07:45 +00:00
Adrien Gallouët
4b4c080cc4 Use aegis256
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-17 16:48:42 +00:00
Adrien Gallouët
43e1dfe86f Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-16 15:20:58 +00:00
Adrien Gallouët
ed1cf51af2 Don't use -j alone for portability
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-16 15:20:41 +00:00
Adrien Gallouët
264f26286d Move static build files in .static
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-11 21:08:59 +00:00
Adrien Gallouët
7c17e16fea Block on sendmsg and revert 4a68866
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-09 16:25:35 +00:00
Adrien Gallouët
38d31c0637 Upload artifact
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-04 10:33:01 +00:00
Adrien Gallouët
bccc9945f4 Try to use submodules
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-04 09:59:59 +00:00
Adrien Gallouët
9c9f679497 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-03 16:56:50 +00:00
Adrien Gallouët
9177778d0f Add .github/workflows/ccpp.yml
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-03 16:27:57 +00:00
Adrien Gallouët
6853b59dc3 Add sodium.sh
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-09-03 16:27:57 +00:00
Adrien Gallouët
d451bc75b0 Doll up
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-23 13:17:59 +00:00
Adrien Gallouët
1f82b15373 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-22 13:08:17 +00:00
Adrien Gallouët
56b5a41633 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-21 15:05:48 +00:00
Adrien Gallouët
004380827f A more friendly command path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-21 15:05:48 +00:00
Adrien Gallouët
a7f57de42a Remove useless tests in ctl
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-21 15:05:48 +00:00
Adrien Gallouët
2f3f9e7e86 Update desc of show
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-20 08:53:47 +00:00
Adrien Gallouët
0528adcfe2 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-20 08:19:55 +00:00
Adrien Gallouët
67ea65b1a8 Don't show all tunnels
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-19 22:40:31 +00:00
Adrien Gallouët
ed82531fc0 Always unlink ctl socket
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-19 21:51:28 +00:00
Adrien Gallouët
e077554304 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-19 13:20:55 +00:00
Adrien Gallouët
b9f31b2445 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-19 13:00:33 +00:00
Adrien Gallouët
76036a6535 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-17 15:00:23 +00:00
Adrien Gallouët
cce55fac21 Unlock glorytun path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-17 14:30:23 +00:00
Adrien Gallouët
a72075036a Use argz for libsodium version
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-15 13:36:31 +00:00
Adrien Gallouët
84184c644a Add command version libsodium
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-15 11:09:12 +00:00
Adrien Gallouët
7f238c2599 Bench chacha if aes is not supported and not asked
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-07-15 10:23:41 +00:00
Adrien Gallouët
170b3df0af Improve error messages
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-27 14:18:31 +00:00
Adrien Gallouët
4a68866201 Try to get all packets from mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-27 14:17:39 +00:00
Adrien Gallouët
5e89ebc550 Improve error messages
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-24 13:04:39 +00:00
Adrien Gallouët
7e95f7a8ae Remove duplicate code in ctl_bind()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-24 12:22:54 +00:00
Adrien Gallouët
968cafe21b Fix errno
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-24 12:07:36 +00:00
Adrien Gallouët
d4e5ea7c0a Abort if fd_set_nonblock() fails
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-24 11:36:01 +00:00
Adrien Gallouët
e6793f9b54 Fix last commit
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-21 15:27:42 +00:00
Adrien Gallouët
5976434285 Just enjoy snprintf()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-06-14 18:42:29 +00:00
Adrien Gallouët
db718d5942 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-03 10:00:59 +00:00
Adrien Gallouët
3da880f5c5 Use -fstack-protector-strong
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-03 09:38:53 +00:00
Adrien Gallouët
86fe69d644 Fix conversion in src/bind.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-03 09:33:07 +00:00
Adrien Gallouët
5c29753343 Fix conversion in src/bench.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-03 09:30:54 +00:00
Adrien Gallouët
70bc9cc205 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-03 09:25:42 +00:00
Adrien Gallouët
5c3ec8e264 Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-03 09:10:21 +00:00
Adrien Gallouët
6496adcd91 Cleanup Makefile
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 15:52:28 +00:00
Adrien Gallouët
4ec2079e22 Always use size_t for MTU
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 14:41:33 +00:00
Adrien Gallouët
f4611efbb2 Fix conversion in src/path.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 14:41:33 +00:00
Adrien Gallouët
d703a66988 Compute sun_path from PID
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 14:15:13 +00:00
Adrien Gallouët
568eeee70b Fix conversion in src/common.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 14:15:13 +00:00
Adrien Gallouët
6e6c72746f Fix conversion in src/tun.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 14:15:02 +00:00
Adrien Gallouët
cd2ee2a7af Fix conversion in src/ip.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-02 14:14:47 +00:00
Adrien Gallouët
e338626c46 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-04-01 15:38:07 +00:00
Adrien Gallouët
71aedce8b2 Ask for a non pedantic c11 compiler 2019-04-01 13:16:29 +00:00
Adrien Gallouët
9c8e043053 Add a stupid untracked Makefile 2019-04-01 07:48:55 +00:00
Adrien Gallouët
871f488097 Remove old sync command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-03-09 15:07:18 +00:00
Adrien Gallouët
159104ce9c Don't wake up without paths
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-03-09 14:39:22 +00:00
Adrien Gallouët
0dddca3b61 Update LICENSE --recursive
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-03-05 21:59:37 +00:00
Adrien Gallouët
cbae4f5a30 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-03-05 11:06:43 +00:00
Adrien Gallouët
61db08063c Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-22 09:16:15 +00:00
Adrien Gallouët
dec3151fd2 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-17 20:21:02 +00:00
Adrien Gallouët
a36f1d5354 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-15 22:05:24 +00:00
Adrien Gallouët
ae713a2197 Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-15 22:01:02 +00:00
Adrien Gallouët
6555cd98d5 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-15 19:37:35 +00:00
Adrien Gallouët
bde9e6e59a Remove sync option
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-13 17:05:40 +00:00
Adrien Gallouët
9a8d95399d Fix typo
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-12 18:04:28 +00:00
Adrien Gallouët
324ba6d525 Update README.md and glorytun-setup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-12 11:10:55 +00:00
Adrien Gallouët
b91788080f Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-10 21:17:15 +00:00
Adrien Gallouët
a65cb2ad15 Add option path rate tx/rx
These two options are mandatory since dynamic shapping
is disabled for now.

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-02-09 16:22:11 +00:00
Adrien Gallouët
9131af6e85 2019
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-01-02 15:53:12 +00:00
Adrien Gallouët
5fca6bcab1 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-01-02 15:52:05 +00:00
Adrien Gallouët
067ddd4aa0 Ignore dirty
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-05 09:11:59 +00:00
Adrien Gallouët
3d184721ab Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-05 09:02:17 +00:00
Adrien Gallouët
20d589fa70 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-05 08:56:31 +00:00
Adrien Gallouët
adb825020a Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-05 08:56:19 +00:00
Adrien Gallouët
e14045ffa2 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-02 09:34:05 +00:00
Adrien Gallouët
4d5ae60844 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-01 15:05:52 +00:00
Adrien Gallouët
5b64c697ea Remove option timeout
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-01 14:56:03 +00:00
Adrien Gallouët
b4f796469f Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-12-01 11:48:37 +00:00
Adrien Gallouët
0e052dc2db Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-11-29 22:24:32 +00:00
Adrien Gallouët
8ff9d3d7a1 Force version.sh to check only local .git
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-11-22 14:19:41 +00:00
Adrien Gallouët
6bcc46c757 Update mud and show status in path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-11-08 17:47:00 +00:00
Adrien Gallouët
3898afd524 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-11-05 11:44:02 +00:00
Adrien Gallouët
f20fff0e87 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-21 08:56:14 +00:00
Adrien Gallouët
9e1001fa17 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-21 08:52:42 +00:00
Adrien Gallouët
9957581e60 Don't use crypto_shorthash_keygen()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-02 16:14:44 +00:00
Adrien Gallouët
61176d4f47 Fix BSD
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-01 15:31:14 +00:00
Adrien Gallouët
e8bda24ec0 Fix ip.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-01 07:19:30 +00:00
Adrien Gallouët
5c9cbfc952 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-01 07:04:32 +00:00
Adrien Gallouët
13c905d725 Cleanup ip.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-10-01 06:57:15 +00:00
Adrien Gallouët
56a3a751db Use siphash to select path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-09-29 16:13:01 +00:00
Adrien Gallouët
6719b19681 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-09-24 13:00:09 +00:00
Adrien Gallouët
310513c569 Don't log useless things in the main loop
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-08-17 14:22:34 +00:00
Adrien Gallouët
a0bdb56441 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-08-16 13:01:14 +00:00
Adrien Gallouët
c15343f8f6 Commands show and path now support pipe output
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-06-15 17:57:09 +00:00
Adrien Gallouët
41f66e55bc Use mud_sync()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-06-15 10:06:51 +00:00
Adrien Gallouët
9c7f98a823 Add option sync to command bind
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-06-07 16:57:02 +00:00
Adrien Gallouët
da350aff9c Add option timeout in command sync
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-06-03 18:02:34 +00:00
Adrien Gallouët
c7fed357fb Improve exit codes for scripts
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-06-02 15:43:08 +00:00
Adrien Gallouët
524ae42069 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-06-02 08:26:09 +00:00
Adrien Gallouët
2dbf5fb765 Add the sync command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-21 09:26:37 +00:00
Adrien Gallouët
a3bb488fd5 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-16 22:07:13 +00:00
Adrien Gallouët
022e478fb9 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-16 21:41:39 +00:00
Adrien Gallouët
f3b44e2f45 Option bufsize is no longer useful
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-15 06:48:02 +00:00
Adrien Gallouët
23b7aeb68f Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-15 06:44:55 +00:00
Adrien Gallouët
1e2004c7dd Ask for a keyfile
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-15 06:42:51 +00:00
Adrien Gallouët
e12d136ba3 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-14 13:11:20 +00:00
Adrien Gallouët
ca96be5fe5 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-11 16:55:44 +00:00
Adrien Gallouët
d0a9c69f7c Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-11 16:51:05 +00:00
Adrien Gallouët
3ffce5da1b Add a compatibility note in the README
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 20:24:14 +00:00
Adrien Gallouët
aeb33342a4 Remove useless mtu log
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 19:53:06 +00:00
Adrien Gallouët
ca71508e5c Show pid
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 19:51:18 +00:00
Adrien Gallouët
36be8008d8 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 14:05:34 +00:00
Adrien Gallouët
be17650555 Not using ICMP Next-hop MTU is a feature
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 13:49:42 +00:00
Adrien Gallouët
873efb4f82 Show help when no arguments
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 13:48:20 +00:00
Adrien Gallouët
357d5a0859 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-10 10:22:16 +00:00
Adrien Gallouët
5c532b2e56 Be more verbose
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-09 15:27:57 +00:00
Adrien Gallouët
0cce48e9fd Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-05 19:35:42 +00:00
Adrien Gallouët
ee9ed7e3a6 Use full hash as version if no tags
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-05 13:17:55 +00:00
Adrien Gallouët
841c2afed0 Update mud (new proto)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-05-05 12:57:49 +00:00
Adrien Gallouët
60a5b3e00a Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-26 20:25:49 +00:00
Adrien Gallouët
e243d8371a Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-26 05:40:21 +00:00
Adrien Gallouët
767aff211f Update mud (bw probing)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-25 09:10:37 +00:00
Adrien Gallouët
eb04190c58 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-23 20:54:34 +00:00
Adrien Gallouët
d25957b108 Show latency-smoothed maxrate per path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-21 12:29:02 +00:00
Adrien Gallouët
a5f634ee28 Show rate per path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-18 16:37:20 +00:00
Adrien Gallouët
1736b6e043 Show rttvar per path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-06 16:46:55 +00:00
Adrien Gallouët
8401b7c112 Show number of packets per path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-04-03 09:49:00 +00:00
Adrien Gallouët
7276305906 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-26 13:22:46 +00:00
Adrien Gallouët
6e75f4282d Don't forget BSD..
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-19 09:53:43 +00:00
Adrien Gallouët
7999344c39 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-19 09:38:18 +00:00
Adrien Gallouët
7a9f6fc8b8 Remove old packet aggregation
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-17 13:21:16 +00:00
Adrien Gallouët
dabd16e4b4 Improve output of show/path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-16 21:15:10 +00:00
Adrien Gallouët
1698a08b08 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-15 22:07:48 +00:00
Adrien Gallouët
4646cbb15e Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-15 22:07:12 +00:00
Adrien Gallouët
c2bd415382 Sanitize memory
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-15 22:06:23 +00:00
Adrien Gallouët
245b8e671e Fix ctl_connect()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-15 22:05:42 +00:00
Adrien Gallouët
c06abdbe3c Add set option kxtimeout
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-14 07:57:32 +00:00
Adrien Gallouët
b0a589b792 Use GT_RUNDIR for local sockets
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-14 07:06:25 +00:00
Adrien Gallouët
66cdcf2ee3 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-14 06:55:37 +00:00
Adrien Gallouët
7c50a9d162 Show public ip and port for each path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-10 15:33:18 +00:00
Adrien Gallouët
6538d301d1 Show mtu for each path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-09 23:17:10 +00:00
Adrien Gallouët
63831d6efc Update mud and path_status
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-09 23:16:13 +00:00
Adrien Gallouët
cbb498bb74 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-06 16:04:04 +00:00
Adrien Gallouët
e2706aecdb Set errno when gt_toaddr() fails
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-06 16:03:25 +00:00
Adrien Gallouët
cb8db71e72 Fix argz mtu
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-04 15:28:56 +00:00
Adrien Gallouët
4fab60ea87 Remove old icmp/auto mtu code
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-04 15:16:24 +00:00
Adrien Gallouët
b4ec962a3b Show port in path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-01 13:29:14 +00:00
Adrien Gallouët
235250e49d Add missing select.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-03-01 11:27:16 +00:00
Adrien Gallouët
016045b222 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-28 21:47:55 +00:00
Adrien Gallouët
8403b0606d Move ssutils to common
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-28 21:40:48 +00:00
Adrien Gallouët
c685ecf124 Show status of paths
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-28 19:55:42 +00:00
Adrien Gallouët
f95aaef092 Create socket directly from ctl_connect()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-28 08:18:18 +00:00
Adrien Gallouët
ff5b966866 Add option 'set tc'
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-27 23:12:36 +00:00
Adrien Gallouët
44f75458d1 Add control CTL_PATH_STATUS
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-27 19:06:45 +00:00
Adrien Gallouët
44dd8124b7 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-27 15:47:18 +00:00
Adrien Gallouët
da44a9f55b Autoselect the device when there is only one
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-27 15:44:49 +00:00
Adrien Gallouët
4fa56178cf Fix last commit
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-27 10:01:38 +00:00
Adrien Gallouët
21df85cd94 Ask for a gnu99 compiler
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-27 09:25:44 +00:00
Adrien Gallouët
e21c83602f Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-24 16:03:44 +00:00
Adrien Gallouët
7eecb435b9 Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-24 13:00:51 +00:00
Adrien Gallouët
1db79f77d7 Fix up|down args in path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-24 12:52:52 +00:00
Adrien Gallouët
3bfe9d6cd1 Add option dev for show
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-24 08:10:51 +00:00
Adrien Gallouët
99b51efbb3 Rework controler
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-20 21:28:17 +00:00
Adrien Gallouët
dd3ba523a4 Eradic empty braces
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-20 11:33:09 +00:00
Adrien Gallouët
d34a9a6ce8 Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-19 21:41:24 +00:00
Adrien Gallouët
bf83c83720 Add command set
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-19 21:09:58 +00:00
Adrien Gallouët
dcc460204d ip_get_mtu() should return a size_t too
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-17 12:20:15 +00:00
Adrien Gallouët
651b5c577c Use size_t for mtu
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-16 15:59:51 +00:00
Adrien Gallouët
7ba60a5b61 Update mud and use argz_addr()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-15 19:04:05 +00:00
Adrien Gallouët
40c6e3bc40 Show dev on error
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-14 10:51:21 +00:00
Adrien Gallouët
155fb32d61 Remove old db files
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-13 19:20:34 +00:00
Adrien Gallouët
b6ef00a0b3 Use show as default command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-13 15:33:18 +00:00
Adrien Gallouët
fe96617f78 ENOENT for opendir() is not a fail for gt_show()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-13 15:17:18 +00:00
Adrien Gallouët
3c2423a38b Add command show
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-12 22:58:57 +00:00
Adrien Gallouët
7548ba2c27 Fix ipv6 default value
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-12 09:41:55 +00:00
Adrien Gallouët
22634d14fe Add missing mach_time.h for macos
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-12 09:24:54 +00:00
Adrien Gallouët
e8262257fb Search for -lm
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-12 08:11:20 +00:00
Adrien Gallouët
e856c3c7d0 Fix Makefile.am
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-12 07:59:16 +00:00
Adrien Gallouët
5b929a90b9 Add missing keygen.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-11 19:56:05 +00:00
Adrien Gallouët
29297ff210 Update argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-11 19:50:47 +00:00
Adrien Gallouët
4b41b9baf5 Code format
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-11 19:49:54 +00:00
Adrien Gallouët
04c93b6fe6 Merge glorytunctl with glorytun and use argz
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-02-11 19:43:19 +00:00
Adrien Gallouët
567e5d0193 Add ctl for mud_add_path() and mud_del_path()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-29 16:30:34 +00:00
Adrien Gallouët
0169a09469 Remove old bind options
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-27 16:42:07 +00:00
Adrien Gallouët
3ce6c15a81 Use -- to stop suboptions
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-27 16:31:11 +00:00
Adrien Gallouët
9ea48eaf66 Add mandatory option
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-27 16:31:11 +00:00
Adrien Gallouët
f843b23365 Add some useless checks
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-26 14:42:48 +00:00
Adrien Gallouët
dc9e19961a Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-25 20:11:11 +00:00
Adrien Gallouët
4047abee33 Use strnlen()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-25 16:14:36 +00:00
Adrien Gallouët
36e9a5d57d Use mud_add_path()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-24 16:29:51 +00:00
Adrien Gallouët
0c3c2ca28b Simplify systemd files
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-24 11:03:56 +00:00
Adrien Gallouët
ecdaeaf368 Update mud and set default peer
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-24 10:15:36 +00:00
Adrien Gallouët
6ce92e43ac Do not touch systemd-networkd
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-19 15:05:14 +00:00
Adrien Gallouët
36ba7ddb7b Cleanup mainctl.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-17 16:16:59 +00:00
Adrien Gallouët
975bb1610d Simplify str.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-17 16:11:22 +00:00
Adrien Gallouët
660a6ace2b Fix perror msg
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-17 15:03:34 +00:00
Adrien Gallouët
aeedc361c0 Cleanup ctl.c
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-16 16:45:59 +00:00
Adrien Gallouët
70086d295a Add a simple unix controller
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-16 16:42:25 +00:00
Adrien Gallouët
69bcf664a8 Update Makefile.am
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2018-01-16 10:40:40 +00:00
Adrien Gallouët
6754ec0385 Setup port in glorytun-setup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-12-20 20:38:59 +00:00
Adrien Gallouët
3b787a2043 Move ICMP parsing code in src/ip.h
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-12-17 16:04:30 +00:00
Adrien Gallouët
8f35528fde Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-12-01 19:55:19 +00:00
Adrien Gallouët
f65ecac5fe Skip ip rule errors for now
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-30 16:31:57 +00:00
Adrien Gallouët
086fa412ed Add CAP_NET_RAW by default (needed by mtu-auto)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-30 16:31:26 +00:00
Adrien Gallouët
8476332224 Set mtu-auto by default in glorytun-setup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-30 16:22:11 +00:00
Adrien Gallouët
9dacd85713 Add missing include
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-30 16:17:47 +00:00
Adrien Gallouët
ff83707581 Update autotools and add missing files
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-27 20:59:33 +00:00
Adrien Gallouët
a02839712e Force restart systemd-networkd
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-27 11:52:05 +00:00
Adrien Gallouët
495138ffe4 Try to guess pref in glorytun-run
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-27 11:12:48 +00:00
Adrien Gallouët
e26ecf37a3 Cleanup glorytun-setup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 20:52:36 +00:00
Adrien Gallouët
827876647f Fix typo
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 17:20:35 +00:00
40 changed files with 1918 additions and 1116 deletions

24
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Build
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- name: Build glorytun
run: |
git submodule update --init --recursive
./sodium.sh
make prefix=. install
- uses: actions/upload-artifact@v1
with:
name: ${{ matrix.os }}
path: ./bin

3
.gitignore vendored
View File

@@ -1,4 +1,4 @@
*.o *.[ios]
*.log *.log
*.scan *.scan
*.cache *.cache
@@ -10,6 +10,7 @@ configure
build-aux build-aux
.deps .deps
.dirstamp .dirstamp
.static
glorytun glorytun
build* build*
VERSION VERSION

6
.gitmodules vendored
View File

@@ -1,3 +1,7 @@
[submodule "argz"]
path = argz
url = https://github.com/angt/argz.git
ignore = dirty
[submodule "mud"] [submodule "mud"]
path = mud path = mud
url = https://github.com/angt/mud.git url = https://git.miegl.cz/miegl/mud.git

View File

@@ -1,4 +1,4 @@
Copyright (c) 2015-2016, angt Copyright (c) 2015-2020, Adrien Gallouët <adrien@gallouet.fr>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

40
Makefile Normal file
View File

@@ -0,0 +1,40 @@
NAME := glorytun
VERSION := $(shell ./version.sh)
DIST := $(NAME)-$(VERSION)
CFLAGS ?= -std=c11 -O2 -Wall -fstack-protector-strong
FLAGS := $(CFLAGS) $(LDFLAGS) $(CPPFLAGS)
CC ?= cc
prefix ?= /usr
Q := @
ifneq ($(X),)
H = $(X)-
FLAGS += -static
endif
FLAGS += -DPACKAGE_NAME=\"$(NAME)\" -DPACKAGE_VERSION=\"$(VERSION)\"
FLAGS += -I.static/$(X)/libsodium-stable/src/libsodium/include
FLAGS += -L.static/$(X)/libsodium-stable/src/libsodium/.libs
SRC := argz/argz.c mud/mud.c $(wildcard src/*.c)
HDR := argz/argz.h mud/mud.h $(wildcard src/*.h)
$(NAME): $(SRC) $(HDR)
$(Q)$(H)$(CC) $(FLAGS) -o $(NAME) $(SRC) -lsodium
$(NAME)-strip: $(NAME)
$(Q)cp $< $@
$(Q)$(H)strip -x $@
.PHONY: install
install: $(NAME)-strip
@echo "$(DESTDIR)$(prefix)/bin/$(NAME)"
$(Q)install -m 755 -d $(DESTDIR)$(prefix)/bin
$(Q)install -m 755 $(NAME)-strip $(DESTDIR)$(prefix)/bin/$(NAME)
.PHONY: clean
clean:
$(Q)rm -f "$(NAME)"
$(Q)rm -f "$(DIST).tar.gz"

View File

@@ -5,27 +5,39 @@ bin_PROGRAMS = glorytun
glorytun_CFLAGS = $(libsodium_CFLAGS) glorytun_CFLAGS = $(libsodium_CFLAGS)
glorytun_LDADD = $(libsodium_LIBS) glorytun_LDADD = $(libsodium_LIBS)
glorytun_SOURCES = \ glorytun_SOURCES = \
src/common.h \ argz/argz.c \
argz/argz.h \
mud/mud.c \
mud/mud.h \
src/bench.c \
src/bind.c \
src/common.c \ src/common.c \
src/ip.h \ src/common.h \
src/str.h \ src/ctl.c \
src/main.c \ src/ctl.h \
src/option.c \
src/option.h \
src/tun.c \
src/tun.h \
src/iface.c \ src/iface.c \
src/iface.h \ src/iface.h \
src/db.c \ src/ip.h \
src/db.h src/keygen.c \
src/list.c \
glorytun_SOURCES += \ src/main.c \
mud/mud.h \ src/path.c \
mud/mud.c src/set.c \
src/show.c \
src/str.h \
src/tun.c \
src/tun.h \
src/version.c
EXTRA_DIST = \ EXTRA_DIST = \
LICENSE \ LICENSE \
Makefile \
README.md \ README.md \
VERSION \ VERSION \
autogen.sh \ autogen.sh \
meson.build \
mud/LICENSE \
mud/README.md \
sodium.sh \
systemd \
version.sh version.sh

View File

@@ -1,52 +1,52 @@
# Glorytun # Glorytun
Small, Simple and Stupid VPN over [mud](https://github.com/angt/mud). Glorytun is a small, simple and secure VPN over [mud](https://github.com/angt/mud).
### Build and Install Please visit the [wiki](https://github.com/angt/glorytun/wiki) for how-to guides, tutorials, etc.
Glorytun depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4. ## Compatibility
On Ubuntu, the following command should be sufficient: Glorytun only depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4.
Which can be installed on a wide variety of systems.
$ sudo apt-get install meson libsodium-dev pkg-config Linux is the platform of choice but the code is standard so it should be easily ported on other posix systems.
It was successfully tested on OpenBSD, FreeBSD and MacOS.
Grab the latest release from github: IPv4 and IPv6 are supported.
On Linux you can have both at the same time by binding `::`.
$ git clone https://github.com/angt/glorytun --recursive ## Features
$ cd glorytun
To build and install the latest version with [meson](http://mesonbuild.com): The key features of Glorytun come directly from mud:
$ meson build * **Fast and highly secure**
$ sudo ninja -C build install
The more classical autotools suite is also available. Glorytun uses a new and very fast AEAD construction called AEGIS-256 if AES-NI is available otherwise ChaCha20-Poly1305 is used.
Of course, you can force the use of ChaCha20-Poly1305 for higher security.
All messages are encrypted, authenticated and timestamped to mitigate a large set of attacks.
This implies that the client and the server must be synchronized, an offset of 10min is accepted by default.
Perfect forward secrecy is also implemented with ECDH over Curve25519. Keys are rotated every hours.
### Easy setup with systemd * **Multipath and failover**
Just call `glorytun-setup` and follow the instructions. Connectivity is now crucial, especially in the SD-WAN world.
This feature allows a TCP connection (and all other protocols) to explore and exploit all available links without being disconnected.
Aggregation should work on all conventional links.
Only very high latency (+500ms) links are not recommended for now.
Backup paths are also supported, they will be used only in case of emergency, it is useful when aggregation is not your priority.
Fist, setup the server: * **Traffic shaping**
$ sudo glorytun-setup Shaping is very important in network, it allows to keep a low latency without sacrificing the bandwidth.
Config filename (tun0): It also helps the multipath scheduler to make better decisions.
Server ip (enter for server conf): Currently it must be configured by hand, but soon Glorytun will do it for you.
Server key (enter to generate a new one):
Your new key: NEW_KEY
Start glorytun now ? (enter to skip): y
Copy the new generated key and use it when configuring the client: * **Path MTU discovery without ICMP**
$ sudo glorytun-setup Bad MTU configuration is a very common problem in the world of VPN.
Config filename (tun0): As it is critical, Glorytun will try to setup it correctly by guessing its value.
Server ip (enter for server conf): SERVER_IP It doesn't rely on Next-hop MTU to avoid ICMP black holes.
Server key (enter to generate a new one): NEW_KEY In asymmetric situations the minimum MTU is selected.
Start glorytun now ? (enter to skip): y
You can check easily if it works by looking at your public ip.
To stop the service:
$ sudo systemctl stop glorytun@tun0
--- ---

1
argz Submodule

Submodule argz added at f88a280d2b

View File

@@ -4,11 +4,10 @@ AC_INIT([glorytun],
[https://github.com/angt/glorytun/issues], [https://github.com/angt/glorytun/issues],
[glorytun], [glorytun],
[https://github.com/angt/glorytun]) [https://github.com/angt/glorytun])
AC_DEFINE_UNQUOTED([VERSION_MAJOR], [m4_esyscmd([./version.sh major])])
AC_CONFIG_SRCDIR([src/common.h]) AC_CONFIG_SRCDIR([src/common.h])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.9 -Wall -Werror foreign tar-ustar subdir-objects]) AM_INIT_AUTOMAKE([1.12 -Wall -Werror foreign tar-ustar subdir-objects])
AM_DEP_TRACK AM_DEP_TRACK
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
AM_PROG_CC_C_O AM_PROG_CC_C_O

View File

@@ -1,6 +1,6 @@
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29) # serial 12 (pkg-config-0.29.2)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl dnl
@@ -41,7 +41,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29]) [m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ
@@ -142,7 +142,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no pkg_failed=no
AC_MSG_CHECKING([for $1]) AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -152,11 +152,11 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.]) See the pkg-config man page for more details.])
if test $pkg_failed = yes; then if test $pkg_failed = yes; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED _PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi fi
# Put the nasty error message in config.log where it belongs # Put the nasty error message in config.log where it belongs
@@ -173,7 +173,7 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl _PKG_TEXT])[]dnl
]) ])
elif test $pkg_failed = untried; then elif test $pkg_failed = untried; then
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE( m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it [The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full is in your PATH or set the PKG_CONFIG environment variable to the full

View File

@@ -1,9 +1,14 @@
project('glorytun', 'c', project('glorytun', 'c',
version: run_command('./version.sh').stdout(), version: run_command('./version.sh').stdout(),
license: 'BSD-3-Clause', license: 'BSD-3-Clause',
default_options : [ 'buildtype=debugoptimized' ] default_options : [
'buildtype=debugoptimized',
'c_std=gnu99'
]
) )
cc = meson.get_compiler('c')
prefix = get_option('prefix') prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir')) bindir = join_paths(prefix, get_option('bindir'))
@@ -12,21 +17,30 @@ conf_data.set('prefix', prefix)
conf_data.set('bindir', bindir) conf_data.set('bindir', bindir)
add_global_arguments('-DPACKAGE_VERSION="'+meson.project_version()+'"', language : 'c') add_global_arguments('-DPACKAGE_VERSION="'+meson.project_version()+'"', language : 'c')
add_global_arguments('-DPACKAGE_NAME="'+meson.project_name()+'"', language : 'c')
src = [ executable('glorytun', install: true,
'src/common.c', sources: [
'src/iface.c', 'argz/argz.c',
'src/option.c',
'src/tun.c',
'mud/mud.c', 'mud/mud.c',
'src/main.c' 'src/bench.c',
] 'src/bind.c',
'src/common.c',
deps = [ 'src/ctl.c',
dependency('libsodium', version : '>=1.0.4') 'src/iface.c',
] 'src/keygen.c',
'src/list.c',
executable('glorytun', install: true, sources: src, dependencies: deps) 'src/main.c',
'src/path.c',
'src/set.c',
'src/show.c',
'src/tun.c',
'src/version.c',
],
dependencies: [
dependency('libsodium', version : '>=1.0.4'),
]
)
systemd = dependency('systemd', required: false) systemd = dependency('systemd', required: false)

2
mud

Submodule mud updated: 13cf44c813...e4988b9e9c

29
sodium.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/sh
mkdir -p .static
cd .static || exit 1
file=LATEST.tar.gz
url=https://download.libsodium.org/libsodium/releases
dir="$PWD"
[ -f "$file" ] || wget -q "$url/$file" -O "$file"
[ -f "$file" ] || curl -SsfLO "$url/$file"
[ -f "$file" ] || {
echo "Couldn't download $url/$file"
exit 1
}
if [ "$1" ]; then
mkdir -p "$1"
cd "$1" || exit 1
fi
rm -rf libsodium-stable
tar zxf "$dir/$file"
cd libsodium-stable || exit 1
NPROC=$(sysctl -n hw.ncpu || nproc) 2>/dev/null
./configure ${1+--host=$1} --enable-minimal --disable-dependency-tracking --enable-static --disable-shared
make "-j$((NPROC+1))"

116
src/bench.c Normal file
View File

@@ -0,0 +1,116 @@
#include "common.h"
#include <inttypes.h>
#include <sodium.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "../argz/argz.h"
#define NPUBBYTES 32
#define KEYBYTES 32
#define ABYTES 16
int
gt_bench(int argc, char **argv)
{
struct argz bench_argz[] = {
{"aes|chacha", NULL, NULL, argz_option},
{NULL}};
if (argz(bench_argz, argc, argv))
return 1;
if (sodium_init() == -1) {
gt_log("sodium init failed\n");
return 1;
}
int term = isatty(1);
int aes = argz_is_set(bench_argz, "aes");
int chacha = argz_is_set(bench_argz, "chacha");
if (!crypto_aead_aegis256_is_available()) {
if (aes) {
gt_log("aes is not available on your platform\n");
return 1;
}
chacha = 1;
}
unsigned char buf[1450 + ABYTES];
unsigned char npub[NPUBBYTES];
unsigned char key[KEYBYTES];
memset(buf, 0, sizeof(buf));
randombytes_buf(npub, sizeof(npub));
randombytes_buf(key, sizeof(key));
if (term) {
printf("cipher: %s\n\n", GT_CIPHER(chacha));
printf(" size min mean max \n");
printf("----------------------------------------------------\n");
}
int64_t size = 20;
for (int i = 0; !gt_quit && size <= 1450; i++) {
struct {
int64_t min, mean, max, n;
} mbps = {.n = 0};
int64_t bytes_max = (int64_t)1 << 24;
while (!gt_quit && mbps.n < 10) {
int64_t bytes = 0;
int64_t base = (int64_t)clock();
while (!gt_quit && bytes <= bytes_max) {
if (chacha) {
crypto_aead_chacha20poly1305_encrypt(
buf, NULL, buf, size, NULL, 0, NULL, npub, key);
} else {
crypto_aead_aegis256_encrypt(buf, NULL, buf, size, NULL, 0, NULL, npub, key);
}
bytes += size;
}
int64_t dt = (int64_t)clock() - base;
bytes_max = (bytes * (CLOCKS_PER_SEC / 3)) / dt;
int64_t _mbps = (8 * bytes * CLOCKS_PER_SEC) / (dt * 1000 * 1000);
if (!mbps.n++) {
mbps.min = _mbps;
mbps.max = _mbps;
mbps.mean = _mbps;
continue;
}
if (mbps.min > _mbps)
mbps.min = _mbps;
if (mbps.max < _mbps)
mbps.max = _mbps;
mbps.mean += (_mbps - mbps.mean) / mbps.n;
if (term) {
printf("\r %5"PRIi64" %9"PRIi64" Mbps %9"PRIi64" Mbps %9"PRIi64" Mbps",
size, mbps.min, mbps.mean, mbps.max);
fflush(stdout);
}
}
if (term) {
printf("\n");
} else {
printf("bench %s %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64"\n",
GT_CIPHER(chacha), size, mbps.min, mbps.mean, mbps.max);
}
size += 2 * 5 * 13;
}
return 0;
}

365
src/bind.c Normal file
View File

@@ -0,0 +1,365 @@
#include "common.h"
#include "ctl.h"
#include "iface.h"
#include "ip.h"
#include "tun.h"
#include <fcntl.h>
#include <sys/select.h>
#include "../argz/argz.h"
#include "../mud/mud.h"
#include <sodium.h>
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
static int
fd_set_nonblock(int fd)
{
if (fd == -1)
return 0;
int ret;
do {
ret = fcntl(fd, F_GETFL, 0);
} while (ret == -1 && errno == EINTR);
int flags = (ret == -1) ? 0 : ret;
do {
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
} while (ret == -1 && errno == EINTR);
return ret;
}
static int
gt_setup_secretkey(struct mud *mud, const char *keyfile)
{
int fd;
do {
fd = open(keyfile, O_RDONLY | O_CLOEXEC);
} while (fd == -1 && errno == EINTR);
if (fd == -1) {
gt_log("couldn't open %s: %s\n", keyfile, strerror(errno));
return -1;
}
unsigned char key[32];
char buf[2 * sizeof(key)];
size_t size = 0;
while (size < sizeof(buf)) {
ssize_t r = read(fd, &buf[size], sizeof(buf) - size);
if (r <= (ssize_t)0) {
if (r && (errno == EAGAIN || errno == EINTR))
continue;
break;
}
size += (size_t)r;
}
close(fd);
if (size != sizeof(buf)) {
gt_log("couldn't read secret key\n");
return -1;
}
if (gt_fromhex(key, sizeof(key), buf, sizeof(buf))) {
gt_log("secret key is not valid\n");
return -1;
}
mud_set_key(mud, key, sizeof(key));
return 0;
}
static size_t
gt_setup_mtu(struct mud *mud, size_t old, const char *tun_name)
{
size_t mtu = mud_get_mtu(mud);
if (!mtu || mtu == old)
return mtu;
if (iface_set_mtu(tun_name, mtu) == -1)
gt_log("couldn't setup MTU at %zu on device %s\n", mtu, tun_name);
return mtu;
}
int
gt_bind(int argc, char **argv)
{
struct sockaddr_storage bind_addr = {.ss_family = AF_INET};
struct sockaddr_storage peer_addr = {0};
unsigned short bind_port = 5000;
unsigned short peer_port = bind_port;
const char *dev = NULL;
const char *keyfile = NULL;
struct argz toz[] = {
{NULL, "IPADDR", &peer_addr, argz_addr},
{NULL, "PORT", &peer_port, argz_ushort},
{NULL}};
struct argz bindz[] = {
{NULL, "IPADDR", &bind_addr, argz_addr},
{NULL, "PORT", &bind_port, argz_ushort},
{"to", NULL, &toz, argz_option},
{"dev", "NAME", &dev, argz_str},
{"keyfile", "FILE", &keyfile, argz_str},
{"chacha", NULL, NULL, argz_option},
{"persist", NULL, NULL, argz_option},
{NULL}};
if (argz(bindz, argc, argv))
return 1;
if (EMPTY(keyfile)) {
gt_log("a keyfile is needed!\n");
return 1;
}
gt_set_port((struct sockaddr *)&bind_addr, bind_port);
gt_set_port((struct sockaddr *)&peer_addr, peer_port);
int chacha = argz_is_set(bindz, "chacha");
int persist = argz_is_set(bindz, "persist");
if (sodium_init() == -1) {
gt_log("couldn't init sodium\n");
return 1;
}
unsigned char hashkey[crypto_shorthash_KEYBYTES];
randombytes_buf(hashkey, sizeof(hashkey));
struct mud *mud = mud_create((struct sockaddr *)&bind_addr);
const int mud_fd = mud_get_fd(mud);
if (mud_fd == -1) {
gt_log("couldn't create mud\n");
return 1;
}
if (gt_setup_secretkey(mud, keyfile))
return 1;
if (!chacha && mud_set_aes(mud)) {
gt_log("AES is not available, enjoy ChaCha20!\n");
chacha = 1;
}
char tun_name[64];
const int tun_fd = tun_create(tun_name, sizeof(tun_name), dev);
if (tun_fd == -1) {
gt_log("couldn't create tun device\n");
return 1;
}
size_t mtu = gt_setup_mtu(mud, 0, tun_name);
if (tun_set_persist(tun_fd, persist) == -1) {
gt_log("couldn't %sable persist mode on device %s\n",
persist ? "en" : "dis", tun_name);
}
if (peer_addr.ss_family) {
if (mud_peer(mud, (struct sockaddr *)&peer_addr)) {
perror("mud_peer");
return 1;
}
}
const int ctl_fd = ctl_create(tun_name);
if (ctl_fd == -1) {
char dir[64];
if (ctl_rundir(dir, sizeof(dir))) {
gt_log("couldn't create %s/%s: %s\n",
dir, tun_name, strerror(errno));
} else {
gt_log("couldn't find a writable run/tmp directory\n");
}
return 1;
}
if (//fd_set_nonblock(tun_fd) ||
//fd_set_nonblock(mud_fd) ||
fd_set_nonblock(ctl_fd)) {
gt_log("couldn't setup non-blocking fds\n");
return 1;
}
const long pid = (long)getpid();
gt_log("running on device %s as pid %li\n", tun_name, pid);
fd_set rfds, wfds;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
int tun_can_read = 0;
int tun_can_write = 0;
int mud_can_read = 0;
int mud_can_write = 0;
int last_fd = MAX(tun_fd, mud_fd);
last_fd = 1 + MAX(last_fd, ctl_fd);
__attribute__((aligned(16)))
unsigned char buf[1500];
while (!gt_quit) {
if (tun_can_write) FD_CLR(tun_fd, &wfds); else FD_SET(tun_fd, &wfds);
if (mud_can_write) FD_CLR(mud_fd, &wfds); else FD_SET(mud_fd, &wfds);
if (tun_can_read) FD_CLR(tun_fd, &rfds); else FD_SET(tun_fd, &rfds);
if (mud_can_read) FD_CLR(mud_fd, &rfds); else FD_SET(mud_fd, &rfds);
FD_SET(ctl_fd, &rfds);
struct timeval tv = {0};
int update = mud_update(mud);
if (update >= 0) {
if (mud_can_read && tun_can_write) {
} else if (tun_can_read && mud_can_write) {
if (update)
tv.tv_usec = 1000;
} else {
tv.tv_usec = 100000;
}
}
const int ret = select(last_fd, &rfds, &wfds, NULL, update < 0 ? NULL : &tv);
if (ret == -1) {
if (errno == EBADF) {
perror("select");
break;
}
continue;
}
if (FD_ISSET(tun_fd, &rfds)) tun_can_read = 1;
if (FD_ISSET(tun_fd, &wfds)) tun_can_write = 1;
if (FD_ISSET(mud_fd, &rfds)) mud_can_read = 1;
if (FD_ISSET(mud_fd, &wfds)) mud_can_write = 1;
mtu = gt_setup_mtu(mud, mtu, tun_name);
if (tun_can_read && mud_can_write && !mud_send_wait(mud)) {
struct ip_common ic;
int r = tun_read(tun_fd, buf, sizeof(buf));
if (r > 0 && !ip_get_common(&ic, buf, r)) {
mud_send(mud, buf, (size_t)r);
mud_can_write = 0;
}
tun_can_read = 0;
}
if (mud_can_read && tun_can_write) {
int r = mud_recv(mud, buf, sizeof(buf));
if (r > 0 && ip_is_valid(buf, r)) {
tun_write(tun_fd, buf, (size_t)r);
tun_can_write = 0;
}
mud_can_read = 0;
}
if (FD_ISSET(ctl_fd, &rfds)) {
struct ctl_msg req, res = {.reply = 1};
struct sockaddr_storage ss;
socklen_t sl = sizeof(ss);
ssize_t r = recvfrom(ctl_fd, &req, sizeof(req), 0,
(struct sockaddr *)&ss, &sl);
if (r == (ssize_t)sizeof(req)) {
res.type = req.type;
switch (req.type) {
case CTL_NONE:
break;
case CTL_STATE:
if (mud_set_state(mud, (struct sockaddr *)&req.path.addr,
req.path.state,
req.path.rate_tx,
req.path.rate_rx,
req.path.beat,
req.path.fixed_rate,
req.path.loss_limit))
res.ret = errno;
break;
case CTL_CONF:
if (mud_set_conf(mud, &req.conf))
res.ret = errno;
res.conf = req.conf;
break;
case CTL_STATUS:
memcpy(res.status.tun_name, tun_name, sizeof(tun_name)); // XXX
res.status.pid = pid;
res.status.mtu = mtu;
res.status.chacha = chacha;
res.status.bind = bind_addr;
res.status.peer = peer_addr;
break;
case CTL_PATH_STATUS: {
unsigned count = 0;
struct mud_path *paths = mud_get_paths(mud, &count);
if (!paths) {
res.ret = errno;
break;
}
res.ret = EAGAIN;
for (unsigned i = 0; i < count; i++) {
memcpy(&res.path_status, &paths[i], sizeof(struct mud_path));
if (sendto(ctl_fd, &res, sizeof(res), 0,
(const struct sockaddr *)&ss, sl) == -1)
perror("sendto(ctl)");
}
free(paths);
res.ret = 0;
} break;
case CTL_BAD:
if (mud_get_bad(mud, &res.bad))
res.ret = errno;
break;
}
if (sendto(ctl_fd, &res, sizeof(res), 0,
(const struct sockaddr *)&ss, sl) == -1)
perror("sendto(ctl)");
} else if (r == -1 && errno != EAGAIN) {
perror("recvfrom(ctl)");
}
}
}
if (gt_reload && tun_fd >= 0)
tun_set_persist(tun_fd, 1);
mud_delete(mud);
ctl_delete(ctl_fd);
return 0;
}

View File

@@ -3,20 +3,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
int
gt_print(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
int ret = vfprintf(stdout, fmt, ap);
va_end(ap);
if (ret < 0)
return 0;
return ret;
}
void void
gt_log(const char *fmt, ...) gt_log(const char *fmt, ...)
{ {
@@ -78,7 +64,128 @@ gt_fromhex(uint8_t *dst, size_t dst_size, const char *src, size_t src_size)
if (_0_(a == -1 || b == -1)) if (_0_(a == -1 || b == -1))
return -1; return -1;
*dst++ = (a << 4) | b; *dst++ = (uint8_t)((a << 4) | b);
}
return 0;
}
void
gt_set_port(struct sockaddr *sa, uint16_t port)
{
switch (sa->sa_family) {
case AF_INET:
((struct sockaddr_in *)sa)->sin_port = htons(port);
break;
case AF_INET6:
((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
break;
}
}
uint16_t
gt_get_port(struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET:
return ntohs(((struct sockaddr_in *)sa)->sin_port);
case AF_INET6:
return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
}
return 0;
}
int
gt_toaddr(char *str, size_t size, struct sockaddr *sa)
{
if (str)
str[0] = 0;
switch (sa->sa_family) {
case AF_INET:
return -!inet_ntop(AF_INET,
&((struct sockaddr_in *)sa)->sin_addr, str, (socklen_t)size);
case AF_INET6:
return -!inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)sa)->sin6_addr, str, (socklen_t)size);
}
errno = EAFNOSUPPORT;
return -1;
}
int
gt_totime(char *str, size_t size, unsigned long long t)
{
if (!str || size < 4) {
errno = EINVAL;
return -1;
}
if (!t) {
memcpy(str, "now", 4);
return 0;
}
struct {
unsigned long long v;
unsigned long long n;
char *name;
} u[] = {
{0, 1000, "ms"},
{0, 60, "s"},
{0, 60, "m"},
{0, 24, "h"},
{0, 0, "d"},
};
size_t len = 0;
unsigned i = 0;
while (u[i].n) {
u[i].v = t % u[i].n;
t /= u[i].n;
i++;
}
u[i++].v = t;
while (i--)
if (u[i].v) {
int ret = snprintf(str + len, size - len, "%llu%s", u[i].v, u[i].name);
if (ret <= 0 || (size_t)ret >= size - len) {
errno = EINVAL;
return -1;
}
len += ret;
}
return 0;
}
int
gt_torate(char *str, size_t size, unsigned long long r)
{
if (!str || size < 5) {
errno = EINVAL;
return -1;
}
unsigned k = 0;
while (r && k < 4 && !(r % 1000)) {
r /= 1000;
k++;
}
int ret = snprintf(str, size, "%llu%sbit%s", r,
&"\0\0k\0M\0G\0T"[k << 1],
&"s"[r <= 1]);
if (ret <= 0 || (size_t)ret >= size) {
errno = EINVAL;
return -1;
} }
return 0; return 0;

View File

@@ -1,42 +1,74 @@
#pragma once #pragma once
#include <stdlib.h> #if defined __linux__ && !defined _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <errno.h>
#include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#define COUNT(x) (sizeof(x)/sizeof(x[0])) #include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define ALIGN_SIZE (1<<4) #ifndef PACKAGE_NAME
#define ALIGN_MASK (ALIGN_SIZE-1) #define PACKAGE_NAME "glorytun"
#endif
#define ALIGN(x) (((x)+ALIGN_MASK)&~ALIGN_MASK) #ifndef PACKAGE_VERSION
#define ALIGN_DOWN(x) ((x)&~ALIGN_MASK) #define PACKAGE_VERSION "0.0.0"
#endif
#define PALIGN(x) ((void *)ALIGN((size_t)(x))) #define COUNT(x) (sizeof(x) / sizeof(x[0]))
#define PALIGN_DOWN(x) ((void *)ALIGN_DOWN((size_t)(x)))
#define _1_(x) (__builtin_expect((x), 1)) #define _1_(x) (__builtin_expect((x), 1))
#define _0_(x) (__builtin_expect((x), 0)) #define _0_(x) (__builtin_expect((x), 0))
#define CLZ(x) (__builtin_clz(x))
#define CLZ(x) (__builtin_clz(x)) #define _printf_(A, B) __attribute__((format(printf, A, B)))
#define _noreturn_ __attribute__((noreturn))
#define _printf_(A,B) __attribute__ ((format(printf,A,B))) #define _unused_ __attribute__((unused))
#define _noreturn_ __attribute__ ((noreturn)) #define _pure_ __attribute__((pure))
#define _unused_ __attribute__ ((unused)) #define _const_ __attribute__((const))
#define _pure_ __attribute__ ((pure)) #define _align_(...) __attribute__((aligned(__VA_ARGS__)))
#define _const_ __attribute__ ((const))
#define _align_(...) __attribute__ ((aligned(__VA_ARGS__)))
#undef MAX #undef MAX
#define MAX(x,y) ({ __typeof__(x) X=(x); __typeof__(y) Y=(y); X > Y ? X : Y; }) #define MAX(x, y) ({ __typeof__(x) X=(x); __typeof__(y) Y=(y); X > Y ? X : Y; })
#undef MIN #undef MIN
#define MIN(x,y) ({ __typeof__(x) X=(x); __typeof__(y) Y=(y); X < Y ? X : Y; }) #define MIN(x, y) ({ __typeof__(x) X=(x); __typeof__(y) Y=(y); X < Y ? X : Y; })
int gt_print (const char *, ...) _printf_(1,2); #define EMPTY(x) ({ __typeof__(x) X=(x); !X || !X[0]; })
void gt_log (const char *, ...) _printf_(1,2);
#define GT_CIPHER(x) ((x) ? "chacha20poly1305" : "aegis256")
extern volatile sig_atomic_t gt_alarm;
extern volatile sig_atomic_t gt_reload;
extern volatile sig_atomic_t gt_quit;
int gt_print (const char *, ...) _printf_(1, 2);
void gt_log (const char *, ...) _printf_(1, 2);
int gt_tohex (char *, size_t, const uint8_t *, size_t); int gt_tohex (char *, size_t, const uint8_t *, size_t);
int gt_fromhex (uint8_t *, size_t, const char *, size_t); int gt_fromhex (uint8_t *, size_t, const char *, size_t);
void gt_set_port (struct sockaddr *, uint16_t);
uint16_t gt_get_port (struct sockaddr *);
int gt_toaddr (char *, size_t, struct sockaddr *);
int gt_totime (char *, size_t, unsigned long long);
int gt_torate (char *, size_t, unsigned long long);
int gt_list (int, char **);
int gt_show (int, char **);
int gt_bind (int, char **);
int gt_path (int, char **);
int gt_keygen (int, char **);
int gt_bench (int, char **);
int gt_set (int, char **);
int gt_version (int, char **);

219
src/ctl.c Normal file
View File

@@ -0,0 +1,219 @@
#include "ctl.h"
#include "common.h"
#include <dirent.h>
#include <libgen.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/un.h>
char *
ctl_rundir(char *dst, size_t size)
{
if (dst && size)
dst[0] = 0;
const char *fmt[] = {
"/run/user/%u/" PACKAGE_NAME,
"/run/" PACKAGE_NAME ".%u",
"/var/run/" PACKAGE_NAME ".%u",
"/tmp/" PACKAGE_NAME ".%u",
};
for (unsigned i = 0; i < COUNT(fmt); i++) {
char path[128];
int ret = snprintf(dst, size, fmt[i], geteuid());
if ((ret <= 0) ||
((size_t)ret >= size) ||
((size_t)ret >= sizeof(path)))
continue;
memcpy(path, dst, (size_t)ret + 1);
char *p = dirname(path);
if (p && !access(p, W_OK))
return dst;
}
errno = EPERM;
return NULL;
}
int
ctl_reply(int fd, struct ctl_msg *res, struct ctl_msg *req)
{
if ((send(fd, req, sizeof(struct ctl_msg), 0) == -1) ||
(recv(fd, res, sizeof(struct ctl_msg), 0) == -1))
return -1;
if (res->type != req->type || !res->reply) {
errno = EBADMSG;
return -1;
}
if (res->ret) {
errno = res->ret;
return -1;
}
return 0;
}
static int
ctl_setsun(struct sockaddr_un *dst, const char *dir, const char *file)
{
struct sockaddr_un sun = {
.sun_family = AF_UNIX,
};
int ret = snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dir, file);
if (ret <= 0 || (size_t)ret >= sizeof(sun.sun_path)) {
errno = EINVAL;
return -1;
}
if (dst)
*dst = sun;
return 0;
}
static int
ctl_bind(int fd, const char *dir, const char *file)
{
char name[10] = {[0] = '.'};
struct sockaddr_un sun;
if (EMPTY(file)) {
unsigned pid = (unsigned)getpid();
for (size_t i = 1; i < sizeof(name) - 1; i++, pid >>= 4)
name[i] = "uncopyrightables"[pid & 15];
file = name;
}
if (ctl_setsun(&sun, dir, file))
return -1;
if (unlink(sun.sun_path) && errno != ENOENT)
return -1;
return bind(fd, (struct sockaddr *)&sun, sizeof(sun));
}
void
ctl_delete(int fd)
{
struct sockaddr_storage ss = {0};
socklen_t sslen = sizeof(ss);
if ((getsockname(fd, (struct sockaddr *)&ss, &sslen) == 0) &&
(ss.ss_family == AF_UNIX))
unlink(((struct sockaddr_un *)&ss)->sun_path);
close(fd);
}
int
ctl_create(const char *file)
{
char dir[64];
if (!ctl_rundir(dir, sizeof(dir)))
return -1;
if (mkdir(dir, 0700) == -1 && errno != EEXIST)
return -1;
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (ctl_bind(fd, dir, file)) {
int err = errno;
close(fd);
errno = err;
return -1;
}
return fd;
}
int
ctl_connect(const char *file)
{
char dir[64];
DIR *dp = NULL;
if (!ctl_rundir(dir, sizeof(dir)))
return -1;
if (!file) {
if (dp = opendir(dir), !dp)
return CTL_ERROR_NONE;
struct dirent *d = NULL;
while (d = readdir(dp), d) {
if (d->d_name[0] == '.')
continue;
if (file) {
closedir(dp);
return CTL_ERROR_MANY;
}
file = &d->d_name[0];
}
if (!file) {
closedir(dp);
return CTL_ERROR_NONE;
}
}
struct sockaddr_un sun;
const int ret = ctl_setsun(&sun, dir, file);
if (dp) {
int err = errno;
closedir(dp);
errno = err;
}
if (ret)
return -1;
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (ctl_bind(fd, dir, NULL) ||
connect(fd, (struct sockaddr *)&sun, sizeof(sun))) {
int err = errno;
ctl_delete(fd);
errno = err;
return -1;
}
return fd;
}
void
ctl_explain_connect(int ret)
{
switch (ret) {
case 0:
break;
case CTL_ERROR_MANY:
gt_log("please select a tunnel\n");
break;
case CTL_ERROR_NONE:
gt_log("no active tunnel\n");
break;
default:
gt_log("unknown error\n"); /* FALLTHRU */
case -1:
if (errno)
perror("connect");
}
}

52
src/ctl.h Normal file
View File

@@ -0,0 +1,52 @@
#pragma once
#include "../mud/mud.h"
#include <sys/socket.h>
#define CTL_ERROR_NONE (-2)
#define CTL_ERROR_MANY (-3)
enum ctl_type {
CTL_NONE = 0,
CTL_STATE,
CTL_CONF,
CTL_STATUS,
CTL_PATH_STATUS,
CTL_BAD,
};
struct ctl_msg {
enum ctl_type type;
int reply, ret;
union {
struct {
struct sockaddr_storage addr;
enum mud_state state;
unsigned long rate_tx;
unsigned long rate_rx;
unsigned long beat;
unsigned char fixed_rate;
unsigned char loss_limit;
} path;
struct {
char tun_name[64];
long pid;
size_t mtu;
int chacha;
struct sockaddr_storage bind;
struct sockaddr_storage peer;
} status;
struct mud_conf conf;
struct mud_path path_status;
struct mud_bad bad;
};
};
char *ctl_rundir (char *, size_t);
int ctl_create (const char *);
int ctl_connect (const char *);
int ctl_reply (int, struct ctl_msg *, struct ctl_msg *);
void ctl_delete (int);
void ctl_explain_connect (int);

158
src/db.c
View File

@@ -1,158 +0,0 @@
#include "common.h"
#include "db.h"
#include "str.h"
#define CBIT(X) (1 & (intptr_t)(X))
#define CBIT_PTR(X) (uint8_t *)(1 | (intptr_t)(X))
#define CBIT_NODE(X) (struct node *)(1 ^ (intptr_t)(X))
struct node {
uint8_t *child[2];
uint32_t point;
};
_pure_ static inline size_t
db_size(const uint8_t *a)
{
return (a[0] ?: str_len((char *)a + 1)) + 1;
}
_pure_ static inline size_t
db_cmp(const uint8_t *a, const uint8_t *b)
{
const size_t size = a[0];
if (size != b[0])
return 1;
if (!size) {
size_t i = str_cmp((char *)a + 1, (char *)b + 1);
return i ? i + 1 : 0;
}
for (size_t i = 1; i <= size; i++) {
if (a[i] != b[i])
return i + 1;
}
return 0;
}
_pure_ static inline int
db_dir(const uint32_t point, uint8_t *data, const size_t size)
{
const size_t pos = point >> 8;
if (pos >= size)
return 0;
return ((point | data[pos]) & 255) == 255;
}
uint8_t *
db_search(uint8_t **p, uint8_t *data)
{
if (_0_(!*p))
return NULL;
uint8_t *r = *p;
const size_t size = db_size(data);
while (CBIT(r)) {
struct node *node = CBIT_NODE(r);
r = node->child[db_dir(node->point, data, size)];
}
if (!db_cmp(r, data))
return r;
return NULL;
}
uint8_t *
db_insert(uint8_t **p, uint8_t *data)
{
if (_0_(CBIT(data)))
return NULL;
if (_0_(!*p)) {
*p = data;
return data;
}
uint8_t *r = *p;
size_t size = db_size(data);
while (CBIT(r)) {
struct node *node = CBIT_NODE(r);
r = node->child[db_dir(node->point, data, size)];
}
const size_t diff = db_cmp(r, data);
if (_0_(!diff))
return r;
const size_t pos = diff - 1;
const uint8_t mask = ~((1u << 31) >> CLZ(r[pos] ^ data[pos]));
const size_t point = (pos << 8) | mask;
while (CBIT(*p)) {
struct node *node = CBIT_NODE(*p);
if (node->point > point)
break;
p = node->child + db_dir(node->point, data, size);
}
struct node *node = malloc(sizeof(struct node));
if (_0_(!node))
return NULL;
const int dir = (mask | r[pos]) == 255;
node->child[dir] = *p;
node->child[1 - dir] = data;
node->point = point;
*p = CBIT_PTR(node);
return data;
}
uint8_t *
db_remove(uint8_t **p, uint8_t *data)
{
if (_0_(!*p))
return NULL;
const size_t size = db_size(data);
uint8_t **p_old = NULL;
struct node *node = NULL;
int dir = 0;
while (CBIT(*p)) {
p_old = p;
node = CBIT_NODE(*p);
dir = db_dir(node->point, data, size);
p = node->child + dir;
}
if (_0_(db_cmp(data, *p)))
return NULL;
uint8_t *r = *p;
if (p_old) {
*p_old = node->child[1 - dir];
free(node);
} else {
*p = NULL;
}
return r;
}

View File

@@ -1,7 +0,0 @@
#pragma once
#include <stdint.h>
uint8_t *db_search (uint8_t **, uint8_t *);
uint8_t *db_insert (uint8_t **, uint8_t *);
uint8_t *db_remove (uint8_t **, uint8_t *);

View File

@@ -1,25 +1,35 @@
#include "iface.h"
#include "common.h" #include "common.h"
#include "str.h"
#include <sys/ioctl.h>
#include <net/if.h> #include <net/if.h>
#include <stdio.h>
#include <sys/ioctl.h>
int int
iface_set_mtu(char *dev_name, int mtu) iface_set_mtu(const char *dev_name, size_t mtu)
{ {
if (mtu > (size_t)0xFFFF) {
errno = EINVAL;
return -1;
}
struct ifreq ifr = { struct ifreq ifr = {
.ifr_mtu = mtu, .ifr_mtu = (int)mtu,
}; };
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1); int ret = snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", dev_name);
if (ret <= 0 || (size_t)ret >= sizeof(ifr.ifr_name)) {
errno = EINVAL;
return -1;
}
int fd = socket(AF_INET, SOCK_DGRAM, 0); int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) if (fd == -1)
return -1; return -1;
int ret = ioctl(fd, SIOCSIFMTU, &ifr); ret = ioctl(fd, SIOCSIFMTU, &ifr);
int err = errno; int err = errno;
close(fd); close(fd);

View File

@@ -1,3 +1,5 @@
#pragma once #pragma once
int iface_set_mtu (char *, int); #include <stddef.h>
int iface_set_mtu (const char *, size_t);

View File

@@ -3,15 +3,29 @@
#include <stdint.h> #include <stdint.h>
struct ip_common { struct ip_common {
uint8_t version;
uint8_t tc; uint8_t tc;
uint8_t proto; uint8_t proto;
uint8_t hdr_size; struct { // data are not reordered
uint16_t size; union {
unsigned char v6[16];
struct {
unsigned char zero[10];
unsigned char ff[2];
unsigned char v4[4];
};
};
unsigned char port[2];
} src, dst;
}; };
_pure_ static inline uint8_t static inline int
ip_get_version(const uint8_t *data, size_t size) ip_read16(const uint8_t *src)
{
return ((int)src[1]) | (((int)src[0]) << 8);
}
static inline uint8_t
ip_get_version(const uint8_t *data, int size)
{ {
if (size < 20) if (size < 20)
return 0; return 0;
@@ -20,26 +34,64 @@ ip_get_version(const uint8_t *data, size_t size)
} }
static inline int static inline int
ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size) ip_is_valid(const uint8_t *data, int size)
{ {
ic->version = ip_get_version(data, size); switch (ip_get_version(data, size)) {
case 4: return size == ip_read16(&data[2]);
case 6: return size == ip_read16(&data[4]) + 40;
}
switch (ic->version) { return 0;
}
static inline int
ip_get_common(struct ip_common *ic, const uint8_t *data, int size)
{
switch (ip_get_version(data, size)) {
case 4: case 4:
ic->tc = data[1]; ic->tc = data[1];
ic->proto = data[9]; ic->proto = data[9];
ic->hdr_size = (data[0] & 0xF) << 2; if (size == ip_read16(&data[2])) {
ic->size = ((data[2] << 8) | data[3]); const int hdrsize = (data[0] & 0xF) << 2;
if (ic->size >= 20) memset(ic->src.zero, 0, sizeof(ic->src.zero));
memset(ic->src.ff, 0xff, sizeof(ic->src.ff));
memcpy(ic->src.v4, &data[12], sizeof(ic->src.v4));
memset(ic->dst.zero, 0, sizeof(ic->dst.zero));
memset(ic->dst.ff, 0xff, sizeof(ic->dst.ff));
memcpy(ic->dst.v4, &data[16], sizeof(ic->dst.v4));
switch (ic->proto) {
case 6: // tcp
case 17: // udp
memcpy(ic->src.port, &data[hdrsize], sizeof(ic->src.port));
memcpy(ic->dst.port, &data[hdrsize + 2], sizeof(ic->dst.port));
break;
default:
memset(ic->src.port, 0, sizeof(ic->src.port));
memset(ic->dst.port, 0, sizeof(ic->dst.port));
}
return 0; return 0;
}
break; break;
case 6: case 6:
ic->tc = ((data[0] & 0xF) << 4) | (data[1] >> 4); ic->tc = (uint8_t)((data[0] << 4) | (data[1] >> 4));
ic->proto = data[6]; ic->proto = data[6];
ic->hdr_size = 40; if (size == ip_read16(&data[4]) + 40) {
ic->size = ((data[4] << 8) | data[5]) + 40; memcpy(ic->src.v6, &data[8], sizeof(ic->src.v6));
return 0; memcpy(ic->dst.v6, &data[24], sizeof(ic->dst.v6));
switch (ic->proto) {
case 6: // tcp
case 17: // udp
memcpy(ic->src.port, &data[40], sizeof(ic->src.port));
memcpy(ic->dst.port, &data[42], sizeof(ic->dst.port));
break;
default:
memset(ic->src.port, 0, sizeof(ic->src.port));
memset(ic->dst.port, 0, sizeof(ic->dst.port));
}
return 0;
}
break;
} }
return -1; return 1;
} }

22
src/keygen.c Normal file
View File

@@ -0,0 +1,22 @@
#include "common.h"
#include <sodium.h>
#include <stdio.h>
int
gt_keygen(int argc, char **argv)
{
if (sodium_init() == -1) {
gt_log("sodium init failed\n");
return 1;
}
unsigned char key[32];
randombytes_buf(key, sizeof(key));
char buf[2 * sizeof(key) + 1];
gt_tohex(buf, sizeof(buf), key, sizeof(key));
printf("%s\n", buf);
return 0;
}

47
src/list.c Normal file
View File

@@ -0,0 +1,47 @@
#include "common.h"
#include "ctl.h"
#include "../argz/argz.h"
#include <dirent.h>
#include <stdio.h>
int
gt_list(int argc, char **argv)
{
struct argz showz[] = {
{"list", NULL, NULL, argz_option},
{NULL}};
if (argz(showz, argc, argv))
return 1;
char dir[64];
if (!ctl_rundir(dir, sizeof(dir)))
return 0;
DIR *dp = opendir(dir);
if (!dp)
return 0;
struct dirent *d = NULL;
while (d = readdir(dp), d) {
if (d->d_name[0] == '.')
continue;
int fd = ctl_connect(d->d_name);
if (fd < 0)
continue;
printf("%s\n", d->d_name);
close(fd);
}
closedir(dp);
return 0;
}

View File

@@ -1,103 +1,25 @@
#include "common.h" #include "common.h"
#include "db.h"
#include "ip.h"
#include "option.h"
#include "str.h"
#include "tun.h"
#include "iface.h"
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h> #include "../argz/argz.h"
#include <netdb.h>
#include "../mud/mud.h" volatile sig_atomic_t gt_alarm;
volatile sig_atomic_t gt_reload;
#ifndef O_CLOEXEC volatile sig_atomic_t gt_quit;
#define O_CLOEXEC 0
#endif
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
#endif
#define GT_MTU(X) ((X)-28)
static struct {
volatile sig_atomic_t quit;
volatile sig_atomic_t reload;
char *dev;
char *keyfile;
char *host;
long port;
struct {
char *list;
char *backup;
long port;
} bind;
long mtu;
long timeout;
long time_tolerance;
int ipv4;
int ipv6;
int mtu_auto;
int chacha20;
int version;
int keygen;
int persist;
struct {
unsigned char *data;
long size;
} buf;
} gt = {
.port = 5000,
.bind = {
.port = 5000,
},
.mtu = 1500,
.timeout = 5000,
.ipv4 = 1,
#ifdef __linux__
.ipv6 = 1,
#endif
.buf = {
.size = 64 * 1024,
},
};
static void static void
fd_set_nonblock(int fd) gt_sa_handler(int sig)
{ {
int ret; switch (sig) {
case SIGALRM:
do { gt_alarm = 1;
ret = fcntl(fd, F_GETFL, 0); return;
} while (ret == -1 && errno == EINTR); case SIGHUP:
gt_reload = 1; /* FALLTHRU */
int flags = (ret == -1) ? 0 : ret; default:
gt_quit = 1;
do { }
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
} while (ret == -1 && errno == EINTR);
if (ret == -1)
perror("fcntl O_NONBLOCK");
}
static void
gt_quit_handler(int sig)
{
gt.reload = (sig == SIGHUP);
gt.quit = 1;
} }
static void static void
@@ -109,11 +31,12 @@ gt_set_signal(void)
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_handler = gt_quit_handler; sa.sa_handler = gt_sa_handler;
sigaction(SIGINT, &sa, NULL); sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL); sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL); sigaction(SIGTERM, &sa, NULL);
sigaction(SIGHUP, &sa, NULL); sigaction(SIGHUP, &sa, NULL);
sigaction(SIGALRM, &sa, NULL);
sa.sa_handler = SIG_IGN; sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL); sigaction(SIGPIPE, &sa, NULL);
@@ -121,401 +44,44 @@ gt_set_signal(void)
sigaction(SIGUSR2, &sa, NULL); sigaction(SIGUSR2, &sa, NULL);
} }
static void
gt_print_secretkey(struct mud *mud)
{
unsigned char key[32];
size_t size = sizeof(key);
if (mud_get_key(mud, key, &size))
return;
char buf[2 * sizeof(key) + 1];
gt_tohex(buf, sizeof(buf), key, size);
gt_print("%s\n", buf);
}
static int
gt_setup_secretkey(struct mud *mud, char *keyfile)
{
int fd;
do {
fd = open(keyfile, O_RDONLY | O_CLOEXEC);
} while (fd == -1 && errno == EINTR);
if (fd == -1) {
perror("open keyfile");
return -1;
}
unsigned char key[32];
char buf[2 * sizeof(key)];
size_t size = 0;
while (size < sizeof(buf)) {
ssize_t r = read(fd, &buf[size], sizeof(buf) - size);
if (r <= (ssize_t)0) {
if (r && (errno == EAGAIN || errno == EINTR))
continue;
break;
}
size += r;
}
close(fd);
if (size != sizeof(buf)) {
gt_log("unable to read secret key\n");
return -1;
}
if (gt_fromhex(key, sizeof(key), buf, sizeof(buf))) {
gt_log("secret key is not valid\n");
return -1;
}
mud_set_key(mud, key, sizeof(key));
return 0;
}
static int
gt_setup_option(int argc, char **argv)
{
// clang-format off
struct option opts[] = {
{ "host", &gt.host, option_str },
{ "port", &gt.port, option_long },
{ "bind", &gt.bind.list, option_str },
{ "bind-backup", &gt.bind.backup, option_str },
{ "bind-port", &gt.bind.port, option_long },
{ "dev", &gt.dev, option_str },
{ "persist", NULL, option_option },
{ "mtu", &gt.mtu, option_long },
{ "mtu-auto", NULL, option_option },
{ "keyfile", &gt.keyfile, option_str },
{ "keygen", NULL, option_option },
{ "timeout", &gt.timeout, option_long },
{ "time-tolerance", &gt.time_tolerance, option_long },
{ "v4only", NULL, option_option },
{ "v6only", NULL, option_option },
{ "chacha20", NULL, option_option },
{ "buf-size", &gt.buf.size, option_long },
{ "version", NULL, option_option },
{ NULL },
};
// clang-format on
if (option(opts, argc, argv))
return 1;
int v4only = option_is_set(opts, "v4only");
int v6only = option_is_set(opts, "v6only");
if (v4only && v6only) {
gt_log("v4only and v6only cannot be both set\n");
return 1;
}
if ((int)gt.timeout <= 0) {
gt_log("bad timeout\n");
return 1;
}
if (gt.buf.size <= 0) {
gt_log("bad buf-size\n");
return 1;
}
if (v4only) {
gt.ipv4 = 1;
gt.ipv6 = 0;
}
if (v6only) {
gt.ipv4 = 0;
gt.ipv6 = 1;
}
gt.mtu_auto = option_is_set(opts, "mtu-auto");
gt.chacha20 = option_is_set(opts, "chacha20");
gt.version = option_is_set(opts, "version");
gt.keygen = option_is_set(opts, "keygen");
gt.persist = option_is_set(opts, "persist");
gt.buf.data = malloc(gt.buf.size);
return 0;
}
static void
gt_setup_mtu(struct mud *mud, char *tun_name)
{
int mtu = mud_get_mtu(mud);
if (mtu == (int)gt.mtu)
return;
gt.mtu = mtu;
gt_log("setup MTU to %i on interface %s\n", mtu, tun_name);
if (iface_set_mtu(tun_name, mtu) == -1)
perror("tun_set_mtu");
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
gt_set_signal(); gt_set_signal();
if (gt_setup_option(argc, argv)) struct {
return 1; char *name;
char *help;
int (*call)(int, char **);
} cmd[] = {
{"list", "list all tunnels", gt_list},
{"show", "show tunnel information", gt_show},
{"bench", "start a crypto bench", gt_bench},
{"bind", "start a new tunnel", gt_bind},
{"set", "change tunnel properties", gt_set},
{"keygen", "generate a new secret key", gt_keygen},
{"path", "manage paths", gt_path},
{"version", "show version", gt_version},
{NULL}};
if (gt.version) { if (argv[1]) {
gt_print(PACKAGE_VERSION "\n"); for (int k = 0; cmd[k].name; k++) {
return 0; if (!strcmp(cmd[k].name, argv[1]))
} return cmd[k].call(argc - 1, argv + 1);
int icmp_fd = -1;
if (gt.ipv4 && gt.mtu_auto) {
icmp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (icmp_fd == -1)
gt_log("couldn't create ICMP socket\n");
}
struct mud *mud = mud_create(gt.bind.port, gt.ipv4, gt.ipv6);
if (!mud) {
gt_log("couldn't create mud\n");
return 1;
}
if (gt.keygen || str_empty(gt.keyfile)) {
if (mud_new_key(mud)) {
gt_log("couldn't generate a new key\n");
return 1;
} }
} }
if (gt.keygen) { printf("available commands:\n\n");
gt_print_secretkey(mud);
return 0;
}
if (!gt.chacha20 && mud_set_aes(mud)) int len = 0;
gt_log("AES is not available\n");
if (gt.timeout > 0) for (int k = 0; cmd[k].name; k++)
mud_set_send_timeout_msec(mud, gt.timeout); len = MAX(len, (int)strlen(cmd[k].name));
if (gt.time_tolerance > 0) for (int k = 0; cmd[k].name; k++)
mud_set_time_tolerance_sec(mud, gt.time_tolerance); printf(" %-*s %s\n", len, cmd[k].name, cmd[k].help);
mud_set_mtu(mud, GT_MTU(gt.mtu)); printf("\n");
char *tun_name = NULL; return 1;
int tun_fd = tun_create(gt.dev, &tun_name);
if (tun_fd == -1) {
gt_log("couldn't create tun device\n");
return 1;
}
if (tun_set_persist(tun_fd, gt.persist) == -1)
perror("tun_set_persist");
if (str_empty(gt.keyfile)) {
gt_print("here is your new secret key:\n");
gt_print_secretkey(mud);
} else {
if (gt_setup_secretkey(mud, gt.keyfile))
return 1;
}
if (gt.host && gt.port) {
if (gt.bind.backup) {
if (mud_peer(mud, gt.bind.backup, gt.host, gt.port, 1)) {
perror("mud_peer (backup)");
return 1;
}
}
if (gt.bind.list) {
char tmp[1024];
char *name = &tmp[0];
str_cpy(tmp, gt.bind.list, sizeof(tmp) - 1);
while (*name) {
char *p = name;
while (*p && *p != ',')
p++;
if (*p)
*p++ = 0;
if (mud_peer(mud, name, gt.host, gt.port, 0)) {
perror("mud_peer");
return 1;
}
name = p;
}
}
}
gt_setup_mtu(mud, tun_name);
int mud_fd = mud_get_fd(mud);
fd_set_nonblock(tun_fd);
fd_set_nonblock(mud_fd);
if (icmp_fd != -1)
fd_set_nonblock(icmp_fd);
gt_log("running...\n");
fd_set rfds;
FD_ZERO(&rfds);
int last_fd = 1 + MAX(tun_fd, MAX(mud_fd, icmp_fd));
while (!gt.quit) {
FD_SET(tun_fd, &rfds);
FD_SET(mud_fd, &rfds);
if (icmp_fd != -1)
FD_SET(icmp_fd, &rfds);
if (select(last_fd, &rfds, NULL, NULL, NULL) == -1) {
if (errno != EBADF)
continue;
perror("select");
return 1;
}
if (icmp_fd != -1 && FD_ISSET(icmp_fd, &rfds)) {
struct sockaddr_storage ss;
socklen_t sl = sizeof(ss);
ssize_t r = recvfrom(icmp_fd, gt.buf.data, gt.buf.size, 0,
(struct sockaddr *)&ss, &sl);
if (r >= 8) {
struct ip_common ic;
if (!ip_get_common(&ic, gt.buf.data, r) && ic.proto == 1) {
unsigned char *data = &gt.buf.data[ic.hdr_size];
if (data[0] == 3) {
int mtu = (data[6] << 8) | data[7];
if (mtu) {
gt_log("received MTU from ICMP: %i\n", mtu);
mud_set_mtu(mud, GT_MTU(mtu));
}
}
}
}
}
if (FD_ISSET(tun_fd, &rfds)) {
size_t size = 0;
while (gt.buf.size - size >= gt.mtu) {
const int r = tun_read(tun_fd, &gt.buf.data[size], gt.buf.size - size);
if (r <= 0 || r > gt.mtu)
break;
struct ip_common ic;
if (ip_get_common(&ic, &gt.buf.data[size], r) || ic.size != r)
break;
size += r;
}
int p = 0;
while (p < size) {
int tc = 0;
int q = p;
while (q < size) {
struct ip_common ic;
if ((ip_get_common(&ic, &gt.buf.data[q], size - q)) ||
(ic.size > size - q))
break;
if (q + ic.size > p + gt.mtu)
break;
q += ic.size;
if (tc < (ic.tc & 0xFC))
tc = ic.tc & 0xFC;
}
if (p >= q)
break;
int r = mud_send(mud, &gt.buf.data[p], q - p, tc);
if (r == -1 && errno == EMSGSIZE) {
gt_setup_mtu(mud, tun_name);
} else {
if (r == -1 && errno != EAGAIN)
perror("mud_send");
}
p = q;
}
}
if (FD_ISSET(mud_fd, &rfds)) {
size_t size = 0;
while (gt.buf.size - size >= gt.mtu) {
const int r = mud_recv(mud, &gt.buf.data[size], gt.buf.size - size);
if (r <= 0) {
if (r == -1 && errno != EAGAIN)
perror("mud_recv");
break;
}
size += r;
}
int p = 0;
while (p < size) {
struct ip_common ic;
if ((ip_get_common(&ic, &gt.buf.data[p], size - p)) ||
(ic.size > size - p))
break;
tun_write(tun_fd, &gt.buf.data[p], ic.size);
p += ic.size;
}
}
}
if (gt.reload && tun_fd >= 0) {
if (tun_set_persist(tun_fd, 1) == -1)
perror("tun_set_persist");
}
return 0;
} }

View File

@@ -1,146 +0,0 @@
#include "common.h"
#include "option.h"
#include "str.h"
int
option_str(void *data, int argc, char **argv)
{
if (argc < 2 || str_empty(argv[1])) {
gt_print("option `%s' need a string argument\n", argv[0]);
return -1;
}
memcpy(data, &argv[1], sizeof(argv[1]));
return 1;
}
int
option_long(void *data, int argc, char **argv)
{
if (argc < 2 || str_empty(argv[1])) {
gt_print("option `%s' need an integer argument\n", argv[0]);
return -1;
}
errno = 0;
char *end;
long val = strtol(argv[1], &end, 0);
if (errno || argv[1] == end) {
gt_print("argument `%s' is not a valid integer\n", argv[1]);
return -1;
}
memcpy(data, &val, sizeof(val));
return 1;
}
int
option_is_set(struct option *opts, const char *name)
{
for (int k = 0; opts[k].name; k++) {
if (!str_cmp(opts[k].name, name))
return opts[k].set;
}
return 0;
}
int
option_option(void *data, int argc, char **argv)
{
if (!data)
return 0;
struct option *opts = (struct option *)data;
for (int k = 0; opts[k].name; k++)
opts[k].set = 0;
for (int i = 1; i < argc; i++) {
int found = 0;
for (int k = 0; opts[k].name; k++) {
if (str_cmp(opts[k].name, argv[i]))
continue;
if (opts[k].set) {
gt_print("option `%s' is already set\n", opts[k].name);
return -1;
}
int ret = opts[k].call(opts[k].data, argc - i, &argv[i]);
if (ret < 0)
return -1;
opts[k].set = 1;
i += ret;
found = 1;
break;
}
if (!found)
return i - 1;
}
return argc;
}
static int
option_usage(struct option *opts, int slen)
{
if (!opts)
return 0;
int len = 0;
for (int k = 0; opts[k].name; k++) {
if (len > 40) {
gt_print("\n%*s", slen, "");
len = 0;
}
len += gt_print(" [%s", opts[k].name);
if (opts[k].call == option_option) {
len += option_usage((struct option *)opts[k].data, slen + len);
} else {
len += gt_print(" ARG");
}
len += gt_print("]");
}
return len;
}
int
option(struct option *opts, int argc, char **argv)
{
int ret = option_option(opts, argc, argv);
if (ret == argc)
return 0;
if (ret < 0 || ret + 1 >= argc)
return 1;
gt_print("option `%s' is unknown\n", argv[ret + 1]);
int slen = gt_print("usage: %s", argv[0]);
if (slen > 40) {
slen = 12;
gt_print("\n%*s", slen, "");
}
option_usage(opts, slen);
gt_print("\n");
return 1;
}

View File

@@ -1,15 +0,0 @@
#pragma once
struct option {
char *name;
void *data;
int (*call) (void *, int, char **);
int set;
};
int option_option (void *, int, char **);
int option_str (void *, int, char **);
int option_long (void *, int, char **);
int option_is_set (struct option *, const char *);
int option (struct option *, int, char **);

192
src/path.c Normal file
View File

@@ -0,0 +1,192 @@
#include "common.h"
#include "ctl.h"
#include <stdio.h>
#include "../argz/argz.h"
static void
gt_path_print(struct mud_path *path, int term)
{
const char *statestr = NULL;
char bindstr[INET6_ADDRSTRLEN];
char beatstr[32];
char txstr[32], rxstr[32];
switch (path->state) {
case MUD_UP: statestr = "up"; break;
case MUD_BACKUP: statestr = "backup"; break;
case MUD_DOWN: statestr = "down"; break;
default: return;
}
if (gt_toaddr(bindstr, sizeof(bindstr),
(struct sockaddr *)&path->local_addr))
return;
if (gt_totime(beatstr, sizeof(beatstr), path->conf.beat / 1000))
return;
if (gt_torate(txstr, sizeof(txstr), path->conf.tx_max_rate * 8))
return;
if (gt_torate(rxstr, sizeof(rxstr), path->conf.rx_max_rate * 8))
return;
printf(term ? "path %s %s losslimit %u%% beat %s "
"rate %s tx %s rx %s\n"
: "path %s %s %u %s %s %s %s\n",
statestr, bindstr,
path->conf.loss_limit * 100U / 255U,
beatstr,
path->conf.fixed_rate ? "fixed" : "auto",
txstr, rxstr);
}
static int
gt_path_cmp_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
{
if (a->ss_family != b->ss_family)
return 1;
if (a->ss_family == AF_INET) {
struct sockaddr_in *A = (struct sockaddr_in *)a;
struct sockaddr_in *B = (struct sockaddr_in *)b;
return ((memcmp(&A->sin_addr, &B->sin_addr, sizeof(A->sin_addr))));
}
if (a->ss_family == AF_INET6) {
struct sockaddr_in6 *A = (struct sockaddr_in6 *)a;
struct sockaddr_in6 *B = (struct sockaddr_in6 *)b;
return ((memcmp(&A->sin6_addr, &B->sin6_addr, sizeof(A->sin6_addr))));
}
return 1;
}
static int
gt_path_print_all(int fd, enum mud_state state, struct sockaddr_storage *addr)
{
struct ctl_msg req = {
.type = CTL_PATH_STATUS,
}, res = {0};
if (send(fd, &req, sizeof(struct ctl_msg), 0) == -1)
return -1;
struct mud_path path[MUD_PATH_MAX];
int count = 0;
while (1) {
if (recv(fd, &res, sizeof(struct ctl_msg), 0) == -1)
return -1;
if (res.type != req.type) {
errno = EBADMSG;
return -1;
}
if (res.ret == EAGAIN) {
memcpy(&path[count], &res.path_status, sizeof(struct mud_path));
count++;
} else if (res.ret) {
errno = res.ret;
return -1;
} else break;
}
int term = isatty(1);
if (!term)
printf("# STATE ADDR LOSSLIMIT BEAT RATE TX RX\n");
for (int i = 0; i < count; i++) {
if (state && path[i].state != state)
continue;
if (addr->ss_family && gt_path_cmp_addr(addr, &path[i].local_addr))
continue;
gt_path_print(&path[i], term);
}
return 0;
}
int
gt_path(int argc, char **argv)
{
const char *dev = NULL;
unsigned int loss_limit = 0;
struct ctl_msg req = {
.type = CTL_STATE,
.path = {
.state = MUD_EMPTY,
},
}, res = {0};
struct argz ratez[] = {
{"fixed|auto", NULL, NULL, argz_option},
{"tx", "BYTES/SEC", &req.path.rate_tx, argz_bytes},
{"rx", "BYTES/SEC", &req.path.rate_rx, argz_bytes},
{NULL}};
struct argz pathz[] = {
{NULL, "IPADDR", &req.path.addr, argz_addr},
{"dev", "NAME", &dev, argz_str},
{"up|backup|down", NULL, NULL, argz_option},
{"rate", NULL, &ratez, argz_option},
{"beat", "SECONDS", &req.path.beat, argz_time},
{"losslimit", "PERCENT", &loss_limit, argz_percent},
{NULL}};
if (argz(pathz, argc, argv))
return 1;
int fd = ctl_connect(dev);
if (fd < 0) {
ctl_explain_connect(fd);
return 1;
}
int set = argz_is_set(pathz, "rate")
|| argz_is_set(pathz, "beat")
|| argz_is_set(pathz, "losslimit");
if (set && !req.path.addr.ss_family) {
gt_log("please specify a path\n");
return 1;
}
if (argz_is_set(pathz, "up")) {
req.path.state = MUD_UP;
} else if (argz_is_set(pathz, "backup")) {
req.path.state = MUD_BACKUP;
} else if (argz_is_set(pathz, "down")) {
req.path.state = MUD_DOWN;
}
if (loss_limit)
req.path.loss_limit = loss_limit * 255 / 100;
if (argz_is_set(ratez, "fixed")) {
req.path.fixed_rate = 3;
} else if (argz_is_set(ratez, "auto")) {
req.path.fixed_rate = 1;
}
int ret = 0;
if (req.path.addr.ss_family && (req.path.state || set))
ret = ctl_reply(fd, &res, &req);
if (!ret)
ret = gt_path_print_all(fd, req.path.state, &req.path.addr);
if (ret == -1)
perror("path");
ctl_delete(fd);
return !!ret;
}

89
src/set.c Normal file
View File

@@ -0,0 +1,89 @@
#include "common.h"
#include "ctl.h"
#include <stdio.h>
#include "../argz/argz.h"
static int
gt_argz_tc(void *data, int argc, char **argv)
{
if (argc < 1 || !argv[0])
return -1;
int val = 0;
const char *s = argv[0];
if ((s[0] == 'C') && (s[1] == 'S') &&
(s[2] >= '0') && (s[2] <= '7') && !s[3]) {
val = (s[2] - '0') << 3;
} else if ((s[0] == 'A') && (s[1] == 'F') &&
(s[2] >= '1') && (s[2] <= '4') &&
(s[3] >= '1') && (s[3] <= '3') && !s[4]) {
val = ((s[2] - '0') << 3) | ((s[3] - '0') << 1);
} else if ((s[0] == 'E') && (s[1] == 'F') && !s[2]) {
val = 46;
} else return -1;
if (data)
*(int *)data = val;
return 1;
}
int
gt_set(int argc, char **argv)
{
const char *dev = NULL;
unsigned long kxtimeout;
unsigned long timetolerance;
unsigned long keepalive;
int tc;
struct argz pathz[] = {
{"dev", "NAME", &dev, argz_str},
{"tc", "CS|AF|EF", &tc, gt_argz_tc},
{"kxtimeout", "SECONDS", &kxtimeout, argz_time},
{"timetolerance", "SECONDS", &timetolerance, argz_time},
{"keepalive", "SECONDS", &keepalive, argz_time},
{NULL}};
if (argz(pathz, argc, argv))
return 1;
struct ctl_msg req = {
.type = CTL_CONF,
.conf = {
.tc = tc ? (tc << 1) | 1 : 0,
.kxtimeout = kxtimeout * UINT64_C(1000),
.timetolerance = timetolerance * UINT64_C(1000),
.keepalive = keepalive * UINT64_C(1000),
},
}, res = {0};
int fd = ctl_connect(dev);
if (fd < 0) {
ctl_explain_connect(fd);
return 1;
}
int ret = ctl_reply(fd, &res, &req);
char t0[32];
char t1[32];
char t2[32];
gt_totime(t0, sizeof(t0), res.conf.kxtimeout / 1000);
gt_totime(t1, sizeof(t1), res.conf.timetolerance / 1000);
gt_totime(t2, sizeof(t2), res.conf.keepalive / 1000);
printf("set kxtimeout %s timetolerance %s keepalive %s tc %i\n", t0, t1, t2, res.conf.tc);
if (ret)
perror("set");
ctl_delete(fd);
return !!ret;
}

143
src/show.c Normal file
View File

@@ -0,0 +1,143 @@
#include "common.h"
#include "ctl.h"
#include "../argz/argz.h"
#include <stdio.h>
static void
gt_show_bad_line(int term, char *name, uint64_t count,
struct sockaddr_storage *ss)
{
if (!count)
return;
char addr[INET6_ADDRSTRLEN];
gt_toaddr(addr, sizeof(addr), (struct sockaddr *)ss);
printf(term ? "%s:\n"
" count: %"PRIu64"\n"
" last: %s port %"PRIu16"\n"
: "%s"
" %"PRIu64
" %s %"PRIu16
"\n",
name, count, addr[0] ? addr : "-",
gt_get_port((struct sockaddr *)ss));
}
static int
gt_show_bad(int fd)
{
struct ctl_msg res, req = {.type = CTL_BAD};
if (ctl_reply(fd, &res, &req))
return -1;
int term = isatty(1);
gt_show_bad_line(term, "decrypt",
res.bad.decrypt.count, &res.bad.decrypt.addr);
gt_show_bad_line(term, "difftime",
res.bad.difftime.count, &res.bad.difftime.addr);
gt_show_bad_line(term, "keyx",
res.bad.keyx.count, &res.bad.keyx.addr);
return 0;
}
static int
gt_show_status(int fd)
{
struct ctl_msg res, req = {.type = CTL_STATUS};
if (ctl_reply(fd, &res, &req))
return -1;
char bindstr[INET6_ADDRSTRLEN];
char peerstr[INET6_ADDRSTRLEN];
gt_toaddr(bindstr, sizeof(bindstr),
(struct sockaddr *)&res.status.bind);
int server = gt_toaddr(peerstr, sizeof(peerstr),
(struct sockaddr *)&res.status.peer);
int term = isatty(1);
if (server) {
printf(term ? "server %s:\n"
" pid: %li\n"
" bind: %s port %"PRIu16"\n"
" mtu: %zu\n"
" cipher: %s\n"
: "server %s"
" %li"
" %s %"PRIu16
" %zu"
" %s"
"\n",
res.status.tun_name,
res.status.pid,
bindstr[0] ? bindstr : "-",
gt_get_port((struct sockaddr *)&res.status.bind),
res.status.mtu,
GT_CIPHER(res.status.chacha));
} else {
printf(term ? "client %s:\n"
" pid: %li\n"
" bind: %s port %"PRIu16"\n"
" peer: %s port %"PRIu16"\n"
" mtu: %zu\n"
" cipher: %s\n"
: "client %s"
" %li"
" %s %"PRIu16
" %s %"PRIu16
" %zu"
" %s"
"\n",
res.status.tun_name,
res.status.pid,
bindstr[0] ? bindstr : "-",
gt_get_port((struct sockaddr *)&res.status.bind),
peerstr[0] ? peerstr : "-",
gt_get_port((struct sockaddr *)&res.status.peer),
res.status.mtu,
GT_CIPHER(res.status.chacha));
}
return 0;
}
int
gt_show(int argc, char **argv)
{
const char *dev = NULL;
struct argz showz[] = {
{"dev", "NAME", &dev, argz_str},
{"bad", NULL, NULL, argz_option},
{NULL}};
if (argz(showz, argc, argv))
return 1;
int fd = ctl_connect(dev);
if (fd < 0) {
ctl_explain_connect(fd);
return 1;
}
int ret = argz_is_set(showz, "bad")
? gt_show_bad(fd)
: gt_show_status(fd);
if (ret == -1)
perror("show");
ctl_delete(fd);
return !!ret;
}

View File

@@ -1,75 +0,0 @@
#pragma once
#include "common.h"
static inline size_t
str_cpy(char *restrict dst, const char *restrict src, size_t len)
{
if (!dst || !src)
return 0;
size_t i;
for (i = 0; i < len && src[i]; i++)
dst[i] = src[i];
dst[i] = 0;
return i;
}
_pure_ static inline int
str_empty(const char *restrict str)
{
return !str || !str[0];
}
_pure_ static inline size_t
str_cmp(const char *restrict sa, const char *restrict sb)
{
if (!sa || !sb)
return 1;
size_t i = 0;
while (sa[i] == sb[i])
if (!sa[i++])
return 0;
return i + 1;
}
_pure_ static inline size_t
str_len(const char *restrict str)
{
if (!str)
return 0;
return strlen(str);
}
static inline char *
str_cat(const char **strs, size_t count)
{
size_t size = 1;
for (size_t i = 0; i < count; i++)
size += str_len(strs[i]);
char *str = malloc(size);
if (!str)
return NULL;
char *p = str;
for (size_t i = 0; i < count; i++) {
size_t len = str_len(strs[i]);
memcpy(p, strs[i], len);
p += len;
}
p[0] = 0;
return str;
}

124
src/tun.c
View File

@@ -1,18 +1,14 @@
#include "common.h"
#include "ip.h"
#include "str.h"
#include "tun.h" #include "tun.h"
#include "common.h"
#include "ip.h"
#include <fcntl.h> #include <fcntl.h>
#include <net/if.h>
#include <stdio.h> #include <stdio.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <net/if.h>
#ifdef __linux__ #ifdef __linux__
#define IFF_TUN 0x0001 #define IFF_TUN 0x0001
#define IFF_NO_PI 0x1000 #define IFF_NO_PI 0x1000
@@ -33,17 +29,23 @@
#ifdef __APPLE__ #ifdef __APPLE__
static int static int
tun_create_by_id(char *name, size_t size, unsigned id) tun_create_by_id(char *name, size_t len, unsigned id)
{ {
int ret = snprintf(name, len, "utun%u", id);
if (ret <= 0 || (size_t)ret >= len) {
errno = EINVAL;
return -1;
}
int fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); int fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if (fd == -1) if (fd == -1)
return -1; return -1;
struct ctl_info ci; struct ctl_info ci = {
.ctl_name = UTUN_CONTROL_NAME,
memset(&ci, 0, sizeof(ci)); };
str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name) - 1);
if (ioctl(fd, CTLIOCGINFO, &ci)) { if (ioctl(fd, CTLIOCGINFO, &ci)) {
int err = errno; int err = errno;
@@ -67,13 +69,11 @@ tun_create_by_id(char *name, size_t size, unsigned id)
return -1; return -1;
} }
snprintf(name, size, "utun%u", id);
return fd; return fd;
} }
static int static int
tun_create_by_name(char *name, size_t size, char *dev_name) tun_create_by_name(char *name, size_t len, const char *dev_name)
{ {
unsigned id = 0; unsigned id = 0;
@@ -82,7 +82,7 @@ tun_create_by_name(char *name, size_t size, char *dev_name)
return -1; return -1;
} }
return tun_create_by_id(name, size, id); return tun_create_by_id(name, len, id);
} }
#else /* not __APPLE__ */ #else /* not __APPLE__ */
@@ -90,25 +90,37 @@ tun_create_by_name(char *name, size_t size, char *dev_name)
#ifdef __linux__ #ifdef __linux__
static int static int
tun_create_by_name(char *name, size_t size, char *dev_name) tun_create_by_name(char *name, size_t len, const char *dev_name)
{ {
int fd = open("/dev/net/tun", O_RDWR); int ret = snprintf(name, len, "%s", dev_name);
if (fd == -1) if (ret <= 0 || (size_t)ret >= len) {
errno = EINVAL;
return -1; return -1;
}
struct ifreq ifr = { struct ifreq ifr = {
.ifr_flags = IFF_TUN | IFF_NO_PI, .ifr_flags = IFF_TUN | IFF_NO_PI,
}; };
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1); ret = snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", dev_name);
if (ioctl(fd, TUNSETIFF, &ifr)) { if (ret <= 0 || (size_t)ret >= sizeof(ifr.ifr_name)) {
close(fd); errno = EINVAL;
return -1; return -1;
} }
str_cpy(name, ifr.ifr_name, size - 1); int fd = open("/dev/net/tun", O_RDWR);
if (fd == -1)
return -1;
if (ioctl(fd, TUNSETIFF, &ifr)) {
int err = errno;
close(fd);
errno = err;
return -1;
}
return fd; return fd;
} }
@@ -116,46 +128,56 @@ tun_create_by_name(char *name, size_t size, char *dev_name)
#else /* not __linux__ not __APPLE__ */ #else /* not __linux__ not __APPLE__ */
static int static int
tun_create_by_name(char *name, size_t size, char *dev_name) tun_create_by_name(char *name, size_t len, const char *dev_name)
{ {
char path[64]; int ret = snprintf(name, len, "%s", dev_name);
snprintf(path, sizeof(path), "/dev/%s", dev_name); if (ret <= 0 || (size_t)ret >= len) {
str_cpy(name, dev_name, size - 1); errno = EINVAL;
return -1;
}
return open(path, O_RDWR); char tmp[64];
ret = snprintf(tmp, sizeof(tmp), "/dev/%s", dev_name);
if (ret <= 0 || (size_t)ret >= sizeof(tmp)) {
errno = EINVAL;
return -1;
}
return open(tmp, O_RDWR);
} }
#endif /* not __APPLE__ */ #endif /* not __APPLE__ */
static int static int
tun_create_by_id(char *name, size_t size, unsigned id) tun_create_by_id(char *name, size_t len, unsigned id)
{ {
char dev_name[64]; char tmp[64];
int ret = snprintf(tmp, sizeof(tmp), "tun%u", id);
snprintf(dev_name, sizeof(dev_name), "tun%u", id); if (ret <= 0 || (size_t)ret >= sizeof(tmp)) {
errno = EINVAL;
return -1;
}
return tun_create_by_name(name, size, dev_name); return tun_create_by_name(name, len, tmp);
} }
#endif #endif
int int
tun_create(char *dev_name, char **ret_name) tun_create(char *name, size_t len, const char *dev_name)
{ {
char name[64] = {0};
int fd = -1; int fd = -1;
if (str_empty(dev_name)) { if (EMPTY(dev_name)) {
for (unsigned id = 0; id < 32 && fd == -1; id++) for (unsigned id = 0; id < 32 && fd == -1; id++)
fd = tun_create_by_id(name, sizeof(name), id); fd = tun_create_by_id(name, len, id);
} else { } else {
fd = tun_create_by_name(name, sizeof(name), dev_name); fd = tun_create_by_name(name, len, dev_name);
} }
if (fd != -1 && ret_name)
*ret_name = strdup(name);
return fd; return fd;
} }
@@ -179,17 +201,17 @@ tun_read(int fd, void *data, size_t size)
}, },
}; };
ssize_t ret = readv(fd, iov, 2); int ret = (int)readv(fd, iov, 2);
if (ret <= (ssize_t)0) if (ret <= 0)
return ret; return ret;
if (ret <= (ssize_t)sizeof(family)) if ((size_t)ret <= sizeof(family))
return 0; return 0;
return ret - sizeof(family); return ret - (int)sizeof(family);
#else #else
return read(fd, data, size); return (int)read(fd, data, size);
#endif #endif
} }
@@ -202,7 +224,7 @@ tun_write(int fd, const void *data, size_t size)
#ifdef GT_BSD_TUN #ifdef GT_BSD_TUN
uint32_t family; uint32_t family;
switch (ip_get_version(data, size)) { switch (ip_get_version(data, (int)size)) {
case 4: case 4:
family = htonl(AF_INET); family = htonl(AF_INET);
break; break;
@@ -225,17 +247,17 @@ tun_write(int fd, const void *data, size_t size)
}, },
}; };
ssize_t ret = writev(fd, iov, 2); int ret = (int)writev(fd, iov, 2);
if (ret <= (ssize_t)0) if (ret <= 0)
return ret; return ret;
if (ret <= (ssize_t)sizeof(family)) if ((size_t)ret <= sizeof(family))
return 0; return 0;
return ret - sizeof(family); return ret - (int)sizeof(family);
#else #else
return write(fd, data, size); return (int)write(fd, data, size);
#endif #endif
} }

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
int tun_create (char *, char **); #include <stddef.h>
int tun_create (char *, size_t, const char *);
int tun_read (int, void *, size_t); int tun_read (int, void *, size_t);
int tun_write (int, const void *, size_t); int tun_write (int, const void *, size_t);
int tun_set_persist (int, int); int tun_set_persist (int, int);

27
src/version.c Normal file
View File

@@ -0,0 +1,27 @@
#include "common.h"
#include <sodium.h>
#include "../argz/argz.h"
int
gt_version(int argc, char **argv)
{
struct argz version_argz[] = {
{"libsodium", NULL, NULL, argz_option},
{NULL}};
if (argz(version_argz, argc, argv))
return 1;
if (argz_is_set(version_argz, "libsodium")) {
printf("%i.%i (%s)\n",
sodium_library_version_major(),
sodium_library_version_minor(),
sodium_version_string());
} else {
printf("%s\n", PACKAGE_VERSION);
}
return 0;
}

View File

@@ -1,29 +1,6 @@
#!/bin/sh #!/bin/sh
if [ ! -f "$1" ]; then exec glorytun bind "$@" \
echo "usage: $(basename "$0") FILE" $BIND $BIND_PORT \
exit 1 ${DEV:+dev "$DEV"} \
fi ${HOST:+to "$HOST" "$PORT"}
. "$(readlink -f "$1")"
DEV="gt${HOST:+c}-$(basename "$1")"
# Setting BIND is like going to 'expert mode'
# This helper is pretty stupid and still needs some work
if [ -n "$HOST" ] && [ -z "$BIND" ]; then
BIND=$(ip route get "$HOST" | awk '/src/{getline;print $0}' RS=' ')
ip rule add from "$BIND" table main pref 32000
ip rule add from all table 200 pref 32001
fi
exec glorytun \
v4only \
keyfile "$1".key \
dev "$DEV" \
${HOST:+host "$HOST"} \
${PORT:+port "$PORT"} \
${BIND:+bind "$BIND"} \
${BIND_PORT:+bind-port "$BIND_PORT"} \
${MTU:+mtu "$MTU"} \
${MTU_AUTO:+mtu-auto}

View File

@@ -7,36 +7,69 @@ _ask() {
read -r "$2" read -r "$2"
} }
_NAME=tun0 _ask "Config filename (tun0)" NAME
_ask "Config filename ($_NAME)" NAME NAME=${NAME:-tun0}
NAME=${NAME:-$_NAME} DIR="/etc/glorytun/$NAME"
if [ -f /etc/glorytun/"$NAME" ]; then if [ -d "$DIR" ]; then
echo "This config already exit!" echo "This config already exit!"
exit 1 exit 1
fi fi
_ask "Server ip (enter for server conf)" HOST _ask "Server ip (enter for server conf)" HOST
if [ -z "$HOST" ]; then
_ask "Bind to port (5000)" BIND_PORT
BIND_PORT=${BIND_PORT:-5000}
else
_ask "Server port (5000)" PORT
PORT=${PORT:-5000}
fi
BIND=0.0.0.0
case "$HOST" in
*:*) BIND=::
esac
_ask "Server key (enter to generate a new one)" KEY _ask "Server key (enter to generate a new one)" KEY
if [ -z "$KEY" ]; then if [ -z "$KEY" ]; then
KEY=$(glorytun keygen) || exit KEY=$(glorytun keygen)
echo "Your new key: $KEY" echo "Your new key: $KEY"
fi fi
mkdir -p /etc/glorytun # install files
FILE="/etc/glorytun/$NAME" mkdir -p "$DIR"
echo "${HOST:+HOST=$HOST}" > "$FILE" cat > "$DIR/env" <<EOF
DEV=gt${HOST:+c}-$NAME
HOST=$HOST
PORT=$PORT
BIND=$BIND
BIND_PORT=$BIND_PORT
OPTIONS=
EOF
touch "$FILE.key" ( umask 077; echo "$KEY" > "$DIR/key" )
chmod 600 "$FILE.key"
echo "$KEY" > "$FILE.key"
[ "$HOST" ] && cat > "$DIR/post.sh" <<'EOF'
#!/bin/sh
PREF=32765
TABLE=200
# keep the current route to HOST
SRC=$(ip route get "$HOST" | awk '/src/{getline;print $0}' RS=' ')
ip rule add from "$SRC" table main pref "$((PREF-1))" || true
# limit to 100Mbit by default
glorytun path up "$SRC" dev "$DEV" rate rx 12500000 tx 12500000
# forward everything else to the tunnel
ip rule add from all table "$TABLE" pref "$PREF" || true
EOF
[ -f "$DIR/post.sh" ] && chmod u+x "$DIR/post.sh"
# start services
_ask "Start glorytun now ? (enter to skip)" START _ask "Start glorytun now ? (enter to skip)" START
case "$START" in case "$START" in y*|Y*)
y*|Y*) systemctl start glorytun@"$NAME" ;;
systemctl restart systemd-networkd
systemctl start glorytun@"$NAME"
;;
esac esac

View File

@@ -5,7 +5,9 @@ After=network.target
[Service] [Service]
Type=simple Type=simple
Restart=always Restart=always
ExecStart=@bindir@/glorytun-run /etc/glorytun/%i EnvironmentFile=/etc/glorytun/%i/env
ExecStart=@bindir@/glorytun-run keyfile /etc/glorytun/%i/key $OPTIONS
ExecStartPost=-/etc/glorytun/%i/post.sh
CapabilityBoundingSet=CAP_NET_ADMIN CapabilityBoundingSet=CAP_NET_ADMIN
[Install] [Install]

View File

@@ -1,13 +1,15 @@
#!/bin/sh #!/bin/sh
[ -z "${VERSION}" ] && VERSION=`git describe --tags --match='v[0-9].*' 2>/dev/null` \ export GIT_DIR=.git
&& VERSION=${VERSION#v} export GIT_WORK_TREE=.
[ -z "${VERSION}" ] && VERSION=`cat VERSION 2>/dev/null` [ -z "$VERSION" ] && VERSION="$(git describe --tags --match='v[0-9].*' 2>/dev/null)" \
&& VERSION="${VERSION#v}"
[ -z "${VERSION}" ] && VERSION=0.0.0 [ -z "$VERSION" ] && VERSION="$(git rev-parse HEAD 2>/dev/null)"
[ "$1" = "major" ] && printf ${VERSION%%.*} \ [ -z "$VERSION" ] && VERSION="$(cat VERSION 2>/dev/null)"
&& exit 0
printf ${VERSION} | tee VERSION [ -z "$VERSION" ] && VERSION="0.0.0"
printf "%s" "$VERSION" | tee VERSION