From ef7a97f6aecb72a1bc9c3872a089a8a6e74675fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 18 Nov 2020 11:55:26 +0100 Subject: [PATCH] Fix Congestion in Takion and add Test --- lib/include/chiaki/takion.h | 13 +++++++++--- lib/src/takion.c | 32 ++++++++++++++--------------- test/takion.c | 41 +++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/lib/include/chiaki/takion.h b/lib/include/chiaki/takion.h index 566a996..f957948 100644 --- a/lib/include/chiaki/takion.h +++ b/lib/include/chiaki/takion.h @@ -58,8 +58,8 @@ typedef ChiakiErrorCode (*ChiakiTakionAVPacketParse)(ChiakiTakionAVPacket *packe typedef struct chiaki_takion_congestion_packet_t { uint16_t word_0; - uint16_t word_1; - uint16_t word_2; + uint16_t received; + uint16_t lost; } ChiakiTakionCongestionPacket; @@ -167,11 +167,14 @@ CHIAKI_EXPORT void chiaki_takion_close(ChiakiTakion *takion); /** * Must be called from within the Takion thread, i.e. inside the callback! */ -static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *gkcrypt_local, ChiakiGKCrypt *gkcrypt_remote) { +static inline void chiaki_takion_set_crypt(ChiakiTakion *takion, ChiakiGKCrypt *gkcrypt_local, ChiakiGKCrypt *gkcrypt_remote) +{ takion->gkcrypt_local = gkcrypt_local; takion->gkcrypt_remote = gkcrypt_remote; } +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *buf, size_t buf_size, uint64_t key_pos, uint8_t *mac_out, uint8_t *mac_old_out); + /** * Get a new key pos and advance by data_size. * @@ -230,6 +233,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_format_header(uint8_t * CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_v7_av_packet_parse(ChiakiTakionAVPacket *packet, ChiakiKeyState *key_state, uint8_t *buf, size_t buf_size); +#define CHIAKI_TAKION_CONGESTION_PACKET_SIZE 0xf + +CHIAKI_EXPORT void chiaki_takion_format_congestion(uint8_t *buf, ChiakiTakionCongestionPacket *packet, uint64_t key_pos); + #ifdef __cplusplus } #endif diff --git a/lib/src/takion.c b/lib/src/takion.c index dcb26f2..80daf4f 100644 --- a/lib/src/takion.c +++ b/lib/src/takion.c @@ -361,7 +361,7 @@ static ChiakiErrorCode chiaki_takion_packet_read_key_pos(ChiakiTakion *takion, u return CHIAKI_ERR_SUCCESS; } -static ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *buf, size_t buf_size, uint64_t key_pos, uint8_t *mac_out, uint8_t *mac_old_out) +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *buf, size_t buf_size, uint64_t key_pos, uint8_t *mac_out, uint8_t *mac_old_out) { if(buf_size < 1) return CHIAKI_ERR_BUF_TOO_SMALL; @@ -383,17 +383,18 @@ static ChiakiErrorCode chiaki_takion_packet_mac(ChiakiGKCrypt *crypt, uint8_t *b if(crypt) { uint8_t key_pos_tmp[sizeof(uint32_t)]; - if(base_type == TAKION_PACKET_TYPE_CONTROL) + if(base_type == TAKION_PACKET_TYPE_CONTROL || base_type == TAKION_PACKET_TYPE_CONGESTION) { memcpy(key_pos_tmp, buf + key_pos_offset, sizeof(uint32_t)); memset(buf + key_pos_offset, 0, sizeof(uint32_t)); } chiaki_gkcrypt_gmac(crypt, key_pos, buf, buf_size, buf + mac_offset); - if(base_type == TAKION_PACKET_TYPE_CONTROL) + if(base_type == TAKION_PACKET_TYPE_CONTROL || base_type == TAKION_PACKET_TYPE_CONGESTION) memcpy(buf + key_pos_offset, key_pos_tmp, sizeof(uint32_t)); } - memcpy(mac_out, buf + mac_offset, CHIAKI_GKCRYPT_GMAC_SIZE); + if(mac_out) + memcpy(mac_out, buf + mac_offset, CHIAKI_GKCRYPT_GMAC_SIZE); return CHIAKI_ERR_SUCCESS; } @@ -484,23 +485,25 @@ static ChiakiErrorCode chiaki_takion_send_message_data_ack(ChiakiTakion *takion, return chiaki_takion_send(takion, buf, sizeof(buf), key_pos); } -CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet) +CHIAKI_EXPORT void chiaki_takion_format_congestion(uint8_t *buf, ChiakiTakionCongestionPacket *packet, uint64_t key_pos) { - uint8_t buf[0xf]; - memset(buf, 0, sizeof(buf)); buf[0] = TAKION_PACKET_TYPE_CONGESTION; *((chiaki_unaligned_uint16_t *)(buf + 1)) = htons(packet->word_0); - *((chiaki_unaligned_uint16_t *)(buf + 3)) = htons(packet->word_1); - *((chiaki_unaligned_uint16_t *)(buf + 5)) = htons(packet->word_2); + *((chiaki_unaligned_uint16_t *)(buf + 3)) = htons(packet->received); + *((chiaki_unaligned_uint16_t *)(buf + 5)) = htons(packet->lost); + *((chiaki_unaligned_uint32_t *)(buf + 7)) = 0; + *((chiaki_unaligned_uint32_t *)(buf + 0xb)) = htonl((uint32_t)key_pos); +} +CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_congestion(ChiakiTakion *takion, ChiakiTakionCongestionPacket *packet) +{ uint64_t key_pos; - ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, sizeof(buf), &key_pos); + ChiakiErrorCode err = chiaki_takion_crypt_advance_key_pos(takion, CHIAKI_TAKION_CONGESTION_PACKET_SIZE, &key_pos); if(err != CHIAKI_ERR_SUCCESS) return err; - *((chiaki_unaligned_uint32_t *)(buf + 0xb)) = htonl((uint32_t)key_pos); // TODO: is this correct? shouldn't key_pos be 0 for mac calculation? - - //chiaki_log_hexdump(takion->log, CHIAKI_LOG_DEBUG, buf, sizeof(buf)); + uint8_t buf[CHIAKI_TAKION_CONGESTION_PACKET_SIZE]; + chiaki_takion_format_congestion(buf, packet, key_pos); return chiaki_takion_send(takion, buf, sizeof(buf), key_pos); } @@ -675,9 +678,6 @@ static void *takion_thread_func(void *user) if(chiaki_takion_send_buffer_init(&takion->send_buffer, takion, TAKION_SEND_BUFFER_SIZE) != CHIAKI_ERR_SUCCESS) goto error_reoder_queue; - // TODO ChiakiCongestionControl congestion_control; - // if(chiaki_congestion_control_start(&congestion_control, takion) != CHIAKI_ERR_SUCCESS) - // goto beach; if(takion->cb) { diff --git a/test/takion.c b/test/takion.c index 6bf342f..8cdf02e 100644 --- a/test/takion.c +++ b/test/takion.c @@ -160,7 +160,40 @@ static MunitResult test_takion_send_buffer(const MunitParameter params[], void * #undef nums_count } +static MunitResult test_takion_format_congestion(const MunitParameter params[], void *user) +{ + static const uint8_t handshake_key[] = { 0x54, 0x65, 0x4c, 0x34, 0x5c, 0xac, 0x56, 0xb8, 0xea, 0xe6, 0x15, 0x2a, 0xde, 0x1c, 0xe2, 0xe8 }; + static const uint8_t ecdh_secret[] = { 0x00, 0x34, 0xf8, 0x21, 0xc7, 0xd9, 0xde, 0xa9, 0xe9, 0x11, 0xca, 0x5a, 0xd6, 0x7d, 0x11, 0xce, 0x4f, 0x02, 0xb1, 0xce, 0x1e, 0xe7, 0xc3, 0x8d, 0x54, 0x39, 0xfa, 0x64, 0xe3, 0xdb, 0xd8, 0x0d }; + ChiakiGKCrypt gkcrypt; + ChiakiErrorCode err = chiaki_gkcrypt_init(&gkcrypt, NULL, 0, 2, handshake_key, ecdh_secret); + if(err != CHIAKI_ERR_SUCCESS) + return MUNIT_ERROR; + + ChiakiTakionCongestionPacket packet; + packet.word_0 = 0x42; + packet.received = 26; + packet.lost = 10; + + const uint64_t key_pos = 0x1e5; + + uint8_t buf[CHIAKI_TAKION_CONGESTION_PACKET_SIZE]; + chiaki_takion_format_congestion(buf, &packet, key_pos); + + static const uint8_t buf_expected[] = { 0x05, 0x00, 0x42, 0x00, 0x1a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe5 }; + munit_assert_memory_equal(sizeof(buf), buf, buf_expected); + + err = chiaki_takion_packet_mac(&gkcrypt, buf, sizeof(buf), key_pos, NULL, NULL); + if(err != CHIAKI_ERR_SUCCESS) + return MUNIT_ERROR; + + static const uint8_t buf_expected_mac[] = { 0x05, 0x00, 0x42, 0x00, 0x1a, 0x00, 0x0a, 0x64, 0x8a, 0x7c, 0x74, 0x00, 0x00, 0x01, 0xe5 }; + munit_assert_memory_equal(sizeof(buf), buf, buf_expected_mac); + + chiaki_gkcrypt_fini(&gkcrypt); + + return MUNIT_OK; +} MunitTest tests_takion[] = { { @@ -187,5 +220,13 @@ MunitTest tests_takion[] = { MUNIT_TEST_OPTION_NONE, NULL }, + { + "/format_congestion", + test_takion_format_congestion, + NULL, + NULL, + MUNIT_TEST_OPTION_NONE, + NULL + }, { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } };