diff --git a/argz b/argz index 6a41785..29ddd07 160000 --- a/argz +++ b/argz @@ -1 +1 @@ -Subproject commit 6a417853b87753b3212f398d4f0ffbaa245f8cb5 +Subproject commit 29ddd07be27de1ede9341cf4eefb68056400cf04 diff --git a/mud b/mud index 582eb29..7013d8e 160000 --- a/mud +++ b/mud @@ -1 +1 @@ -Subproject commit 582eb2961784e30ea1d067c2ab4e792f9a4c3d0e +Subproject commit 7013d8e3230238c01243e31de39f0404e2576e55 diff --git a/src/bind.c b/src/bind.c index 50e59ae..1ca2dbd 100644 --- a/src/bind.c +++ b/src/bind.c @@ -16,12 +16,6 @@ #define O_CLOEXEC 0 #endif -#ifdef __linux__ -#define GT_IPV6 1 -#else -#define GT_IPV6 0 -#endif - #define GT_MTU(X) ((X)-28) static void @@ -109,12 +103,26 @@ gt_setup_mtu(struct mud *mud, const char *tun_name, size_t *old_mtu) *old_mtu = (size_t)mtu; } +static void +gt_setup_port(struct sockaddr_storage *ss, uint16_t port) +{ + switch (ss->ss_family) { + case AF_INET: + ((struct sockaddr_in *)ss)->sin_port = htons(port); + break; + case AF_INET6: + ((struct sockaddr_in6 *)ss)->sin6_port = htons(port); + break; + } +} + 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 port = bind_port; - const char *host = NULL; + unsigned short peer_port = bind_port; const char *dev = NULL; const char *keyfile = NULL; unsigned long timeout = 5000; @@ -128,15 +136,15 @@ gt_bind(int argc, char **argv) {}}; struct argz toz[] = { - {NULL, "IPADDR", &host, argz_str}, - {NULL, "PORT", &port, argz_ushort}, + {NULL, "IPADDR", &peer_addr, argz_addr}, + {NULL, "PORT", &peer_port, argz_ushort}, {}}; struct argz bindz[] = { - {"port", "PORT", &bind_port, argz_ushort}, + {NULL, "IPADDR", &bind_addr, argz_addr}, + {NULL, "PORT", &bind_port, argz_ushort}, {"to", NULL, &toz, argz_option}, {"dev", "NAME", &dev, argz_str}, - {"v4only|v6only", NULL, NULL, argz_option}, {"mtu", NULL, &mtuz, argz_option}, {"keyfile", "FILE", &keyfile, argz_str}, {"chacha", NULL, NULL, argz_option}, @@ -149,6 +157,9 @@ gt_bind(int argc, char **argv) if (argz(bindz, argc, argv)) return 1; + gt_setup_port(&bind_addr, bind_port); + gt_setup_port(&peer_addr, peer_port); + unsigned char *buf = malloc(bufsize); if (!buf) { @@ -156,33 +167,20 @@ gt_bind(int argc, char **argv) return 1; } - int ipv4 = 1; - int ipv6 = GT_IPV6; - - if (argz_is_set(bindz, "v4only")) { - ipv4 = 1; - ipv6 = 0; - } - - if (argz_is_set(bindz, "v6only")) { - ipv4 = 0; - ipv6 = 1; - } - int mtu_auto = argz_is_set(mtuz, "auto"); int chacha = argz_is_set(bindz, "chacha"); int persist = argz_is_set(bindz, "persist"); int icmp_fd = -1; - if (ipv4 && mtu_auto && host) { + if (mtu_auto && (peer_addr.ss_family == AF_INET)) { 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(bind_port, ipv4, ipv6); + struct mud *mud = mud_create((struct sockaddr *)&bind_addr); if (!mud) { gt_log("couldn't create mud\n"); @@ -227,8 +225,8 @@ gt_bind(int argc, char **argv) if (tun_set_persist(tun_fd, persist) == -1) perror("tun_set_persist"); - if (host && port) { - if (mud_peer(mud, host, port)) { + if (peer_addr.ss_family) { + if (mud_peer(mud, (struct sockaddr *)&peer_addr)) { perror("mud_peer"); return 1; } @@ -300,36 +298,28 @@ gt_bind(int argc, char **argv) if (r == (ssize_t)sizeof(msg)) { switch (msg.type) { case CTL_PATH_ADD: - gt_log("[ctl path add] addr=%s\n", - &msg.path.add.addr[0]); - if (mud_add_path(mud, &msg.path.add.addr[0])) { + if (mud_add_path(mud, (struct sockaddr *)&msg.path_addr)) { reply.reply = errno; perror("mud_add_path"); } break; case CTL_PATH_DEL: - gt_log("[ctl path del] addr=%s\n", - &msg.path.del.addr[0]); - if (mud_del_path(mud, &msg.path.del.addr[0])) { + if (mud_del_path(mud, (struct sockaddr *)&msg.path_addr)) { reply.reply = errno; perror("mud_del_path"); } break; case CTL_STATUS: - gt_log("[ctl status]\n"); reply = (struct ctl_msg){ .type = CTL_STATUS_REPLY, .status = { .mtu = mtu, .mtu_auto = (icmp_fd != -1), .chacha = chacha, - .port = port, - .bind_port = bind_port, - .ipv4 = ipv4, - .ipv6 = ipv6, + .bind = bind_addr, + .peer = peer_addr, }, }; - str_cpy(reply.status.addr, sizeof(reply.status.addr) - 1, host); break; default: reply = (struct ctl_msg){ diff --git a/src/ctl.h b/src/ctl.h index 777bd86..3b4ea62 100644 --- a/src/ctl.h +++ b/src/ctl.h @@ -1,5 +1,7 @@ #pragma once +#include + enum ctl_type { CTL_UNKNOWN, CTL_PATH_ADD, @@ -15,20 +17,13 @@ struct ctl_msg { struct { enum ctl_type type; } unknown; - struct { - struct { - char addr[256]; - } add, del; - } path; + struct sockaddr_storage path_addr; struct { size_t mtu; int mtu_auto; int chacha; - char addr[256]; - unsigned short port; - unsigned short bind_port; - int ipv4; - int ipv6; + struct sockaddr_storage bind; + struct sockaddr_storage peer; } status; int reply; }; diff --git a/src/path.c b/src/path.c index 63ee05f..402bf57 100644 --- a/src/path.c +++ b/src/path.c @@ -11,10 +11,10 @@ int gt_path(int argc, char **argv) { const char *dev = "tun0"; - const char *addr = NULL; + struct sockaddr_storage addr = { 0 }; struct argz actionz[] = { - {NULL, "IPADDR", &addr, argz_str}, + {NULL, "IPADDR", &addr, argz_addr}, {}}; struct argz pathz[] = { @@ -30,13 +30,13 @@ gt_path(int argc, char **argv) if (argz_is_set(pathz, "up")) { msg = (struct ctl_msg){ .type = CTL_PATH_ADD, + .path_addr = addr, }; - str_cpy(msg.path.add.addr, sizeof(msg.path.add.addr) - 1, addr); } else if (argz_is_set(pathz, "down")) { msg = (struct ctl_msg){ .type = CTL_PATH_DEL, + .path_addr = addr, }; - str_cpy(msg.path.del.addr, sizeof(msg.path.del.addr) - 1, addr); } else { gt_log("nothing to do..\n"); return 0; diff --git a/src/show.c b/src/show.c index e66eafc..8bdc54f 100644 --- a/src/show.c +++ b/src/show.c @@ -6,6 +6,35 @@ #include #include #include +#include + +static unsigned short +gt_ss_port(struct sockaddr_storage *ss) +{ + switch (ss->ss_family) { + case AF_INET: + return ntohs(((struct sockaddr_in *)ss)->sin_port); + case AF_INET6: + return ntohs(((struct sockaddr_in6 *)ss)->sin6_port); + } + + return 0; +} + +static int +gt_ss_addr(char *str, size_t size, struct sockaddr_storage *ss) +{ + switch (ss->ss_family) { + case AF_INET: + return -!inet_ntop(AF_INET, + &((struct sockaddr_in *)ss)->sin_addr, str, size); + case AF_INET6: + return -!inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)ss)->sin6_addr, str, size); + } + + return -1; +} static int gt_show_tunnel(int fd, const char *dev) @@ -28,39 +57,37 @@ gt_show_tunnel(int fd, const char *dev) if (reply.type != CTL_STATUS_REPLY) return -1; - if (str_empty(reply.status.addr)) { + char bindstr[INET6_ADDRSTRLEN] = {0}; + char peerstr[INET6_ADDRSTRLEN] = {0}; + + if (gt_ss_addr(bindstr, sizeof(bindstr), &reply.status.bind) || + gt_ss_addr(peerstr, sizeof(peerstr), &reply.status.peer)) + return -1; + + if (reply.status.peer.ss_family == 0) { printf("server %s:\n" + " bind: %s port %hu\n" " mtu: %zu\n" " auto mtu: %s\n" - " bind port: %hu\n" - " cipher: %s\n" - " ipv4: %s\n" - " ipv6: %s\n", + " cipher: %s\n", dev, + bindstr, gt_ss_port(&reply.status.bind), reply.status.mtu, reply.status.mtu_auto ? "enabled" : "disabled", - reply.status.bind_port, - reply.status.chacha ? "chacha20poly1305" : "aes256gcm", - reply.status.ipv4 ? "enabled" : "disabled", - reply.status.ipv6 ? "enabled" : "disabled"); + reply.status.chacha ? "chacha20poly1305" : "aes256gcm"); } else { printf("client %s:\n" - " host: %s\n" - " port: %hu\n" + " bind: %s port %hu\n" + " peer: %s port %hu\n" " mtu: %zu\n" " auto mtu: %s\n" - " bind port: %hu\n" - " cipher: %s\n" - " ipv4: %s\n" - " ipv6: %s\n", + " cipher: %s\n", dev, - reply.status.addr, reply.status.port, + bindstr, gt_ss_port(&reply.status.bind), + peerstr, gt_ss_port(&reply.status.peer), reply.status.mtu, reply.status.mtu_auto ? "enabled" : "disabled", - reply.status.bind_port, - reply.status.chacha ? "chacha20poly1305" : "aes256gcm", - reply.status.ipv4 ? "enabled" : "disabled", - reply.status.ipv6 ? "enabled" : "disabled"); + reply.status.chacha ? "chacha20poly1305" : "aes256gcm"); } return 0; diff --git a/systemd/glorytun-run b/systemd/glorytun-run index 264c514..cf5a8d9 100755 --- a/systemd/glorytun-run +++ b/systemd/glorytun-run @@ -1,6 +1,6 @@ #!/bin/sh exec glorytun bind "$@" \ + $BIND $BIND_PORT \ ${DEV:+dev "$DEV"} \ - ${HOST:+to "$HOST" "$PORT"} \ - ${BIND_PORT:+port "$BIND_PORT"} + ${HOST:+to "$HOST" "$PORT"} diff --git a/systemd/glorytun-setup b/systemd/glorytun-setup index ceed5fd..21a214e 100755 --- a/systemd/glorytun-setup +++ b/systemd/glorytun-setup @@ -25,6 +25,11 @@ else PORT=${PORT:-5000} fi +BIND=0.0.0.0 +case "$HOST" in + *:*) BIND=:: +esac + _ask "Server key (enter to generate a new one)" KEY if [ -z "$KEY" ]; then KEY=$(glorytun keygen) @@ -38,8 +43,9 @@ cat > "$DIR/env" < "$DIR/key" )