Compare commits

..

51 Commits

Author SHA1 Message Date
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
Adrien Gallouët
d1940692b2 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 14:11:36 +00:00
Adrien Gallouët
d3307a22f8 Add missing netinet/in.h (for freebsd)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 14:02:53 +00:00
Adrien Gallouët
93cefd6dba Dependency systemd is not mandatory
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 13:52:20 +00:00
Adrien Gallouët
21718c8c14 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 13:22:51 +00:00
Adrien Gallouët
aa54a72bbc Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 13:18:07 +00:00
Adrien Gallouët
32e6e7575a Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 13:13:37 +00:00
Adrien Gallouët
19eea3e96d Add a start section in glorytun-setup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 12:44:13 +00:00
Adrien Gallouët
75b2903ac2 Add unit systemd files
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-26 08:23:25 +00:00
Adrien Gallouët
0f5a6f5d98 Update .gitignore
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 14:43:55 +00:00
Adrien Gallouët
ed90fdea02 Cleanup meson build
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 14:42:56 +00:00
Adrien Gallouët
520bd33cb3 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 08:35:31 +00:00
Adrien Gallouët
361c695c5c Remove .build.sh
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 08:33:44 +00:00
Adrien Gallouët
bc5d622169 Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 08:32:48 +00:00
Adrien Gallouët
7859746f66 Add meson.build
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 08:19:22 +00:00
Adrien Gallouët
c3b8c44c68 Show only version
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-17 08:18:30 +00:00
Adrien Gallouët
297e93ed54 Add persist option
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-16 15:52:30 +00:00
Adrien Gallouët
325575c6a7 Update mud and add option keygen
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-16 15:20:11 +00:00
Adrien Gallouët
3b1c9db3f8 Remove gt_na() and gt_fatal()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2017-11-15 23:31:17 +00:00
Adrien Gallouët
557d3f7869 Update mud 2017-03-07 10:46:38 +00:00
Adrien Gallouët
195908d379 Add iface.[ch] 2017-03-07 10:36:23 +00:00
Adrien Gallouët
eb5c6853c1 Allow undefined PACKAGE_STRING 2017-03-07 10:36:16 +00:00
Adrien Gallouët
3c2481dc33 Allow undefined TUNSETPERSIST 2017-02-10 15:13:05 +00:00
Adrien Gallouët
355040f576 Don't destroy tun on SIGHUP 2017-02-10 11:54:19 +00:00
Adrien Gallouët
bbf1c12f7a Update mud 2017-01-29 12:03:27 +00:00
Adrien Gallouët
c54303da8f Update mud 2017-01-20 09:53:58 +00:00
Adrien Gallouët
e3440cf1e9 Update mud 2017-01-19 14:55:09 +00:00
Adrien Gallouët
86916f1999 Add buf-size option and increase buffer size 2017-01-19 14:13:29 +00:00
Adrien Gallouët
9cebabfe01 Remove while(1) 2017-01-19 12:47:06 +00:00
Adrien Gallouët
0664fc3b21 Update mud 2017-01-18 15:27:18 +00:00
Adrien Gallouët
2cb24c0523 Update mud 2017-01-16 16:11:18 +00:00
Adrien Gallouët
65be22202c Update mud 2017-01-12 13:26:35 +00:00
Adrien Gallouët
6cc32bafd9 Code cleanup 2017-01-12 13:26:23 +00:00
Adrien Gallouët
6c268e658f Reset default MTU to 1500 2017-01-06 13:17:46 +00:00
Adrien Gallouët
33e24632d0 Update mud 2017-01-06 11:50:31 +00:00
Adrien Gallouët
e1b4c6aafc Add debug.bin 2017-01-06 11:02:09 +00:00
Adrien Gallouët
09d1932588 Code cleanup 2017-01-06 10:16:13 +00:00
Adrien Gallouët
4988479df4 Drop packets with bad length (too small) 2017-01-05 16:45:14 +00:00
Adrien Gallouët
7779e61c15 Update mud 2017-01-04 14:37:51 +00:00
Adrien Gallouët
2cc8caec35 Don't try to send empty packet 2017-01-04 14:35:26 +00:00
Adrien Gallouët
8c8715187b Code cleanup 2017-01-04 14:27:55 +00:00
Adrien Gallouët
c591a4d3cc Drop too large packets 2017-01-04 14:15:18 +00:00
Adrien Gallouët
76cd7ed4b8 Don't handle errors in tun.c 2017-01-04 14:07:30 +00:00
22 changed files with 426 additions and 189 deletions

