diff --git a/src/path.c b/src/path.c index f583002..a3d15a5 100644 --- a/src/path.c +++ b/src/path.c @@ -1,12 +1,55 @@ #include "common.h" #include "ctl.h" #include "str.h" +#include "ssutils.h" #include #include #include "../argz/argz.h" +int +gt_path_status(int fd) +{ + struct ctl_msg req = { + .type = CTL_PATH_STATUS, + }, res = {0}; + + if (send(fd, &req, sizeof(struct ctl_msg), 0) == -1) + return -1; + + do { + if (recv(fd, &res, sizeof(struct ctl_msg), 0) == -1) + return -1; + + char bindstr[INET6_ADDRSTRLEN] = {0}; + char peerstr[INET6_ADDRSTRLEN] = {0}; + + if (gt_ss_addr(bindstr, sizeof(bindstr), &res.path_status.local_addr) || + gt_ss_addr(peerstr, sizeof(peerstr), &res.path_status.addr)) + return -2; + + const char *statestr = NULL; + + switch (res.path_status.state) { + case MUD_UP: statestr = "UP"; break; + case MUD_BACKUP: statestr = "BACKUP"; break; + case MUD_DOWN: statestr = "DOWN"; break; + default: return -2; + } + + printf("path %s\n" + " bind: %s\n" + " peer: %s\n" + " rtt: %.3f\n", + statestr, bindstr, peerstr, + res.path_status.rtt/(double)1e3); + + } while (res.ret == EAGAIN); + + return 0; +} + int gt_path(int argc, char **argv) { @@ -25,33 +68,38 @@ gt_path(int argc, char **argv) if (argz(pathz, argc, argv)) return 1; - if (!req.path.addr.ss_family) { - return 0; // TODO - } - - if (argz_is_set(pathz, "up")) { - req.path.state = MUD_UP; - } else if (argz_is_set(pathz, "backup")) { - req.path.state = MUD_BACKUP; - } else if (argz_is_set(pathz, "down")) { - req.path.state = MUD_DOWN; - } else { - return 0; // TODO - } - int fd = ctl_connect("/run/" PACKAGE_NAME, dev); if (fd == -1) { - perror("path"); - return 1; - } - - if (ctl_reply(fd, &res, &req)) { perror("path"); ctl_delete(fd); return 1; } + int ret = 0; + + if (!req.path.addr.ss_family) { + ret = gt_path_status(fd); + + if (ret == -2) + gt_log("bad reply from server\n"); + } else { + if (argz_is_set(pathz, "up")) { + req.path.state = MUD_UP; + } else if (argz_is_set(pathz, "backup")) { + req.path.state = MUD_BACKUP; + } else if (argz_is_set(pathz, "down")) { + req.path.state = MUD_DOWN; + } + + if (req.path.state) + ret = ctl_reply(fd, &res, &req); + } + + if (ret == -1) + perror("path"); + ctl_delete(fd); + return 0; } diff --git a/src/show.c b/src/show.c index e75c592..752ea13 100644 --- a/src/show.c +++ b/src/show.c @@ -1,6 +1,7 @@ #include "common.h" #include "ctl.h" #include "str.h" +#include "ssutils.h" #include "../argz/argz.h" @@ -10,34 +11,6 @@ #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_dev_status(int fd, const char *dev) { diff --git a/src/ssutils.h b/src/ssutils.h new file mode 100644 index 0000000..89056c3 --- /dev/null +++ b/src/ssutils.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +static inline 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 inline 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; +}