diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-07-08 02:30:03 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-07-08 02:43:33 +0200 |
commit | fc743caf3bcc45da705ac10b656279558db28955 (patch) | |
tree | 57a6ede75fbcf4943d727ef7dd218990d6e7097d /src | |
parent | go test: don't rely on undefined append behavior (diff) | |
download | wireguard-tools-fc743caf3bcc45da705ac10b656279558db28955.tar.xz wireguard-tools-fc743caf3bcc45da705ac10b656279558db28955.zip |
persistent keepalive: add userspace support
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/config.c | 30 | ||||
-rw-r--r-- | src/set.c | 2 | ||||
-rw-r--r-- | src/show.c | 46 | ||||
-rw-r--r-- | src/showconf.c | 3 |
4 files changed, 70 insertions, 11 deletions
diff --git a/src/config.c b/src/config.c index 9066178..c24aa87 100644 --- a/src/config.c +++ b/src/config.c @@ -182,6 +182,27 @@ static inline bool parse_endpoint(struct sockaddr_storage *endpoint, const char return true; } +static inline bool parse_persistent_keepalive(__u16 *interval, const char *value) +{ + unsigned long ret; + char *end; + + if (!strcasecmp(value, "off")) { + *interval = 0; + return true; + } + + ret = strtoul(value, &end, 10); + if (!*value || *value == '-' || *end || (ret && (ret < 10 || ret > 3600))) { + fprintf(stderr, "The persistent keepalive interval must be 0/off or 10-3600. Found: `%s`\n", value); + return false; + } + + *interval = (__u16)ret; + return true; +} + + static inline bool parse_ipmasks(struct inflatable_device *buf, size_t peer_offset, const char *value) { struct wgpeer *peer; @@ -263,6 +284,7 @@ static bool process_line(struct config_ctx *ctx, const char *line) ctx->is_peer_section = true; ctx->is_device_section = false; peer_from_offset(ctx->buf.dev, ctx->peer_offset)->replace_ipmasks = true; + peer_from_offset(ctx->buf.dev, ctx->peer_offset)->persistent_keepalive_interval = (__u16)-1; return true; } @@ -288,6 +310,8 @@ static bool process_line(struct config_ctx *ctx, const char *line) ret = parse_key(peer_from_offset(ctx->buf.dev, ctx->peer_offset)->public_key, value); else if (key_match("AllowedIPs")) ret = parse_ipmasks(&ctx->buf, ctx->peer_offset, value); + else if (key_match("PersistentKeepalive")) + ret = parse_persistent_keepalive(&peer_from_offset(ctx->buf.dev, ctx->peer_offset)->persistent_keepalive_interval, value); else goto error; } else @@ -476,6 +500,7 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc) perror("use_space"); goto error; } + peer_from_offset(buf.dev, peer_offset)->persistent_keepalive_interval = (__u16)-1; ++buf.dev->num_peers; if (!parse_key(peer_from_offset(buf.dev, peer_offset)->public_key, argv[1])) goto error; @@ -501,6 +526,11 @@ bool config_read_cmd(struct wgdevice **device, char *argv[], int argc) free(line); argv += 2; argc -= 2; + } else if (!strcmp(argv[0], "persistent-keepalive") && argc >= 2 && buf.dev->num_peers) { + if (!parse_persistent_keepalive(&peer_from_offset(buf.dev, peer_offset)->persistent_keepalive_interval, argv[1])) + goto error; + argv += 2; + argc -= 2; } else { fprintf(stderr, "Invalid argument: %s\n", argv[0]); goto error; @@ -13,7 +13,7 @@ int set_main(int argc, char *argv[]) int ret = 1; if (argc < 3) { - fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [private-key <file path>] [peer <base64 public key> [remove] [endpoint <ip>:<port>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]); + fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [private-key <file path>] [peer <base64 public key> [remove] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]); return 1; } @@ -121,13 +121,11 @@ static char *endpoint(const struct sockaddr_storage *addr) return buf; } -static char *ago(const struct timeval *t) +static size_t pretty_time(char *buf, const size_t len, unsigned long long left) { - static char buf[1024]; - unsigned long long left, years, days, hours, minutes, seconds; size_t offset = 0; + unsigned long long years, days, hours, minutes, seconds; - left = time(NULL) - t->tv_sec; years = left / (365 * 24 * 60 * 60); left = left % (365 * 24 * 60 * 60); days = left / (24 * 60 * 60); @@ -138,15 +136,25 @@ static char *ago(const struct timeval *t) seconds = left % 60; if (years) - offset += snprintf(buf + offset, sizeof(buf) - offset, "%s%llu " TERMINAL_FG_CYAN "year%s" TERMINAL_RESET, offset ? ", " : "", years, years == 1 ? "" : "s"); + offset += snprintf(buf + offset, len - offset, "%s%llu " TERMINAL_FG_CYAN "year%s" TERMINAL_RESET, offset ? ", " : "", years, years == 1 ? "" : "s"); if (days) - offset += snprintf(buf + offset, sizeof(buf) - offset, "%s%llu " TERMINAL_FG_CYAN "day%s" TERMINAL_RESET, offset ? ", " : "", days, days == 1 ? "" : "s"); + offset += snprintf(buf + offset, len - offset, "%s%llu " TERMINAL_FG_CYAN "day%s" TERMINAL_RESET, offset ? ", " : "", days, days == 1 ? "" : "s"); if (hours) - offset += snprintf(buf + offset, sizeof(buf) - offset, "%s%llu " TERMINAL_FG_CYAN "hour%s" TERMINAL_RESET, offset ? ", " : "", hours, hours == 1 ? "" : "s"); + offset += snprintf(buf + offset, len - offset, "%s%llu " TERMINAL_FG_CYAN "hour%s" TERMINAL_RESET, offset ? ", " : "", hours, hours == 1 ? "" : "s"); if (minutes) - offset += snprintf(buf + offset, sizeof(buf) - offset, "%s%llu " TERMINAL_FG_CYAN "minute%s" TERMINAL_RESET, offset ? ", " : "", minutes, minutes == 1 ? "" : "s"); + offset += snprintf(buf + offset, len - offset, "%s%llu " TERMINAL_FG_CYAN "minute%s" TERMINAL_RESET, offset ? ", " : "", minutes, minutes == 1 ? "" : "s"); if (seconds) - offset += snprintf(buf + offset, sizeof(buf) - offset, "%s%llu " TERMINAL_FG_CYAN "second%s" TERMINAL_RESET, offset ? ", " : "", seconds, seconds == 1 ? "" : "s"); + offset += snprintf(buf + offset, len - offset, "%s%llu " TERMINAL_FG_CYAN "second%s" TERMINAL_RESET, offset ? ", " : "", seconds, seconds == 1 ? "" : "s"); + + return offset; +} + +static char *ago(const struct timeval *t) +{ + static char buf[1024]; + size_t offset; + + offset = pretty_time(buf, sizeof(buf), time(NULL) - t->tv_sec); if (offset) snprintf(buf + offset, sizeof(buf) - offset, " ago"); else @@ -155,6 +163,13 @@ static char *ago(const struct timeval *t) return buf; } +static char *every(uint16_t seconds) +{ + static char buf[1024] = "every "; + pretty_time(buf + strlen("every "), sizeof(buf) - strlen("every "), seconds); + return buf; +} + static char *bytes(uint64_t b) { static char buf[1024]; @@ -176,7 +191,7 @@ static char *bytes(uint64_t b) static const char *COMMAND_NAME = NULL; static void show_usage(void) { - fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | preshared-key | listen-port | peers | endpoints | allowed-ips | latest-handshake | bandwidth]\n", PROG_NAME, COMMAND_NAME); + fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | preshared-key | listen-port | peers | endpoints | allowed-ips | latest-handshake | bandwidth | persistent-keepalive]\n", PROG_NAME, COMMAND_NAME); } static void pretty_print(struct wgdevice *device) @@ -216,6 +231,8 @@ static void pretty_print(struct wgdevice *device) terminal_printf("%s received, ", bytes(peer->rx_bytes)); terminal_printf("%s sent\n", bytes(peer->tx_bytes)); } + if (peer->persistent_keepalive_interval) + terminal_printf(" " TERMINAL_BOLD "persistent keepalive" TERMINAL_RESET ": %s\n", every(peer->persistent_keepalive_interval)); if (i + 1 < device->num_peers) terminal_printf("\n"); } @@ -275,6 +292,15 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int printf("%s\t", device->interface); printf("%s\t%" PRIu64 "\t%" PRIu64 "\n", key(peer->public_key), (uint64_t)peer->rx_bytes, (uint64_t)peer->tx_bytes); } + } else if (!strcmp(param, "persistent-keepalive")) { + for_each_wgpeer(device, peer, i) { + if (with_interface) + printf("%s\t", device->interface); + if (peer->persistent_keepalive_interval) + printf("%s\t%u\n", key(peer->public_key), peer->persistent_keepalive_interval); + else + printf("%s\toff\n", key(peer->public_key)); + } } else if (!strcmp(param, "peers")) { for_each_wgpeer(device, peer, i) { if (with_interface) diff --git a/src/showconf.c b/src/showconf.c index faf2482..95d2e17 100644 --- a/src/showconf.c +++ b/src/showconf.c @@ -91,6 +91,9 @@ int showconf_main(int argc, char *argv[]) } } + if (peer->persistent_keepalive_interval) + printf("PersistentKeepalive = %u\n", peer->persistent_keepalive_interval); + if (i + 1 < device->num_peers) printf("\n"); } |