Rework mud_set_conf()

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2020-04-17 21:25:08 +00:00
parent a4e72918df
commit faeb599a19
2 changed files with 33 additions and 57 deletions

84
mud.c
View File

@@ -131,7 +131,6 @@ struct mud_msg {
struct mud_keyx { struct mud_keyx {
uint64_t time; uint64_t time;
uint64_t timeout;
unsigned char secret[crypto_scalarmult_SCALARBYTES]; unsigned char secret[crypto_scalarmult_SCALARBYTES];
unsigned char remote[MUD_PUBKEY_SIZE]; unsigned char remote[MUD_PUBKEY_SIZE];
unsigned char local[MUD_PUBKEY_SIZE]; unsigned char local[MUD_PUBKEY_SIZE];
@@ -143,15 +142,13 @@ struct mud_keyx {
struct mud { struct mud {
int fd; int fd;
int backup; int backup;
uint64_t keepalive; struct mud_conf conf;
uint64_t time_tolerance;
struct sockaddr_storage addr; struct sockaddr_storage addr;
struct mud_path *paths; struct mud_path *paths;
unsigned count; unsigned count;
struct mud_keyx keyx; struct mud_keyx keyx;
uint64_t last_recv_time; uint64_t last_recv_time;
size_t mtu; size_t mtu;
int tc;
struct { struct {
int set; int set;
struct sockaddr_storage addr; struct sockaddr_storage addr;
@@ -408,7 +405,7 @@ mud_send_path(struct mud *mud, struct mud_path *path, uint64_t now,
cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_TOS; cmsg->cmsg_type = IP_TOS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_len = CMSG_LEN(sizeof(int));
memcpy(CMSG_DATA(cmsg), &mud->tc, sizeof(int)); memcpy(CMSG_DATA(cmsg), &mud->conf.tc, sizeof(int));
} else if (path->addr.ss_family == AF_INET6) { } else if (path->addr.ss_family == AF_INET6) {
msg.msg_namelen = sizeof(struct sockaddr_in6); msg.msg_namelen = sizeof(struct sockaddr_in6);
@@ -430,7 +427,7 @@ mud_send_path(struct mud *mud, struct mud_path *path, uint64_t now,
cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_TCLASS; cmsg->cmsg_type = IPV6_TCLASS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_len = CMSG_LEN(sizeof(int));
memcpy(CMSG_DATA(cmsg), &mud->tc, sizeof(int)); memcpy(CMSG_DATA(cmsg), &mud->conf.tc, sizeof(int));
} else { } else {
errno = EAFNOSUPPORT; errno = EAFNOSUPPORT;
return -1; return -1;
@@ -708,59 +705,36 @@ mud_set_key(struct mud *mud, unsigned char *key, size_t size)
return 0; return 0;
} }
static int
mud_set_msec(uint64_t *dst, unsigned long msec)
{
if (!msec)
return 0;
const uint64_t x = msec * MUD_ONE_MSEC;
if ((x >> MUD_TIME_BITS) ||
((uint64_t)msec != x / MUD_ONE_MSEC)) {
errno = ERANGE;
return -1;
}
*dst = x;
return 0;
}
int int
mud_set_conf(struct mud *mud, struct mud_conf *conf) mud_set_conf(struct mud *mud, struct mud_conf *conf)
{ {
uint64_t keepalive = mud->keepalive; struct mud_conf c = mud->conf;
uint64_t timetolerance = mud->time_tolerance; int ret = 0;
uint64_t kxtimeout = mud->keyx.timeout;
int tc = mud->tc;
if (mud_set_msec(&keepalive, conf->keepalive)) if (conf->keepalive)
return -1; c.keepalive = conf->keepalive;
if (mud_set_msec(&timetolerance, conf->timetolerance)) if (conf->timetolerance)
return -2; c.timetolerance = conf->timetolerance;
if (mud_set_msec(&kxtimeout, conf->kxtimeout)) if (conf->kxtimeout)
return -3; c.kxtimeout = conf->kxtimeout;
if (conf->tc & 1) { if (conf->tc & 1) {
tc = conf->tc >> 1; int tc = conf->tc >> 1;
if (tc < 0 || tc > 255) { if (tc < 0 || tc > 255) {
errno = ERANGE; errno = ERANGE;
return -5; ret = -1;
} }
c.tc = tc;
} else if (conf->tc) { } else if (conf->tc) {
errno = EINVAL; errno = EINVAL;
return -5; ret = -1;
} }
mud->keepalive = keepalive; *conf = mud->conf = c;
mud->time_tolerance = timetolerance;
mud->keyx.timeout = kxtimeout;
mud->tc = tc;
return 0; return ret;
} }
size_t size_t
@@ -829,9 +803,11 @@ mud_keyx(struct mud_keyx *kx, unsigned char *remote, int aes)
} }
static int static int
mud_keyx_init(struct mud_keyx *kx, uint64_t now) mud_keyx_init(struct mud *mud, uint64_t now)
{ {
if (!mud_timeout(now, kx->time, kx->timeout)) struct mud_keyx *kx = &mud->keyx;
if (!mud_timeout(now, kx->time, mud->conf.kxtimeout))
return 1; return 1;
static const unsigned char test[crypto_scalarmult_BYTES] = { static const unsigned char test[crypto_scalarmult_BYTES] = {
@@ -908,10 +884,10 @@ mud_create(struct sockaddr *addr)
return NULL; return NULL;
} }
mud->keepalive = 25 * MUD_ONE_SEC; mud->conf.keepalive = 25 * MUD_ONE_SEC;
mud->time_tolerance = 10 * MUD_ONE_MIN; mud->conf.timetolerance = 10 * MUD_ONE_MIN;
mud->keyx.timeout = 60 * MUD_ONE_MIN; mud->conf.kxtimeout = 60 * MUD_ONE_MIN;
mud->tc = 192; // CS6 mud->conf.tc = 192; // CS6
memcpy(&mud->addr, addr, addrlen); memcpy(&mud->addr, addr, addrlen);
@@ -1297,7 +1273,7 @@ mud_recv_msg(struct mud *mud, struct mud_path *path,
if (memcmp(msg->pkey, mud->keyx.remote, MUD_PUBKEY_SIZE)) { if (memcmp(msg->pkey, mud->keyx.remote, MUD_PUBKEY_SIZE)) {
if (!mud->peer.set) if (!mud->peer.set)
mud_keyx_init(&mud->keyx, now); mud_keyx_init(mud, now);
if (mud_keyx(&mud->keyx, msg->pkey, msg->aes)) { if (mud_keyx(&mud->keyx, msg->pkey, msg->aes)) {
mud->bad.keyx.addr = path->addr; mud->bad.keyx.addr = path->addr;
mud->bad.keyx.time = now; mud->bad.keyx.time = now;
@@ -1347,8 +1323,8 @@ mud_recv(struct mud *mud, void *data, size_t size)
mud_unmapv4(&addr); mud_unmapv4(&addr);
if ((MUD_TIME_MASK(now - sent_time) > mud->time_tolerance) && if ((MUD_TIME_MASK(now - sent_time) > mud->conf.timetolerance) &&
(MUD_TIME_MASK(sent_time - now) > mud->time_tolerance)) { (MUD_TIME_MASK(sent_time - now) > mud->conf.timetolerance)) {
mud->bad.difftime.addr = addr; mud->bad.difftime.addr = addr;
mud->bad.difftime.time = now; mud->bad.difftime.time = now;
mud->bad.difftime.count++; mud->bad.difftime.count++;
@@ -1433,7 +1409,7 @@ mud_update(struct mud *mud)
uint64_t now = mud_now(mud); uint64_t now = mud_now(mud);
if (mud->peer.set && !mud_keyx_init(&mud->keyx, now)) if (mud->peer.set && !mud_keyx_init(mud, now))
now = mud_now(mud); now = mud_now(mud);
for (unsigned i = 0; i < mud->count; i++) { for (unsigned i = 0; i < mud->count; i++) {
@@ -1475,7 +1451,7 @@ mud_update(struct mud *mud)
if (path->msg.sent >= MUD_MSG_SENT_MAX) { if (path->msg.sent >= MUD_MSG_SENT_MAX) {
timeout = 2 * MUD_MSG_SENT_MAX * timeout; timeout = 2 * MUD_MSG_SENT_MAX * timeout;
} else if (path->ok && mud_timeout(now, path->idle, MUD_ONE_SEC)) { } else if (path->ok && mud_timeout(now, path->idle, MUD_ONE_SEC)) {
timeout = mud->keepalive; timeout = mud->conf.keepalive;
} }
if (mud_timeout(now, path->msg.time, timeout)) { if (mud_timeout(now, path->msg.time, timeout)) {

6
mud.h
View File

@@ -23,9 +23,9 @@ struct mud_stat {
}; };
struct mud_conf { struct mud_conf {
unsigned long keepalive; uint64_t keepalive;
unsigned long timetolerance; uint64_t timetolerance;
unsigned long kxtimeout; uint64_t kxtimeout;
int tc; int tc;
}; };