Compare commits

...

28 Commits

Author SHA1 Message Date
Adrien Gallouët
7f30cdc5ee Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-02-05 14:01:13 +00:00
Adrien Gallouët
b2077f5cd4 Use mud_set_conf()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-16 17:48:02 +00:00
Adrien Gallouët
a9408e799d Show beat
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-11 15:04:55 +00:00
Adrien Gallouët
61c7b48e3f Add beat option in path command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-11 09:55:17 +00:00
Adrien Gallouët
4db90b42b6 Use mud based keepalive
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-11 09:12:47 +00:00
Adrien Gallouët
3df542b6d7 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-09 22:25:42 +00:00
Adrien Gallouët
4a0027e640 Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-09 17:39:58 +00:00
Adrien Gallouët
296d80782a Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-08 14:38:28 +00:00
Adrien Gallouët
1c38034265 Code cleanup
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-07 13:00:51 +00:00
Adrien Gallouët
0b26eb108d Add rate fixed|auto option
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-07 12:46:28 +00:00
Adrien Gallouët
ac167e74f5 Fix keepalive and use a small value for now
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-04 16:17:36 +00:00
Adrien Gallouët
203feba186 Update README.md about backup path
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 16:26:21 +00:00
Adrien Gallouët
3b938df408 Happy New Year
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:57:16 +00:00
Adrien Gallouët
0ccb3de68d Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:39:10 +00:00
Adrien Gallouët
020b115171 Add keepalive
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:28:27 +00:00
Adrien Gallouët
53e7a7ba0a Resize and align buf
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2020-01-03 15:09:06 +00:00
Adrien Gallouët
1ae7775ce1 Cleanup Makefile
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-12-31 20:04:52 +00:00
Adrien Gallouët
c75f5d5620 Do not allow mtu manipulation anymore
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-12-31 19:34:20 +00:00
Adrien Gallouët
5f72198a96 Fix upload-artifact
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-12-10 14:54:49 +00:00
Adrien Gallouët
c01dbe3e4b Update README.md
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-19 13:38:59 +00:00
Adrien Gallouët
6be944d7cb Update mud
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-19 12:00:07 +00:00
Adrien Gallouët
009d482fd1 Be careful with dirname()
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-15 10:43:41 +00:00
Adrien Gallouët
b9aaab661f Probe run/tmp directory at runtime
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-14 19:19:23 +00:00
Adrien Gallouët
a4f63ecf40 Add rundir option for make
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-13 14:12:58 +00:00
Adrien Gallouët
0ceedaec10 Update Makefile
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-13 13:54:15 +00:00
Adrien Gallouët
34486c20b1 Update EXTRA_DIST
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-13 13:39:07 +00:00
Adrien Gallouët
b1fca4c1d2 301 to wikis
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-11-12 11:19:56 +00:00
Adrien Gallouët
5e0900c8ee Add option losslimit in the set command
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2019-10-23 13:52:40 +00:00
14 changed files with 166 additions and 311 deletions

View File

@@ -20,5 +20,5 @@ jobs:
- uses: actions/upload-artifact@v1
with:
name: bin
name: ${{ matrix.os }}
path: ./bin

View File

