diff options
Diffstat (limited to 'tests/ngtcp2_pkt_test.c')
-rw-r--r-- | tests/ngtcp2_pkt_test.c | 1644 |
1 files changed, 1644 insertions, 0 deletions
diff --git a/tests/ngtcp2_pkt_test.c b/tests/ngtcp2_pkt_test.c new file mode 100644 index 0000000..f225610 --- /dev/null +++ b/tests/ngtcp2_pkt_test.c @@ -0,0 +1,1644 @@ +/* + * ngtcp2 + * + * Copyright (c) 2017 ngtcp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "ngtcp2_pkt_test.h" + +#include <CUnit/CUnit.h> + +#include "ngtcp2_pkt.h" +#include "ngtcp2_test_helper.h" +#include "ngtcp2_conv.h" +#include "ngtcp2_cid.h" +#include "ngtcp2_str.h" +#include "ngtcp2_vec.h" + +static int null_retry_encrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead, + const ngtcp2_crypto_aead_ctx *aead_ctx, + const uint8_t *plaintext, size_t plaintextlen, + const uint8_t *nonce, size_t noncelen, + const uint8_t *aad, size_t aadlen) { + (void)dest; + (void)aead; + (void)aead_ctx; + (void)plaintext; + (void)plaintextlen; + (void)nonce; + (void)noncelen; + (void)aad; + (void)aadlen; + + if (plaintextlen && plaintext != dest) { + memcpy(dest, plaintext, plaintextlen); + } + memset(dest + plaintextlen, 0, NGTCP2_RETRY_TAGLEN); + + return 0; +} + +void test_ngtcp2_pkt_decode_version_cid(void) { + uint8_t buf[NGTCP2_MAX_UDP_PAYLOAD_SIZE]; + ngtcp2_version_cid vc; + int rv; + uint8_t *p; + + /* Supported QUIC version */ + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, NGTCP2_PROTO_VER_V1); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + *p++ = NGTCP2_MAX_CIDLEN - 1; + p = ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN - 1); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), 0); + + CU_ASSERT(0 == rv); + CU_ASSERT(NGTCP2_PROTO_VER_V1 == vc.version); + CU_ASSERT(NGTCP2_MAX_CIDLEN == vc.dcidlen); + CU_ASSERT(&buf[6] == vc.dcid); + CU_ASSERT(NGTCP2_MAX_CIDLEN - 1 == vc.scidlen); + CU_ASSERT(&buf[6 + NGTCP2_MAX_CIDLEN + 1] == vc.scid); + + /* Unsupported QUIC version */ + memset(buf, 0, sizeof(buf)); + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, 0xffffff00); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + *p++ = NGTCP2_MAX_CIDLEN - 1; + ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN - 1); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, sizeof(buf), 0); + + CU_ASSERT(NGTCP2_ERR_VERSION_NEGOTIATION == rv); + CU_ASSERT(0xffffff00 == vc.version); + CU_ASSERT(NGTCP2_MAX_CIDLEN == vc.dcidlen); + CU_ASSERT(&buf[6] == vc.dcid); + CU_ASSERT(NGTCP2_MAX_CIDLEN - 1 == vc.scidlen); + CU_ASSERT(&buf[6 + NGTCP2_MAX_CIDLEN + 1] == vc.scid); + + /* Unsupported QUIC version with UDP payload size < 1200 */ + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, 0xffffff00); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + *p++ = NGTCP2_MAX_CIDLEN - 1; + p = ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN - 1); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), 0); + + CU_ASSERT(NGTCP2_ERR_INVALID_ARGUMENT == rv); + + /* Supported QUIC version with long CID */ + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, NGTCP2_PROTO_VER_V1); + *p++ = NGTCP2_MAX_CIDLEN + 1; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN + 1); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), 0); + + CU_ASSERT(NGTCP2_ERR_INVALID_ARGUMENT == rv); + + /* Unsupported QUIC version with long CID */ + memset(buf, 0, sizeof(buf)); + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, 0xffffff00); + *p++ = NGTCP2_MAX_CIDLEN + 1; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN + 1); + *p++ = NGTCP2_MAX_CIDLEN; + ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, sizeof(buf), 0); + + CU_ASSERT(NGTCP2_ERR_VERSION_NEGOTIATION == rv); + CU_ASSERT(0xffffff00 == vc.version); + CU_ASSERT(NGTCP2_MAX_CIDLEN + 1 == vc.dcidlen); + CU_ASSERT(&buf[6] == vc.dcid); + CU_ASSERT(NGTCP2_MAX_CIDLEN == vc.scidlen); + CU_ASSERT(&buf[6 + NGTCP2_MAX_CIDLEN + 1 + 1] == vc.scid); + + /* VN */ + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, 0); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + *p++ = NGTCP2_MAX_CIDLEN - 1; + p = ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN - 1); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), 0); + + CU_ASSERT(0 == rv); + CU_ASSERT(0 == vc.version); + CU_ASSERT(NGTCP2_MAX_CIDLEN == vc.dcidlen); + CU_ASSERT(&buf[6] == vc.dcid); + CU_ASSERT(NGTCP2_MAX_CIDLEN - 1 == vc.scidlen); + CU_ASSERT(&buf[6 + NGTCP2_MAX_CIDLEN + 1] == vc.scid); + + /* VN with long CID */ + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, 0); + *p++ = NGTCP2_MAX_CIDLEN + 1; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN + 1); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), 0); + + CU_ASSERT(0 == rv); + CU_ASSERT(0 == vc.version); + CU_ASSERT(NGTCP2_MAX_CIDLEN + 1 == vc.dcidlen); + CU_ASSERT(&buf[6] == vc.dcid); + CU_ASSERT(NGTCP2_MAX_CIDLEN == vc.scidlen); + CU_ASSERT(&buf[6 + NGTCP2_MAX_CIDLEN + 1 + 1] == vc.scid); + + /* Malformed Long packet */ + p = buf; + *p++ = NGTCP2_HEADER_FORM_BIT; + p = ngtcp2_put_uint32be(p, NGTCP2_PROTO_VER_V1); + *p++ = NGTCP2_MAX_CIDLEN; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + *p++ = NGTCP2_MAX_CIDLEN - 1; + p = ngtcp2_setmem(p, 0xf2, NGTCP2_MAX_CIDLEN - 1); + --p; + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), 0); + + CU_ASSERT(NGTCP2_ERR_INVALID_ARGUMENT == rv); + + /* Short packet */ + p = buf; + *p++ = 0; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), + NGTCP2_MAX_CIDLEN); + + CU_ASSERT(0 == rv); + CU_ASSERT(0 == vc.version); + CU_ASSERT(&buf[1] == vc.dcid); + CU_ASSERT(NGTCP2_MAX_CIDLEN == vc.dcidlen); + CU_ASSERT(NULL == vc.scid); + CU_ASSERT(0 == vc.scidlen); + + /* Malformed Short packet */ + p = buf; + *p++ = 0; + p = ngtcp2_setmem(p, 0xf1, NGTCP2_MAX_CIDLEN); + --p; + + rv = ngtcp2_pkt_decode_version_cid(&vc, buf, (size_t)(p - buf), + NGTCP2_MAX_CIDLEN); + + CU_ASSERT(NGTCP2_ERR_INVALID_ARGUMENT == rv); +} + +void test_ngtcp2_pkt_decode_hd_long(void) { + ngtcp2_pkt_hd hd, nhd; + uint8_t buf[256]; + ngtcp2_ssize rv; + ngtcp2_cid dcid, scid; + size_t len; + + dcid_init(&dcid); + scid_init(&scid); + + /* Handshake */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_HANDSHAKE, + &dcid, &scid, 0xe1e2e3e4u, 4, NGTCP2_PROTO_VER_V1, 16383); + + rv = ngtcp2_pkt_encode_hd_long(buf, sizeof(buf), &hd); + + len = 1 + 4 + 1 + dcid.datalen + 1 + scid.datalen + NGTCP2_PKT_LENGTHLEN + 4; + + CU_ASSERT((ngtcp2_ssize)len == rv); + CU_ASSERT(buf[0] & NGTCP2_FIXED_BIT_MASK); + + rv = pkt_decode_hd_long(&nhd, buf, len); + + CU_ASSERT((ngtcp2_ssize)len == rv); + CU_ASSERT(hd.type == nhd.type); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(ngtcp2_cid_eq(&hd.dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_eq(&hd.scid, &nhd.scid)); + CU_ASSERT(0xe1e2e3e4u == nhd.pkt_num); + CU_ASSERT(hd.version == nhd.version); + CU_ASSERT(hd.len == nhd.len); + + /* Handshake without Fixed Bit set */ + ngtcp2_pkt_hd_init( + &hd, NGTCP2_PKT_FLAG_LONG_FORM | NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR, + NGTCP2_PKT_HANDSHAKE, &dcid, &scid, 0xe1e2e3e4u, 4, NGTCP2_PROTO_VER_V1, + 16383); + + rv = ngtcp2_pkt_encode_hd_long(buf, sizeof(buf), &hd); + + len = 1 + 4 + 1 + dcid.datalen + 1 + scid.datalen + NGTCP2_PKT_LENGTHLEN + 4; + + CU_ASSERT((ngtcp2_ssize)len == rv); + CU_ASSERT((buf[0] & NGTCP2_FIXED_BIT_MASK) == 0); + + rv = pkt_decode_hd_long(&nhd, buf, len); + + CU_ASSERT((ngtcp2_ssize)len == rv); + CU_ASSERT(hd.type == nhd.type); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(ngtcp2_cid_eq(&hd.dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_eq(&hd.scid, &nhd.scid)); + CU_ASSERT(0xe1e2e3e4u == nhd.pkt_num); + CU_ASSERT(hd.version == nhd.version); + CU_ASSERT(hd.len == nhd.len); + + /* VN */ + /* Set random packet type */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_LONG_FORM, NGTCP2_PKT_HANDSHAKE, + &dcid, &scid, 0, 4, NGTCP2_PROTO_VER_V1, 0); + + rv = ngtcp2_pkt_encode_hd_long(buf, sizeof(buf), &hd); + /* Set version field to 0 */ + memset(&buf[1], 0, 4); + + len = 1 + 4 + 1 + dcid.datalen + 1 + scid.datalen; + + CU_ASSERT((ngtcp2_ssize)len == rv - NGTCP2_PKT_LENGTHLEN - 4 /* pkt_num */); + + rv = pkt_decode_hd_long(&nhd, buf, len); + + CU_ASSERT((ngtcp2_ssize)len == rv); + CU_ASSERT(NGTCP2_PKT_VERSION_NEGOTIATION == nhd.type); + CU_ASSERT((hd.flags & ~NGTCP2_PKT_FLAG_LONG_FORM) == nhd.flags); + CU_ASSERT(ngtcp2_cid_eq(&hd.dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_eq(&hd.scid, &nhd.scid)); + CU_ASSERT(hd.pkt_num == nhd.pkt_num); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(hd.len == nhd.len); +} + +void test_ngtcp2_pkt_decode_hd_short(void) { + ngtcp2_pkt_hd hd, nhd; + uint8_t buf[256]; + ngtcp2_ssize rv; + size_t expectedlen; + ngtcp2_cid dcid, zcid; + + dcid_init(&dcid); + ngtcp2_cid_zero(&zcid); + + /* 4 bytes packet number */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_NONE, NGTCP2_PKT_1RTT, &dcid, NULL, + 0xe1e2e3e4u, 4, 0xd1d2d3d4u, 0); + + expectedlen = 1 + dcid.datalen + 4; + + rv = ngtcp2_pkt_encode_hd_short(buf, sizeof(buf), &hd); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(buf[0] & NGTCP2_FIXED_BIT_MASK); + + rv = pkt_decode_hd_short(&nhd, buf, expectedlen, dcid.datalen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(NGTCP2_PKT_1RTT == nhd.type); + CU_ASSERT(ngtcp2_cid_eq(&dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_empty(&nhd.scid)); + CU_ASSERT(0xe1e2e3e4u == nhd.pkt_num); + CU_ASSERT(hd.pkt_numlen == nhd.pkt_numlen); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(0 == nhd.len); + + /* 4 bytes packet number without Fixed Bit set */ + ngtcp2_pkt_hd_init( + &hd, NGTCP2_PKT_FLAG_NONE | NGTCP2_PKT_FLAG_FIXED_BIT_CLEAR, + NGTCP2_PKT_1RTT, &dcid, NULL, 0xe1e2e3e4u, 4, 0xd1d2d3d4u, 0); + + expectedlen = 1 + dcid.datalen + 4; + + rv = ngtcp2_pkt_encode_hd_short(buf, sizeof(buf), &hd); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT((buf[0] & NGTCP2_FIXED_BIT_MASK) == 0); + + rv = pkt_decode_hd_short(&nhd, buf, expectedlen, dcid.datalen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(NGTCP2_PKT_1RTT == nhd.type); + CU_ASSERT(ngtcp2_cid_eq(&dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_empty(&nhd.scid)); + CU_ASSERT(0xe1e2e3e4u == nhd.pkt_num); + CU_ASSERT(hd.pkt_numlen == nhd.pkt_numlen); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(0 == nhd.len); + + /* 2 bytes packet number */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_NONE, NGTCP2_PKT_1RTT, &dcid, NULL, + 0xe1e2e3e4u, 2, 0xd1d2d3d4u, 0); + + expectedlen = 1 + dcid.datalen + 2; + + rv = ngtcp2_pkt_encode_hd_short(buf, sizeof(buf), &hd); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + + rv = pkt_decode_hd_short(&nhd, buf, expectedlen, dcid.datalen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(NGTCP2_PKT_1RTT == nhd.type); + CU_ASSERT(ngtcp2_cid_eq(&dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_empty(&nhd.scid)); + CU_ASSERT(0xe3e4u == nhd.pkt_num); + CU_ASSERT(hd.pkt_numlen == nhd.pkt_numlen); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(0 == nhd.len); + + /* 1 byte packet number */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_NONE, NGTCP2_PKT_1RTT, &dcid, NULL, + 0xe1e2e3e4u, 1, 0xd1d2d3d4u, 0); + + expectedlen = 1 + dcid.datalen + 1; + + rv = ngtcp2_pkt_encode_hd_short(buf, sizeof(buf), &hd); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + + rv = pkt_decode_hd_short(&nhd, buf, expectedlen, dcid.datalen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(NGTCP2_PKT_1RTT == nhd.type); + CU_ASSERT(ngtcp2_cid_eq(&dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_empty(&nhd.scid)); + CU_ASSERT(0xe4 == nhd.pkt_num); + CU_ASSERT(hd.pkt_numlen == nhd.pkt_numlen); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(0 == nhd.len); + + /* With Key Phase */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_KEY_PHASE, NGTCP2_PKT_1RTT, &dcid, + NULL, 0xe1e2e3e4u, 4, 0xd1d2d3d4u, 0); + + expectedlen = 1 + dcid.datalen + 4; + + rv = ngtcp2_pkt_encode_hd_short(buf, sizeof(buf), &hd); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + + rv = pkt_decode_hd_short(&nhd, buf, expectedlen, dcid.datalen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + /* key phase bit is protected by header protection and + ngtcp2_pkt_decode_hd_short does not decode it. */ + CU_ASSERT(NGTCP2_PKT_FLAG_NONE == nhd.flags); + CU_ASSERT(NGTCP2_PKT_1RTT == nhd.type); + CU_ASSERT(ngtcp2_cid_eq(&dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_empty(&nhd.scid)); + CU_ASSERT(0xe1e2e3e4u == nhd.pkt_num); + CU_ASSERT(hd.pkt_numlen == nhd.pkt_numlen); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(0 == nhd.len); + + /* With empty DCID */ + ngtcp2_pkt_hd_init(&hd, NGTCP2_PKT_FLAG_NONE, NGTCP2_PKT_1RTT, NULL, NULL, + 0xe1e2e3e4u, 4, 0xd1d2d3d4u, 0); + + expectedlen = 1 + 4; + + rv = ngtcp2_pkt_encode_hd_short(buf, sizeof(buf), &hd); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + + rv = pkt_decode_hd_short(&nhd, buf, expectedlen, 0); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(hd.flags == nhd.flags); + CU_ASSERT(NGTCP2_PKT_1RTT == nhd.type); + CU_ASSERT(ngtcp2_cid_empty(&nhd.dcid)); + CU_ASSERT(ngtcp2_cid_empty(&nhd.scid)); + CU_ASSERT(0xe1e2e3e4u == nhd.pkt_num); + CU_ASSERT(hd.pkt_numlen == nhd.pkt_numlen); + CU_ASSERT(0 == nhd.version); + CU_ASSERT(0 == nhd.len); +} + +void test_ngtcp2_pkt_decode_stream_frame(void) { + uint8_t buf[256]; + size_t buflen; + ngtcp2_frame fr; + ngtcp2_ssize rv; + size_t expectedlen; + + /* 32 bits Stream ID + 62 bits Offset + Data Length */ + buflen = ngtcp2_t_encode_stream_frame(buf, NGTCP2_STREAM_LEN_BIT, 0xf1f2f3f4u, + 0x31f2f3f4f5f6f7f8llu, 0x14); + + expectedlen = 1 + 8 + 8 + 1 + 20; + + CU_ASSERT(expectedlen == buflen); + + rv = ngtcp2_pkt_decode_stream_frame(&fr.stream, buf, buflen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(0 == fr.stream.fin); + CU_ASSERT(0xf1f2f3f4u == fr.stream.stream_id); + CU_ASSERT(0x31f2f3f4f5f6f7f8llu == fr.stream.offset); + CU_ASSERT(1 == fr.stream.datacnt); + CU_ASSERT(0x14 == fr.stream.data[0].len); + + /* Cutting 1 bytes from the tail must cause invalid argument + error */ + rv = ngtcp2_pkt_decode_stream_frame(&fr.stream, buf, buflen - 1); + + CU_ASSERT(NGTCP2_ERR_FRAME_ENCODING == rv); + + memset(&fr, 0, sizeof(fr)); + + /* 6 bits Stream ID + no Offset + Data Length */ + buflen = ngtcp2_t_encode_stream_frame(buf, NGTCP2_STREAM_LEN_BIT, 0x31, 0x00, + 0x14); + + expectedlen = 1 + 1 + 0 + 1 + 20; + + CU_ASSERT(expectedlen == buflen); + + rv = ngtcp2_pkt_decode_stream_frame(&fr.stream, buf, buflen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(0 == fr.stream.fin); + CU_ASSERT(0x31 == fr.stream.stream_id); + CU_ASSERT(0x00 == fr.stream.offset); + CU_ASSERT(1 == fr.stream.datacnt); + CU_ASSERT(0x14 == fr.stream.data[0].len); + + /* Cutting 1 bytes from the tail must cause invalid argument + error */ + rv = ngtcp2_pkt_decode_stream_frame(&fr.stream, buf, buflen - 1); + + CU_ASSERT(NGTCP2_ERR_FRAME_ENCODING == rv); + + memset(&fr, 0, sizeof(fr)); + + /* Fin bit set + no Data Length */ + buflen = ngtcp2_t_encode_stream_frame(buf, NGTCP2_STREAM_FIN_BIT, 0x31f2f3f4u, + 0x00, 0x14); + + expectedlen = 1 + 4 + 20; + + CU_ASSERT(expectedlen == buflen); + + rv = ngtcp2_pkt_decode_stream_frame(&fr.stream, buf, buflen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(1 == fr.stream.fin); + CU_ASSERT(0x31f2f3f4u == fr.stream.stream_id); + CU_ASSERT(0x00 == fr.stream.offset); + CU_ASSERT(1 == fr.stream.datacnt); + CU_ASSERT(0x14 == fr.stream.data[0].len); + + memset(&fr, 0, sizeof(fr)); +} + +void test_ngtcp2_pkt_decode_ack_frame(void) { + uint8_t buf[256]; + size_t buflen; + ngtcp2_frame fr; + ngtcp2_ssize rv; + size_t expectedlen; + + /* 62 bits Largest Acknowledged */ + buflen = ngtcp2_t_encode_ack_frame(buf, 0x31f2f3f4f5f6f7f8llu, + 0x31e2e3e4e5e6e7e8llu, 99, + 0x31d2d3d4d5d6d7d8llu); + + expectedlen = 1 + 8 + 1 + 1 + 8 + 2 + 8; + + CU_ASSERT(expectedlen == buflen); + + rv = ngtcp2_pkt_decode_ack_frame(&fr.ack, buf, buflen); + + CU_ASSERT((ngtcp2_ssize)expectedlen == rv); + CU_ASSERT(0x31f2f3f4f5f6f7f8llu == fr.ack.largest_ack); + CU_ASSERT(1 == fr.ack.rangecnt); + CU_ASSERT(0x31e2e3e4e5e6e7e8llu == fr.ack.first_ack_range); + CU_ASSERT(99 == fr.ack.ranges[0].gap); + CU_ASSERT(0x31d2d3d4d5d6d7d8llu == fr.ack.ranges[0].len); +} + +void test_ngtcp2_pkt_decode_padding_frame(void) { + uint8_t buf[256]; + ngtcp2_frame fr; + ngtcp2_ssize rv; + size_t paddinglen = 31; + + memset(buf, 0, paddinglen); + buf[paddinglen] = NGTCP2_FRAME_STREAM; + + rv = ngtcp2_pkt_decode_padding_frame(&fr.padding, buf, paddinglen + 1); + + CU_ASSERT((ngtcp2_ssize)paddinglen == rv); + CU_ASSERT((size_t)31 == fr.padding.len); +} + +void test_ngtcp2_pkt_encode_stream_frame(void) { + const uint8_t data[] = "0123456789abcdef0"; + uint8_t buf[256]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + size_t i; + + /* 32 bits Stream ID + 62 bits Offset + Data Length */ + fr.type = NGTCP2_FRAME_STREAM; + fr.stream.fin = 0; + fr.stream.stream_id = 0xf1f2f3f4u; + fr.stream.offset = 0x31f2f3f4f5f6f7f8llu; + fr.stream.datacnt = 1; + fr.stream.data[0].len = strsize(data); + fr.stream.data[0].base = (uint8_t *)data; + + framelen = 1 + 8 + 8 + 1 + 17; + + rv = ngtcp2_pkt_encode_stream_frame(buf, sizeof(buf), &fr.stream); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_stream_frame(&nfr.stream, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT((NGTCP2_STREAM_OFF_BIT | NGTCP2_STREAM_LEN_BIT) == + nfr.stream.flags); + CU_ASSERT(fr.stream.fin == nfr.stream.fin); + CU_ASSERT(fr.stream.stream_id == nfr.stream.stream_id); + CU_ASSERT(fr.stream.offset == nfr.stream.offset); + CU_ASSERT(1 == nfr.stream.datacnt); + CU_ASSERT(fr.stream.data[0].len == nfr.stream.data[0].len); + CU_ASSERT(0 == memcmp(fr.stream.data[0].base, nfr.stream.data[0].base, + fr.stream.data[0].len)); + + memset(&nfr, 0, sizeof(nfr)); + + /* 6 bits Stream ID + No Offset + Data Length */ + fr.type = NGTCP2_FRAME_STREAM; + fr.stream.fin = 0; + fr.stream.stream_id = 0x31; + fr.stream.offset = 0; + fr.stream.datacnt = 1; + fr.stream.data[0].len = strsize(data); + fr.stream.data[0].base = (uint8_t *)data; + + framelen = 1 + 1 + 1 + 17; + + rv = ngtcp2_pkt_encode_stream_frame(buf, sizeof(buf), &fr.stream); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_stream_frame(&nfr.stream, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(NGTCP2_STREAM_LEN_BIT == nfr.stream.flags); + CU_ASSERT(fr.stream.fin == nfr.stream.fin); + CU_ASSERT(fr.stream.stream_id == nfr.stream.stream_id); + CU_ASSERT(fr.stream.offset == nfr.stream.offset); + CU_ASSERT(1 == nfr.stream.datacnt); + CU_ASSERT(fr.stream.data[0].len == nfr.stream.data[0].len); + CU_ASSERT(0 == memcmp(fr.stream.data[0].base, nfr.stream.data[0].base, + fr.stream.data[0].len)); + + memset(&nfr, 0, sizeof(nfr)); + + /* Fin + 32 bits Stream ID + 62 bits Offset + Data Length */ + fr.type = NGTCP2_FRAME_STREAM; + fr.stream.fin = 1; + fr.stream.stream_id = 0xf1f2f3f4u; + fr.stream.offset = 0x31f2f3f4f5f6f7f8llu; + fr.stream.datacnt = 1; + fr.stream.data[0].len = strsize(data); + fr.stream.data[0].base = (uint8_t *)data; + + framelen = 1 + 8 + 8 + 1 + 17; + + rv = ngtcp2_pkt_encode_stream_frame(buf, sizeof(buf), &fr.stream); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_stream_frame(&nfr.stream, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT((NGTCP2_STREAM_FIN_BIT | NGTCP2_STREAM_OFF_BIT | + NGTCP2_STREAM_LEN_BIT) == nfr.stream.flags); + CU_ASSERT(fr.stream.fin == nfr.stream.fin); + CU_ASSERT(fr.stream.stream_id == nfr.stream.stream_id); + CU_ASSERT(fr.stream.offset == nfr.stream.offset); + CU_ASSERT(1 == nfr.stream.datacnt); + CU_ASSERT(fr.stream.data[0].len == nfr.stream.data[0].len); + CU_ASSERT(0 == memcmp(fr.stream.data[0].base, nfr.stream.data[0].base, + fr.stream.data[0].len)); + + /* Make sure that we check the length properly. */ + for (i = 1; i < framelen; ++i) { + rv = ngtcp2_pkt_decode_stream_frame(&nfr.stream, buf, i); + + CU_ASSERT(NGTCP2_ERR_FRAME_ENCODING == rv); + } + + memset(&nfr, 0, sizeof(nfr)); + + /* NOBUF: Fin + 32 bits Stream ID + 62 bits Offset + Data Length */ + fr.type = NGTCP2_FRAME_STREAM; + fr.stream.fin = 1; + fr.stream.stream_id = 0xf1f2f3f4u; + fr.stream.offset = 0x31f2f3f4f5f6f7f8llu; + fr.stream.datacnt = 1; + fr.stream.data[0].len = strsize(data); + fr.stream.data[0].base = (uint8_t *)data; + + framelen = 1 + 8 + 8 + 1 + 17; + + rv = ngtcp2_pkt_encode_stream_frame(buf, framelen - 1, &fr.stream); + + CU_ASSERT(NGTCP2_ERR_NOBUF == rv); +} + +void test_ngtcp2_pkt_encode_ack_frame(void) { + uint8_t buf[256]; + ngtcp2_max_frame mfr, nmfr; + ngtcp2_frame *fr = &mfr.fr, *nfr = &nmfr.fr; + ngtcp2_ssize rv; + size_t framelen; + size_t i; + ngtcp2_ack_range *ranges; + + /* 0 Num Blocks */ + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4llu; + fr->ack.first_ack_range = 0; + fr->ack.ack_delay = 0; + fr->ack.rangecnt = 0; + + framelen = 1 + 8 + 1 + 1 + 1; + + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_ack_frame(&nfr->ack, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.rangecnt == nfr->ack.rangecnt); + + memset(&nmfr, 0, sizeof(nmfr)); + + /* 2 Num Blocks */ + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4llu; + fr->ack.first_ack_range = 0xe1e2e3e4llu; + fr->ack.ack_delay = 0xf1f2; + fr->ack.rangecnt = 2; + ranges = fr->ack.ranges; + ranges[0].gap = 255; + ranges[0].len = 0xd1d2d3d4llu; + ranges[1].gap = 1; + ranges[1].len = 0xd1d2d3d4llu; + + framelen = 1 + 8 + 4 + 1 + 8 + (2 + 8) + (1 + 8); + + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_ack_frame(&nfr->ack, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.rangecnt == nfr->ack.rangecnt); + + for (i = 0; i < fr->ack.rangecnt; ++i) { + CU_ASSERT(fr->ack.ranges[i].gap == nfr->ack.ranges[i].gap); + CU_ASSERT(fr->ack.ranges[i].len == nfr->ack.ranges[i].len); + } + + memset(&nmfr, 0, sizeof(nmfr)); +} + +void test_ngtcp2_pkt_encode_ack_ecn_frame(void) { + uint8_t buf[256]; + ngtcp2_max_frame mfr, nmfr; + ngtcp2_frame *fr = &mfr.fr, *nfr = &nmfr.fr; + ngtcp2_ssize rv; + size_t framelen; + size_t i; + ngtcp2_ack_range *ranges; + + /* 0 Num Blocks */ + fr->type = NGTCP2_FRAME_ACK_ECN; + fr->ack.largest_ack = 0xf1f2f3f4llu; + fr->ack.first_ack_range = 0; + fr->ack.ack_delay = 0; + fr->ack.rangecnt = 0; + fr->ack.ecn.ect0 = 64; + fr->ack.ecn.ect1 = 16384; + fr->ack.ecn.ce = 1073741824; + + framelen = 1 + 8 + 1 + 1 + 1 + 2 + 4 + 8; + + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_ack_frame(&nfr->ack, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.rangecnt == nfr->ack.rangecnt); + CU_ASSERT(fr->ack.ecn.ect0 == nfr->ack.ecn.ect0); + CU_ASSERT(fr->ack.ecn.ect1 == nfr->ack.ecn.ect1); + CU_ASSERT(fr->ack.ecn.ce == nfr->ack.ecn.ce); + + memset(&nmfr, 0, sizeof(nmfr)); + + /* 2 Num Blocks */ + fr->type = NGTCP2_FRAME_ACK_ECN; + fr->ack.largest_ack = 0xf1f2f3f4llu; + fr->ack.first_ack_range = 0xe1e2e3e4llu; + fr->ack.ack_delay = 0xf1f2; + fr->ack.rangecnt = 2; + ranges = fr->ack.ranges; + ranges[0].gap = 255; + ranges[0].len = 0xd1d2d3d4llu; + ranges[1].gap = 1; + ranges[1].len = 0xd1d2d3d4llu; + fr->ack.ecn.ect0 = 0; + fr->ack.ecn.ect1 = 64; + fr->ack.ecn.ce = 16384; + + framelen = 1 + 8 + 4 + 1 + 8 + (2 + 8) + (1 + 8) + 1 + 2 + 4; + + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_ack_frame(&nfr->ack, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.rangecnt == nfr->ack.rangecnt); + + for (i = 0; i < fr->ack.rangecnt; ++i) { + CU_ASSERT(fr->ack.ranges[i].gap == nfr->ack.ranges[i].gap); + CU_ASSERT(fr->ack.ranges[i].len == nfr->ack.ranges[i].len); + } + + CU_ASSERT(fr->ack.ecn.ect0 == nfr->ack.ecn.ect0); + CU_ASSERT(fr->ack.ecn.ect1 == nfr->ack.ecn.ect1); + CU_ASSERT(fr->ack.ecn.ce == nfr->ack.ecn.ce); + + memset(&nmfr, 0, sizeof(nmfr)); +} + +void test_ngtcp2_pkt_encode_reset_stream_frame(void) { + uint8_t buf[32]; + ngtcp2_reset_stream fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 4 + 4 + 8; + + fr.type = NGTCP2_FRAME_RESET_STREAM; + fr.stream_id = 1000000007; + fr.app_error_code = 0xe1e2; + fr.final_size = 0x31f2f3f4f5f6f7f8llu; + + rv = ngtcp2_pkt_encode_reset_stream_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_reset_stream_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.stream_id == nfr.stream_id); + CU_ASSERT(fr.app_error_code == nfr.app_error_code); + CU_ASSERT(fr.final_size == nfr.final_size); +} + +void test_ngtcp2_pkt_encode_connection_close_frame(void) { + uint8_t buf[2048]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + uint8_t reason[1024]; + + memset(reason, 0xfa, sizeof(reason)); + + /* no Reason Phrase */ + fr.type = NGTCP2_FRAME_CONNECTION_CLOSE; + fr.connection_close.error_code = 0xf1f2u; + fr.connection_close.frame_type = 255; + fr.connection_close.reasonlen = 0; + fr.connection_close.reason = NULL; + + framelen = 1 + 4 + 2 + 1; + + rv = ngtcp2_pkt_encode_connection_close_frame(buf, sizeof(buf), + &fr.connection_close); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_connection_close_frame(&nfr.connection_close, buf, + framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.connection_close.error_code == nfr.connection_close.error_code); + CU_ASSERT(fr.connection_close.reasonlen == nfr.connection_close.reasonlen); + CU_ASSERT(fr.connection_close.reason == nfr.connection_close.reason); + + memset(&nfr, 0, sizeof(nfr)); + + /* 1024 bytes Reason Phrase */ + fr.type = NGTCP2_FRAME_CONNECTION_CLOSE; + fr.connection_close.error_code = 0xf3f4u; + fr.connection_close.frame_type = 0; + fr.connection_close.reasonlen = sizeof(reason); + fr.connection_close.reason = reason; + + framelen = 1 + 4 + 1 + 2 + sizeof(reason); + + rv = ngtcp2_pkt_encode_connection_close_frame(buf, sizeof(buf), + &fr.connection_close); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_connection_close_frame(&nfr.connection_close, buf, + framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.connection_close.error_code == nfr.connection_close.error_code); + CU_ASSERT(fr.connection_close.reasonlen == nfr.connection_close.reasonlen); + CU_ASSERT(0 == memcmp(reason, nfr.connection_close.reason, sizeof(reason))); + + memset(&nfr, 0, sizeof(nfr)); +} + +void test_ngtcp2_pkt_encode_connection_close_app_frame(void) { + uint8_t buf[2048]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + uint8_t reason[1024]; + + memset(reason, 0xfa, sizeof(reason)); + + /* no Reason Phrase */ + fr.type = NGTCP2_FRAME_CONNECTION_CLOSE_APP; + fr.connection_close.error_code = 0xf1f2u; + fr.connection_close.frame_type = 0xff; /* This must be ignored. */ + fr.connection_close.reasonlen = 0; + fr.connection_close.reason = NULL; + + framelen = 1 + 4 + 1; + + rv = ngtcp2_pkt_encode_connection_close_frame(buf, sizeof(buf), + &fr.connection_close); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_connection_close_frame(&nfr.connection_close, buf, + framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.connection_close.error_code == nfr.connection_close.error_code); + CU_ASSERT(0 == nfr.connection_close.frame_type); + CU_ASSERT(fr.connection_close.reasonlen == nfr.connection_close.reasonlen); + CU_ASSERT(fr.connection_close.reason == nfr.connection_close.reason); + + memset(&nfr, 0, sizeof(nfr)); +} + +void test_ngtcp2_pkt_encode_max_data_frame(void) { + uint8_t buf[16]; + ngtcp2_max_data fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8; + + fr.type = NGTCP2_FRAME_MAX_DATA; + fr.max_data = 0x31f2f3f4f5f6f7f8llu; + + rv = ngtcp2_pkt_encode_max_data_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_max_data_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.max_data == nfr.max_data); +} + +void test_ngtcp2_pkt_encode_max_stream_data_frame(void) { + uint8_t buf[17]; + ngtcp2_max_stream_data fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8 + 8; + + fr.type = NGTCP2_FRAME_MAX_STREAM_DATA; + fr.stream_id = 0xf1f2f3f4u; + fr.max_stream_data = 0x35f6f7f8f9fafbfcllu; + + rv = ngtcp2_pkt_encode_max_stream_data_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_max_stream_data_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.stream_id == nfr.stream_id); + CU_ASSERT(fr.max_stream_data == nfr.max_stream_data); +} + +void test_ngtcp2_pkt_encode_max_streams_frame(void) { + uint8_t buf[16]; + ngtcp2_max_streams fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8; + + fr.type = NGTCP2_FRAME_MAX_STREAMS_BIDI; + fr.max_streams = 0xf1f2f3f4u; + + rv = ngtcp2_pkt_encode_max_streams_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_max_streams_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.max_streams == nfr.max_streams); +} + +void test_ngtcp2_pkt_encode_ping_frame(void) { + uint8_t buf[3]; + ngtcp2_ping fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + + fr.type = NGTCP2_FRAME_PING; + + framelen = 1; + + rv = ngtcp2_pkt_encode_ping_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_ping_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); +} + +void test_ngtcp2_pkt_encode_data_blocked_frame(void) { + uint8_t buf[9]; + ngtcp2_data_blocked fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8; + + fr.type = NGTCP2_FRAME_DATA_BLOCKED; + fr.offset = 0x31f2f3f4f5f6f7f8llu; + + rv = ngtcp2_pkt_encode_data_blocked_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_data_blocked_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.offset == nfr.offset); +} + +void test_ngtcp2_pkt_encode_stream_data_blocked_frame(void) { + uint8_t buf[17]; + ngtcp2_stream_data_blocked fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8 + 8; + + fr.type = NGTCP2_FRAME_STREAM_DATA_BLOCKED; + fr.stream_id = 0xf1f2f3f4u; + fr.offset = 0x35f6f7f8f9fafbfcllu; + + rv = ngtcp2_pkt_encode_stream_data_blocked_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_stream_data_blocked_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.stream_id == nfr.stream_id); + CU_ASSERT(fr.offset == nfr.offset); +} + +void test_ngtcp2_pkt_encode_streams_blocked_frame(void) { + uint8_t buf[9]; + ngtcp2_streams_blocked fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8; + + fr.type = NGTCP2_FRAME_STREAMS_BLOCKED_BIDI; + fr.max_streams = 0xf1f2f3f4u; + + rv = ngtcp2_pkt_encode_streams_blocked_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_streams_blocked_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.max_streams == nfr.max_streams); +} + +void test_ngtcp2_pkt_encode_new_connection_id_frame(void) { + uint8_t buf[256]; + ngtcp2_new_connection_id fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 4 + 2 + 1 + 18 + NGTCP2_STATELESS_RESET_TOKENLEN; + + fr.type = NGTCP2_FRAME_NEW_CONNECTION_ID; + fr.seq = 1000000009; + fr.retire_prior_to = 255; + scid_init(&fr.cid); + memset(fr.stateless_reset_token, 0xe1, sizeof(fr.stateless_reset_token)); + + rv = ngtcp2_pkt_encode_new_connection_id_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_new_connection_id_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.seq == nfr.seq); + CU_ASSERT(ngtcp2_cid_eq(&fr.cid, &nfr.cid)); + CU_ASSERT(0 == memcmp(fr.stateless_reset_token, nfr.stateless_reset_token, + sizeof(fr.stateless_reset_token))); +} + +void test_ngtcp2_pkt_encode_stop_sending_frame(void) { + uint8_t buf[16]; + ngtcp2_stop_sending fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8 + 4; + + fr.type = NGTCP2_FRAME_STOP_SENDING; + fr.stream_id = 0xf1f2f3f4u; + fr.app_error_code = 0xe1e2u; + + rv = ngtcp2_pkt_encode_stop_sending_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_stop_sending_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.stream_id == nfr.stream_id); + CU_ASSERT(fr.app_error_code == nfr.app_error_code); +} + +void test_ngtcp2_pkt_encode_path_challenge_frame(void) { + uint8_t buf[9]; + ngtcp2_path_challenge fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8; + size_t i; + + fr.type = NGTCP2_FRAME_PATH_CHALLENGE; + for (i = 0; i < sizeof(fr.data); ++i) { + fr.data[i] = (uint8_t)(i + 1); + } + + rv = ngtcp2_pkt_encode_path_challenge_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_path_challenge_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(0 == memcmp(fr.data, nfr.data, sizeof(fr.data))); +} + +void test_ngtcp2_pkt_encode_path_response_frame(void) { + uint8_t buf[9]; + ngtcp2_path_response fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1 + 8; + size_t i; + + fr.type = NGTCP2_FRAME_PATH_RESPONSE; + for (i = 0; i < sizeof(fr.data); ++i) { + fr.data[i] = (uint8_t)(i + 1); + } + + rv = ngtcp2_pkt_encode_path_response_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_path_response_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(0 == memcmp(fr.data, nfr.data, sizeof(fr.data))); +} + +void test_ngtcp2_pkt_encode_crypto_frame(void) { + const uint8_t data[] = "0123456789abcdef1"; + uint8_t buf[256]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + + fr.type = NGTCP2_FRAME_CRYPTO; + fr.crypto.offset = 0x31f2f3f4f5f6f7f8llu; + fr.crypto.datacnt = 1; + fr.crypto.data[0].len = strsize(data); + fr.crypto.data[0].base = (uint8_t *)data; + + framelen = 1 + 8 + 1 + 17; + + rv = ngtcp2_pkt_encode_crypto_frame(buf, sizeof(buf), &fr.crypto); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_crypto_frame(&nfr.crypto, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.crypto.offset == nfr.crypto.offset); + CU_ASSERT(fr.crypto.datacnt == nfr.crypto.datacnt); + CU_ASSERT(fr.crypto.data[0].len == nfr.crypto.data[0].len); + CU_ASSERT(0 == memcmp(fr.crypto.data[0].base, nfr.crypto.data[0].base, + fr.crypto.data[0].len)); +} + +void test_ngtcp2_pkt_encode_new_token_frame(void) { + const uint8_t token[] = "0123456789abcdef2"; + uint8_t buf[256]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + + fr.type = NGTCP2_FRAME_NEW_TOKEN; + ngtcp2_vec_init(&fr.new_token.token, token, strsize(token)); + + framelen = 1 + 1 + strsize(token); + + rv = ngtcp2_pkt_encode_new_token_frame(buf, sizeof(buf), &fr.new_token); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_new_token_frame(&nfr.new_token, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.new_token.token.len == nfr.new_token.token.len); + CU_ASSERT(0 == memcmp(fr.new_token.token.base, nfr.new_token.token.base, + fr.new_token.token.len)); +} + +void test_ngtcp2_pkt_encode_retire_connection_id_frame(void) { + uint8_t buf[256]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + + fr.type = NGTCP2_FRAME_RETIRE_CONNECTION_ID; + fr.retire_connection_id.seq = 1000000007; + + framelen = 1 + ngtcp2_put_uvarintlen(fr.retire_connection_id.seq); + + rv = ngtcp2_pkt_encode_retire_connection_id_frame(buf, sizeof(buf), + &fr.retire_connection_id); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_retire_connection_id_frame(&nfr.retire_connection_id, + buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.retire_connection_id.seq == nfr.retire_connection_id.seq); +} + +void test_ngtcp2_pkt_encode_handshake_done_frame(void) { + uint8_t buf[16]; + ngtcp2_handshake_done fr, nfr; + ngtcp2_ssize rv; + size_t framelen = 1; + + fr.type = NGTCP2_FRAME_HANDSHAKE_DONE; + + rv = ngtcp2_pkt_encode_handshake_done_frame(buf, sizeof(buf), &fr); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_handshake_done_frame(&nfr, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); +} + +void test_ngtcp2_pkt_encode_datagram_frame(void) { + const uint8_t data[] = "0123456789abcdef3"; + uint8_t buf[256]; + ngtcp2_frame fr, nfr; + ngtcp2_ssize rv; + size_t framelen; + + fr.type = NGTCP2_FRAME_DATAGRAM_LEN; + fr.datagram.datacnt = 1; + fr.datagram.data = fr.datagram.rdata; + fr.datagram.rdata[0].len = strsize(data); + fr.datagram.rdata[0].base = (uint8_t *)data; + + framelen = 1 + 1 + 17; + + rv = ngtcp2_pkt_encode_datagram_frame(buf, sizeof(buf), &fr.datagram); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_datagram_frame(&nfr.datagram, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.datagram.datacnt == nfr.datagram.datacnt); + CU_ASSERT(fr.datagram.data->len == nfr.datagram.data->len); + CU_ASSERT(0 == memcmp(fr.datagram.data->base, nfr.datagram.data->base, + fr.datagram.data->len)); + + memset(&nfr, 0, sizeof(nfr)); + + /* Without length field */ + fr.type = NGTCP2_FRAME_DATAGRAM; + fr.datagram.datacnt = 1; + fr.datagram.data = fr.datagram.rdata; + fr.datagram.rdata[0].len = strsize(data); + fr.datagram.rdata[0].base = (uint8_t *)data; + + framelen = 1 + 17; + + rv = ngtcp2_pkt_encode_datagram_frame(buf, sizeof(buf), &fr.datagram); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_datagram_frame(&nfr.datagram, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.datagram.datacnt == nfr.datagram.datacnt); + CU_ASSERT(fr.datagram.data->len == nfr.datagram.data->len); + CU_ASSERT(0 == memcmp(fr.datagram.data->base, nfr.datagram.data->base, + fr.datagram.data->len)); + + memset(&nfr, 0, sizeof(nfr)); + + /* Zero length data with length field */ + fr.type = NGTCP2_FRAME_DATAGRAM_LEN; + fr.datagram.datacnt = 0; + fr.datagram.data = NULL; + + framelen = 1 + 1; + + rv = ngtcp2_pkt_encode_datagram_frame(buf, sizeof(buf), &fr.datagram); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_datagram_frame(&nfr.datagram, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.datagram.datacnt == nfr.datagram.datacnt); + CU_ASSERT(NULL == nfr.datagram.data); + + /* Zero length data without length field */ + fr.type = NGTCP2_FRAME_DATAGRAM; + fr.datagram.datacnt = 0; + fr.datagram.data = NULL; + + framelen = 1; + + rv = ngtcp2_pkt_encode_datagram_frame(buf, sizeof(buf), &fr.datagram); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + + rv = ngtcp2_pkt_decode_datagram_frame(&nfr.datagram, buf, framelen); + + CU_ASSERT((ngtcp2_ssize)framelen == rv); + CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr.datagram.datacnt == nfr.datagram.datacnt); + CU_ASSERT(NULL == nfr.datagram.data); +} + +void test_ngtcp2_pkt_adjust_pkt_num(void) { + CU_ASSERT(0xaa831f94llu == + ngtcp2_pkt_adjust_pkt_num(0xaa82f30ellu, 0x1f94, 16)); + + CU_ASSERT(0xff == ngtcp2_pkt_adjust_pkt_num(0x0100, 0xff, 8)); + CU_ASSERT(0x01ff == ngtcp2_pkt_adjust_pkt_num(0x01ff, 0xff, 8)); + CU_ASSERT(0x0fff == ngtcp2_pkt_adjust_pkt_num(0x1000, 0xff, 8)); + CU_ASSERT(0x80 == ngtcp2_pkt_adjust_pkt_num(0x00, 0x80, 8)); + CU_ASSERT(0x3fffffffffffffabllu == + ngtcp2_pkt_adjust_pkt_num(NGTCP2_MAX_PKT_NUM, 0xab, 8)); + CU_ASSERT(0x4000000000000000llu == + ngtcp2_pkt_adjust_pkt_num(NGTCP2_MAX_PKT_NUM, 0x00, 8)); + CU_ASSERT(250 == ngtcp2_pkt_adjust_pkt_num(255, 250, 8)); + CU_ASSERT(8 == ngtcp2_pkt_adjust_pkt_num(50, 8, 8)); + CU_ASSERT(0 == ngtcp2_pkt_adjust_pkt_num(-1, 0, 8)); +} + +void test_ngtcp2_pkt_validate_ack(void) { + int rv; + ngtcp2_ack fr; + + /* too long first_ack_range */ + fr.largest_ack = 1; + fr.first_ack_range = 2; + fr.rangecnt = 0; + + rv = ngtcp2_pkt_validate_ack(&fr); + + CU_ASSERT(NGTCP2_ERR_ACK_FRAME == rv); + + /* gap is too large */ + fr.largest_ack = 250; + fr.first_ack_range = 1; + fr.rangecnt = 1; + fr.ranges[0].gap = 248; + fr.ranges[0].len = 0; + + rv = ngtcp2_pkt_validate_ack(&fr); + + CU_ASSERT(NGTCP2_ERR_ACK_FRAME == rv); + + /* too large range len */ + fr.largest_ack = 250; + fr.first_ack_range = 0; + fr.rangecnt = 1; + fr.ranges[0].gap = 248; + fr.ranges[0].len = 1; + + rv = ngtcp2_pkt_validate_ack(&fr); + + CU_ASSERT(NGTCP2_ERR_ACK_FRAME == rv); +} + +void test_ngtcp2_pkt_write_stateless_reset(void) { + uint8_t buf[256]; + ngtcp2_ssize spktlen; + uint8_t token[NGTCP2_STATELESS_RESET_TOKENLEN]; + uint8_t rand[256]; + size_t i; + uint8_t *p; + size_t randlen; + + memset(rand, 0, sizeof(rand)); + for (i = 0; i < NGTCP2_STATELESS_RESET_TOKENLEN; ++i) { + token[i] = (uint8_t)(i + 1); + } + + spktlen = ngtcp2_pkt_write_stateless_reset(buf, sizeof(buf), token, rand, + sizeof(rand)); + + p = buf; + + CU_ASSERT(256 == spktlen); + CU_ASSERT(0 == (*p & NGTCP2_HEADER_FORM_BIT)); + CU_ASSERT((*p & NGTCP2_FIXED_BIT_MASK)); + + ++p; + + randlen = (size_t)(spktlen - (p - buf) - NGTCP2_STATELESS_RESET_TOKENLEN); + + CU_ASSERT(0 == memcmp(rand, p, randlen)); + + p += randlen; + + CU_ASSERT(0 == memcmp(token, p, NGTCP2_STATELESS_RESET_TOKENLEN)); + + p += NGTCP2_STATELESS_RESET_TOKENLEN; + + CU_ASSERT(spktlen == p - buf); + + /* Not enough buffer */ + spktlen = ngtcp2_pkt_write_stateless_reset( + buf, + NGTCP2_MIN_STATELESS_RESET_RANDLEN - 1 + NGTCP2_STATELESS_RESET_TOKENLEN, + token, rand, sizeof(rand)); + + CU_ASSERT(NGTCP2_ERR_NOBUF == spktlen); +} + +void test_ngtcp2_pkt_write_retry(void) { + uint8_t buf[256]; + ngtcp2_ssize spktlen; + ngtcp2_cid scid, dcid, odcid; + ngtcp2_pkt_hd nhd; + uint8_t token[32]; + size_t i; + ngtcp2_pkt_retry retry; + ngtcp2_ssize nread; + int rv; + ngtcp2_crypto_aead aead = {0}; + ngtcp2_crypto_aead_ctx aead_ctx = {0}; + uint8_t tag[NGTCP2_RETRY_TAGLEN] = {0}; + + scid_init(&scid); + dcid_init(&dcid); + rcid_init(&odcid); + + for (i = 0; i < sizeof(token); ++i) { + token[i] = (uint8_t)i; + } + + spktlen = ngtcp2_pkt_write_retry(buf, sizeof(buf), NGTCP2_PROTO_VER_V1, &dcid, + &scid, &odcid, token, sizeof(token), + null_retry_encrypt, &aead, &aead_ctx); + + CU_ASSERT(spktlen > 0); + + memset(&nhd, 0, sizeof(nhd)); + + nread = ngtcp2_pkt_decode_hd_long(&nhd, buf, (size_t)spktlen); + + CU_ASSERT(nread > 0); + CU_ASSERT(NGTCP2_PKT_RETRY == nhd.type); + CU_ASSERT(NGTCP2_PROTO_VER_V1 == nhd.version); + CU_ASSERT(ngtcp2_cid_eq(&dcid, &nhd.dcid)); + CU_ASSERT(ngtcp2_cid_eq(&scid, &nhd.scid)); + + rv = ngtcp2_pkt_decode_retry(&retry, buf + nread, (size_t)(spktlen - nread)); + + CU_ASSERT(0 == rv); + CU_ASSERT(sizeof(token) == retry.token.len); + CU_ASSERT(0 == memcmp(token, retry.token.base, sizeof(token))); + CU_ASSERT(0 == memcmp(tag, retry.tag, sizeof(tag))); +} + +void test_ngtcp2_pkt_write_version_negotiation(void) { + uint8_t buf[256]; + ngtcp2_ssize spktlen; + const uint32_t sv[] = {0xf1f2f3f4, 0x1f2f3f4f}; + const uint8_t *p; + size_t i; + ngtcp2_cid dcid, scid; + uint32_t v; + + dcid_init(&dcid); + scid_init(&scid); + + spktlen = ngtcp2_pkt_write_version_negotiation( + buf, sizeof(buf), 133, dcid.data, dcid.datalen, scid.data, scid.datalen, + sv, ngtcp2_arraylen(sv)); + + CU_ASSERT((ngtcp2_ssize)(1 + 4 + 1 + dcid.datalen + 1 + scid.datalen + + ngtcp2_arraylen(sv) * 4) == spktlen); + + p = buf; + + CU_ASSERT((0x80 | 133) == buf[0]); + + ++p; + + p = ngtcp2_get_uint32(&v, p); + + CU_ASSERT(0 == v); + + CU_ASSERT(dcid.datalen == *p); + + ++p; + + CU_ASSERT(0 == memcmp(dcid.data, p, dcid.datalen)); + + p += dcid.datalen; + + CU_ASSERT(scid.datalen == *p); + + ++p; + + CU_ASSERT(0 == memcmp(scid.data, p, scid.datalen)); + + p += scid.datalen; + + for (i = 0; i < ngtcp2_arraylen(sv); ++i) { + p = ngtcp2_get_uint32(&v, p); + + CU_ASSERT(sv[i] == v); + } +} + +void test_ngtcp2_pkt_stream_max_datalen(void) { + size_t len; + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 0, 2); + + CU_ASSERT((size_t)-1 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 0, 3); + + CU_ASSERT(0 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1, 3); + + CU_ASSERT(0 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1, 4); + + CU_ASSERT(1 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 1, 1, 4); + + CU_ASSERT(0 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 63, 66); + + CU_ASSERT(63 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 63, 65); + + CU_ASSERT(62 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1396, 1400); + + CU_ASSERT(1396 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1396, 1399); + + CU_ASSERT(1395 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1396, 9); + + CU_ASSERT(6 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 16385, 16391); + + CU_ASSERT(16385 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 16385, 16390); + + CU_ASSERT(16384 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1073741824, 1073741834); + + CU_ASSERT(1073741824 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 1073741824, 1073741833); + + CU_ASSERT(1073741823 == len); + + len = ngtcp2_pkt_stream_max_datalen(63, 0, 16383, 16387); + + CU_ASSERT(16383 == len); +} |