Use LSB to mark mud packets
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
73
mud.c
73
mud.c
@@ -64,6 +64,9 @@
|
|||||||
#define MUD_MAC_SIZE (16U)
|
#define MUD_MAC_SIZE (16U)
|
||||||
#define MUD_PUB_SIZE (crypto_scalarmult_BYTES)
|
#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_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE)
|
||||||
#define MUD_PACKET_MAX_SIZE (1472U)
|
#define MUD_PACKET_MAX_SIZE (1472U)
|
||||||
|
|
||||||
@@ -119,7 +122,6 @@ struct mud_addr {
|
|||||||
|
|
||||||
struct mud_packet {
|
struct mud_packet {
|
||||||
struct {
|
struct {
|
||||||
unsigned char zero[MUD_U48_SIZE];
|
|
||||||
unsigned char time[MUD_U48_SIZE];
|
unsigned char time[MUD_U48_SIZE];
|
||||||
unsigned char kiss[MUD_KISS_SIZE];
|
unsigned char kiss[MUD_KISS_SIZE];
|
||||||
struct mud_addr addr;
|
struct mud_addr addr;
|
||||||
@@ -239,7 +241,7 @@ mud_now(void)
|
|||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
now = (tv.tv_sec - MUD_EPOCH) * MUD_ONE_SEC + tv.tv_usec;
|
now = (tv.tv_sec - MUD_EPOCH) * MUD_ONE_SEC + tv.tv_usec;
|
||||||
#endif
|
#endif
|
||||||
return now;
|
return now & ~UINT64_C(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
@@ -809,7 +811,7 @@ mud_create(struct sockaddr *addr)
|
|||||||
if (!addr)
|
if (!addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
uint64_t now = mud_now();
|
const uint64_t now = mud_now();
|
||||||
|
|
||||||
if (now >> 48)
|
if (now >> 48)
|
||||||
return NULL;
|
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;
|
struct mud_packet *packet = (struct mud_packet *)data;
|
||||||
size_t size = 0;
|
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));
|
memcpy(packet->hdr.kiss, mud->local.kiss, sizeof(mud->local.kiss));
|
||||||
|
|
||||||
if (path->addr.ss_family == AF_INET) {
|
if (path->addr.ss_family == AF_INET) {
|
||||||
@@ -1074,25 +1076,28 @@ mud_kiss_path(struct mud *mud, unsigned char *kiss)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct mud_packet *packet = (struct mud_packet *)data;
|
||||||
|
|
||||||
if (size <= MUD_PACKET_SIZE(0))
|
if (size <= MUD_PACKET_SIZE(0))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (packet->hdr.code == mud_conf)
|
switch (packet->hdr.code) {
|
||||||
return size != MUD_PACKET_SIZE(sizeof(packet->data.conf));
|
case mud_conf:
|
||||||
|
if (size != MUD_PACKET_SIZE(sizeof(packet->data.conf)))
|
||||||
if (packet->hdr.code == mud_stat)
|
return 1;
|
||||||
return size != MUD_PACKET_SIZE(sizeof(packet->data.stat));
|
break;
|
||||||
|
case mud_stat:
|
||||||
return 0;
|
if (size != MUD_PACKET_SIZE(sizeof(packet->data.stat)))
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case mud_fake:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
mud_packet_check(struct mud *mud, unsigned char *data, size_t size)
|
|
||||||
{
|
|
||||||
unsigned char tmp[MUD_PACKET_MAX_SIZE];
|
unsigned char tmp[MUD_PACKET_MAX_SIZE];
|
||||||
|
|
||||||
struct mud_crypto_opt opt = {
|
struct mud_crypto_opt opt = {
|
||||||
@@ -1198,22 +1203,13 @@ mud_recv(struct mud *mud, void *data, size_t size)
|
|||||||
.msg_controllen = sizeof(ctrl),
|
.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)
|
if (packet_size <= (ssize_t)MUD_PACKET_MIN_SIZE)
|
||||||
return -(packet_size == (ssize_t)-1);
|
return -(packet_size == (ssize_t)-1);
|
||||||
|
|
||||||
uint64_t now = mud_now();
|
const uint64_t now = mud_now();
|
||||||
uint64_t send_time = mud_read48(packet);
|
const 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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
mud_unmapv4(&addr);
|
mud_unmapv4(&addr);
|
||||||
|
|
||||||
@@ -1223,18 +1219,14 @@ mud_recv(struct mud *mud, void *data, size_t size)
|
|||||||
return 0;
|
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;
|
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);
|
ret = mud_decrypt(mud, data, size, packet, packet_size);
|
||||||
|
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
mud->bad.decrypt.addr = addr;
|
mud->bad.decrypt.addr = addr;
|
||||||
mud->bad.decrypt.time = now;
|
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);
|
struct mud_path *path = mud_get_path(mud, &local_addr, &addr, 1);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
@@ -1257,7 +1254,7 @@ mud_recv(struct mud *mud, void *data, size_t size)
|
|||||||
path->mtu.ok = path->recv_max;
|
path->mtu.ok = path->recv_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mud_packet) {
|
if (MUD_PACKET(send_time)) {
|
||||||
mud_packet_recv(mud, path, now, packet, packet_size);
|
mud_packet_recv(mud, path, now, packet, packet_size);
|
||||||
} else if (mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT)) {
|
} else if (mud_timeout(now, path->stat_time, MUD_STAT_TIMEOUT)) {
|
||||||
mud_packet_send(mud, mud_stat, path, now, MSG_CONFIRM);
|
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)
|
mud_send(struct mud *mud, const void *data, size_t size, int tc)
|
||||||
{
|
{
|
||||||
unsigned char packet[MUD_PACKET_MAX_SIZE];
|
unsigned char packet[MUD_PACKET_MAX_SIZE];
|
||||||
uint64_t now = mud_now();
|
const uint64_t now = mud_now();
|
||||||
|
|
||||||
mud_update(mud, now);
|
mud_update(mud, now);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user