Give a kiss to get some love

This commit is contained in:
Adrien Gallouët
2016-12-08 11:19:25 +00:00
parent c156aa68e3
commit 35368f10ab

52
mud.c
View File

@@ -48,6 +48,7 @@
#define MUD_KEY_SIZE (32U) #define MUD_KEY_SIZE (32U)
#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_SID_SIZE (8U)
#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)
@@ -75,6 +76,10 @@ struct mud_path {
unsigned char data[256]; unsigned char data[256];
size_t size; size_t size;
} ctrl; } ctrl;
struct {
uint64_t send_time;
int remote;
} kiss;
struct { struct {
uint64_t send_time; uint64_t send_time;
int remote; int remote;
@@ -119,7 +124,7 @@ struct mud_crypto_key {
}; };
enum mud_packet_code { enum mud_packet_code {
mud_ping, mud_kiss,
mud_stat, mud_stat,
mud_keyx, mud_keyx,
mud_mtux, mud_mtux,
@@ -133,6 +138,7 @@ struct mud_packet {
unsigned char code; unsigned char code;
} hdr; } hdr;
union { union {
unsigned char kiss[MUD_SID_SIZE];
struct { struct {
unsigned char sdt[MUD_U48_SIZE]; unsigned char sdt[MUD_U48_SIZE];
unsigned char rdt[MUD_U48_SIZE]; unsigned char rdt[MUD_U48_SIZE];
@@ -164,6 +170,7 @@ struct mud {
int remote; int remote;
int local; int local;
} mtu; } mtu;
unsigned char kiss[MUD_SID_SIZE];
}; };
static int static int
@@ -690,6 +697,8 @@ mud_create(int port, int v4, int v6, int aes, int mtu)
mud->crypto.aes = aes && crypto_aead_aes256gcm_is_available(); mud->crypto.aes = aes && crypto_aead_aes256gcm_is_available();
mud_keyx_init(mud); mud_keyx_init(mud);
randombytes_buf(mud->kiss, sizeof(mud->kiss));
return mud; return mud;
} }
@@ -850,6 +859,10 @@ mud_packet_send(struct mud *mud, enum mud_packet_code code,
packet.hdr.code = (unsigned char)code; packet.hdr.code = (unsigned char)code;
switch (code) { switch (code) {
case mud_kiss:
size = sizeof(packet.data.kiss);
memcpy(&packet.data.kiss, &mud->kiss, size);
break;
case mud_stat: case mud_stat:
size = sizeof(packet.data.stat); size = sizeof(packet.data.stat);
mud_write48(packet.data.stat.sdt, path->sdt); mud_write48(packet.data.stat.sdt, path->sdt);
@@ -944,6 +957,19 @@ mud_recv_keyx(struct mud *mud, struct mud_path *path, uint64_t now,
mud->crypto.recv_time = now; mud->crypto.recv_time = now;
} }
static void
mud_kiss_path(struct mud *mud, struct mud_path *path)
{
while (mud->path) {
struct mud_path *p = mud->path;
mud->path = p->next;
if (p != path)
free(p);
}
mud->path = path;
}
static void static void
mud_packet_recv(struct mud *mud, struct mud_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)
@@ -954,6 +980,20 @@ mud_packet_recv(struct mud *mud, struct mud_path *path, uint64_t now,
return; return;
switch (packet->hdr.code) { switch (packet->hdr.code) {
case mud_kiss:
if (size < mud_packet_size(sizeof(packet->data.kiss)))
return;
path->kiss.remote = !memcmp(mud->kiss, packet->data.kiss,
sizeof(mud->kiss));
if (path->state.active)
break;
if (!path->kiss.remote) {
memcpy(mud->kiss, packet->data.kiss, sizeof(mud->kiss));
mud_kiss_path(mud, path);
path->kiss.remote = 1;
}
mud_packet_send(mud, mud_kiss, path, now);
break;
case mud_stat: case mud_stat:
if (size < mud_packet_size(sizeof(packet->data.stat))) if (size < mud_packet_size(sizeof(packet->data.stat)))
return; return;
@@ -1109,6 +1149,13 @@ mud_update(struct mud *mud)
uint64_t now = mud_now(mud); uint64_t now = mud_now(mud);
if ((!path->kiss.remote) &&
(mud_timeout(now, path->kiss.send_time, mud->send_timeout))) {
mud_packet_send(mud, mud_kiss, path, now);
path->kiss.send_time = now;
continue;
}
if ((mud_timeout(now, mud->crypto.send_time, mud->send_timeout)) && if ((mud_timeout(now, mud->crypto.send_time, mud->send_timeout)) &&
(mud_timeout(now, mud->crypto.recv_time, MUD_KEYX_TIMEOUT))) { (mud_timeout(now, mud->crypto.recv_time, MUD_KEYX_TIMEOUT))) {
mud_packet_send(mud, mud_keyx, path, now); mud_packet_send(mud, mud_keyx, path, now);
@@ -1129,9 +1176,6 @@ mud_update(struct mud *mud)
path->bak.send_time = now; path->bak.send_time = now;
continue; continue;
} }
if (!path->send_time)
mud_packet_send(mud, mud_ping, path, now);
} }
} }