Rework command set

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2020-04-17 21:36:41 +00:00
parent 3622f928ca
commit dafc7e8106
6 changed files with 125 additions and 16 deletions

2
mud

Submodule mud updated: a4e72918df...faeb599a19

View File

@@ -310,6 +310,7 @@ gt_bind(int argc, char **argv)
case CTL_CONF: case CTL_CONF:
if (mud_set_conf(mud, &req.conf)) if (mud_set_conf(mud, &req.conf))
res.ret = errno; res.ret = errno;
res.conf = req.conf;
break; break;
case CTL_STATUS: case CTL_STATUS:
memcpy(res.status.tun_name, tun_name, sizeof(tun_name)); // XXX memcpy(res.status.tun_name, tun_name, sizeof(tun_name)); // XXX

View File

@@ -114,3 +114,79 @@ gt_toaddr(char *str, size_t size, struct sockaddr *sa)
errno = EAFNOSUPPORT; errno = EAFNOSUPPORT;
return -1; return -1;
} }
int
gt_totime(char *str, size_t size, unsigned long long t)
{
if (!str || size < 4) {
errno = EINVAL;
return -1;
}
if (!t) {
memcpy(str, "now", 4);
return 0;
}
struct {
unsigned long long v;
unsigned long long n;
char *name;
} u[] = {
{0, 1000, "ms"},
{0, 60, "s"},
{0, 60, "m"},
{0, 24, "h"},
{0, 0, "d"},
};
size_t len = 0;
unsigned i = 0;
while (u[i].n) {
u[i].v = t % u[i].n;
t /= u[i].n;
i++;
}
u[i++].v = t;
while (i--)
if (u[i].v) {
int ret = snprintf(str + len, size - len, "%llu%s", u[i].v, u[i].name);
if (ret <= 0 || (size_t)ret >= size - len) {
errno = EINVAL;
return -1;
}
len += ret;
}
return 0;
}
int
gt_torate(char *str, size_t size, unsigned long long r)
{
if (!str || size < 5) {
errno = EINVAL;
return -1;
}
unsigned k = 0;
while (r && k < 4 && !(r % 1000)) {
r /= 1000;
k++;
}
int ret = snprintf(str, size, "%llu%sbit%s", r,
&"\0\0k\0M\0G\0T"[k << 1],
&"s"[r <= 1]);
if (ret <= 0 || (size_t)ret >= size) {
errno = EINVAL;
return -1;
}
return 0;
}

View File

@@ -61,6 +61,8 @@ void gt_set_port (struct sockaddr *, uint16_t);
uint16_t gt_get_port (struct sockaddr *); uint16_t gt_get_port (struct sockaddr *);
int gt_toaddr (char *, size_t, struct sockaddr *); int gt_toaddr (char *, size_t, struct sockaddr *);
int gt_totime (char *, size_t, unsigned long long);
int gt_torate (char *, size_t, unsigned long long);
int gt_list (int, char **); int gt_list (int, char **);
int gt_show (int, char **); int gt_show (int, char **);

View File

@@ -10,6 +10,8 @@ gt_path_print(struct mud_path *path, int term)
{ {
const char *statestr = NULL; const char *statestr = NULL;
char bindstr[INET6_ADDRSTRLEN]; char bindstr[INET6_ADDRSTRLEN];
char beatstr[32];
char txstr[32], rxstr[32];
switch (path->state) { switch (path->state) {
case MUD_UP: statestr = "up"; break; case MUD_UP: statestr = "up"; break;
@@ -22,15 +24,23 @@ gt_path_print(struct mud_path *path, int term)
(struct sockaddr *)&path->local_addr)) (struct sockaddr *)&path->local_addr))
return; return;
printf(term ? "path %s %s losslimit %u%% beat %"PRIu64"ms " if (gt_totime(beatstr, sizeof(beatstr), path->conf.beat / 1000))
"rate %s tx %"PRIu64" rx %"PRIu64"\n" return;
: "path %s %s %u %"PRIu64" %s %"PRIu64" %"PRIu64"\n",
if (gt_torate(txstr, sizeof(txstr), path->conf.tx_max_rate * 8))
return;
if (gt_torate(rxstr, sizeof(rxstr), path->conf.rx_max_rate * 8))
return;
printf(term ? "path %s %s losslimit %u%% beat %s "
"rate %s tx %s rx %s\n"
: "path %s %s %u %s %s %s %s\n",
statestr, bindstr, statestr, bindstr,
path->conf.loss_limit * 100U / 255U, path->conf.loss_limit * 100U / 255U,
path->conf.beat / 1000, beatstr,
path->conf.fixed_rate ? "fixed" : "auto", path->conf.fixed_rate ? "fixed" : "auto",
path->conf.tx_max_rate, txstr, rxstr);
path->conf.rx_max_rate);
} }
static int static int

View File

@@ -26,7 +26,7 @@ gt_argz_tc(void *data, int argc, char **argv)
} else return -1; } else return -1;
if (data) if (data)
*(int *)data = (val << 1) | 1; *(int *)data = val;
return 1; return 1;
} }
@@ -35,22 +35,32 @@ int
gt_set(int argc, char **argv) gt_set(int argc, char **argv)
{ {
const char *dev = NULL; const char *dev = NULL;
unsigned long kxtimeout;
struct ctl_msg req = { unsigned long timetolerance;
.type = CTL_CONF, unsigned long keepalive;
}, res = {0}; int tc;
struct argz pathz[] = { struct argz pathz[] = {
{"dev", "NAME", &dev, argz_str}, {"dev", "NAME", &dev, argz_str},
{"tc", "CS|AF|EF", &req.conf.tc, gt_argz_tc}, {"tc", "CS|AF|EF", &tc, gt_argz_tc},
{"kxtimeout", "SECONDS", &req.conf.kxtimeout, argz_time}, {"kxtimeout", "SECONDS", &kxtimeout, argz_time},
{"timetolerance", "SECONDS", &req.conf.timetolerance, argz_time}, {"timetolerance", "SECONDS", &timetolerance, argz_time},
{"keepalive", "SECONDS", &req.conf.keepalive, argz_time}, {"keepalive", "SECONDS", &keepalive, argz_time},
{NULL}}; {NULL}};
if (argz(pathz, argc, argv)) if (argz(pathz, argc, argv))
return 1; return 1;
struct ctl_msg req = {
.type = CTL_CONF,
.conf = {
.tc = tc ? (tc << 1) | 1 : 0,
.kxtimeout = kxtimeout * UINT64_C(1000),
.timetolerance = timetolerance * UINT64_C(1000),
.keepalive = keepalive * UINT64_C(1000),
},
}, res = {0};
int fd = ctl_connect(dev); int fd = ctl_connect(dev);
if (fd < 0) { if (fd < 0) {
@@ -60,6 +70,16 @@ gt_set(int argc, char **argv)
int ret = ctl_reply(fd, &res, &req); int ret = ctl_reply(fd, &res, &req);
char t0[32];
char t1[32];
char t2[32];
gt_totime(t0, sizeof(t0), res.conf.kxtimeout / 1000);
gt_totime(t1, sizeof(t1), res.conf.timetolerance / 1000);
gt_totime(t2, sizeof(t2), res.conf.keepalive / 1000);
printf("set kxtimeout %s timetolerance %s keepalive %s tc %i\n", t0, t1, t2, res.conf.tc);
if (ret) if (ret)
perror("set"); perror("set");