diff --git a/Makefile.am b/Makefile.am index a4b8204..42a09f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,7 @@ glorytun_SOURCES = \ src/keygen.c \ src/main.c \ src/path.c \ + src/set.c \ src/show.c \ src/str.h \ src/tun.c \ diff --git a/meson.build b/meson.build index 1ef448d..2342d5b 100644 --- a/meson.build +++ b/meson.build @@ -28,6 +28,7 @@ executable('glorytun', install: true, 'src/keygen.c', 'src/main.c', 'src/path.c', + 'src/set.c', 'src/show.c', 'src/tun.c', ], diff --git a/mud b/mud index 53f8d31..1aded8e 160000 --- a/mud +++ b/mud @@ -1 +1 @@ -Subproject commit 53f8d31f770fe13e2b9c5ee0f43801980b1b0b75 +Subproject commit 1aded8ec296c7bc6e7de62a9cea3edacf7471fdd diff --git a/src/bind.c b/src/bind.c index f98f886..f53e579 100644 --- a/src/bind.c +++ b/src/bind.c @@ -87,20 +87,17 @@ gt_setup_secretkey(struct mud *mud, const char *keyfile) return 0; } -static void -gt_setup_mtu(struct mud *mud, const char *tun_name, size_t *old_mtu) +static size_t +gt_setup_mtu(struct mud *mud, const char *tun_name) { size_t mtu = mud_get_mtu(mud); - if (mtu == *old_mtu) - return; - gt_log("setup MTU to %zu on interface %s\n", mtu, tun_name); if (iface_set_mtu(tun_name, mtu) == -1) perror("tun_set_mtu"); - *old_mtu = mtu; + return mtu; } static void @@ -125,8 +122,6 @@ gt_bind(int argc, char **argv) unsigned short peer_port = bind_port; const char *dev = NULL; const char *keyfile = NULL; - unsigned long timeout = 5000; - unsigned long timetolerance = 0; size_t bufsize = 64 * 1024 * 1024; size_t mtu = 1500; @@ -148,8 +143,6 @@ gt_bind(int argc, char **argv) {"mtu", NULL, &mtuz, argz_option}, {"keyfile", "FILE", &keyfile, argz_str}, {"chacha", NULL, NULL, argz_option}, - {"timeout", "SECONDS", &timeout, argz_time}, - {"timetolerance", "SECONDS", &timetolerance, argz_time}, {"persist", NULL, NULL, argz_option}, {"bufsize", "BYTES", &bufsize, argz_bytes}, {}}; @@ -202,16 +195,6 @@ gt_bind(int argc, char **argv) chacha = 1; } - if (timeout && mud_set_send_timeout(mud, timeout)) { - perror("timeout"); - return 1; - } - - if (timetolerance && mud_set_time_tolerance(mud, timetolerance)) { - perror("timetolerance"); - return 1; - } - mud_set_mtu(mud, GT_MTU(mtu)); char tun_name[64]; @@ -232,7 +215,7 @@ gt_bind(int argc, char **argv) } } - gt_setup_mtu(mud, tun_name, &mtu); + mtu = gt_setup_mtu(mud, tun_name); int ctl_fd = ctl_create("/run/" PACKAGE_NAME, tun_name); @@ -309,6 +292,16 @@ gt_bind(int argc, char **argv) perror("mud_del_path"); } break; + case CTL_MTU: + reply.reply = (int)mud_set_mtu(mud, GT_MTU((size_t)msg.mtu)); + mtu = gt_setup_mtu(mud, tun_name); + break; + case CTL_TIMEOUT: + reply.reply = mud_set_send_timeout(mud, msg.timeout); + break; + case CTL_TIMETOLERANCE: + reply.reply = mud_set_time_tolerance(mud, msg.timetolerance); + break; case CTL_STATUS: reply = (struct ctl_msg){ .type = CTL_STATUS_REPLY, @@ -383,7 +376,7 @@ gt_bind(int argc, char **argv) int r = mud_send(mud, &buf[p], q - p, tc); if (r == -1 && errno == EMSGSIZE) { - gt_setup_mtu(mud, tun_name, &mtu); + mtu = gt_setup_mtu(mud, tun_name); } else { if (r == -1 && errno != EAGAIN) perror("mud_send"); diff --git a/src/ctl.h b/src/ctl.h index 3b4ea62..1011c14 100644 --- a/src/ctl.h +++ b/src/ctl.h @@ -8,6 +8,9 @@ enum ctl_type { CTL_PATH_DEL, CTL_STATUS, CTL_STATUS_REPLY, + CTL_MTU, + CTL_TIMEOUT, + CTL_TIMETOLERANCE, CTL_REPLY, }; @@ -25,6 +28,9 @@ struct ctl_msg { struct sockaddr_storage bind; struct sockaddr_storage peer; } status; + int mtu; + unsigned long timeout; + unsigned long timetolerance; int reply; }; }; diff --git a/src/main.c b/src/main.c index 3c174f4..04cf3fe 100644 --- a/src/main.c +++ b/src/main.c @@ -55,6 +55,7 @@ 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 main(int argc, char **argv) @@ -69,6 +70,7 @@ main(int argc, char **argv) {"show", "show all running tunnels", 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}, diff --git a/src/set.c b/src/set.c new file mode 100644 index 0000000..7970051 --- /dev/null +++ b/src/set.c @@ -0,0 +1,121 @@ +#include "common.h" +#include "ctl.h" +#include "str.h" + +#include +#include + +#include "../argz/argz.h" + +static ssize_t +gt_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)) { + int err = errno; + ctl_delete(fd); + errno = err; + return -1; + } + + if (res->type == CTL_REPLY) { + if (res->reply < 0) { + errno = res->reply; + return -1; + } + } else { + errno = EINTR; + return -1; + } + + return 0; +} + +static int +gt_set_mtu(int fd, size_t mtu) +{ + struct ctl_msg res, req = { + .type = CTL_MTU, + .mtu = mtu, + }; + + int ret = gt_reply(fd, &res, &req); + + if (!ret) + printf("new mtu: %i\n", res.reply); + + return ret; +} + +static int +gt_set_timeout(int fd, unsigned long timeout) +{ + struct ctl_msg res, req = { + .type = CTL_TIMEOUT, + .timeout = timeout, + }; + + return gt_reply(fd, &res, &req); +} + +static int +gt_set_timetolerance(int fd, unsigned long timetolerance) +{ + struct ctl_msg res, req = { + .type = CTL_TIMETOLERANCE, + .timetolerance = timetolerance, + }; + + return gt_reply(fd, &res, &req); +} + +int +gt_set(int argc, char **argv) +{ + const char *dev = "tun0"; + unsigned long timetolerance = 0; + unsigned long timeout = 0; + size_t mtu = 0; + + struct argz pathz[] = { + {"dev", "NAME", &dev, argz_str}, + {"mtu", "BYTES", &mtu, argz_bytes}, + {"timeout", "SECONDS", &timeout, argz_time}, + {"timetolerance", "SECONDS", &timetolerance, argz_time}, + {}}; + + if (argz(pathz, argc, argv)) + return 1; + + int fd = ctl_create("/run/" PACKAGE_NAME, NULL); + + if (fd == -1) { + perror("ctl_create"); + return 1; + } + + if (ctl_connect(fd, "/run/" PACKAGE_NAME, dev) == -1) { + gt_log("couldn't connect to %s\n", dev); + ctl_delete(fd); + return 1; + } + + if (mtu && gt_set_mtu(fd, mtu)) { + perror("mtu"); + return 1; + } + + if (timeout && gt_set_timeout(fd, timeout)) { + perror("timeout"); + return 1; + } + + if (timetolerance && gt_set_timetolerance(fd, timetolerance)) { + perror("timetolerance"); + return 1; + } + + ctl_delete(fd); + + return 0; +}