Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bd936929e | ||
|
|
289d88f3a7 | ||
|
|
1673110de1 | ||
|
|
1ce919c1e5 | ||
|
|
e19fcaa2b0 | ||
|
|
104fb37075 | ||
|
|
6787e90be7 | ||
|
|
639853b665 | ||
|
|
57ea0d283d | ||
|
|
0c82c06119 | ||
|
|
65f636555b | ||
|
|
c93cef5491 | ||
|
|
1fed2813e5 | ||
|
|
860651d02f | ||
|
|
fd7ddf7814 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
*.o
|
*.[ios]
|
||||||
*.log
|
*.log
|
||||||
*.scan
|
*.scan
|
||||||
*.cache
|
*.cache
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -19,7 +19,7 @@ SRC := argz/argz.c mud/mud.c mud/aegis256/aegis256.c $(wildcard src/*.c)
|
|||||||
.PHONY: $(NAME)
|
.PHONY: $(NAME)
|
||||||
$(NAME):
|
$(NAME):
|
||||||
@echo "Building $(NAME)"
|
@echo "Building $(NAME)"
|
||||||
@$(CC) $(FLAGS) -o $(NAME) $(SRC) -lsodium -lm
|
@$(CC) $(FLAGS) -o $(NAME) $(SRC) -lsodium
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: $(NAME)
|
install: $(NAME)
|
||||||
|
|||||||
39
README.md
39
README.md
@@ -11,6 +11,7 @@ Linux is the platform of choice but the code is standard so it should be easily
|
|||||||
It was successfully tested on OpenBSD, FreeBSD and MacOS.
|
It was successfully tested on OpenBSD, FreeBSD and MacOS.
|
||||||
|
|
||||||
IPv4 and IPv6 are supported.
|
IPv4 and IPv6 are supported.
|
||||||
|
On Linux you can have both at the same time by binding `::`.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -18,17 +19,16 @@ The key features of Glorytun come directly from mud:
|
|||||||
|
|
||||||
* **Fast and highly secure**
|
* **Fast and highly secure**
|
||||||
|
|
||||||
The use of UDP and [libsodium](https://github.com/jedisct1/libsodium) allows you to secure
|
The use of UDP and libsodium allows you to secure your communications without impacting performance.
|
||||||
your communications without impacting performance.
|
Glorytun uses AEGIS-256 (a new and very fast AEAD construction) only if AES-NI is available otherwise ChaCha20-Poly1305 is used.
|
||||||
Glorytun uses AEGIS-256 only if AES-NI is available otherwise ChaCha20Poly1305 is used.
|
Of course, you can force the use of ChaCha20-Poly1305 for higher security.
|
||||||
If you are not cpu bounded, you can force the use of ChaCha20Poly1305 for higher security.
|
All messages are encrypted, authenticated and timestamped to mitigate a large set of attacks.
|
||||||
All messages are encrypted, authenticated and marked with a timestamp.
|
Perfect forward secrecy is also implemented with ECDH over Curve25519. Keys are rotated every hours.
|
||||||
Perfect forward secrecy is also implemented with ECDH over Curve25519.
|
|
||||||
|
|
||||||
* **Multipath and active failover**
|
* **Multipath and active failover**
|
||||||
|
|
||||||
This is the main feature of Glorytun that allows to build an SD-WAN like service.
|
Connectivity is now crucial, especially in the SD-WAN world.
|
||||||
This allows a TCP connection to explore and exploit multiple links without being disconnected.
|
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.
|
Aggregation should work on all conventional links, only very high latency (+500ms) links are not recommended for now.
|
||||||
|
|
||||||
* **Traffic shaping**
|
* **Traffic shaping**
|
||||||
@@ -41,7 +41,7 @@ The key features of Glorytun come directly from mud:
|
|||||||
|
|
||||||
Bad MTU configuration is a very common problem in the world of VPN.
|
Bad MTU configuration is a very common problem in the world of VPN.
|
||||||
As it is critical, Glorytun will try to setup it correctly by guessing its value.
|
As it is critical, Glorytun will try to setup it correctly by guessing its value.
|
||||||
It doesn't rely on ICMP Next-hop MTU to avoid black holes.
|
It doesn't rely on Next-hop MTU to avoid ICMP black holes.
|
||||||
In asymmetric situations the minimum MTU is selected.
|
In asymmetric situations the minimum MTU is selected.
|
||||||
|
|
||||||
## Caveats
|
## Caveats
|
||||||
@@ -71,19 +71,16 @@ The more classical autotools suite is also available.
|
|||||||
|
|
||||||
Just run `glorytun` with no arguments to view the list of available commands:
|
Just run `glorytun` with no arguments to view the list of available commands:
|
||||||
|
|
||||||
```
|
$ glorytun
|
||||||
$ glorytun
|
available commands:
|
||||||
available commands:
|
|
||||||
|
|
||||||
show show tunnel info
|
show show tunnel info
|
||||||
bench start a crypto bench
|
bench start a crypto bench
|
||||||
bind start a new tunnel
|
bind start a new tunnel
|
||||||
set change tunnel properties
|
set change tunnel properties
|
||||||
keygen generate a new secret key
|
keygen generate a new secret key
|
||||||
path manage paths
|
path manage paths
|
||||||
version show version
|
version show version
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Use the keyword `help` after a command to show its usage.
|
Use the keyword `help` after a command to show its usage.
|
||||||
|
|
||||||
|
|||||||
2
argz
2
argz
Submodule argz updated: 47ad9daf43...ff7bc660e2
@@ -14,7 +14,6 @@ AM_PROG_CC_C_O
|
|||||||
AC_PROG_CC_C99
|
AC_PROG_CC_C99
|
||||||
AC_USE_SYSTEM_EXTENSIONS
|
AC_USE_SYSTEM_EXTENSIONS
|
||||||
AC_SEARCH_LIBS([socket], [socket])
|
AC_SEARCH_LIBS([socket], [socket])
|
||||||
AC_SEARCH_LIBS([fmin], [m])
|
|
||||||
AC_CHECK_LIB([rt], [clock_gettime])
|
AC_CHECK_LIB([rt], [clock_gettime])
|
||||||
AC_CHECK_FUNCS([clock_gettime])
|
AC_CHECK_FUNCS([clock_gettime])
|
||||||
PKG_CHECK_MODULES([libsodium], [libsodium >= 1.0.4])
|
PKG_CHECK_MODULES([libsodium], [libsodium >= 1.0.4])
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ executable('glorytun', install: true,
|
|||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('libsodium', version : '>=1.0.4'),
|
dependency('libsodium', version : '>=1.0.4'),
|
||||||
cc.find_library('m', required : false)
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
mud
2
mud
Submodule mud updated: b59ab48407...d0dc6076c8
132
src/bench.c
132
src/bench.c
@@ -1,74 +1,34 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#if defined __APPLE__
|
|
||||||
#include <mach/mach_time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../argz/argz.h"
|
#include "../argz/argz.h"
|
||||||
#include "../mud/aegis256/aegis256.h"
|
#include "../mud/aegis256/aegis256.h"
|
||||||
|
|
||||||
#define STR_S(X) (((X) > 1) ? "s" : "")
|
|
||||||
|
|
||||||
#define NPUBBYTES 32
|
#define NPUBBYTES 32
|
||||||
#define KEYBYTES 32
|
#define KEYBYTES 32
|
||||||
#define ABYTES 16
|
#define ABYTES 16
|
||||||
|
|
||||||
static unsigned long long
|
|
||||||
gt_now(void)
|
|
||||||
{
|
|
||||||
#if defined __APPLE__
|
|
||||||
static mach_timebase_info_data_t mtid;
|
|
||||||
if (!mtid.denom)
|
|
||||||
mach_timebase_info(&mtid);
|
|
||||||
return (mach_absolute_time() * mtid.numer / mtid.denom) / 1000ULL;
|
|
||||||
#elif defined CLOCK_MONOTONIC
|
|
||||||
struct timespec tv;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &tv);
|
|
||||||
return (unsigned long long)tv.tv_sec * 1000000ULL
|
|
||||||
+ (unsigned long long)tv.tv_nsec / 1000ULL;
|
|
||||||
#else
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
return (unsigned long long)tv.tv_sec * 1000000ULL
|
|
||||||
+ (unsigned long long)tv.tv_usec;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
gt_bench(int argc, char **argv)
|
gt_bench(int argc, char **argv)
|
||||||
{
|
{
|
||||||
unsigned long precision = 10;
|
|
||||||
size_t bufsize = 64 * 1024;
|
|
||||||
unsigned long duration = 1000;
|
|
||||||
|
|
||||||
struct argz bench_argz[] = {
|
struct argz bench_argz[] = {
|
||||||
{"aes|chacha", NULL, NULL, argz_option},
|
{"aes|chacha", NULL, NULL, argz_option},
|
||||||
{"precision", "EXPONENT", &precision, argz_ulong},
|
|
||||||
{"bufsize", "BYTES", &bufsize, argz_bytes},
|
|
||||||
{"duration", "SECONDS", &duration, argz_time},
|
|
||||||
{NULL}};
|
{NULL}};
|
||||||
|
|
||||||
if (argz(bench_argz, argc, argv))
|
if (argz(bench_argz, argc, argv))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (duration == 0 || bufsize == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (sodium_init() == -1) {
|
if (sodium_init() == -1) {
|
||||||
gt_log("sodium init failed\n");
|
gt_log("sodium init failed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
duration /= 1000;
|
|
||||||
|
|
||||||
int term = isatty(1);
|
int term = isatty(1);
|
||||||
int aes = argz_is_set(bench_argz, "aes");
|
int aes = argz_is_set(bench_argz, "aes");
|
||||||
int chacha = argz_is_set(bench_argz, "chacha");
|
int chacha = argz_is_set(bench_argz, "chacha");
|
||||||
@@ -81,71 +41,65 @@ gt_bench(int argc, char **argv)
|
|||||||
chacha = 1;
|
chacha = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *buf = calloc(1, bufsize + ABYTES);
|
unsigned char buf[1450 + ABYTES];
|
||||||
|
|
||||||
if (!buf) {
|
|
||||||
perror("calloc");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char npub[NPUBBYTES];
|
unsigned char npub[NPUBBYTES];
|
||||||
unsigned char key[KEYBYTES];
|
unsigned char key[KEYBYTES];
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
randombytes_buf(npub, sizeof(npub));
|
randombytes_buf(npub, sizeof(npub));
|
||||||
randombytes_buf(key, sizeof(key));
|
randombytes_buf(key, sizeof(key));
|
||||||
|
|
||||||
if (term) {
|
if (term) {
|
||||||
printf("\n");
|
printf("cipher: %s\n\n", GT_CIPHER(chacha));
|
||||||
printf(" %-10s %s\n", "bench", chacha ? "chacha20poly1305" : "aegis256");
|
printf(" size min mean max \n");
|
||||||
printf(" %-10s %s\n", "libsodium", sodium_version_string());
|
printf("----------------------------------------------------\n");
|
||||||
printf("\n");
|
|
||||||
printf(" %-10s 2^(-%lu)\n", "precision", precision);
|
|
||||||
printf(" %-10s %zu byte%s\n", "bufsize", bufsize, STR_S(bufsize));
|
|
||||||
printf(" %-10s %lu second%s\n", "duration", duration, STR_S(duration));
|
|
||||||
printf("\n");
|
|
||||||
printf("------------------------------------------------------------\n");
|
|
||||||
printf(" %3s %9s %14s %14s %14s\n", "2^n", "min", "avg", "max", "delta");
|
|
||||||
printf("------------------------------------------------------------\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; !gt_quit && bufsize >> i; i++) {
|
int64_t size = 20;
|
||||||
unsigned long long total_dt = 0ULL;
|
|
||||||
size_t total_bytes = 0;
|
|
||||||
double mbps = 0.0;
|
|
||||||
double mbps_min = INFINITY;
|
|
||||||
double mbps_max = 0.0;
|
|
||||||
double mbps_dlt = INFINITY;
|
|
||||||
|
|
||||||
while (!gt_quit && mbps_dlt > ldexp(mbps, -(int)precision)) {
|
for (int i = 0; !gt_quit && size <= 1450; i++) {
|
||||||
unsigned long long now = gt_now();
|
struct {
|
||||||
double mbps_old = mbps;
|
int64_t min, mean, max, n;
|
||||||
size_t bytes = 0;
|
} mbps = { .n = 0 };
|
||||||
|
|
||||||
gt_alarm = 0;
|
int64_t bytes_max = (int64_t)1 << 24;
|
||||||
alarm((unsigned int)duration);
|
|
||||||
|
|
||||||
while (!gt_quit && !gt_alarm) {
|
while (!gt_quit && mbps.n < 10) {
|
||||||
|
int64_t bytes = 0;
|
||||||
|
int64_t base = (int64_t)clock();
|
||||||
|
|
||||||
|
while (!gt_quit && bytes <= bytes_max) {
|
||||||
if (chacha) {
|
if (chacha) {
|
||||||
crypto_aead_chacha20poly1305_encrypt(
|
crypto_aead_chacha20poly1305_encrypt(
|
||||||
buf, NULL, buf, 1ULL << i, NULL, 0, NULL, npub, key);
|
buf, NULL, buf, size, NULL, 0, NULL, npub, key);
|
||||||
} else {
|
} else {
|
||||||
aegis256_encrypt(
|
aegis256_encrypt(buf, NULL, buf, size, NULL, 0, npub, key);
|
||||||
buf, NULL, buf, 1ULL << i, NULL, 0, npub, key);
|
|
||||||
}
|
}
|
||||||
bytes += 1ULL << i;
|
bytes += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_dt += gt_now() - now;
|
int64_t dt = (int64_t)clock() - base;
|
||||||
total_bytes += bytes;
|
bytes_max = (bytes * (CLOCKS_PER_SEC / 3)) / dt;
|
||||||
|
int64_t _mbps = (8 * bytes * CLOCKS_PER_SEC) / (dt * 1000 * 1000);
|
||||||
|
|
||||||
mbps = ((double)total_bytes * 8.0) / (double)total_dt;
|
if (!mbps.n++) {
|
||||||
mbps_min = fmin(mbps_min, mbps);
|
mbps.min = _mbps;
|
||||||
mbps_max = fmax(mbps_max, mbps);
|
mbps.max = _mbps;
|
||||||
mbps_dlt = fabs(mbps_old - 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) {
|
if (term) {
|
||||||
printf("\r %3i %9.2f Mbps %9.2f Mbps %9.2f Mbps %9.2e",
|
printf("\r %5"PRIi64" %9"PRIi64" Mbps %9"PRIi64" Mbps %9"PRIi64" Mbps",
|
||||||
i, mbps_min, mbps, mbps_max, mbps_dlt);
|
size, mbps.min, mbps.mean, mbps.max);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,12 +107,12 @@ gt_bench(int argc, char **argv)
|
|||||||
if (term) {
|
if (term) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
} else {
|
} else {
|
||||||
printf("%i %.2f %.2f %.2f\n", i, mbps_min, mbps, mbps_max);
|
printf("bench %s %"PRIi64" %"PRIi64" %"PRIi64" %"PRIi64"\n",
|
||||||
|
GT_CIPHER(chacha), size, mbps.min, mbps.mean, mbps.max);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
size += 2 * 5 * 13;
|
||||||
free(buf);
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,6 +370,10 @@ gt_bind(int argc, char **argv)
|
|||||||
res.status.bind = bind_addr;
|
res.status.bind = bind_addr;
|
||||||
res.status.peer = peer_addr;
|
res.status.peer = peer_addr;
|
||||||
break;
|
break;
|
||||||
|
case CTL_BAD:
|
||||||
|
if (mud_get_bad(mud, &res.bad))
|
||||||
|
res.ret = errno;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (sendto(ctl_fd, &res, sizeof(res), 0,
|
if (sendto(ctl_fd, &res, sizeof(res), 0,
|
||||||
(const struct sockaddr *)&ss, sl) == -1)
|
(const struct sockaddr *)&ss, sl) == -1)
|
||||||
|
|||||||
@@ -54,6 +54,8 @@
|
|||||||
#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; })
|
||||||
|
|
||||||
|
#define GT_CIPHER(x) ((x) ? "chacha20poly1305" : "aegis256")
|
||||||
|
|
||||||
extern volatile sig_atomic_t gt_alarm;
|
extern volatile sig_atomic_t gt_alarm;
|
||||||
extern volatile sig_atomic_t gt_reload;
|
extern volatile sig_atomic_t gt_reload;
|
||||||
extern volatile sig_atomic_t gt_quit;
|
extern volatile sig_atomic_t gt_quit;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum ctl_type {
|
|||||||
CTL_KXTIMEOUT,
|
CTL_KXTIMEOUT,
|
||||||
CTL_TIMETOLERANCE,
|
CTL_TIMETOLERANCE,
|
||||||
CTL_PATH_STATUS,
|
CTL_PATH_STATUS,
|
||||||
|
CTL_BAD,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ctl_msg {
|
struct ctl_msg {
|
||||||
@@ -37,6 +38,7 @@ struct ctl_msg {
|
|||||||
struct sockaddr_storage bind;
|
struct sockaddr_storage bind;
|
||||||
struct sockaddr_storage peer;
|
struct sockaddr_storage peer;
|
||||||
} status;
|
} status;
|
||||||
|
struct mud_bad bad;
|
||||||
size_t mtu;
|
size_t mtu;
|
||||||
int tc;
|
int tc;
|
||||||
unsigned long ms;
|
unsigned long ms;
|
||||||
|
|||||||
49
src/path.c
49
src/path.c
@@ -34,27 +34,26 @@ gt_path_print_status(struct mud_path *path, int term)
|
|||||||
const char *statusstr = path->ok ? "OK" : "DEGRADED";
|
const char *statusstr = path->ok ? "OK" : "DEGRADED";
|
||||||
|
|
||||||
printf(term ? "path %s\n"
|
printf(term ? "path %s\n"
|
||||||
" status: %s\n"
|
" status: %s\n"
|
||||||
" bind: %s port %"PRIu16"\n"
|
" bind: %s port %"PRIu16"\n"
|
||||||
" public: %s port %"PRIu16"\n"
|
" public: %s port %"PRIu16"\n"
|
||||||
" peer: %s port %"PRIu16"\n"
|
" peer: %s port %"PRIu16"\n"
|
||||||
" mtu: %zu bytes\n"
|
" mtu: %zu bytes\n"
|
||||||
" rtt: %.3f ms\n"
|
" rtt: %.3f ms\n"
|
||||||
" rttvar: %.3f ms\n"
|
" rttvar: %.3f ms\n"
|
||||||
" rate tx: %"PRIu64" bytes/sec\n"
|
" tx:\n"
|
||||||
" rate rx: %"PRIu64" bytes/sec\n"
|
" rate: %"PRIu64" bytes/sec\n"
|
||||||
" total tx: %"PRIu64" packets\n"
|
" loss: %"PRIu64" percent\n"
|
||||||
" total rx: %"PRIu64" packets\n"
|
" total: %"PRIu64" packets\n"
|
||||||
|
" rx:\n"
|
||||||
|
" rate: %"PRIu64" bytes/sec\n"
|
||||||
|
" loss: %"PRIu64" percent\n"
|
||||||
|
" total: %"PRIu64" packets\n"
|
||||||
: "path %s %s"
|
: "path %s %s"
|
||||||
" %s %"PRIu16
|
" %s %"PRIu16" %s %"PRIu16" %s %"PRIu16
|
||||||
" %s %"PRIu16
|
" %zu %.3f %.3f"
|
||||||
" %s %"PRIu16
|
" %"PRIu64" %"PRIu64" %"PRIu64
|
||||||
" %zu"
|
" %"PRIu64" %"PRIu64" %"PRIu64
|
||||||
" %.3f %.3f"
|
|
||||||
" %"PRIu64
|
|
||||||
" %"PRIu64
|
|
||||||
" %"PRIu64
|
|
||||||
" %"PRIu64
|
|
||||||
"\n",
|
"\n",
|
||||||
statestr,
|
statestr,
|
||||||
statusstr,
|
statusstr,
|
||||||
@@ -67,10 +66,12 @@ gt_path_print_status(struct mud_path *path, int term)
|
|||||||
path->mtu.ok,
|
path->mtu.ok,
|
||||||
(double)path->rtt.val / 1e3,
|
(double)path->rtt.val / 1e3,
|
||||||
(double)path->rtt.var / 1e3,
|
(double)path->rtt.var / 1e3,
|
||||||
path->rate_tx,
|
path->tx.rate,
|
||||||
path->rate_rx,
|
path->tx.loss,
|
||||||
path->send.total,
|
path->tx.total,
|
||||||
path->recv.total);
|
path->rx.rate,
|
||||||
|
path->rx.loss,
|
||||||
|
path->rx.total);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|||||||
50
src/show.c
50
src/show.c
@@ -11,6 +11,47 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.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
|
static int
|
||||||
gt_show_status(int fd)
|
gt_show_status(int fd)
|
||||||
{
|
{
|
||||||
@@ -47,7 +88,7 @@ gt_show_status(int fd)
|
|||||||
bindstr[0] ? bindstr : "-",
|
bindstr[0] ? bindstr : "-",
|
||||||
gt_get_port((struct sockaddr *)&res.status.bind),
|
gt_get_port((struct sockaddr *)&res.status.bind),
|
||||||
res.status.mtu,
|
res.status.mtu,
|
||||||
res.status.chacha ? "chacha20poly1305" : "aes256gcm");
|
GT_CIPHER(res.status.chacha));
|
||||||
} else {
|
} else {
|
||||||
printf(term ? "client %s:\n"
|
printf(term ? "client %s:\n"
|
||||||
" pid: %li\n"
|
" pid: %li\n"
|
||||||
@@ -69,7 +110,7 @@ gt_show_status(int fd)
|
|||||||
peerstr[0] ? peerstr : "-",
|
peerstr[0] ? peerstr : "-",
|
||||||
gt_get_port((struct sockaddr *)&res.status.peer),
|
gt_get_port((struct sockaddr *)&res.status.peer),
|
||||||
res.status.mtu,
|
res.status.mtu,
|
||||||
res.status.chacha ? "chacha20poly1305" : "aes256gcm");
|
GT_CIPHER(res.status.chacha));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -82,6 +123,7 @@ gt_show(int argc, char **argv)
|
|||||||
|
|
||||||
struct argz showz[] = {
|
struct argz showz[] = {
|
||||||
{"dev", "NAME", &dev, argz_str},
|
{"dev", "NAME", &dev, argz_str},
|
||||||
|
{"bad", NULL, NULL, argz_option},
|
||||||
{NULL}};
|
{NULL}};
|
||||||
|
|
||||||
if (argz(showz, argc, argv))
|
if (argz(showz, argc, argv))
|
||||||
@@ -106,7 +148,9 @@ gt_show(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = gt_show_status(fd);
|
int ret = argz_is_set(showz, "bad")
|
||||||
|
? gt_show_bad(fd)
|
||||||
|
: gt_show_status(fd);
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
perror("show");
|
perror("show");
|
||||||
|
|||||||
Reference in New Issue
Block a user