Give a kiss to get some love
This commit is contained in:
52
mud.c
52
mud.c
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user