View File

@@ -1,15 +0,0 @@
#!/bin/sh
export CC="gcc -static"
git clone https://github.com/jedisct1/libsodium --depth=1 --branch stable
cd libsodium || exit 1
./autogen.sh && ./configure --enable-minimal --disable-shared --prefix=/usr && make install
cd ..
./autogen.sh && ./configure && make
[ -x glorytun ] || exit 1
mkdir -p deploy
strip -s glorytun
mv glorytun deploy/glorytun-$(cat VERSION)-$(uname -m).bin

2
.gitignore vendored
View File

@@ -11,3 +11,5 @@ build-aux
.deps .deps
.dirstamp .dirstamp
glorytun glorytun
build*
VERSION

View File

@@ -14,11 +14,10 @@ glorytun_SOURCES = \
src/option.h \ src/option.h \
src/tun.c \ src/tun.c \
src/tun.h \ src/tun.h \
src/iface.c \
src/iface.h \
src/db.c \ src/db.c \
src/db.h src/db.h \
glorytun_CFLAGS += -I$(srcdir)/mud
glorytun_SOURCES += \
mud/mud.h \ mud/mud.h \
mud/mud.c mud/mud.c
@@ -26,5 +25,13 @@ EXTRA_DIST = \
LICENSE \ LICENSE \
README.md \ README.md \
VERSION \ VERSION \
systemd/glorytun-client.network \
systemd/glorytun-run \
systemd/glorytun-setup \
systemd/glorytun.network \
systemd/glorytun@.service.in \
mud/LICENSE \
mud/README.md \
meson.build \
autogen.sh \ autogen.sh \
version.sh version.sh

View File

@@ -1,18 +1,53 @@
# π₁(Glorytun)=0 # Glorytun
Small, Simple and Stupid VPN over [mud](https://github.com/angt/mud). Small, Simple and Stupid VPN over [mud](https://github.com/angt/mud).
#### Build and Install ### Build and Install
Glorytun depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4. Glorytun depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4.
To build and install the latest version: On Ubuntu, the following command should be sufficient:
$ git clone https://github.com/angt/glorytun --recursive --branch mud $ sudo apt-get install meson libsodium-dev pkg-config
Grab the latest release from github:
$ git clone https://github.com/angt/glorytun --recursive
$ cd glorytun $ cd glorytun
$ ./autogen.sh
$ ./configure To build and install the latest version with [meson](http://mesonbuild.com):
$ make
# make install $ meson build
$ sudo ninja -C build install
The more classical autotools suite is also available.
### Easy setup with systemd
Just call `glorytun-setup` and follow the instructions.
First, setup the server:
$ sudo glorytun-setup
Config filename (tun0):
Server ip (enter for server conf):
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:
$ sudo glorytun-setup
Config filename (tun0):
Server ip (enter for server conf): SERVER_IP
Server key (enter to generate a new one): NEW_KEY
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
---
For feature requests and bug reports, please create an [issue](https://github.com/angt/glorytun/issues). For feature requests and bug reports, please create an [issue](https://github.com/angt/glorytun/issues).

View File

@@ -8,7 +8,7 @@ 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

49
meson.build Normal file
View File

@@ -0,0 +1,49 @@
project('glorytun', 'c',
version: run_command('./version.sh').stdout(),
license: 'BSD-3-Clause',
default_options : [ 'buildtype=debugoptimized' ]
)
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))
conf_data = configuration_data()
conf_data.set('prefix', prefix)
conf_data.set('bindir', bindir)
add_global_arguments('-DPACKAGE_VERSION="'+meson.project_version()+'"', language : 'c')
src = [
'src/common.c',
'src/iface.c',
'src/option.c',
'src/tun.c',
'mud/mud.c',
'src/main.c'
]
deps = [
dependency('libsodium', version : '>=1.0.4')
]
executable('glorytun', install: true, sources: src, dependencies: deps)
systemd = dependency('systemd', required: false)
if systemd.found()
systemdutildir = systemd.get_pkgconfig_variable('systemdutildir')
configure_file(
input: 'systemd/glorytun@.service.in',
output: 'glorytun@.service',
configuration: conf_data,
install_dir: join_paths(systemdutildir, 'system')
)
install_data('systemd/glorytun.network',
install_dir: join_paths(systemdutildir, 'network'))
install_data('systemd/glorytun-client.network',
install_dir: join_paths(systemdutildir, 'network'))
install_data('systemd/glorytun-run',
install_dir: bindir)
install_data('systemd/glorytun-setup',
install_dir: bindir)
endif

2
mud

Submodule mud updated: fd1a1285ac...13cf44c813

View File

@@ -26,23 +26,6 @@ gt_log(const char *fmt, ...)
va_end(ap); va_end(ap);
} }
void
gt_fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
void
gt_na(const char *name)
{
gt_log("%s is not available on your platform\n", name);
}
int int
gt_tohex(char *dst, size_t dst_size, const uint8_t *src, size_t src_size) gt_tohex(char *dst, size_t dst_size, const uint8_t *src, size_t src_size)
{ {

View File

@@ -37,8 +37,6 @@
int gt_print (const char *, ...) _printf_(1,2); int gt_print (const char *, ...) _printf_(1,2);
void gt_log (const char *, ...) _printf_(1,2); void gt_log (const char *, ...) _printf_(1,2);
void gt_fatal (const char *, ...) _printf_(1,2) _noreturn_;
void gt_na (const char *);
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);

30
src/iface.c Normal file
View File

@@ -0,0 +1,30 @@
#include "common.h"
#include "str.h"
#include "iface.h"
#include <sys/ioctl.h>
#include <net/if.h>
int
iface_set_mtu(char *dev_name, int mtu)
{
struct ifreq ifr = {
.ifr_mtu = mtu,
};
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1);
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
return -1;
int ret = ioctl(fd, SIOCSIFMTU, &ifr);
int err = errno;
close(fd);
errno = err;
return ret;
}

