From 6e8a3cef1e3d8f8f67c33a783dfcefdd82f3b4e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Gallou=C3=ABt?= Date: Fri, 3 Jan 2020 12:29:49 +0000 Subject: [PATCH] Update protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Adrien Gallouët --- mud.c | 161 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 90 insertions(+), 71 deletions(-) diff --git a/mud.c b/mud.c index a2c8491..a3165f6 100644 --- a/mud.c +++ b/mud.c @@ -62,7 +62,10 @@ #define MUD_ONE_SEC (1000 * MUD_ONE_MSEC) #define MUD_ONE_MIN (60 * MUD_ONE_SEC) -#define MUD_U48_SIZE (6U) +#define MUD_TIME_SIZE (6U) +#define MUD_TIME_BITS (MUD_TIME_SIZE * 8U) +#define MUD_TIME_MASK(X) ((X) & ((UINT64_C(1) << MUD_TIME_BITS) - 2)) + #define MUD_KEY_SIZE (32U) #define MUD_MAC_SIZE (16U) @@ -71,19 +74,19 @@ #define MUD_MSG_SENT_MAX (5) #define MUD_MSG_TIMEOUT (100 * MUD_ONE_MSEC) -#define MUD_PKT_MIN_SIZE (MUD_U48_SIZE + MUD_MAC_SIZE) +#define MUD_PKT_MIN_SIZE (MUD_TIME_SIZE + MUD_MAC_SIZE) #define MUD_PKT_MAX_SIZE (1500U) #define MUD_MTU_MIN (1280U + MUD_PKT_MIN_SIZE) #define MUD_MTU_MAX (1450U + MUD_PKT_MIN_SIZE) -#define MUD_TIME_BITS (48) -#define MUD_TIME_MASK(X) ((X) & ((UINT64_C(1) << MUD_TIME_BITS) - 2)) - #define MUD_CTRL_SIZE (CMSG_SPACE(MUD_PKTINFO_SIZE) + \ CMSG_SPACE(sizeof(struct in6_pktinfo)) + \ CMSG_SPACE(sizeof(int))) +#define MUD_STORE_MSG(D,S) mud_store((D),(S),sizeof(D)) +#define MUD_LOAD_MSG(S) mud_load((S),sizeof(S)) + struct mud_crypto_opt { unsigned char *dst; const unsigned char *src; @@ -110,21 +113,19 @@ struct mud_addr { }; struct mud_msg { - unsigned char sent_time[MUD_U48_SIZE]; + unsigned char sent_time[MUD_TIME_SIZE]; unsigned char state; - struct mud_addr addr; - unsigned char pkey[MUD_PUBKEY_SIZE]; unsigned char aes; - unsigned char mtu[MUD_U48_SIZE]; - unsigned char fwd_total[MUD_U48_SIZE]; - unsigned char fwd_bytes[MUD_U48_SIZE]; - unsigned char tx_bytes[MUD_U48_SIZE]; - unsigned char tx_total[MUD_U48_SIZE]; - unsigned char rx_bytes[MUD_U48_SIZE]; - unsigned char rx_total[MUD_U48_SIZE]; - unsigned char tx_max_rate[MUD_U48_SIZE]; - unsigned char msg_timeout[MUD_U48_SIZE]; + unsigned char pkey[MUD_PUBKEY_SIZE]; + struct { + unsigned char bytes[sizeof(uint64_t)]; + unsigned char total[sizeof(uint64_t)]; + } tx, rx, fw; + unsigned char max_rate[sizeof(uint64_t)]; + unsigned char timeout[MUD_TIME_SIZE]; + unsigned char mtu[2]; unsigned char loss; + struct mud_addr addr; }; struct mud_keyx { @@ -179,32 +180,32 @@ mud_encrypt_opt(const struct mud_crypto_key *k, if (k->aes) { unsigned char npub[AEGIS256_NPUBBYTES]; - memcpy(npub, c->dst, MUD_U48_SIZE); - memset(npub + MUD_U48_SIZE, 0, sizeof(npub) - MUD_U48_SIZE); + memcpy(npub, c->dst, MUD_TIME_SIZE); + memset(npub + MUD_TIME_SIZE, 0, sizeof(npub) - MUD_TIME_SIZE); return aegis256_encrypt( - c->dst + MUD_U48_SIZE, + c->dst + MUD_TIME_SIZE, NULL, c->src, c->size, c->dst, - MUD_U48_SIZE, + MUD_TIME_SIZE, npub, k->encrypt.key ); } else { unsigned char npub[crypto_aead_chacha20poly1305_NPUBBYTES]; - memcpy(npub, c->dst, MUD_U48_SIZE); - memset(npub + MUD_U48_SIZE, 0, sizeof(npub) - MUD_U48_SIZE); + memcpy(npub, c->dst, MUD_TIME_SIZE); + memset(npub + MUD_TIME_SIZE, 0, sizeof(npub) - MUD_TIME_SIZE); return crypto_aead_chacha20poly1305_encrypt( - c->dst + MUD_U48_SIZE, + c->dst + MUD_TIME_SIZE, NULL, c->src, c->size, c->dst, - MUD_U48_SIZE, + MUD_TIME_SIZE, NULL, npub, k->encrypt.key @@ -219,31 +220,31 @@ mud_decrypt_opt(const struct mud_crypto_key *k, if (k->aes) { unsigned char npub[AEGIS256_NPUBBYTES]; - memcpy(npub, c->src, MUD_U48_SIZE); - memset(npub + MUD_U48_SIZE, 0, sizeof(npub) - MUD_U48_SIZE); + memcpy(npub, c->src, MUD_TIME_SIZE); + memset(npub + MUD_TIME_SIZE, 0, sizeof(npub) - MUD_TIME_SIZE); return aegis256_decrypt( c->dst, NULL, - c->src + MUD_U48_SIZE, - c->size - MUD_U48_SIZE, - c->src, MUD_U48_SIZE, + c->src + MUD_TIME_SIZE, + c->size - MUD_TIME_SIZE, + c->src, MUD_TIME_SIZE, npub, k->decrypt.key ); } else { unsigned char npub[crypto_aead_chacha20poly1305_NPUBBYTES]; - memcpy(npub, c->src, MUD_U48_SIZE); - memset(npub + MUD_U48_SIZE, 0, sizeof(npub) - MUD_U48_SIZE); + memcpy(npub, c->src, MUD_TIME_SIZE); + memset(npub + MUD_TIME_SIZE, 0, sizeof(npub) - MUD_TIME_SIZE); return crypto_aead_chacha20poly1305_decrypt( c->dst, NULL, NULL, - c->src + MUD_U48_SIZE, - c->size - MUD_U48_SIZE, - c->src, MUD_U48_SIZE, + c->src + MUD_TIME_SIZE, + c->size - MUD_TIME_SIZE, + c->src, MUD_TIME_SIZE, npub, k->decrypt.key ); @@ -251,25 +252,42 @@ mud_decrypt_opt(const struct mud_crypto_key *k, } static void -mud_write48(unsigned char *dst, uint64_t src) +mud_store(unsigned char *dst, uint64_t src, size_t size) { - dst[0] = (unsigned char)(UINT64_C(255) & (src)); - dst[1] = (unsigned char)(UINT64_C(255) & (src >> 8)); - dst[2] = (unsigned char)(UINT64_C(255) & (src >> 16)); - dst[3] = (unsigned char)(UINT64_C(255) & (src >> 24)); - dst[4] = (unsigned char)(UINT64_C(255) & (src >> 32)); - dst[5] = (unsigned char)(UINT64_C(255) & (src >> 40)); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + memcpy(dst, &src, size); +#else + dst[0] = (unsigned char)(src); + dst[1] = (unsigned char)(src >> 8); + if (size < 48) return; + dst[2] = (unsigned char)(src >> 16); + dst[3] = (unsigned char)(src >> 24); + dst[4] = (unsigned char)(src >> 32); + dst[5] = (unsigned char)(src >> 40); + if (size < 64) return; + dst[6] = (unsigned char)(src >> 48); + dst[7] = (unsigned char)(src >> 56); +#endif } static uint64_t -mud_read48(const unsigned char *src) +mud_load(const unsigned char *src, size_t size) { - uint64_t ret = src[0]; + uint64_t ret = 0; +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + memcpy(&ret, src, size); +#else + ret = src[0]; ret |= ((uint64_t)src[1]) << 8; + if (size < 48) return ret; ret |= ((uint64_t)src[2]) << 16; ret |= ((uint64_t)src[3]) << 24; ret |= ((uint64_t)src[4]) << 32; ret |= ((uint64_t)src[5]) << 40; + if (size < 64) return ret; + ret |= ((uint64_t)src[6]) << 48; + ret |= ((uint64_t)src[7]) << 56; +#endif return ret; } @@ -976,7 +994,7 @@ mud_encrypt(struct mud *mud, uint64_t now, .size = src_size, }; - mud_write48(dst, now); + mud_store(dst, now, MUD_TIME_SIZE); if (mud->keyx.use_next) { mud_encrypt_opt(&mud->keyx.next, &opt); @@ -1055,7 +1073,7 @@ mud_localaddr(struct sockaddr_storage *addr, struct msghdr *msg) static int mud_send_msg(struct mud *mud, struct mud_path *path, uint64_t now, - uint64_t sent_time, uint64_t fwd_bytes, uint64_t fwd_total, + uint64_t sent_time, uint64_t fw_bytes, uint64_t fw_total, size_t size) { unsigned char dst[MUD_PKT_MAX_SIZE]; @@ -1067,8 +1085,8 @@ mud_send_msg(struct mud *mud, struct mud_path *path, uint64_t now, if (size < MUD_PKT_MIN_SIZE + sizeof(struct mud_msg)) size = MUD_PKT_MIN_SIZE + sizeof(struct mud_msg); - mud_write48(dst, MUD_MSG_MARK(now)); - mud_write48(msg->sent_time, sent_time); + mud_store(dst, MUD_MSG_MARK(now), MUD_TIME_SIZE); + MUD_STORE_MSG(msg->sent_time, sent_time); if (path->addr.ss_family == AF_INET) { msg->addr.ff[0] = 0xFF; @@ -1093,16 +1111,17 @@ mud_send_msg(struct mud *mud, struct mud_path *path, uint64_t now, msg->aes = (unsigned char)mud->keyx.aes; if (!path->mtu.probe) - mud_write48(msg->mtu, path->mtu.ok); + MUD_STORE_MSG(msg->mtu, path->mtu.ok); + + MUD_STORE_MSG(msg->tx.bytes, path->tx.bytes); + MUD_STORE_MSG(msg->rx.bytes, path->rx.bytes); + MUD_STORE_MSG(msg->tx.total, path->tx.total); + MUD_STORE_MSG(msg->rx.total, path->rx.total); + MUD_STORE_MSG(msg->fw.bytes, fw_bytes); + MUD_STORE_MSG(msg->fw.total, fw_total); + MUD_STORE_MSG(msg->max_rate, path->conf.rx_max_rate); + MUD_STORE_MSG(msg->timeout, path->conf.msg_timeout); - mud_write48(msg->tx_bytes, path->tx.bytes); - mud_write48(msg->rx_bytes, path->rx.bytes); - mud_write48(msg->tx_total, path->tx.total); - mud_write48(msg->rx_total, path->rx.total); - mud_write48(msg->fwd_bytes, fwd_bytes); - mud_write48(msg->fwd_total, fwd_total); - mud_write48(msg->tx_max_rate, path->conf.rx_max_rate); - mud_write48(msg->msg_timeout, path->conf.msg_timeout); msg->loss = (unsigned char)path->tx.loss; const struct mud_crypto_opt opt = { @@ -1231,15 +1250,15 @@ mud_recv_msg(struct mud *mud, struct mud_path *path, mud_ss_from_packet(&path->r_addr, msg); - const uint64_t tx_time = mud_read48(msg->sent_time); + const uint64_t tx_time = MUD_LOAD_MSG(msg->sent_time); if (tx_time) { mud_update_stat(&path->rtt, MUD_TIME_MASK(now - tx_time)); - const uint64_t tx_bytes = mud_read48(msg->fwd_bytes); - const uint64_t tx_total = mud_read48(msg->fwd_total); - const uint64_t rx_bytes = mud_read48(msg->rx_bytes); - const uint64_t rx_total = mud_read48(msg->rx_total); + const uint64_t tx_bytes = MUD_LOAD_MSG(msg->fw.bytes); + const uint64_t tx_total = MUD_LOAD_MSG(msg->fw.total); + const uint64_t rx_bytes = MUD_LOAD_MSG(msg->rx.bytes); + const uint64_t rx_total = MUD_LOAD_MSG(msg->rx.total); const uint64_t rx_time = sent_time; if ((tx_time > path->msg.tx.time) && (tx_bytes > path->msg.tx.bytes) && @@ -1272,14 +1291,14 @@ mud_recv_msg(struct mud *mud, struct mud_path *path, } } else { path->state = (enum mud_state)msg->state; - path->mtu.ok = mud_read48(msg->mtu); - path->conf.msg_timeout = mud_read48(msg->msg_timeout); + path->mtu.ok = MUD_LOAD_MSG(msg->mtu); + path->conf.msg_timeout = MUD_LOAD_MSG(msg->timeout); - const uint64_t tx_max_rate = mud_read48(msg->tx_max_rate); + const uint64_t max_rate = MUD_LOAD_MSG(msg->max_rate); - if (path->conf.tx_max_rate != tx_max_rate) { - path->conf.tx_max_rate = tx_max_rate; - path->tx.rate = tx_max_rate; + if (path->conf.tx_max_rate != max_rate) { + path->conf.tx_max_rate = max_rate; + path->tx.rate = max_rate; } path->msg.sent++; @@ -1300,8 +1319,8 @@ mud_recv_msg(struct mud *mud, struct mud_path *path, } mud_send_msg(mud, path, now, sent_time, - mud_read48(msg->tx_bytes), - mud_read48(msg->tx_total), + MUD_LOAD_MSG(msg->tx.bytes), + MUD_LOAD_MSG(msg->tx.total), size); } @@ -1334,7 +1353,7 @@ mud_recv(struct mud *mud, void *data, size_t size) return 0; const uint64_t now = mud_now(mud); - const uint64_t sent_time = mud_read48(packet); + const uint64_t sent_time = mud_load(packet, MUD_TIME_SIZE); mud_unmapv4(&addr);