Code cleanup

This commit is contained in:
Adrien Gallouët
2016-12-08 10:08:46 +00:00
parent cb9ecb592f
commit c156aa68e3

196
mud.c
View File

@@ -52,12 +52,12 @@
#define MUD_PACKET_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE) #define MUD_PACKET_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE)
#define MUD_PACKET_MAX_SIZE (1500U) #define MUD_PACKET_MAX_SIZE (1500U)
#define MUD_PONG_TIMEOUT (100 * MUD_ONE_MSEC) #define MUD_STAT_TIMEOUT (100 * MUD_ONE_MSEC)
#define MUD_KEYX_TIMEOUT (60 * MUD_ONE_MIN) #define MUD_KEYX_TIMEOUT (60 * MUD_ONE_MIN)
#define MUD_SEND_TIMEOUT (MUD_ONE_SEC) #define MUD_SEND_TIMEOUT (MUD_ONE_SEC)
#define MUD_TIME_TOLERANCE (10 * MUD_ONE_MIN) #define MUD_TIME_TOLERANCE (10 * MUD_ONE_MIN)
struct ipaddr { struct mud_ipaddr {
int family; int family;
union { union {
struct in_addr v4; struct in_addr v4;
@@ -65,11 +65,11 @@ struct ipaddr {
} ip; } ip;
}; };
struct path { struct mud_path {
struct { struct {
unsigned active : 1; unsigned active : 1;
} state; } state;
struct ipaddr local_addr; struct mud_ipaddr local_addr;
struct sockaddr_storage addr; struct sockaddr_storage addr;
struct { struct {
unsigned char data[256]; unsigned char data[256];
@@ -92,16 +92,16 @@ struct path {
uint64_t limit; uint64_t limit;
uint64_t recv_time; uint64_t recv_time;
uint64_t send_time; uint64_t send_time;
uint64_t pong_time; uint64_t stat_time;
struct path *next; struct mud_path *next;
}; };
struct crypto_pub { struct mud_crypto_pub {
unsigned char send[MUD_PUB_SIZE + 1]; unsigned char send[MUD_PUB_SIZE + 1];
unsigned char recv[MUD_PUB_SIZE + 1]; unsigned char recv[MUD_PUB_SIZE + 1];
}; };
struct crypto_opt { struct mud_crypto_opt {
unsigned char *dst; unsigned char *dst;
struct { struct {
const unsigned char *data; const unsigned char *data;
@@ -110,7 +110,7 @@ struct crypto_opt {
unsigned char npub[16]; unsigned char npub[16];
}; };
struct crypto_key { struct mud_crypto_key {
struct { struct {
unsigned char key[MUD_KEY_SIZE]; unsigned char key[MUD_KEY_SIZE];
crypto_aead_aes256gcm_state state; crypto_aead_aes256gcm_state state;
@@ -118,30 +118,9 @@ struct crypto_key {
int aes; int aes;
}; };
struct mud { enum mud_packet_code {
int fd;
uint64_t send_timeout;
uint64_t time_tolerance;
struct path *path;
struct {
uint64_t recv_time;
uint64_t send_time;
unsigned char secret[crypto_scalarmult_SCALARBYTES];
struct crypto_pub public;
struct crypto_key private, last, next, current;
int use_next;
int aes;
} crypto;
struct {
uint64_t send_time;
int remote;
int local;
} mtu;
};
enum mud_msg {
mud_ping, mud_ping,
mud_pong, mud_stat,
mud_keyx, mud_keyx,
mud_mtux, mud_mtux,
mud_bakx, mud_bakx,
@@ -158,16 +137,37 @@ struct mud_packet {
unsigned char sdt[MUD_U48_SIZE]; unsigned char sdt[MUD_U48_SIZE];
unsigned char rdt[MUD_U48_SIZE]; unsigned char rdt[MUD_U48_SIZE];
unsigned char rst[MUD_U48_SIZE]; unsigned char rst[MUD_U48_SIZE];
} pong; } stat;
struct crypto_pub public; struct mud_crypto_pub public;
unsigned char mtu[MUD_U48_SIZE]; unsigned char mtu[MUD_U48_SIZE];
unsigned char backup; unsigned char backup;
} data; } data;
unsigned char _do_not_use_[MUD_MAC_SIZE]; unsigned char _do_not_use_[MUD_MAC_SIZE];
}; };
struct mud {
int fd;
uint64_t send_timeout;
uint64_t time_tolerance;
struct mud_path *path;
struct {
uint64_t recv_time;
uint64_t send_time;
unsigned char secret[crypto_scalarmult_SCALARBYTES];
struct mud_crypto_pub public;
struct mud_crypto_key private, last, next, current;
int use_next;
int aes;
} crypto;
struct {
uint64_t send_time;
int remote;
int local;
} mtu;
};
static int static int
mud_encrypt_opt(const struct crypto_key *k, const struct crypto_opt *c) mud_encrypt_opt(const struct mud_crypto_key *k, const struct mud_crypto_opt *c)
{ {
if (k->aes) { if (k->aes) {
return crypto_aead_aes256gcm_encrypt_afternm( return crypto_aead_aes256gcm_encrypt_afternm(
@@ -182,7 +182,7 @@ mud_encrypt_opt(const struct crypto_key *k, const struct crypto_opt *c)
} }
static int static int
mud_decrypt_opt(const struct crypto_key *k, const struct crypto_opt *c) mud_decrypt_opt(const struct mud_crypto_key *k, const struct mud_crypto_opt *c)
{ {
if (k->aes) { if (k->aes) {
return crypto_aead_aes256gcm_decrypt_afternm( return crypto_aead_aes256gcm_decrypt_afternm(
@@ -306,7 +306,7 @@ mud_addrinfo(struct sockaddr_storage *addr, const char *host, int port)
} }
static ssize_t static ssize_t
mud_send_path(struct mud *mud, struct path *path, uint64_t now, mud_send_path(struct mud *mud, struct mud_path *path, uint64_t now,
void *data, size_t size, int tc) void *data, size_t size, int tc)
{ {
if (!size) if (!size)
@@ -342,7 +342,7 @@ mud_sso_int(int fd, int level, int optname, int opt)
} }
static int static int
mud_cmp_ipaddr(struct ipaddr *a, struct ipaddr *b) mud_cmp_ipaddr(struct mud_ipaddr *a, struct mud_ipaddr *b)
{ {
if (a == b) if (a == b)
return 0; return 0;
@@ -390,7 +390,7 @@ mud_cmp_addr(struct sockaddr *a, struct sockaddr *b)
} }
static void static void
mud_set_path(struct path *path, struct ipaddr *local_addr, mud_set_path(struct mud_path *path, struct mud_ipaddr *local_addr,
struct sockaddr *addr) struct sockaddr *addr)
{ {
struct msghdr msg = { struct msghdr msg = {
@@ -401,7 +401,7 @@ mud_set_path(struct path *path, struct ipaddr *local_addr,
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
memset(path->ctrl.data, 0, sizeof(path->ctrl.data)); memset(path->ctrl.data, 0, sizeof(path->ctrl.data));
memmove(&path->local_addr, local_addr, sizeof(struct ipaddr)); memmove(&path->local_addr, local_addr, sizeof(struct mud_ipaddr));
if (addr->sa_family == AF_INET) { if (addr->sa_family == AF_INET) {
memmove(&path->addr, addr, sizeof(struct sockaddr_in)); memmove(&path->addr, addr, sizeof(struct sockaddr_in));
@@ -448,14 +448,14 @@ mud_set_path(struct path *path, struct ipaddr *local_addr,
} }
} }
static struct path * static struct mud_path *
mud_path(struct mud *mud, struct ipaddr *local_addr, mud_path(struct mud *mud, struct mud_ipaddr *local_addr,
struct sockaddr *addr, int create) struct sockaddr *addr, int create)
{ {
if (local_addr->family != addr->sa_family) if (local_addr->family != addr->sa_family)
return NULL; return NULL;
struct path *path; struct mud_path *path;
for (path = mud->path; path; path = path->next) { for (path = mud->path; path; path = path->next) {
if (mud_cmp_ipaddr(local_addr, &path->local_addr)) if (mud_cmp_ipaddr(local_addr, &path->local_addr))
@@ -470,7 +470,7 @@ mud_path(struct mud *mud, struct ipaddr *local_addr,
if (path || !create) if (path || !create)
return path; return path;
path = calloc(1, sizeof(struct path)); path = calloc(1, sizeof(struct mud_path));
if (!path) if (!path)
return NULL; return NULL;
@@ -483,27 +483,6 @@ mud_path(struct mud *mud, struct ipaddr *local_addr,
return path; return path;
} }
static int
mud_ipaddrinfo(struct ipaddr *ipaddr, const char *name)
{
if (!name) {
errno = EINVAL;
return -1;
}
if (inet_pton(AF_INET, name, &ipaddr->ip.v4) == 1) {
ipaddr->family = AF_INET;
return 0;
}
if (inet_pton(AF_INET6, name, &ipaddr->ip.v6) == 1) {
ipaddr->family = AF_INET6;
return 0;
}
return -1;
}
int int
mud_peer(struct mud *mud, const char *name, const char *host, int port, mud_peer(struct mud *mud, const char *name, const char *host, int port,
int backup) int backup)
@@ -513,10 +492,18 @@ mud_peer(struct mud *mud, const char *name, const char *host, int port,
return -1; return -1;
} }
struct ipaddr local_addr; struct mud_ipaddr local_addr;
if (mud_ipaddrinfo(&local_addr, name)) if (inet_pton(AF_INET, name, &local_addr.ip.v4) == 1) {
local_addr.family = AF_INET;
} else {
if (inet_pton(AF_INET6, name, &local_addr.ip.v6) == 1) {
local_addr.family = AF_INET6;
} else {
errno = EINVAL;
return -1; return -1;
}
}
struct sockaddr_storage addr; struct sockaddr_storage addr;
@@ -525,7 +512,7 @@ mud_peer(struct mud *mud, const char *name, const char *host, int port,
mud_unmapv4((struct sockaddr *)&addr); mud_unmapv4((struct sockaddr *)&addr);
struct path *path = mud_path(mud, &local_addr, (struct sockaddr *)&addr, 1); struct mud_path *path = mud_path(mud, &local_addr, (struct sockaddr *)&addr, 1);
if (!path) { if (!path) {
errno = ENOMEM; errno = ENOMEM;
@@ -719,7 +706,7 @@ mud_delete(struct mud *mud)
return; return;
while (mud->path) { while (mud->path) {
struct path *path = mud->path; struct mud_path *path = mud->path;
mud->path = path->next; mud->path = path->next;
free(path); free(path);
} }
@@ -746,7 +733,7 @@ mud_encrypt(struct mud *mud, uint64_t nonce,
if (size > dst_size) if (size > dst_size)
return 0; return 0;
struct crypto_opt opt = { struct mud_crypto_opt opt = {
.dst = dst + MUD_U48_SIZE, .dst = dst + MUD_U48_SIZE,
.src = { .src = {
.data = src, .data = src,
@@ -779,7 +766,7 @@ mud_decrypt(struct mud *mud,
if (size > dst_size) if (size > dst_size)
return 0; return 0;
struct crypto_opt opt = { struct mud_crypto_opt opt = {
.dst = dst, .dst = dst,
.src = { .src = {
.data = src + MUD_U48_SIZE, .data = src + MUD_U48_SIZE,
@@ -809,7 +796,7 @@ mud_decrypt(struct mud *mud,
} }
static int static int
mud_localaddr(struct ipaddr *local_addr, struct msghdr *msg, int family) mud_localaddr(struct mud_ipaddr *local_addr, struct msghdr *msg, int family)
{ {
int cmsg_level = IPPROTO_IP; int cmsg_level = IPPROTO_IP;
int cmsg_type = MUD_PKTINFO; int cmsg_type = MUD_PKTINFO;
@@ -852,39 +839,38 @@ mud_packet_size(size_t size)
} }
static void static void
mud_packet_send(struct mud *mud, enum mud_msg msg, struct path *path, mud_packet_send(struct mud *mud, enum mud_packet_code code,
uint64_t now) struct mud_path *path, uint64_t now)
{ {
struct mud_packet packet; struct mud_packet packet;
size_t size = 0; size_t size = 0;
memset(packet.hdr.zero, 0, MUD_U48_SIZE); memset(packet.hdr.zero, 0, MUD_U48_SIZE);
mud_write48(packet.hdr.time, now); mud_write48(packet.hdr.time, now);
packet.hdr.code = (unsigned char)msg; packet.hdr.code = (unsigned char)code;
switch (msg) { switch (code) {
case mud_pong: case mud_stat:
mud_write48(packet.data.pong.sdt, path->sdt); size = sizeof(packet.data.stat);
mud_write48(packet.data.pong.rdt, path->rdt); mud_write48(packet.data.stat.sdt, path->sdt);
mud_write48(packet.data.pong.rst, path->rst); mud_write48(packet.data.stat.rdt, path->rdt);
size = sizeof(packet.data.pong); mud_write48(packet.data.stat.rst, path->rst);
break; break;
case mud_keyx: case mud_keyx:
memcpy(&packet.data.public, &mud->crypto.public,
sizeof(mud->crypto.public));
size = sizeof(packet.data.public); size = sizeof(packet.data.public);
memcpy(&packet.data.public, &mud->crypto.public, size);
break; break;
case mud_mtux: case mud_mtux:
mud_write48(packet.data.mtu, mud->mtu.local);
size = sizeof(packet.data.mtu); size = sizeof(packet.data.mtu);
mud_write48(packet.data.mtu, mud->mtu.local);
break; break;
case mud_bakx: case mud_bakx:
packet.data.backup = (unsigned char)path->bak.local;
size = sizeof(packet.data.backup); size = sizeof(packet.data.backup);
packet.data.backup = (unsigned char)path->bak.local;
break; break;
} }
struct crypto_opt opt = { struct mud_crypto_opt opt = {
.dst = (unsigned char *)&packet.data + size, .dst = (unsigned char *)&packet.data + size,
.ad = { .ad = {
.data = packet.hdr.zero, .data = packet.hdr.zero,
@@ -897,14 +883,14 @@ mud_packet_send(struct mud *mud, enum mud_msg msg, struct path *path,
} }
static void static void
mud_recv_keyx(struct mud *mud, struct path *path, uint64_t now, mud_recv_keyx(struct mud *mud, struct mud_path *path, uint64_t now,
struct crypto_pub *public) struct mud_crypto_pub *public)
{ {
struct crypto_key *key = &mud->crypto.next; struct mud_crypto_key *key = &mud->crypto.next;
struct { struct {
unsigned char secret[crypto_scalarmult_BYTES]; unsigned char secret[crypto_scalarmult_BYTES];
struct crypto_pub public; struct mud_crypto_pub public;
} shared_send, shared_recv; } shared_send, shared_recv;
memcpy(&shared_recv.public, public, sizeof(shared_recv.public)); memcpy(&shared_recv.public, public, sizeof(shared_recv.public));
@@ -959,7 +945,7 @@ mud_recv_keyx(struct mud *mud, struct path *path, uint64_t now,
} }
static void static void
mud_packet_recv(struct mud *mud, struct path *path, uint64_t now, mud_packet_recv(struct mud *mud, struct mud_path *path, uint64_t now,
unsigned char *data, size_t size) unsigned char *data, size_t size)
{ {
struct mud_packet *packet = (struct mud_packet *)data; struct mud_packet *packet = (struct mud_packet *)data;
@@ -968,12 +954,12 @@ mud_packet_recv(struct mud *mud, struct path *path, uint64_t now,
return; return;
switch (packet->hdr.code) { switch (packet->hdr.code) {
case mud_pong: case mud_stat:
if (size < mud_packet_size(sizeof(packet->data.pong))) if (size < mud_packet_size(sizeof(packet->data.stat)))
return; return;
path->r_sdt = mud_read48(packet->data.pong.sdt); path->r_sdt = mud_read48(packet->data.stat.sdt);
path->r_rdt = mud_read48(packet->data.pong.rdt); path->r_rdt = mud_read48(packet->data.stat.rdt);
path->r_rst = mud_read48(packet->data.pong.rst); path->r_rst = mud_read48(packet->data.stat.rst);
path->r_dt = path->rst - path->r_rst; path->r_dt = path->rst - path->r_rst;
path->rtt = now - path->r_rst; path->rtt = now - path->r_rst;
break; break;
@@ -1047,7 +1033,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
if (mud_packet) { if (mud_packet) {
unsigned char tmp[sizeof(packet)]; unsigned char tmp[sizeof(packet)];
struct crypto_opt opt = { struct mud_crypto_opt opt = {
.dst = tmp, .dst = tmp,
.src = { .src = {
.data = packet + packet_size - MUD_MAC_SIZE, .data = packet + packet_size - MUD_MAC_SIZE,
@@ -1064,12 +1050,12 @@ mud_recv(struct mud *mud, void *data, size_t size)
mud_unmapv4((struct sockaddr *)&addr); mud_unmapv4((struct sockaddr *)&addr);
struct ipaddr local_addr; struct mud_ipaddr local_addr;
if (mud_localaddr(&local_addr, &msg, addr.ss_family)) if (mud_localaddr(&local_addr, &msg, addr.ss_family))
return 0; return 0;
struct path *path = mud_path(mud, &local_addr, struct mud_path *path = mud_path(mud, &local_addr,
(struct sockaddr *)&addr, mud_packet); (struct sockaddr *)&addr, mud_packet);
if (!path) if (!path)
@@ -1086,9 +1072,9 @@ mud_recv(struct mud *mud, void *data, size_t size)
path->rst = send_time; path->rst = send_time;
if ((!path->bak.local) && (path->recv_time) && if ((!path->bak.local) && (path->recv_time) &&
(mud_timeout(now, path->pong_time, MUD_PONG_TIMEOUT))) { (mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT))) {
mud_packet_send(mud, mud_pong, path, now); mud_packet_send(mud, mud_stat, path, now);
path->pong_time = now; path->stat_time = now;
} }
path->recv_time = now; path->recv_time = now;
@@ -1115,7 +1101,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
static void static void
mud_update(struct mud *mud) mud_update(struct mud *mud)
{ {
struct path *path; struct mud_path *path;
for (path = mud->path; path; path = path->next) { for (path = mud->path; path; path = path->next) {
if (!path->state.active) if (!path->state.active)
@@ -1172,8 +1158,8 @@ mud_send(struct mud *mud, const void *data, size_t size, int tc)
return -1; return -1;
} }
struct path *path; struct mud_path *path;
struct path *path_min = NULL; struct mud_path *path_min = NULL;
int64_t limit_min = INT64_MAX; int64_t limit_min = INT64_MAX;
for (path = mud->path; path; path = path->next) { for (path = mud->path; path; path = path->next) {