Rework controler

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2018-02-20 21:28:17 +00:00
parent dd3ba523a4
commit 99b51efbb3
6 changed files with 82 additions and 120 deletions

View File

@@ -271,59 +271,49 @@ gt_bind(int argc, char **argv)
}
if (FD_ISSET(ctl_fd, &rfds)) {
struct ctl_msg msg, reply = {.type = CTL_REPLY};
struct ctl_msg req, res = {.reply = 1};
struct sockaddr_storage ss;
socklen_t sl = sizeof(ss);
ssize_t r = recvfrom(ctl_fd, &msg, sizeof(msg), 0,
ssize_t r = recvfrom(ctl_fd, &req, sizeof(req), 0,
(struct sockaddr *)&ss, &sl);
if (r == (ssize_t)sizeof(msg)) {
switch (msg.type) {
if (r == (ssize_t)sizeof(req)) {
res.type = req.type;
switch (req.type) {
case CTL_NONE:
break;
case CTL_PATH_ADD:
if (mud_add_path(mud, (struct sockaddr *)&msg.path_addr)) {
reply.reply = errno;
perror("mud_add_path");
}
if (mud_add_path(mud, (struct sockaddr *)&req.path_addr))
res.ret = errno;
break;
case CTL_PATH_DEL:
if (mud_del_path(mud, (struct sockaddr *)&msg.path_addr)) {
reply.reply = errno;
perror("mud_del_path");
}
if (mud_del_path(mud, (struct sockaddr *)&req.path_addr))
res.ret = errno;
break;
case CTL_MTU:
reply.reply = (int)mud_set_mtu(mud, GT_MTU((size_t)msg.mtu));
mtu = gt_setup_mtu(mud, tun_name);
mud_set_mtu(mud, GT_MTU((size_t)req.mtu));
res.mtu = gt_setup_mtu(mud, tun_name);
mtu = res.mtu;
break;
case CTL_TIMEOUT:
reply.reply = mud_set_send_timeout(mud, msg.timeout);
if (mud_set_send_timeout(mud, req.timeout))
res.ret = errno;
break;
case CTL_TIMETOLERANCE:
reply.reply = mud_set_time_tolerance(mud, msg.timetolerance);
if (mud_set_time_tolerance(mud, req.timetolerance))
res.ret = errno;
break;
case CTL_STATUS:
reply = (struct ctl_msg){
.type = CTL_STATUS_REPLY,
.status = {
.mtu = mtu,
.mtu_auto = (icmp_fd != -1),
.chacha = chacha,
.bind = bind_addr,
.peer = peer_addr,
},
};
break;
default:
reply = (struct ctl_msg){
.type = CTL_UNKNOWN,
.unknown = {
.type = msg.type,
},
};
res.status.mtu = mtu;
res.status.mtu_auto = (icmp_fd != -1);
res.status.chacha = chacha;
res.status.bind = bind_addr;
res.status.peer = peer_addr;
break;
}
if (sendto(ctl_fd, &reply, sizeof(reply), 0,
if (sendto(ctl_fd, &res, sizeof(res), 0,
(const struct sockaddr *)&ss, sl) == -1)
perror("sendto(ctl)");
} else if (r == -1 && errno != EAGAIN) {

View File

@@ -8,6 +8,26 @@
#include <sys/stat.h>
#include <sys/un.h>
int
ctl_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))
return -1;
if (res->type != req->type || !res->reply) {
errno = EINTR;
return -1;
}
if (res->ret) {
errno = res->ret;
return -1;
}
return 0;
}
static int
ctl_setsun(struct sockaddr_un *dst, const char *dir, const char *file)
{

View File

@@ -3,23 +3,19 @@
#include <sys/socket.h>
enum ctl_type {
CTL_UNKNOWN,
CTL_NONE = 0,
CTL_PATH_ADD,
CTL_PATH_DEL,
CTL_STATUS,
CTL_STATUS_REPLY,
CTL_MTU,
CTL_TIMEOUT,
CTL_TIMETOLERANCE,
CTL_REPLY,
};
struct ctl_msg {
enum ctl_type type;
int reply, ret;
union {
struct {
enum ctl_type type;
} unknown;
struct sockaddr_storage path_addr;
struct {
size_t mtu;
@@ -31,10 +27,10 @@ struct ctl_msg {
int mtu;
unsigned long timeout;
unsigned long timetolerance;
int reply;
};
};
int ctl_create (const char *, const char *);
int ctl_connect (int, const char *, const char *);
int ctl_reply (int, struct ctl_msg *, struct ctl_msg *);
void ctl_delete (int);

View File

@@ -25,15 +25,15 @@ gt_path(int argc, char **argv)
if (argz(pathz, argc, argv))
return 1;
struct ctl_msg msg;
struct ctl_msg req, res = {0};
if (argz_is_set(pathz, "up")) {
msg = (struct ctl_msg){
req = (struct ctl_msg){
.type = CTL_PATH_ADD,
.path_addr = addr,
};
} else if (argz_is_set(pathz, "down")) {
msg = (struct ctl_msg){
req = (struct ctl_msg){
.type = CTL_PATH_DEL,
.path_addr = addr,
};
@@ -55,30 +55,14 @@ gt_path(int argc, char **argv)
return 1;
}
struct ctl_msg reply;
int ret = 0;
if ((send(fd, &msg, sizeof(msg), 0) == -1) ||
(recv(fd, &reply, sizeof(reply), 0) == -1)) {
perror("send/recv");
ctl_delete(fd);
return 1;
}
switch (reply.type) {
case CTL_REPLY:
if (reply.reply) {
errno = reply.reply;
perror("error");
}
break;
case CTL_UNKNOWN:
printf("unknown command: %i\n", reply.unknown.type);
break;
default:
gt_log("bad reply from server: %i\n", reply.type);
if (ctl_reply(fd, &res, &req)) {
perror(dev);
ret = 1;
}
ctl_delete(fd);
return 0;
return ret;
}

View File

@@ -7,30 +7,6 @@
#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)
{
@@ -39,10 +15,10 @@ gt_set_mtu(int fd, size_t mtu)
.mtu = mtu,
};
int ret = gt_reply(fd, &res, &req);
int ret = ctl_reply(fd, &res, &req);
if (!ret)
printf("new mtu: %i\n", res.reply);
printf("new mtu: %i\n", res.mtu);
return ret;
}
@@ -55,7 +31,7 @@ gt_set_timeout(int fd, unsigned long timeout)
.timeout = timeout,
};
return gt_reply(fd, &res, &req);
return ctl_reply(fd, &res, &req);
}
static int
@@ -66,7 +42,7 @@ gt_set_timetolerance(int fd, unsigned long timetolerance)
.timetolerance = timetolerance,
};
return gt_reply(fd, &res, &req);
return ctl_reply(fd, &res, &req);
}
int
@@ -100,22 +76,24 @@ gt_set(int argc, char **argv)
return 1;
}
int ret = 0;
if (mtu && gt_set_mtu(fd, mtu)) {
perror("mtu");
return 1;
ret = 1;
}
if (timeout && gt_set_timeout(fd, timeout)) {
if (!ret && timeout && gt_set_timeout(fd, timeout)) {
perror("timeout");
return 1;
ret = 1;
}
if (timetolerance && gt_set_timetolerance(fd, timetolerance)) {
if (!ret && timetolerance && gt_set_timetolerance(fd, timetolerance)) {
perror("timetolerance");
return 1;
ret = 1;
}
ctl_delete(fd);
return 0;
return ret;
}

View File

@@ -44,37 +44,31 @@ gt_show_tunnel(int fd, const char *dev)
return -1;
}
struct ctl_msg reply, msg = {
.type = CTL_STATUS,
};
struct ctl_msg res, req = {.type = CTL_STATUS};
if ((send(fd, &msg, sizeof(msg), 0) == -1) ||
(recv(fd, &reply, sizeof(reply), 0) == -1)) {
if (ctl_reply(fd, &res, &req)) {
perror(dev);
return -1;
}
if (reply.type != CTL_STATUS_REPLY)
return -1;
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))
if (gt_ss_addr(bindstr, sizeof(bindstr), &res.status.bind) ||
gt_ss_addr(peerstr, sizeof(peerstr), &res.status.peer))
return -1;
if (reply.status.peer.ss_family == 0) {
if (res.status.peer.ss_family == 0) {
printf("server %s:\n"
" bind: %s port %hu\n"
" mtu: %zu\n"
" auto mtu: %s\n"
" cipher: %s\n",
dev,
bindstr, gt_ss_port(&reply.status.bind),
reply.status.mtu,
reply.status.mtu_auto ? "enabled" : "disabled",
reply.status.chacha ? "chacha20poly1305" : "aes256gcm");
bindstr, gt_ss_port(&res.status.bind),
res.status.mtu,
res.status.mtu_auto ? "enabled" : "disabled",
res.status.chacha ? "chacha20poly1305" : "aes256gcm");
} else {
printf("client %s:\n"
" bind: %s port %hu\n"
@@ -83,11 +77,11 @@ gt_show_tunnel(int fd, const char *dev)
" auto mtu: %s\n"
" cipher: %s\n",
dev,
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.chacha ? "chacha20poly1305" : "aes256gcm");
bindstr, gt_ss_port(&res.status.bind),
peerstr, gt_ss_port(&res.status.peer),
res.status.mtu,
res.status.mtu_auto ? "enabled" : "disabled",
res.status.chacha ? "chacha20poly1305" : "aes256gcm");
}
return 0;