3
src/iface.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
int iface_set_mtu (char *, int);

View File

@@ -10,16 +10,17 @@ struct ip_common {
uint16_t size; uint16_t size;
}; };
_pure_ _pure_ static inline uint8_t
static inline uint8_t ip_get_version (const uint8_t *data, size_t size) ip_get_version(const uint8_t *data, size_t size)
{ {
if (size<20) if (size < 20)
return 0; return 0;
return data[0]>>4; return data[0] >> 4;
} }
static inline int ip_get_common (struct ip_common *ic, const uint8_t *data, size_t size) static inline int
ip_get_common(struct ip_common *ic, const uint8_t *data, size_t size)
{ {
ic->version = ip_get_version(data, size); ic->version = ip_get_version(data, size);
@@ -27,14 +28,16 @@ static inline int ip_get_common (struct ip_common *ic, const uint8_t *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; ic->hdr_size = (data[0] & 0xF) << 2;
ic->size = ((data[2]<<8)|data[3]); ic->size = ((data[2] << 8) | data[3]);
return 0; if (ic->size >= 20)
return 0;
break;
case 6: case 6:
ic->tc = ((data[0]&0xF)<<4)|(data[1]>>4); ic->tc = ((data[0] & 0xF) << 4) | (data[1] >> 4);
ic->proto = data[6]; ic->proto = data[6];
ic->hdr_size = 40; ic->hdr_size = 40;
ic->size = ((data[4]<<8)|data[5])+40; ic->size = ((data[4] << 8) | data[5]) + 40;
return 0; return 0;
} }

View File

@@ -5,6 +5,7 @@
#include "option.h" #include "option.h"
#include "str.h" #include "str.h"
#include "tun.h" #include "tun.h"
#include "iface.h"
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
@@ -14,20 +15,26 @@
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/time.h> #include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include "mud.h" #include "../mud/mud.h"
#ifndef O_CLOEXEC #ifndef O_CLOEXEC
#define O_CLOEXEC 0 #define O_CLOEXEC 0
#endif #endif
#define GT_MTU(X) ((X) - 28) #ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
#endif
#define GT_MTU(X) ((X)-28)
static struct { static struct {
volatile sig_atomic_t quit; volatile sig_atomic_t quit;
volatile sig_atomic_t reload;
char *dev; char *dev;
char *keyfile; char *keyfile;
char *host; char *host;
@@ -45,16 +52,26 @@ static struct {
int mtu_auto; int mtu_auto;
int chacha20; int chacha20;
int version; int version;
int keygen;
int persist;
struct {
unsigned char *data;
long size;
} buf;
} gt = { } gt = {
.port = 5000, .port = 5000,
.bind = { .bind = {
.port = 5000, .port = 5000,
}, },
.mtu = 1500,
.timeout = 5000, .timeout = 5000,
.ipv4 = 1, .ipv4 = 1,
#ifdef __linux__ #ifdef __linux__
.ipv6 = 1, .ipv6 = 1,
#endif #endif
.buf = {
.size = 64 * 1024,
},
}; };
static void static void
@@ -79,6 +96,7 @@ fd_set_nonblock(int fd)
static void static void
gt_quit_handler(int sig) gt_quit_handler(int sig)
{ {
gt.reload = (sig == SIGHUP);
gt.quit = 1; gt.quit = 1;
} }
@@ -95,9 +113,9 @@ gt_set_signal(void)
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);
sa.sa_handler = SIG_IGN; sa.sa_handler = SIG_IGN;
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL); sigaction(SIGPIPE, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGUSR2, &sa, NULL); sigaction(SIGUSR2, &sa, NULL);
@@ -115,7 +133,7 @@ gt_print_secretkey(struct mud *mud)
char buf[2 * sizeof(key) + 1]; char buf[2 * sizeof(key) + 1];
gt_tohex(buf, sizeof(buf), key, size); gt_tohex(buf, sizeof(buf), key, size);
gt_print("secret key: %s\n", buf); gt_print("%s\n", buf);
} }
static int static int
@@ -177,14 +195,17 @@ gt_setup_option(int argc, char **argv)
{ "bind-backup", &gt.bind.backup, option_str }, { "bind-backup", &gt.bind.backup, option_str },
{ "bind-port", &gt.bind.port, option_long }, { "bind-port", &gt.bind.port, option_long },
{ "dev", &gt.dev, option_str }, { "dev", &gt.dev, option_str },
{ "persist", NULL, option_option },
{ "mtu", &gt.mtu, option_long }, { "mtu", &gt.mtu, option_long },
{ "mtu-auto", NULL, option_option }, { "mtu-auto", NULL, option_option },
{ "keyfile", &gt.keyfile, option_str }, { "keyfile", &gt.keyfile, option_str },
{ "keygen", NULL, option_option },
{ "timeout", &gt.timeout, option_long }, { "timeout", &gt.timeout, option_long },
{ "time-tolerance", &gt.time_tolerance, option_long }, { "time-tolerance", &gt.time_tolerance, option_long },
{ "v4only", NULL, option_option }, { "v4only", NULL, option_option },
{ "v6only", NULL, option_option }, { "v6only", NULL, option_option },
{ "chacha20", NULL, option_option }, { "chacha20", NULL, option_option },
{ "buf-size", &gt.buf.size, option_long },
{ "version", NULL, option_option }, { "version", NULL, option_option },
{ NULL }, { NULL },
}; };
@@ -202,13 +223,13 @@ gt_setup_option(int argc, char **argv)
return 1; return 1;
} }
if (gt.host && !option_is_set(opts, "keyfile")) { if ((int)gt.timeout <= 0) {
gt_log("keyfile option must be set\n"); gt_log("bad timeout\n");
return 1; return 1;
} }
if ((int)gt.timeout <= 0) { if (gt.buf.size <= 0) {
gt_log("bad timeout\n"); gt_log("bad buf-size\n");
return 1; return 1;
} }
@@ -225,6 +246,10 @@ gt_setup_option(int argc, char **argv)
gt.mtu_auto = option_is_set(opts, "mtu-auto"); gt.mtu_auto = option_is_set(opts, "mtu-auto");
gt.chacha20 = option_is_set(opts, "chacha20"); gt.chacha20 = option_is_set(opts, "chacha20");
gt.version = option_is_set(opts, "version"); 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; return 0;
} }
@@ -241,7 +266,7 @@ gt_setup_mtu(struct mud *mud, char *tun_name)
gt_log("setup MTU to %i on interface %s\n", mtu, tun_name); gt_log("setup MTU to %i on interface %s\n", mtu, tun_name);
if (tun_set_mtu(tun_name, mtu) == -1) if (iface_set_mtu(tun_name, mtu) == -1)
perror("tun_set_mtu"); perror("tun_set_mtu");
} }
@@ -254,7 +279,7 @@ main(int argc, char **argv)
return 1; return 1;
if (gt.version) { if (gt.version) {
gt_print(PACKAGE_STRING "\n"); gt_print(PACKAGE_VERSION "\n");
return 0; return 0;
} }
@@ -267,6 +292,36 @@ main(int argc, char **argv)
gt_log("couldn't create ICMP socket\n"); 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) {
gt_print_secretkey(mud);
return 0;
}
if (!gt.chacha20 && mud_set_aes(mud))
gt_log("AES is not available\n");
if (gt.timeout > 0)
mud_set_send_timeout_msec(mud, gt.timeout);
if (gt.time_tolerance > 0)
mud_set_time_tolerance_sec(mud, gt.time_tolerance);
mud_set_mtu(mud, GT_MTU(gt.mtu));
char *tun_name = NULL; char *tun_name = NULL;
int tun_fd = tun_create(gt.dev, &tun_name); int tun_fd = tun_create(gt.dev, &tun_name);
@@ -276,26 +331,17 @@ main(int argc, char **argv)
return 1; return 1;
} }
struct mud *mud = mud_create(gt.bind.port, gt.ipv4, gt.ipv6, if (tun_set_persist(tun_fd, gt.persist) == -1)
!gt.chacha20, GT_MTU(gt.mtu)); perror("tun_set_persist");
if (!mud) {
gt_log("couldn't create mud\n");
return 1;
}
if (str_empty(gt.keyfile)) { if (str_empty(gt.keyfile)) {
gt_print("here is your new secret key:\n");
gt_print_secretkey(mud); gt_print_secretkey(mud);
} else { } else {
if (gt_setup_secretkey(mud, gt.keyfile)) if (gt_setup_secretkey(mud, gt.keyfile))
return 1; return 1;
} }
mud_set_send_timeout_msec(mud, gt.timeout);
if (gt.time_tolerance > 0)
mud_set_time_tolerance_sec(mud, gt.time_tolerance);
if (gt.host && gt.port) { if (gt.host && gt.port) {
if (gt.bind.backup) { if (gt.bind.backup) {
if (mud_peer(mud, gt.bind.backup, gt.host, gt.port, 1)) { if (mud_peer(mud, gt.bind.backup, gt.host, gt.port, 1)) {
@@ -344,8 +390,6 @@ main(int argc, char **argv)
fd_set rfds; fd_set rfds;
FD_ZERO(&rfds); FD_ZERO(&rfds);
unsigned char buf[8 * 1024];
int last_fd = 1 + MAX(tun_fd, MAX(mud_fd, icmp_fd)); int last_fd = 1 + MAX(tun_fd, MAX(mud_fd, icmp_fd));
while (!gt.quit) { while (!gt.quit) {
@@ -365,12 +409,12 @@ main(int argc, char **argv)
if (icmp_fd != -1 && FD_ISSET(icmp_fd, &rfds)) { if (icmp_fd != -1 && FD_ISSET(icmp_fd, &rfds)) {
struct sockaddr_storage ss; struct sockaddr_storage ss;
socklen_t sl = sizeof(ss); socklen_t sl = sizeof(ss);
ssize_t r = recvfrom(icmp_fd, buf, sizeof(buf), 0, ssize_t r = recvfrom(icmp_fd, gt.buf.data, gt.buf.size, 0,
(struct sockaddr *)&ss, &sl); (struct sockaddr *)&ss, &sl);
if (r >= 8) { if (r >= 8) {
struct ip_common ic; struct ip_common ic;
if (!ip_get_common(&ic, buf, r) && ic.proto == 1) { if (!ip_get_common(&ic, gt.buf.data, r) && ic.proto == 1) {
unsigned char *data = &buf[ic.hdr_size]; unsigned char *data = &gt.buf.data[ic.hdr_size];
if (data[0] == 3) { if (data[0] == 3) {
int mtu = (data[6] << 8) | data[7]; int mtu = (data[6] << 8) | data[7];
if (mtu) { if (mtu) {
@@ -385,15 +429,15 @@ main(int argc, char **argv)
if (FD_ISSET(tun_fd, &rfds)) { if (FD_ISSET(tun_fd, &rfds)) {
size_t size = 0; size_t size = 0;
while (sizeof(buf) - size > gt.mtu) { while (gt.buf.size - size >= gt.mtu) {
const ssize_t r = tun_read(tun_fd, &buf[size], const int r = tun_read(tun_fd, &gt.buf.data[size], gt.buf.size - size);
sizeof(buf) - size);
if (r <= 0) if (r <= 0 || r > gt.mtu)
break; break;
struct ip_common ic; struct ip_common ic;
if (ip_get_common(&ic, &buf[size], r) || ic.size != r) if (ip_get_common(&ic, &gt.buf.data[size], r) || ic.size != r)
break; break;
size += r; size += r;
@@ -408,11 +452,9 @@ main(int argc, char **argv)
while (q < size) { while (q < size) {
struct ip_common ic; struct ip_common ic;
if ((ip_get_common(&ic, &buf[q], size - q)) || if ((ip_get_common(&ic, &gt.buf.data[q], size - q)) ||
(ic.size > size - q)) { (ic.size > size - q))
size = q;
break; break;
}
if (q + ic.size > p + gt.mtu) if (q + ic.size > p + gt.mtu)
break; break;
@@ -423,7 +465,10 @@ main(int argc, char **argv)
tc = ic.tc & 0xFC; tc = ic.tc & 0xFC;
} }
int r = mud_send(mud, &buf[p], q - p, tc); if (p >= q)
break;
int r = mud_send(mud, &gt.buf.data[p], q - p, tc);
if (r == -1 && errno == EMSGSIZE) { if (r == -1 && errno == EMSGSIZE) {
gt_setup_mtu(mud, tun_name); gt_setup_mtu(mud, tun_name);
@@ -437,31 +482,40 @@ main(int argc, char **argv)
} }
if (FD_ISSET(mud_fd, &rfds)) { if (FD_ISSET(mud_fd, &rfds)) {
while (1) { size_t size = 0;
const int size = mud_recv(mud, buf, sizeof(buf));
if (size <= 0) { while (gt.buf.size - size >= gt.mtu) {
if (size == -1 && errno != EAGAIN) 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"); perror("mud_recv");
break; break;
} }
int p = 0; size += r;
}
while (p < size) { int p = 0;
struct ip_common ic;
if ((ip_get_common(&ic, &buf[p], size - p)) || while (p < size) {
(ic.size > size - p)) struct ip_common ic;
break;
tun_write(tun_fd, &buf[p], ic.size); if ((ip_get_common(&ic, &gt.buf.data[p], size - p)) ||
(ic.size > size - p))
break;
p += ic.size; 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; return 0;
} }

View File

@@ -2,14 +2,15 @@
#include "common.h" #include "common.h"
static inline size_t str_cpy (char *restrict dst, const char *restrict src, size_t len) static inline size_t
str_cpy(char *restrict dst, const char *restrict src, size_t len)
{ {
if (!dst || !src) if (!dst || !src)
return 0; return 0;
size_t i; size_t i;
for (i=0; i<len && src[i]; i++) for (i = 0; i < len && src[i]; i++)
dst[i] = src[i]; dst[i] = src[i];
dst[i] = 0; dst[i] = 0;
@@ -17,29 +18,29 @@ static inline size_t str_cpy (char *restrict dst, const char *restrict src, size
return i; return i;
} }
_pure_ _pure_ static inline int
static inline int str_empty (const char *restrict str) str_empty(const char *restrict str)
{ {
return !str || !str[0]; return !str || !str[0];
} }
_pure_ _pure_ static inline size_t
static inline size_t str_cmp (const char *restrict sa, const char *restrict sb) str_cmp(const char *restrict sa, const char *restrict sb)
{ {
if (!sa || !sb) if (!sa || !sb)
return 1; return 1;
size_t i = 0; size_t i = 0;
while (sa[i]==sb[i]) while (sa[i] == sb[i])
if (!sa[i++]) if (!sa[i++])
return 0; return 0;
return i+1; return i + 1;
} }
_pure_ _pure_ static inline size_t
static inline size_t str_len (const char *restrict str) str_len(const char *restrict str)
{ {
if (!str) if (!str)
return 0; return 0;
@@ -47,11 +48,12 @@ static inline size_t str_len (const char *restrict str)
return strlen(str); return strlen(str);
} }
static inline char *str_cat (const char **strs, size_t count) static inline char *
str_cat(const char **strs, size_t count)
{ {
size_t size = 1; size_t size = 1;
for (size_t i=0; i<count; i++) for (size_t i = 0; i < count; i++)
size += str_len(strs[i]); size += str_len(strs[i]);
char *str = malloc(size); char *str = malloc(size);
@@ -61,7 +63,7 @@ static inline char *str_cat (const char **strs, size_t count)
char *p = str; char *p = str;
for (size_t i=0; i<count; i++) { for (size_t i = 0; i < count; i++) {
size_t len = str_len(strs[i]); size_t len = str_len(strs[i]);
memcpy(p, strs[i], len); memcpy(p, strs[i], len);
p += len; p += len;

View File

@@ -17,6 +17,7 @@
#define IFF_TUN 0x0001 #define IFF_TUN 0x0001
#define IFF_NO_PI 0x1000 #define IFF_NO_PI 0x1000
#define TUNSETIFF _IOW('T', 202, int) #define TUNSETIFF _IOW('T', 202, int)
#define TUNSETPERSIST _IOW('T', 203, int)
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
@@ -45,7 +46,9 @@ tun_create_by_id(char *name, size_t size, unsigned id)
str_cpy(ci.ctl_name, UTUN_CONTROL_NAME, sizeof(ci.ctl_name) - 1); 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;
close(fd); close(fd);
errno = err;
return -1; return -1;
} }
@@ -58,7 +61,9 @@ tun_create_by_id(char *name, size_t size, unsigned id)
}; };
if (connect(fd, (struct sockaddr *)&sc, sizeof(sc))) { if (connect(fd, (struct sockaddr *)&sc, sizeof(sc))) {
int err = errno;
close(fd); close(fd);
errno = err;
return -1; return -1;
} }
@@ -72,8 +77,10 @@ tun_create_by_name(char *name, size_t size, char *dev_name)
{ {
unsigned id = 0; unsigned id = 0;
if (sscanf(dev_name, "utun%u", &id) != 1) if (sscanf(dev_name, "utun%u", &id) != 1) {
errno = EINVAL;
return -1; return -1;
}
return tun_create_by_id(name, size, id); return tun_create_by_id(name, size, id);
} }
@@ -152,11 +159,11 @@ tun_create(char *dev_name, char **ret_name)
return fd; return fd;
} }
ssize_t int
tun_read(int fd, void *data, size_t size) tun_read(int fd, void *data, size_t size)
{ {
if (!size) if (!size)
return -1; return 0;
#ifdef GT_BSD_TUN #ifdef GT_BSD_TUN
uint32_t family; uint32_t family;
@@ -173,35 +180,24 @@ tun_read(int fd, void *data, size_t size)
}; };
ssize_t ret = readv(fd, iov, 2); ssize_t ret = readv(fd, iov, 2);
#else
ssize_t ret = read(fd, data, size);
#endif
if (ret == -1) { if (ret <= (ssize_t)0)
if (errno == EAGAIN || errno == EINTR) return ret;
return -1;
if (errno) if (ret <= (ssize_t)sizeof(family))
perror("tun read");
return 0;
}
#ifdef GT_BSD_TUN
if (ret < (ssize_t)sizeof(family))
return 0; return 0;
return ret - sizeof(family); return ret - sizeof(family);
#else #else
return ret; return read(fd, data, size);
#endif #endif
} }
ssize_t int
tun_write(int fd, const void *data, size_t size) tun_write(int fd, const void *data, size_t size)
{ {
if (!size) if (!size)
return -1; return 0;
#ifdef GT_BSD_TUN #ifdef GT_BSD_TUN
uint32_t family; uint32_t family;
@@ -214,6 +210,7 @@ tun_write(int fd, const void *data, size_t size)
family = htonl(AF_INET6); family = htonl(AF_INET6);
break; break;
default: default:
errno = EINVAL;
return -1; return -1;
} }
@@ -229,49 +226,26 @@ tun_write(int fd, const void *data, size_t size)
}; };
ssize_t ret = writev(fd, iov, 2); ssize_t ret = writev(fd, iov, 2);
#else
ssize_t ret = write(fd, data, size);
#endif
if (ret == -1) { if (ret <= (ssize_t)0)
if (errno == EAGAIN || errno == EINTR) return ret;
return -1;
if (errno) if (ret <= (ssize_t)sizeof(family))
perror("tun write");
return 0;
}
#ifdef GT_BSD_TUN
if (ret < (ssize_t)sizeof(family))
return 0; return 0;
return ret - sizeof(family); return ret - sizeof(family);
#else #else
return ret; return write(fd, data, size);
#endif #endif
} }
int int
tun_set_mtu(char *dev_name, int mtu) tun_set_persist(int fd, int on)
{ {
struct ifreq ifr = { #ifdef TUNSETPERSIST
.ifr_mtu = mtu, return ioctl(fd, TUNSETPERSIST, on);
}; #else
errno = ENOSYS;
str_cpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1); return -1;
#endif
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
return -1;
int ret = ioctl(fd, SIOCSIFMTU, &ifr);
int err = errno;
close(fd);
errno = err;
return ret;
} }

View File

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

View File

@@ -0,0 +1,10 @@
[Match]
Name=gtc-*
[Network]
Description=Glorytun client device
DHCP=ipv4
[DHCP]
CriticalConnection=yes
RouteTable=200

37
systemd/glorytun-run Executable file
View File

@@ -0,0 +1,37 @@
#!/bin/sh
set -e
if [ ! -f "$1" ]; then
echo "usage: $(basename "$0") FILE"
exit 1
fi
. "$(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" ]; then
if [ -z "$PREF" ]; then
PREF=$(ip rule | awk '/from all lookup main/{print $1; exit}' | tr -d :)
PREF=$((PREF-1))
fi
if [ -z "$BIND" ]; then
BIND=$(ip route get "$HOST" | awk '/src/{getline;print $0}' RS=' ')
ip rule add from "$BIND" table main pref "$((PREF-1))" || true
fi
ip rule add from all table 200 pref "$PREF" || true
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}

41
systemd/glorytun-setup Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/sh
set -e
_ask() {
printf "%s: " "$1"
read -r "$2"
}
_ask "Config filename (tun0)" NAME
NAME=${NAME:-tun0}
if [ -f /etc/glorytun/"$NAME" ]; then
echo "This config already exit!"
exit 1
fi
_ask "Server ip (enter for server conf)" HOST
_ask "Server key (enter to generate a new one)" KEY
if [ -z "$KEY" ]; then
KEY=$(glorytun keygen)
echo "Your new key: $KEY"
fi
# install files
mkdir -p /etc/glorytun
cat > /etc/glorytun/"$NAME" <<EOF
${HOST:+HOST="$HOST"}
MTU_AUTO=yes
EOF
( umask 077; echo "$KEY" > /etc/glorytun/"$NAME".key )
# start services
_ask "Start glorytun now ? (enter to skip)" START
case "$START" in y*|Y*)
systemctl restart systemd-networkd
systemctl start glorytun@"$NAME" ;;
esac

14
systemd/glorytun.network Normal file
View File

@@ -0,0 +1,14 @@
[Match]
Name=gt-*
[Network]
Description=Glorytun server device
Address=0.0.0.0/24
DHCPServer=yes
IPMasquerade=yes
[DHCPServer]
PoolOffset=2
PoolSize=1
EmitDNS=yes
DNS=9.9.9.9

View File

@@ -0,0 +1,12 @@
[Unit]
Description=Glorytun on %I
After=network.target
[Service]
Type=simple
Restart=always
ExecStart=@bindir@/glorytun-run /etc/glorytun/%i
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
[Install]
WantedBy=multi-user.target