Use LSB to mark mud packets

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
Adrien Gallouët
2018-03-15 20:49:43 +00:00
parent 0c037c5831
commit fd48ff08b9

75
mud.c
View File

@@ -64,6 +64,9 @@
#define MUD_MAC_SIZE (16U)
#define MUD_PUB_SIZE (crypto_scalarmult_BYTES)
#define MUD_PACKET(X) ((X) & UINT64_C(1))
#define MUD_PACKET_MARK(X) ((X) | UINT64_C(1))
#define MUD_PACKET_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE)
#define MUD_PACKET_MAX_SIZE (1472U)
@@ -119,7 +122,6 @@ struct mud_addr {
struct mud_packet {
struct {
unsigned char zero[MUD_U48_SIZE];
unsigned char time[MUD_U48_SIZE];
unsigned char kiss[MUD_KISS_SIZE];
struct mud_addr addr;
@@ -239,7 +241,7 @@ mud_now(void)
gettimeofday(&tv, NULL);
now = (tv.tv_sec - MUD_EPOCH) * MUD_ONE_SEC + tv.tv_usec;
#endif
return now;
return now & ~UINT64_C(1);
}
static uint64_t
@@ -809,7 +811,7 @@ mud_create(struct sockaddr *addr)
if (!addr)
return NULL;
uint64_t now = mud_now();
const uint64_t now = mud_now();
if (now >> 48)
return NULL;
@@ -1008,7 +1010,7 @@ mud_packet_send(struct mud *mud, enum mud_packet_code code,
struct mud_packet *packet = (struct mud_packet *)data;
size_t size = 0;
mud_write48(packet->hdr.time, now);
mud_write48(packet->hdr.time, MUD_PACKET_MARK(now));
memcpy(packet->hdr.kiss, mud->local.kiss, sizeof(mud->local.kiss));
if (path->addr.ss_family == AF_INET) {
@@ -1074,25 +1076,28 @@ mud_kiss_path(struct mud *mud, unsigned char *kiss)
}
static int
mud_packet_check_size(unsigned char *data, size_t size)
mud_packet_check(struct mud *mud, unsigned char *data, size_t size)
{
struct mud_packet *packet = (struct mud_packet *)data;
if (size <= MUD_PACKET_SIZE(0))
return 1;
if (packet->hdr.code == mud_conf)
return size != MUD_PACKET_SIZE(sizeof(packet->data.conf));
switch (packet->hdr.code) {
case mud_conf:
if (size != MUD_PACKET_SIZE(sizeof(packet->data.conf)))
return 1;
break;
case mud_stat:
if (size != MUD_PACKET_SIZE(sizeof(packet->data.stat)))
return 1;
break;
case mud_fake:
break;
default:
return 1;
}
if (packet->hdr.code == mud_stat)
return size != MUD_PACKET_SIZE(sizeof(packet->data.stat));
return 0;
}
static int
mud_packet_check(struct mud *mud, unsigned char *data, size_t size)
{
unsigned char tmp[MUD_PACKET_MAX_SIZE];
struct mud_crypto_opt opt = {
@@ -1198,22 +1203,13 @@ mud_recv(struct mud *mud, void *data, size_t size)
.msg_controllen = sizeof(ctrl),
};
ssize_t packet_size = recvmsg(mud->fd, &msg, 0);
const ssize_t packet_size = recvmsg(mud->fd, &msg, 0);
if (packet_size <= (ssize_t)MUD_PACKET_MIN_SIZE)
return -(packet_size == (ssize_t)-1);
uint64_t now = mud_now();
uint64_t send_time = mud_read48(packet);
int mud_packet = !send_time;
if (mud_packet) {
if (mud_packet_check_size(packet, packet_size))
return 0;
send_time = mud_read48(&packet[MUD_U48_SIZE]);
}
const uint64_t now = mud_now();
const uint64_t send_time = mud_read48(packet);
mud_unmapv4(&addr);
@@ -1223,18 +1219,14 @@ mud_recv(struct mud *mud, void *data, size_t size)
return 0;
}
if (mud_packet && mud_packet_check(mud, packet, packet_size))
return 0;
struct sockaddr_storage local_addr;
if (mud_localaddr(&local_addr, &msg, addr.ss_family))
return 0;
int ret = 0;
if (!mud_packet) {
if (MUD_PACKET(send_time)) {
if (mud_packet_check(mud, packet, packet_size))
return 0;
} else {
ret = mud_decrypt(mud, data, size, packet, packet_size);
if (ret == -1) {
mud->bad.decrypt.addr = addr;
mud->bad.decrypt.time = now;
@@ -1242,6 +1234,11 @@ mud_recv(struct mud *mud, void *data, size_t size)
}
}
struct sockaddr_storage local_addr;
if (mud_localaddr(&local_addr, &msg, addr.ss_family))
return 0;
struct mud_path *path = mud_get_path(mud, &local_addr, &addr, 1);
if (!path)
@@ -1257,7 +1254,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
path->mtu.ok = path->recv_max;
}
if (mud_packet) {
if (MUD_PACKET(send_time)) {
mud_packet_recv(mud, path, now, packet, packet_size);
} else if (mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT)) {
mud_packet_send(mud, mud_stat, path, now, MSG_CONFIRM);
@@ -1323,7 +1320,7 @@ int
mud_send(struct mud *mud, const void *data, size_t size, int tc)
{
unsigned char packet[MUD_PACKET_MAX_SIZE];
uint64_t now = mud_now();
const uint64_t now = mud_now();
mud_update(mud, now);