@@ -1,4 +1,4 @@
Copyright (c) 2015-2019, Adrien Gallouët <adrien@gallouet.fr>
Copyright (c) 2015-2020, Adrien Gallouët <adrien@gallouet.fr>
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -2,11 +2,12 @@ NAME := glorytun
VERSION := $(shell ./version.sh)
DIST := $(NAME)-$(VERSION)
CC ?= cc
DESTDIR ?=
CC ?= gcc
INSTALL ?= install
prefix ?= /usr
CFLAGS ?= -std=c11 -O2 -Wall -fstack-protector-strong
Q := @
CFLAGS := -std=c11 -O2 -Wall -fstack-protector-strong
FLAGS := $(CFLAGS) $(LDFLAGS) $(CPPFLAGS)
FLAGS += -DPACKAGE_NAME=\"$(NAME)\" -DPACKAGE_VERSION=\"$(VERSION)\"
@@ -15,21 +16,19 @@ FLAGS += -I.static/$(CROSS)/libsodium-stable/src/libsodium/include
FLAGS += -L.static/$(CROSS)/libsodium-stable/src/libsodium/.libs
SRC := argz/argz.c mud/mud.c mud/aegis256/aegis256.c $(wildcard src/*.c)
HDR := argz/argz.h mud/mud.h mud/aegis256/aegis256.h $(wildcard src/*.h)
.PHONY: $(NAME)
$(NAME):
@echo "Building $(NAME)"
@$(CC) $(FLAGS) -o $(NAME) $(SRC) -lsodium
$(NAME): $(SRC) $(HDR)
@echo "$(NAME)"
$(Q)$(CC) $(FLAGS) -o $(NAME) $(SRC) -lsodium
.PHONY: install
install: $(NAME)
@echo "Installing $(NAME)"
@$(INSTALL) -m 755 -d $(DESTDIR)$(prefix)/bin
@$(INSTALL) -m 755 -s $(NAME) $(DESTDIR)$(prefix)/bin
@echo "$(DESTDIR)$(prefix)/bin/$(NAME)"
$(Q)install -m 755 -d $(DESTDIR)$(prefix)/bin
$(Q)install -m 755 -s $(NAME) $(DESTDIR)$(prefix)/bin
.PHONY: dist
dist:
@echo "Building $(DIST).tar.gz"
@(git --git-dir=.git ls-files --recurse-submodules -- ':!:.*' ':!:**/.*' && echo VERSION) | ( \
tar zcf $(DIST).tar.gz -T- --transform 's:^:$(DIST)/:' || \
tar zcf $(DIST).tar.gz -T- -s ':^:$(DIST)/:' ) 2>/dev/null
.PHONY: clean
clean:
$(Q)rm -f "$(NAME)"
$(Q)rm -f "$(DIST).tar.gz"

View File

@@ -31,11 +31,13 @@ glorytun_SOURCES = \
EXTRA_DIST = \
LICENSE \
Makefile \
README.md \
VERSION \
autogen.sh \
meson.build \
mud/LICENSE \
mud/README.md \
sodium.sh \
systemd \
version.sh

View File

@@ -2,6 +2,8 @@
Glorytun is a small, simple and secure VPN over [mud](https://github.com/angt/mud).
Please visit the [wiki](https://github.com/angt/glorytun/wiki) for how-to guides, tutorials, etc.
## Compatibility
Glorytun only depends on [libsodium](https://github.com/jedisct1/libsodium) version >= 1.0.4.
@@ -19,17 +21,19 @@ The key features of Glorytun come directly from mud:
* **Fast and highly secure**
The use of UDP and libsodium allows you to secure 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 a new and very fast AEAD construction called AEGIS-256 if AES-NI is available otherwise ChaCha20-Poly1305 is used.
Of course, you can force the use of ChaCha20-Poly1305 for higher security.
All messages are encrypted, authenticated and timestamped to mitigate a large set of attacks.
This implies that the client and the server must be synchronized, an offset of 10min is accepted by default.
Perfect forward secrecy is also implemented with ECDH over Curve25519. Keys are rotated every hours.
* **Multipath and active failover**
* **Multipath and failover**
Connectivity is now crucial, especially in the SD-WAN world.
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.
Backup paths are also supported, they will be used only in case of emergency, it is useful when aggregation is not your priority.
* **Traffic shaping**
@@ -44,87 +48,6 @@ The key features of Glorytun come directly from mud:
It doesn't rely on Next-hop MTU to avoid ICMP black holes.
In asymmetric situations the minimum MTU is selected.
## Caveats
Glorytun is strongly secure by default and protects against replay attacks,
the clock between the client and the server must be synchronized.
By default, an offset of 10min is accepted.
## Build and Install
You will need `git`, `make`, `gcc` and `libsodium`:
$ sudo apt install git make gcc libsodium-dev # debian based
$ sudo yum install git make gcc libsodium-devel # redhat based
To build and install the latest release from github:
$ git clone https://github.com/angt/glorytun --recursive
$ cd glorytun
$ sudo make install
This will install the binary in `/usr/bin` by default.
The more classical autotools suite is also available.
## Usage
Just run `glorytun` with no arguments to view the list of available commands:
$ glorytun
available commands:
show show tunnel info
bench start a crypto bench
bind start a new tunnel
set change tunnel properties
keygen generate a new secret key
path manage paths
version show version
Use the keyword `help` after a command to show its usage.
## Mini HowTo
Glorytun does not touch the configuration of its network interface (except for the MTU),
It is up to the user to do it according to the tools available
on his system (systemd-networkd, netifd, ...).
This also allows a wide variety of configurations.
To start a server:
# (umask 066; glorytun keygen > my_secret_key)
# glorytun bind 0.0.0.0 keyfile my_secret_key &
You should now have an unconfigured network interface (let's say `tun0`).
For example, the simplest setup with `ifconfig`:
# ifconfig tun0 10.0.1.1 pointopoint 10.0.1.2 up
To check if the server is running, simply call `glorytun show`.
It will show you all of the running tunnels.
To start a new client, you need to get the secret key generated for the server.
Then simply call:
# glorytun bind 0.0.0.0 to SERVER_IP keyfile my_secret_key &
# ifconfig tun0 10.0.1.2 pointopoint 10.0.1.1 up
Now you have to setup your path, let's say you have an ADSL link that can do 1Mbit upload and 20Mbit download then call:
# glorytun path up LOCAL_IPADDR rate tx 1mbit rx 20mbit
Again, to check if your path is working, you can watch its status with `glorytun path`.
You should now be able to ping your server with `ping 10.0.1.1`.
If you use systemd-networkd, you can easily setup your tunnels with the helper program `glorytun-setup`.
## Thanks
* @jedisct1 for all his help and the code for MacOS/BSD.
* The team OTB (@bessa, @gregdel, @pouulet, @sduponch and @simon) for all tests and discussions.
* OVH to support this soft :)
---
For feature requests and bug reports, please create an [issue](https://github.com/angt/glorytun/issues).

2
argz

Submodule argz updated: ff7bc660e2...f88a280d2b

2
mud

Submodule mud updated: d0dc6076c8...5be4096452

View File

@@ -91,7 +91,7 @@ gt_setup_mtu(struct mud *mud, size_t old, const char *tun_name)
{
size_t mtu = mud_get_mtu(mud);
if (mtu == old)
if (!mtu || mtu == old)
return mtu;
if (iface_set_mtu(tun_name, mtu) == -1)
@@ -185,11 +185,16 @@ gt_bind(int argc, char **argv)
}
}
const int ctl_fd = ctl_create(GT_RUNDIR, tun_name);
const int ctl_fd = ctl_create(tun_name);
if (ctl_fd == -1) {
gt_log("couldn't create "GT_RUNDIR"/%s: %s\n",
tun_name, strerror(errno));
char dir[64];
if (ctl_rundir(dir, sizeof(dir))) {
gt_log("couldn't create %s/%s: %s\n",
dir, tun_name, strerror(errno));
} else {
gt_log("couldn't find a writable run/tmp directory\n");
}
return 1;
}
@@ -216,48 +221,31 @@ gt_bind(int argc, char **argv)
int last_fd = MAX(tun_fd, mud_fd);
last_fd = 1 + MAX(last_fd, ctl_fd);
unsigned char buf[4096];
__attribute__((aligned(16)))
unsigned char buf[1500];
while (!gt_quit) {
if (tun_can_write) {
FD_CLR(tun_fd, &wfds);
} else {
FD_SET(tun_fd, &wfds);
}
if (mud_can_write) {
FD_CLR(mud_fd, &wfds);
} else {
FD_SET(mud_fd, &wfds);
}
if (tun_can_read) {
FD_CLR(tun_fd, &rfds);
} else {
FD_SET(tun_fd, &rfds);
}
if (mud_can_read) {
FD_CLR(mud_fd, &rfds);
} else {
FD_SET(mud_fd, &rfds);
}
if (tun_can_write) FD_CLR(tun_fd, &wfds); else FD_SET(tun_fd, &wfds);
if (mud_can_write) FD_CLR(mud_fd, &wfds); else FD_SET(mud_fd, &wfds);
if (tun_can_read) FD_CLR(tun_fd, &rfds); else FD_SET(tun_fd, &rfds);
if (mud_can_read) FD_CLR(mud_fd, &rfds); else FD_SET(mud_fd, &rfds);
FD_SET(ctl_fd, &rfds);
struct timeval tv = {
.tv_usec = 100000,
};
struct timeval tv = { 0 };
int update = mud_update(mud);
if (mud_can_read && tun_can_write) {
tv.tv_usec = 0;
} else if (tun_can_read && mud_can_write) {
long send_wait = mud_send_wait(mud);
if (send_wait >= 0)
tv.tv_usec = send_wait * 1000;
if (update >= 0) {
if (mud_can_read && tun_can_write) {
} else if (tun_can_read && mud_can_write) {
if (update)
tv.tv_usec = 1000;
} else {
tv.tv_usec = 100000;
}
}
const int ret = select(last_fd, &rfds, &wfds, NULL, &tv);
const int ret = select(last_fd, &rfds, &wfds, NULL, update < 0 ? NULL : &tv);
if (ret == -1) {
if (errno == EBADF) {
@@ -267,17 +255,10 @@ gt_bind(int argc, char **argv)
continue;
}
if (FD_ISSET(tun_fd, &rfds))
tun_can_read = 1;
if (FD_ISSET(tun_fd, &wfds))
tun_can_write = 1;
if (FD_ISSET(mud_fd, &rfds))
mud_can_read = 1;
if (FD_ISSET(mud_fd, &wfds))
mud_can_write = 1;
if (FD_ISSET(tun_fd, &rfds)) tun_can_read = 1;
if (FD_ISSET(tun_fd, &wfds)) tun_can_write = 1;
if (FD_ISSET(mud_fd, &rfds)) mud_can_read = 1;
if (FD_ISSET(mud_fd, &wfds)) mud_can_write = 1;
mtu = gt_setup_mtu(mud, mtu, tun_name);
@@ -286,7 +267,7 @@ gt_bind(int argc, char **argv)
int r = tun_read(tun_fd, buf, sizeof(buf));
if (r > 0 && !ip_get_common(&ic, buf, r)) {
mud_send(mud, buf, (size_t)r, ic.tc);
mud_send(mud, buf, (size_t)r);
mud_can_write = 0;
}
@@ -320,9 +301,25 @@ gt_bind(int argc, char **argv)
break;
case CTL_STATE:
if (mud_set_state(mud, (struct sockaddr *)&req.path.addr,
req.path.state, req.path.rate_tx, req.path.rate_rx))
req.path.state,
req.path.rate_tx,
req.path.rate_rx,
req.path.beat,
req.path.fixed_rate))
res.ret = errno;
break;
case CTL_CONF:
if (mud_set_conf(mud, &req.conf))
res.ret = errno;
break;
case CTL_STATUS:
memcpy(res.status.tun_name, tun_name, sizeof(tun_name)); // XXX
res.status.pid = pid;
res.status.mtu = mtu;
res.status.chacha = chacha;
res.status.bind = bind_addr;
res.status.peer = peer_addr;
break;
case CTL_PATH_STATUS:
{
unsigned count = 0;
@@ -346,30 +343,6 @@ gt_bind(int argc, char **argv)
res.ret = 0;
}
break;
case CTL_MTU:
mud_set_mtu(mud, req.mtu);
res.mtu = mtu = gt_setup_mtu(mud, mtu, tun_name);
break;
case CTL_TC:
if (mud_set_tc(mud, req.tc))
res.ret = errno;
break;
case CTL_KXTIMEOUT:
if (mud_set_keyx_timeout(mud, req.ms))
res.ret = errno;
break;
case CTL_TIMETOLERANCE:
if (mud_set_time_tolerance(mud, req.ms))
res.ret = errno;
break;
case CTL_STATUS:
memcpy(res.status.tun_name, tun_name, sizeof(tun_name)); // XXX
res.status.pid = pid;
res.status.mtu = mtu;
res.status.chacha = chacha;
res.status.bind = bind_addr;
res.status.peer = peer_addr;
break;
case CTL_BAD:
if (mud_get_bad(mud, &res.bad))
res.ret = errno;

View File

@@ -21,10 +21,6 @@
#define PACKAGE_VERSION "0.0.0"
#endif
#ifndef GT_RUNDIR
#define GT_RUNDIR "/run/" PACKAGE_NAME
#endif
#define COUNT(x) (sizeof(x)/sizeof(x[0]))
#define ALIGN_SIZE (1<<4)

View File

@@ -5,11 +5,45 @@
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <libgen.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/un.h>
char *
ctl_rundir(char *dst, size_t size)
{
if (dst && size)
dst[0] = 0;
const char *fmt[] = {
"/run/user/%u/" PACKAGE_NAME,
"/run/" PACKAGE_NAME ".%u",
"/var/run/" PACKAGE_NAME ".%u",
"/tmp/" PACKAGE_NAME ".%u",
};
for (unsigned i = 0; i < COUNT(fmt); i++) {
char path[128];
int ret = snprintf(dst, size, fmt[i], geteuid());
if ((ret <= 0) ||
((size_t)ret >= size) ||
((size_t)ret >= sizeof(path)))
continue;
memcpy(path, dst, (size_t)ret + 1);
char *p = dirname(path);
if (p && !access(p, W_OK))
return dst;
}
errno = EINTR;
return NULL;
}
int
ctl_reply(int fd, struct ctl_msg *res, struct ctl_msg *req)
{
@@ -88,12 +122,12 @@ ctl_delete(int fd)
}
int
ctl_create(const char *dir, const char *file)
ctl_create(const char *file)
{
if (str_empty(dir)) {
errno = EINVAL;
char dir[64];
if (!ctl_rundir(dir, sizeof(dir)))
return -1;
}
if (mkdir(dir, 0700) == -1 && errno != EEXIST)
return -1;
@@ -111,14 +145,13 @@ ctl_create(const char *dir, const char *file)
}
int
ctl_connect(const char *dir, const char *file)
ctl_connect(const char *file)
{
char dir[64];
DIR *dp = NULL;
if (str_empty(dir)) {
errno = EINVAL;
if (!ctl_rundir(dir, sizeof(dir)))
return -1;
}
if (!file) {
if (dp = opendir(dir), !dp)
@@ -156,9 +189,10 @@ ctl_connect(const char *dir, const char *file)
if (ret)
return -1;
int fd = ctl_create(dir, NULL);
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (connect(fd, (struct sockaddr *)&sun, sizeof(sun))) {
if (ctl_bind(fd, dir, NULL) ||
connect(fd, (struct sockaddr *)&sun, sizeof(sun))) {
int err = errno;
ctl_delete(fd);
errno = err;

View File

@@ -10,11 +10,8 @@
enum ctl_type {
CTL_NONE = 0,
CTL_STATE,
CTL_CONF,
CTL_STATUS,
CTL_MTU,
CTL_TC,
CTL_KXTIMEOUT,
CTL_TIMETOLERANCE,
CTL_PATH_STATUS,
CTL_BAD,
};
@@ -28,8 +25,9 @@ struct ctl_msg {
enum mud_state state;
unsigned long rate_tx;
unsigned long rate_rx;
unsigned long beat;
unsigned char fixed_rate;
} path;
struct mud_path path_status;
struct {
char tun_name[64];
long pid;
@@ -38,14 +36,14 @@ struct ctl_msg {
struct sockaddr_storage bind;
struct sockaddr_storage peer;
} status;
struct mud_conf conf;
struct mud_path path_status;
struct mud_bad bad;
size_t mtu;
int tc;
unsigned long ms;
};
};
int ctl_create (const char *, const char *);
int ctl_connect (const char *, const char *);
int ctl_reply (int, struct ctl_msg *, struct ctl_msg *);
void ctl_delete (int);
char *ctl_rundir (char *, size_t);
int ctl_create (const char *);
int ctl_connect (const char *);
int ctl_reply (int, struct ctl_msg *, struct ctl_msg *);
void ctl_delete (int);

View File

@@ -31,8 +31,6 @@ gt_path_print_status(struct mud_path *path, int term)
default: return;
}
const char *statusstr = path->ok ? "OK" : "DEGRADED";
printf(term ? "path %s\n"
" status: %s\n"
" bind: %s port %"PRIu16"\n"
@@ -41,6 +39,8 @@ gt_path_print_status(struct mud_path *path, int term)
" mtu: %zu bytes\n"
" rtt: %.3f ms\n"
" rttvar: %.3f ms\n"
" rate: %s\n"
" beat: %"PRIu64" ms\n"
" tx:\n"
" rate: %"PRIu64" bytes/sec\n"
" loss: %"PRIu64" percent\n"
@@ -52,11 +52,13 @@ gt_path_print_status(struct mud_path *path, int term)
: "path %s %s"
" %s %"PRIu16" %s %"PRIu16" %s %"PRIu16
" %zu %.3f %.3f"
" %s"
" %"PRIu64
" %"PRIu64" %"PRIu64" %"PRIu64
" %"PRIu64" %"PRIu64" %"PRIu64
"\n",
statestr,
statusstr,
path->ok ? "OK" : "DEGRADED",
bindstr[0] ? bindstr : "-",
gt_get_port((struct sockaddr *)&path->local_addr),
publstr[0] ? publstr : "-",
@@ -66,11 +68,13 @@ gt_path_print_status(struct mud_path *path, int term)
path->mtu.ok,
(double)path->rtt.val / 1e3,
(double)path->rtt.var / 1e3,
path->conf.fixed_rate ? "fixed" : "auto",
path->conf.beat / 1000,
path->tx.rate,
path->tx.loss,
path->tx.loss * 100 / 255,
path->tx.total,
path->rx.rate,
path->rx.loss,
path->rx.loss * 100 / 255,
path->rx.total);
}
@@ -96,7 +100,7 @@ gt_path_cmp_addr(struct sockaddr_storage *a, struct sockaddr_storage *b)
}
static int
gt_path_status(int fd, int state, struct sockaddr_storage *addr)
gt_path_status(int fd, enum mud_state state, struct sockaddr_storage *addr)
{
struct ctl_msg req = {
.type = CTL_PATH_STATUS,
@@ -150,6 +154,7 @@ gt_path(int argc, char **argv)
}, res = {0};
struct argz ratez[] = {
{"fixed|auto", NULL, NULL, argz_option},
{"tx", "BYTES/SEC", &req.path.rate_tx, argz_bytes},
{"rx", "BYTES/SEC", &req.path.rate_rx, argz_bytes},
{NULL}};
@@ -159,12 +164,13 @@ gt_path(int argc, char **argv)
{"dev", "NAME", &dev, argz_str},
{"up|backup|down", NULL, NULL, argz_option},
{"rate", NULL, &ratez, argz_option},
{"beat", "SECONDS", &req.path.beat, argz_time},
{NULL}};
if (argz(pathz, argc, argv))
return 1;
int fd = ctl_connect(GT_RUNDIR, dev);
int fd = ctl_connect(dev);
if (fd < 0) {
switch (fd) {
@@ -198,6 +204,12 @@ gt_path(int argc, char **argv)
req.path.state = MUD_DOWN;
}
if (argz_is_set(ratez, "fixed")) {
req.path.fixed_rate = 3;
} else if (argz_is_set(ratez, "auto")) {
req.path.fixed_rate = 1;
}
int ret;
if (!req.path.addr.ss_family ||

112
src/set.c
View File

@@ -7,80 +7,6 @@
#include "../argz/argz.h"
static int
gt_set_mtu(int fd, size_t mtu)
{
struct ctl_msg res, req = {
.type = CTL_MTU,
.mtu = mtu,
};
int ret = ctl_reply(fd, &res, &req);
if (ret) {
perror("set mtu");
return 1;
}
printf("mtu set to %zu\n", res.mtu);
return 0;
}
static int
gt_set_kxtimeout(int fd, unsigned long ms)
{
struct ctl_msg res, req = {
.type = CTL_KXTIMEOUT,
.ms = ms,
};
int ret = ctl_reply(fd, &res, &req);
if (ret) {
perror("set kxtimeout");
return 1;
}
return 0;
}
static int
gt_set_timetolerance(int fd, unsigned long ms)
{
struct ctl_msg res, req = {
.type = CTL_TIMETOLERANCE,
.ms = ms,
};
int ret = ctl_reply(fd, &res, &req);
if (ret) {
perror("set timetolerance");
return 1;
}
return 0;
}
static int
gt_set_tc(int fd, int tc)
{
struct ctl_msg res, req = {
.type = CTL_TC,
.tc = tc,
};
int ret = ctl_reply(fd, &res, &req);
if (ret) {
perror("set tc");
return 1;
}
return 0;
}
static int
gt_argz_tc(void *data, int argc, char **argv)
{
@@ -102,7 +28,7 @@ gt_argz_tc(void *data, int argc, char **argv)
} else return -1;
if (data)
*(int *)data = val;
*(int *)data = (val << 1) | 1;
return 1;
}
@@ -111,23 +37,24 @@ int
gt_set(int argc, char **argv)
{
const char *dev = NULL;
size_t mtu;
int tc;
unsigned long kxtimeout;
unsigned long timetolerance;
struct ctl_msg req = {
.type = CTL_CONF,
}, res = {0};
struct argz pathz[] = {
{"dev", "NAME", &dev, argz_str},
{"mtu", "BYTES", &mtu, argz_bytes},
{"tc", "CS|AF|EF", &tc, gt_argz_tc},
{"kxtimeout", "SECONDS", &kxtimeout, argz_time},
{"timetolerance", "SECONDS", &timetolerance, argz_time},
{"tc", "CS|AF|EF", &req.conf.tc, gt_argz_tc},
{"kxtimeout", "SECONDS", &req.conf.kxtimeout, argz_time},
{"timetolerance", "SECONDS", &req.conf.timetolerance, argz_time},
{"losslimit", "PERCENT", &req.conf.losslimit, argz_percent},
{"keepalive", "SECONDS", &req.conf.keepalive, argz_time},
{NULL}};
if (argz(pathz, argc, argv))
return 1;
int fd = ctl_connect(GT_RUNDIR, dev);
int fd = ctl_connect(dev);
if (fd < 0) {
switch (fd) {
@@ -146,21 +73,12 @@ gt_set(int argc, char **argv)
return 1;
}
int ret = 0;
int ret = ctl_reply(fd, &res, &req);
if (argz_is_set(pathz, "mtu"))
ret |= gt_set_mtu(fd, mtu);
if (argz_is_set(pathz, "tc"))
ret |= gt_set_tc(fd, tc);
if (argz_is_set(pathz, "kxtimeout"))
ret |= gt_set_kxtimeout(fd, kxtimeout);
if (argz_is_set(pathz, "timetolerance"))
ret |= gt_set_timetolerance(fd, timetolerance);
if (ret)
perror("set");
ctl_delete(fd);
return ret;
return !!ret;
}

View File

@@ -129,7 +129,7 @@ gt_show(int argc, char **argv)
if (argz(showz, argc, argv))
return 1;
int fd = ctl_connect(GT_RUNDIR, dev);
int fd = ctl_connect(dev);
if (fd < 0) {
switch (fd) {