From 0ccd621694cabdf5b401408a32bca337fe6003a8 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Date: Sun, 25 Jun 2017 19:18:38 +0900 Subject: [PATCH] Adjust packet number --- lib/includes/ngtcp2/ngtcp2.h | 3 ++- lib/ngtcp2_conn.c | 4 +++- lib/ngtcp2_conn.h | 1 + lib/ngtcp2_pkt.c | 34 +++++++++++++++++++++++++++------- lib/ngtcp2_pkt.h | 17 ++++++++++++++++- tests/main.c | 2 ++ tests/ngtcp2_pkt_test.c | 15 ++++++++++++--- tests/ngtcp2_pkt_test.h | 1 + tests/ngtcp2_upe_test.c | 6 +++--- 9 files changed, 67 insertions(+), 16 deletions(-) diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h index 98e51817..1e77be4f 100644 --- a/lib/includes/ngtcp2/ngtcp2.h +++ b/lib/includes/ngtcp2/ngtcp2.h @@ -331,7 +331,8 @@ NGTCP2_EXTERN ssize_t ngtcp2_pkt_decode_hd(ngtcp2_pkt_hd *dest, NGTCP2_EXTERN ssize_t ngtcp2_pkt_decode_frame(ngtcp2_frame *dest, const uint8_t *payload, - size_t payloadlen); + size_t payloadlen, + uint64_t max_rx_pkt_num); /** * @function diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c index 40a01010..8666a8f3 100644 --- a/lib/ngtcp2_conn.c +++ b/lib/ngtcp2_conn.c @@ -586,6 +586,8 @@ static int ngtcp2_conn_recv_cleartext(ngtcp2_conn *conn, uint8_t exptype, pkt += nread; pktlen -= (size_t)nread; + hd.pkt_num = ngtcp2_pkt_adjust_pkt_num(conn->max_rx_pkt_num, hd.pkt_num, 32); + rv = conn_call_recv_pkt(conn, &hd); if (rv != 0) { return rv; @@ -615,7 +617,7 @@ static int ngtcp2_conn_recv_cleartext(ngtcp2_conn *conn, uint8_t exptype, } for (; pktlen;) { - nread = ngtcp2_pkt_decode_frame(&fr, pkt, pktlen); + nread = ngtcp2_pkt_decode_frame(&fr, pkt, pktlen, conn->max_rx_pkt_num); if (nread < 0) { return (int)nread; } diff --git a/lib/ngtcp2_conn.h b/lib/ngtcp2_conn.h index aff0f7cd..ebbb3969 100644 --- a/lib/ngtcp2_conn.h +++ b/lib/ngtcp2_conn.h @@ -96,6 +96,7 @@ struct ngtcp2_conn { ngtcp2_strm strm0; uint64_t conn_id; uint64_t next_tx_pkt_num; + uint64_t max_rx_pkt_num; ngtcp2_mem *mem; void *user_data; uint32_t version; diff --git a/lib/ngtcp2_pkt.c b/lib/ngtcp2_pkt.c index 73b3bf5d..e42d669a 100644 --- a/lib/ngtcp2_pkt.c +++ b/lib/ngtcp2_pkt.c @@ -245,7 +245,7 @@ ssize_t ngtcp2_pkt_encode_hd_short(uint8_t *out, size_t outlen, static int has_mask(uint8_t b, uint8_t mask) { return (b & mask) == mask; } ssize_t ngtcp2_pkt_decode_frame(ngtcp2_frame *dest, const uint8_t *payload, - size_t payloadlen) { + size_t payloadlen, uint64_t max_rx_pkt_num) { uint8_t type; if (payloadlen == 0) { @@ -259,7 +259,8 @@ ssize_t ngtcp2_pkt_decode_frame(ngtcp2_frame *dest, const uint8_t *payload, } if (has_mask(type, NGTCP2_FRAME_ACK)) { - return ngtcp2_pkt_decode_ack_frame(&dest->ack, payload, payloadlen); + return ngtcp2_pkt_decode_ack_frame(&dest->ack, payload, payloadlen, + max_rx_pkt_num); } switch (type) { @@ -402,7 +403,8 @@ ssize_t ngtcp2_pkt_decode_stream_frame(ngtcp2_stream *dest, } ssize_t ngtcp2_pkt_decode_ack_frame(ngtcp2_ack *dest, const uint8_t *payload, - size_t payloadlen) { + size_t payloadlen, + uint64_t max_rx_pkt_num) { uint8_t type; size_t num_blks = 0; size_t num_ts; @@ -482,16 +484,19 @@ ssize_t ngtcp2_pkt_decode_ack_frame(ngtcp2_ack *dest, const uint8_t *payload, switch (lalen) { case 1: - dest->largest_ack = *p; + dest->largest_ack = ngtcp2_pkt_adjust_pkt_num(max_rx_pkt_num, *p, 8); break; case 2: - dest->largest_ack = ngtcp2_get_uint16(p); + dest->largest_ack = + ngtcp2_pkt_adjust_pkt_num(max_rx_pkt_num, ngtcp2_get_uint16(p), 16); break; case 4: - dest->largest_ack = ngtcp2_get_uint32(p); + dest->largest_ack = + ngtcp2_pkt_adjust_pkt_num(max_rx_pkt_num, ngtcp2_get_uint32(p), 32); break; case 6: - dest->largest_ack = ngtcp2_get_uint48(p); + dest->largest_ack = + ngtcp2_pkt_adjust_pkt_num(max_rx_pkt_num, ngtcp2_get_uint48(p), 48); break; } @@ -849,3 +854,18 @@ size_t ngtcp2_pkt_decode_version_negotiation(uint32_t *dest, return payloadlen / sizeof(uint32_t); } + +uint64_t ngtcp2_pkt_adjust_pkt_num(uint64_t max_pkt_num, uint64_t pkt_num, + size_t n) { + uint64_t k = max_pkt_num + 1; + uint64_t u = k & ~((1llu << n) - 1); + uint64_t a = u | pkt_num; + uint64_t b = (u + (1llu << n)) | pkt_num; + uint64_t a1 = k < a ? a - k : k - a; + uint64_t b1 = k < b ? b - k : k - b; + + if (a1 < b1) { + return a; + } + return b; +} diff --git a/lib/ngtcp2_pkt.h b/lib/ngtcp2_pkt.h index abf61eba..930f369e 100644 --- a/lib/ngtcp2_pkt.h +++ b/lib/ngtcp2_pkt.h @@ -157,7 +157,7 @@ ssize_t ngtcp2_pkt_decode_stream_frame(ngtcp2_stream *dest, * Payload is too short to include ACK frame */ ssize_t ngtcp2_pkt_decode_ack_frame(ngtcp2_ack *dest, const uint8_t *payload, - size_t payloadlen); + size_t payloadlen, uint64_t max_rx_pkt_num); /* * ngtcp2_pkt_decode_padding_frame decodes contiguous PADDING frames @@ -261,4 +261,19 @@ ssize_t ngtcp2_pkt_encode_ack_frame(uint8_t *out, size_t outlen, ssize_t ngtcp2_pkt_encode_padding_frame(uint8_t *out, size_t outlen, const ngtcp2_padding *fr); +/** + * ngtcp2_pkt_adjust_pkt_num find the full 64 bits packet number for + * |pkt_num|, which is expected to be least significant |n| bits. The + * |max_pkt_num| is the highest successfully authenticated packet + * number. + */ +uint64_t ngtcp2_pkt_adjust_pkt_num(uint64_t max_pkt_num, uint64_t pkt_num, + size_t n); + +/** + * ngtcp2_pkt_adjust_ack_pkt_num adjusts all packet numbers in |ack| + * using the maximum packet number |max_pkt_num| received so far. + */ +void ngtcp2_pkt_adjust_ack_pkt_num(ngtcp2_ack *ack, uint64_t max_pkt_num); + #endif /* NGTCP2_PKT_H */ diff --git a/tests/main.c b/tests/main.c index dd3c6043..0698f61c 100644 --- a/tests/main.c +++ b/tests/main.c @@ -68,6 +68,8 @@ int main() { test_ngtcp2_pkt_encode_stream_frame) || !CU_add_test(pSuite, "pkt_encode_ack_frame", test_ngtcp2_pkt_encode_ack_frame) || + !CU_add_test(pSuite, "pkt_adjust_pkt_num", + test_ngtcp2_pkt_adjust_pkt_num) || !CU_add_test(pSuite, "upe_encode", test_ngtcp2_upe_encode) || !CU_add_test(pSuite, "upe_encode_version_negotiation", test_ngtcp2_upe_encode_version_negotiation)) { diff --git a/tests/ngtcp2_pkt_test.c b/tests/ngtcp2_pkt_test.c index af70820e..eea3cf0b 100644 --- a/tests/ngtcp2_pkt_test.c +++ b/tests/ngtcp2_pkt_test.c @@ -269,10 +269,11 @@ void test_ngtcp2_pkt_decode_ack_frame(void) { CU_ASSERT(expectedlen == buflen); - rv = ngtcp2_pkt_decode_ack_frame(&fr.ack, buf, buflen); + rv = ngtcp2_pkt_decode_ack_frame(&fr.ack, buf, buflen, 0); CU_ASSERT((ssize_t)expectedlen == rv); CU_ASSERT(0xf1f2f3f4f5f6llu == fr.ack.largest_ack); + fprintf(stderr, "%016lx\n", fr.ack.largest_ack); } void test_ngtcp2_pkt_decode_padding_frame(void) { @@ -468,7 +469,7 @@ void test_ngtcp2_pkt_encode_ack_frame(void) { CU_ASSERT((ssize_t)framelen == rv); - rv = ngtcp2_pkt_decode_ack_frame(&nfr.ack, buf, framelen); + rv = ngtcp2_pkt_decode_ack_frame(&nfr.ack, buf, framelen, 0); CU_ASSERT((ssize_t)framelen == rv); CU_ASSERT(fr.type == nfr.type); @@ -497,7 +498,7 @@ void test_ngtcp2_pkt_encode_ack_frame(void) { CU_ASSERT((ssize_t)framelen == rv); - rv = ngtcp2_pkt_decode_ack_frame(&nfr.ack, buf, framelen); + rv = ngtcp2_pkt_decode_ack_frame(&nfr.ack, buf, framelen, 0); CU_ASSERT((ssize_t)framelen == rv); CU_ASSERT(fr.type == nfr.type); @@ -514,3 +515,11 @@ void test_ngtcp2_pkt_encode_ack_frame(void) { memset(&nfr, 0, sizeof(nfr)); } + +void test_ngtcp2_pkt_adjust_pkt_num(void) { + CU_ASSERT(0xaa831f94llu == + ngtcp2_pkt_adjust_pkt_num(0xaa82f30ellu, 0x1f94, 16)); + + CU_ASSERT(0x01ff == ngtcp2_pkt_adjust_pkt_num(0x0100, 0xff, 1)); + CU_ASSERT(0x02ff == ngtcp2_pkt_adjust_pkt_num(0x01ff, 0xff, 1)); +} diff --git a/tests/ngtcp2_pkt_test.h b/tests/ngtcp2_pkt_test.h index 6a8f42b0..83f5d968 100644 --- a/tests/ngtcp2_pkt_test.h +++ b/tests/ngtcp2_pkt_test.h @@ -36,5 +36,6 @@ void test_ngtcp2_pkt_decode_ack_frame(void); void test_ngtcp2_pkt_decode_padding_frame(void); void test_ngtcp2_pkt_encode_stream_frame(void); void test_ngtcp2_pkt_encode_ack_frame(void); +void test_ngtcp2_pkt_adjust_pkt_num(void); #endif /* NGTCP2_PKT_TEST_H */ diff --git a/tests/ngtcp2_upe_test.c b/tests/ngtcp2_upe_test.c index 0ce888e6..b0d71624 100644 --- a/tests/ngtcp2_upe_test.c +++ b/tests/ngtcp2_upe_test.c @@ -105,7 +105,7 @@ void test_ngtcp2_upe_encode(void) { pktlen -= (size_t)nread; /* Read first STREAM frame */ - nread = ngtcp2_pkt_decode_frame(&ns, out, pktlen); + nread = ngtcp2_pkt_decode_frame(&ns, out, pktlen, 0); CU_ASSERT(nread > 0); CU_ASSERT(s1.type == ns.type); @@ -118,7 +118,7 @@ void test_ngtcp2_upe_encode(void) { pktlen -= (size_t)nread; /* Read second STREAM frame */ - nread = ngtcp2_pkt_decode_frame(&ns, out, pktlen); + nread = ngtcp2_pkt_decode_frame(&ns, out, pktlen, 0); CU_ASSERT(nread > 0); CU_ASSERT(s2.type == ns.type); @@ -131,7 +131,7 @@ void test_ngtcp2_upe_encode(void) { pktlen -= (size_t)nread; /* Read PADDING frames to the end */ - nread = ngtcp2_pkt_decode_frame(&ns, out, pktlen); + nread = ngtcp2_pkt_decode_frame(&ns, out, pktlen, 0); CU_ASSERT(nread == (ssize_t)pktlen); CU_ASSERT(NGTCP2_FRAME_PADDING == ns.type); -- GitLab