diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h index 35186d68656db9631487b691a85a8d8c70f30b96..37d45eb7d8025ae547951375d7a375d0f57f9ef3 100644 --- a/lib/includes/ngtcp2/ngtcp2.h +++ b/lib/includes/ngtcp2/ngtcp2.h @@ -312,7 +312,7 @@ typedef struct { uint16_t ack_delay; uint64_t first_ack_blklen; size_t num_blks; - ngtcp2_ack_blk blks[255]; + ngtcp2_ack_blk blks[1]; } ngtcp2_ack; typedef struct { diff --git a/lib/ngtcp2_acktr.c b/lib/ngtcp2_acktr.c index 1e9e47e9eeac15b60737db8e3459f039f60216c3..dfe6c8c9afde5ce0daeb11e6503a373ccf264e57 100644 --- a/lib/ngtcp2_acktr.c +++ b/lib/ngtcp2_acktr.c @@ -67,11 +67,17 @@ int ngtcp2_acktr_init(ngtcp2_acktr *acktr, ngtcp2_mem *mem) { void ngtcp2_acktr_free(ngtcp2_acktr *acktr) { ngtcp2_acktr_entry *ent, *next; + ngtcp2_acktr_ack_entry *ack_ent; + size_t i; if (acktr == NULL) { return; } + for (i = 0; i < acktr->acks.len; ++i) { + ack_ent = ngtcp2_ringbuf_get(&acktr->acks, i); + ngtcp2_mem_free(acktr->mem, ack_ent->ack); + } ngtcp2_ringbuf_free(&acktr->acks); for (ent = acktr->ent; ent;) { @@ -165,12 +171,12 @@ void ngtcp2_acktr_pop(ngtcp2_acktr *acktr) { ngtcp2_acktr_entry_del(ent, acktr->mem); } -void ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, uint64_t pkt_num, - const ngtcp2_ack *fr, uint8_t unprotected) { +void ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, uint64_t pkt_num, ngtcp2_ack *fr, + uint8_t unprotected) { ngtcp2_acktr_ack_entry *ent; ent = ngtcp2_ringbuf_push_front(&acktr->acks); - ent->ack = *fr; + ent->ack = fr; ent->pkt_num = pkt_num; ent->unprotected = unprotected; } @@ -200,7 +206,7 @@ static void acktr_on_ack(ngtcp2_acktr *acktr, size_t ack_ent_offset) { size_t i; ent = ngtcp2_ringbuf_get(&acktr->acks, ack_ent_offset); - fr = &ent->ack; + fr = ent->ack; largest_ack = fr->largest_ack; /* Assume that ngtcp2_pkt_validate_ack(fr) returns 0 */ @@ -250,6 +256,10 @@ static void acktr_on_ack(ngtcp2_acktr *acktr, size_t ack_ent_offset) { } fin: + for (i = ack_ent_offset; i < acktr->acks.len; ++i) { + ent = ngtcp2_ringbuf_get(&acktr->acks, i); + ngtcp2_mem_free(acktr->mem, ent->ack); + } ngtcp2_ringbuf_resize(&acktr->acks, ack_ent_offset); } diff --git a/lib/ngtcp2_acktr.h b/lib/ngtcp2_acktr.h index d45662bdbdec0aefbc56f6918641b2902f8a0606..654e3c53bc685e80ffec5e2eda79546f0b11465d 100644 --- a/lib/ngtcp2_acktr.h +++ b/lib/ngtcp2_acktr.h @@ -64,7 +64,7 @@ int ngtcp2_acktr_entry_new(ngtcp2_acktr_entry **ent, uint64_t pkt_num, void ngtcp2_acktr_entry_del(ngtcp2_acktr_entry *ent, ngtcp2_mem *mem); typedef struct { - ngtcp2_ack ack; + ngtcp2_ack *ack; uint64_t pkt_num; uint8_t unprotected; } ngtcp2_acktr_ack_entry; @@ -136,10 +136,11 @@ void ngtcp2_acktr_pop(ngtcp2_acktr *acktr); /* * ngtcp2_acktr_add_ack adds the outgoing ACK frame |fr| to |acktr|. * |pkt_num| is the packet number which |fr| belongs. |unprotected| - * is nonzero if the packet is an unprotected packet. + * is nonzero if the packet is an unprotected packet. This function + * transfers the ownership of |fr| to |acktr|. */ -void ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, uint64_t pkt_num, - const ngtcp2_ack *fr, uint8_t unprotected); +void ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, uint64_t pkt_num, ngtcp2_ack *fr, + uint8_t unprotected); /* * ngtcp2_acktr_recv_ack processes the incoming ACK frame |fr|. diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c index b633a6eacbbb41f592d2df456485f3ba6727a658..3c65da5912d59857654e323a05020cd992d748e6 100644 --- a/lib/ngtcp2_conn.c +++ b/lib/ngtcp2_conn.c @@ -369,18 +369,59 @@ static int conn_next_ack_expired(ngtcp2_conn *conn, ngtcp2_tstamp ts) { } /* - * conn_create_ack_frame fills ACK frame pointed by |ack|. + * conn_ensure_ack_blks makes sure that |(*pfr)->ack.blks| can contain + * at least |n| ngtcp2_ack_blk. |*pfr| points to the ngtcp2_frame + * object. |*pnum_blks_max| is the number of ngtpc2_ack_blk which + * |*pfr| can contain. * - * There is a case that there is no ACK frame to send. To distinguish - * this case, call this function with |ack| after assigning - * `~NGTCP2_FRAME_ACK` to ack->type. If there is ACK frame to send, - * ack->type will be NGTCP2_FRAME_ACK. + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * NGTCP2_ERR_NOMEM + * Out of memory. + */ +static int conn_ensure_ack_blks(ngtcp2_conn *conn, ngtcp2_frame **pfr, + size_t *pnum_blks_max, size_t n) { + ngtcp2_frame *fr; + + if (n <= *pnum_blks_max) { + return 0; + } + + *pnum_blks_max *= 2; + fr = ngtcp2_mem_realloc(conn->mem, *pfr, + sizeof(ngtcp2_ack) + + sizeof(ngtcp2_ack_blk) * (*pnum_blks_max - 1)); + if (fr == NULL) { + return NGTCP2_ERR_NOMEM; + } + + *pfr = fr; + + return 0; +} + +/* + * conn_create_ack_frame creates ACK frame, and assigns its pointer to + * |*pfr| if there are any received packets to acknowledge. If there + * are no packets to acknowledge, this function returns 0, and |*pfr| + * is untouched. The caller is advised to set |*pfr| to NULL before + * calling this function, and check it after this function returns. + * + * The memory for ACK frame is dynamically allocated by this function. + * A caller is responsible to free it. * * Call conn_commit_tx_ack after a created ACK frame is successfully * serialized into a packet. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * NGTCP2_ERR_NOMEM + * Out of memory. */ -static void conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_ack *ack, - ngtcp2_tstamp ts) { +static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr, + ngtcp2_tstamp ts) { uint64_t first_pkt_num; ngtcp2_tstamp ack_delay; uint64_t last_pkt_num; @@ -388,19 +429,35 @@ static void conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_ack *ack, int initial = 1; uint64_t gap; ngtcp2_acktr_entry **prpkt; + ngtcp2_frame *fr; + ngtcp2_ack *ack; + /* TODO Measure an actual size of ACK bloks to find the best default + value. */ + size_t num_blks_max = 8; + size_t blk_idx; + int rv; if (!conn->acktr.active_ack) { conn_invalidate_next_ack_expiry(conn); - return; + return 0; } prpkt = ngtcp2_acktr_get(&conn->acktr); if (*prpkt == NULL) { /* TODO This might not be necessary if we don't forget ACK. */ conn_invalidate_next_ack_expiry(conn); - return; + return 0; + } + + fr = ngtcp2_mem_malloc(conn->mem, + sizeof(ngtcp2_ack) + + sizeof(ngtcp2_ack_blk) * (num_blks_max - 1)); + if (fr == NULL) { + return NGTCP2_ERR_NOMEM; } + ack = &fr->ack; + first_pkt_num = last_pkt_num = (*prpkt)->pkt_num; ack_delay = ts - (*prpkt)->tstamp; @@ -421,7 +478,14 @@ static void conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_ack *ack, ack->ack_delay = (uint16_t)ack_delay; ack->first_ack_blklen = first_pkt_num - last_pkt_num; } else { - blk = &ack->blks[ack->num_blks++]; + blk_idx = ack->num_blks++; + rv = conn_ensure_ack_blks(conn, &fr, &num_blks_max, ack->num_blks); + if (rv != 0) { + ngtcp2_mem_free(conn->mem, fr); + return rv; + } + ack = &fr->ack; + blk = &ack->blks[blk_idx]; blk->gap = (uint8_t)gap; blk->blklen = first_pkt_num - last_pkt_num + 1; } @@ -447,7 +511,14 @@ static void conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_ack *ack, ack->ack_delay = (uint16_t)ack_delay; ack->first_ack_blklen = first_pkt_num - last_pkt_num; } else if (first_pkt_num != last_pkt_num) { - blk = &ack->blks[ack->num_blks++]; + blk_idx = ack->num_blks++; + rv = conn_ensure_ack_blks(conn, &fr, &num_blks_max, ack->num_blks); + if (rv != 0) { + ngtcp2_mem_free(conn->mem, fr); + return rv; + } + ack = &fr->ack; + blk = &ack->blks[blk_idx]; blk->gap = (uint8_t)gap; blk->blklen = first_pkt_num - last_pkt_num + 1; } @@ -457,6 +528,10 @@ static void conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_ack *ack, if (*prpkt) { ngtcp2_acktr_forget(&conn->acktr, *prpkt); } + + *pfr = fr; + + return 0; } /* @@ -646,7 +721,7 @@ static ssize_t conn_retransmit_protected(ngtcp2_conn *conn, uint8_t *dest, ngtcp2_pkt_hd hd = ent->hd; ngtcp2_frame_chain **pfrc, *frc; ngtcp2_rtb_entry *nent = NULL; - ngtcp2_frame localfr; + ngtcp2_frame *ackfr; int pkt_empty = 1; ssize_t nwrite; ngtcp2_crypto_ctx ctx; @@ -748,32 +823,38 @@ static ssize_t conn_retransmit_protected(ngtcp2_conn *conn, uint8_t *dest, } /* ACK is added last so that we don't send ACK only frame here. */ - localfr.type = (uint8_t)~NGTCP2_FRAME_ACK; + ackfr = NULL; /* TODO Is it better to check the remaining space in packet? */ if (ack_expired) { - conn_create_ack_frame(conn, &localfr.ack, ts); - if (localfr.type == NGTCP2_FRAME_ACK) { - rv = ngtcp2_ppe_encode_frame(&ppe, &localfr); + rv = conn_create_ack_frame(conn, &ackfr, ts); + if (rv != 0) { + return rv; + } + if (ackfr) { + rv = ngtcp2_ppe_encode_frame(&ppe, ackfr); if (rv == 0) { conn_commit_tx_ack(conn); if (!send_pkt_cb_called) { rv = conn_call_send_pkt(conn, &hd); if (rv != 0) { + ngtcp2_mem_free(conn->mem, ackfr); return rv; } send_pkt_cb_called = 1; } - rv = conn_call_send_frame(conn, &hd, &localfr); + rv = conn_call_send_frame(conn, &hd, ackfr); if (rv != 0) { + ngtcp2_mem_free(conn->mem, ackfr); return rv; } pkt_empty = 0; - ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &localfr.ack, 0); + ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &ackfr->ack, 0); } else { assert(NGTCP2_ERR_NOBUF == rv); + ngtcp2_mem_free(conn->mem, ackfr); } } } @@ -962,7 +1043,7 @@ static ssize_t conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest, ngtcp2_ppe ppe; ngtcp2_pkt_hd hd; ngtcp2_frame_chain *frc = NULL, **pfrc, *frc_head = NULL, *frc_next; - ngtcp2_frame *fr, localfr; + ngtcp2_frame *fr, *ackfr, paddingfr; size_t nwrite; ssize_t spktlen; ngtcp2_crypto_ctx ctx; @@ -993,22 +1074,27 @@ static ssize_t conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest, /* Encode ACK here */ if (type != NGTCP2_PKT_CLIENT_INITIAL && ack_expired) { - localfr.type = (uint8_t)~NGTCP2_FRAME_ACK; + ackfr = NULL; /* TODO Should we retransmit ACK frame? */ - conn_create_ack_frame(conn, &localfr.ack, ts); - if (localfr.type == NGTCP2_FRAME_ACK) { - rv = ngtcp2_ppe_encode_frame(&ppe, &localfr); + rv = conn_create_ack_frame(conn, &ackfr, ts); + if (rv != 0) { + return rv; + } + if (ackfr) { + rv = ngtcp2_ppe_encode_frame(&ppe, ackfr); if (rv != 0) { + ngtcp2_mem_free(conn->mem, ackfr); return rv; } conn_commit_tx_ack(conn); - rv = conn_call_send_frame(conn, &hd, &localfr); + rv = conn_call_send_frame(conn, &hd, ackfr); if (rv != 0) { + ngtcp2_mem_free(conn->mem, ackfr); return rv; } - ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &localfr.ack, 1); + ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &ackfr->ack, 1); } if (ngtcp2_ppe_left(&ppe) < NGTCP2_STREAM_OVERHEAD + 1) { @@ -1060,10 +1146,10 @@ static ssize_t conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest, } if (type == NGTCP2_PKT_CLIENT_INITIAL) { - localfr.type = NGTCP2_FRAME_PADDING; - localfr.padding.len = ngtcp2_ppe_padding(&ppe); - if (localfr.padding.len > 0) { - rv = conn_call_send_frame(conn, &hd, &localfr); + paddingfr.type = NGTCP2_FRAME_PADDING; + paddingfr.padding.len = ngtcp2_ppe_padding(&ppe); + if (paddingfr.padding.len > 0) { + rv = conn_call_send_frame(conn, &hd, &paddingfr); if (rv != 0) { goto fail; } @@ -1120,6 +1206,8 @@ fail: * User-defined callback function failed. * NGTCP2_ERR_NOBUF * Buffer is too small. + * NGTCP2_ERR_NOMEM + * Out of memory. */ static ssize_t conn_write_handshake_ack_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, uint8_t type, @@ -1127,7 +1215,7 @@ static ssize_t conn_write_handshake_ack_pkt(ngtcp2_conn *conn, uint8_t *dest, int rv; ngtcp2_ppe ppe; ngtcp2_pkt_hd hd; - ngtcp2_frame fr; + ngtcp2_frame *ackfr; ngtcp2_crypto_ctx ctx; int ack_expired = conn_next_ack_expired(conn, ts); @@ -1135,9 +1223,12 @@ static ssize_t conn_write_handshake_ack_pkt(ngtcp2_conn *conn, uint8_t *dest, return 0; } - fr.type = (uint8_t)~NGTCP2_FRAME_ACK; - conn_create_ack_frame(conn, &fr.ack, ts); - if (fr.type != NGTCP2_FRAME_ACK) { + ackfr = NULL; + rv = conn_create_ack_frame(conn, &ackfr, ts); + if (rv != 0) { + return rv; + } + if (!ackfr) { return 0; } @@ -1153,30 +1244,34 @@ static ssize_t conn_write_handshake_ack_pkt(ngtcp2_conn *conn, uint8_t *dest, rv = ngtcp2_ppe_encode_hd(&ppe, &hd); if (rv != 0) { - return rv; + goto fail; } rv = conn_call_send_pkt(conn, &hd); if (rv != 0) { - return rv; + goto fail; } - rv = ngtcp2_ppe_encode_frame(&ppe, &fr); + rv = ngtcp2_ppe_encode_frame(&ppe, ackfr); if (rv != 0) { - return rv; + goto fail; } conn_commit_tx_ack(conn); - rv = conn_call_send_frame(conn, &hd, &fr); + rv = conn_call_send_frame(conn, &hd, ackfr); if (rv != 0) { - return rv; + goto fail; } - ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &fr.ack, 1); + ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &ackfr->ack, 1); ++conn->last_tx_pkt_num; return ngtcp2_ppe_final(&ppe, NULL); + +fail: + ngtcp2_mem_free(conn->mem, ackfr); + return rv; } /* @@ -1390,7 +1485,7 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, int rv; ngtcp2_ppe ppe; ngtcp2_pkt_hd hd; - ngtcp2_frame ackfr; + ngtcp2_frame *ackfr; ssize_t nwrite; ngtcp2_crypto_ctx ctx; ngtcp2_frame_chain **pfrc, *nfrc, *frc; @@ -1400,17 +1495,19 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, int pkt_empty = 1; int ack_expired = conn_next_ack_expired(conn, ts); - ackfr.type = (uint8_t)~NGTCP2_FRAME_ACK; + ackfr = NULL; if (ack_expired) { - conn_create_ack_frame(conn, &ackfr.ack, ts); + rv = conn_create_ack_frame(conn, &ackfr, ts); + if (rv != 0) { + return rv; + } } - if ((ackfr.type == NGTCP2_FRAME_ACK || conn->frq || - conn_should_send_max_data(conn)) && + if ((ackfr || conn->frq || conn_should_send_max_data(conn)) && conn->unsent_max_rx_offset_high > conn->max_rx_offset_high) { rv = ngtcp2_frame_chain_new(&nfrc, conn->mem); if (rv != 0) { - return rv; + goto fail; } nfrc->fr.type = NGTCP2_FRAME_MAX_DATA; nfrc->fr.max_data.max_data = conn->unsent_max_rx_offset_high; @@ -1424,7 +1521,7 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, strm = conn->fc_strms; rv = ngtcp2_frame_chain_new(&nfrc, conn->mem); if (rv != 0) { - return rv; + goto fail; } nfrc->fr.type = NGTCP2_FRAME_MAX_STREAM_DATA; nfrc->fr.max_stream_data.stream_id = strm->stream_id; @@ -1444,7 +1541,7 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, strm = strm_next; } - if (ackfr.type != NGTCP2_FRAME_ACK && + if (!ackfr && conn->max_remote_stream_id <= conn->local_settings.max_stream_id && conn->frq == NULL) { return 0; @@ -1463,18 +1560,20 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, rv = ngtcp2_ppe_encode_hd(&ppe, &hd); if (rv != 0) { - return rv; + goto fail; } - if (ackfr.type == NGTCP2_FRAME_ACK) { - rv = conn_ppe_write_frame(conn, &ppe, &send_pkt_cb_called, &hd, &ackfr); + if (ackfr) { + rv = conn_ppe_write_frame(conn, &ppe, &send_pkt_cb_called, &hd, ackfr); if (rv != 0) { - return rv; + goto fail; } conn_commit_tx_ack(conn); pkt_empty = 0; - ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &ackfr.ack, 0); + ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &ackfr->ack, 0); + /* Now ackfr is owned by conn->acktr. */ + ackfr = NULL; } for (pfrc = &conn->frq; *pfrc;) { @@ -1567,6 +1666,10 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, ++conn->last_tx_pkt_num; return nwrite; + +fail: + ngtcp2_mem_free(conn->mem, ackfr); + return rv; } /* @@ -1621,15 +1724,16 @@ static ssize_t conn_write_single_frame_pkt(ngtcp2_conn *conn, uint8_t *dest, return rv; } - if (fr->type == NGTCP2_FRAME_ACK) { - ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &fr->ack, 0); - } - nwrite = ngtcp2_ppe_final(&ppe, NULL); if (nwrite < 0) { return nwrite; } + /* Do this when we are sure that there is no error. */ + if (fr->type == NGTCP2_FRAME_ACK) { + ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &fr->ack, 0); + } + ++conn->last_tx_pkt_num; return nwrite; @@ -1647,26 +1751,33 @@ static ssize_t conn_write_single_frame_pkt(ngtcp2_conn *conn, uint8_t *dest, * User-defined callback function failed. * NGTCP2_ERR_NOBUF * Buffer is too small. + * NGTCP2_ERR_NOMEM + * Out of memory. */ static ssize_t conn_write_protected_ack_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, ngtcp2_tstamp ts) { + int rv; ssize_t spktlen; - ngtcp2_frame ackfr; + ngtcp2_frame *ackfr; int ack_expired = conn_next_ack_expired(conn, ts); if (!ack_expired) { return 0; } - ackfr.type = (uint8_t)~NGTCP2_FRAME_ACK; - conn_create_ack_frame(conn, &ackfr.ack, ts); + ackfr = NULL; + rv = conn_create_ack_frame(conn, &ackfr, ts); + if (rv != 0) { + return rv; + } - if (ackfr.type != NGTCP2_FRAME_ACK) { + if (!ackfr) { return 0; } - spktlen = conn_write_single_frame_pkt(conn, dest, destlen, &ackfr); + spktlen = conn_write_single_frame_pkt(conn, dest, destlen, ackfr); if (spktlen < 0) { + ngtcp2_mem_free(conn->mem, ackfr); return spktlen; } @@ -2146,7 +2257,8 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, size_t pktlen, ngtcp2_tstamp ts) { ssize_t nread; ngtcp2_pkt_hd hd; - ngtcp2_frame fr; + ngtcp2_max_frame mfr; + ngtcp2_frame *fr = &mfr.fr; int rv; int require_ack = 0; uint64_t rx_offset; @@ -2243,7 +2355,7 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, pktlen = (size_t)nwrite; for (; pktlen;) { - nread = ngtcp2_pkt_decode_frame(&fr, pkt, pktlen); + nread = ngtcp2_pkt_decode_frame(fr, pkt, pktlen); if (nread < 0) { return (int)nread; } @@ -2251,12 +2363,12 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, pkt += nread; pktlen -= (size_t)nread; - rv = conn_call_recv_frame(conn, &hd, &fr); + rv = conn_call_recv_frame(conn, &hd, fr); if (rv != 0) { return rv; } - switch (fr.type) { + switch (fr->type) { case NGTCP2_FRAME_ACK: switch (hd.type) { case NGTCP2_PKT_CLIENT_INITIAL: @@ -2264,7 +2376,7 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, return NGTCP2_ERR_PROTO; } /* TODO Assume that all packets here are unprotected */ - rv = conn_recv_ack(conn, &fr.ack, 1); + rv = conn_recv_ack(conn, &fr->ack, 1); if (rv != 0) { return rv; } @@ -2281,25 +2393,25 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, return NGTCP2_ERR_PROTO; } - assert(fr.type == NGTCP2_FRAME_STREAM); + assert(fr->type == NGTCP2_FRAME_STREAM); - if (fr.stream.stream_id != 0) { + if (fr->stream.stream_id != 0) { continue; } - if (fr.stream.datalen == 0) { + if (fr->stream.datalen == 0) { return NGTCP2_ERR_FRAME_FORMAT; } - if (hd.type == NGTCP2_PKT_CLIENT_INITIAL && fr.stream.offset != 0) { + if (hd.type == NGTCP2_PKT_CLIENT_INITIAL && fr->stream.offset != 0) { return NGTCP2_ERR_PROTO; } - if (fr.stream.fin) { + if (fr->stream.fin) { return NGTCP2_ERR_PROTO; } - fr_end_offset = fr.stream.offset + fr.stream.datalen; + fr_end_offset = fr->stream.offset + fr->stream.datalen; rx_offset = ngtcp2_strm_rx_offset(conn->strm0); if (rx_offset >= fr_end_offset) { continue; @@ -2317,10 +2429,10 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, return NGTCP2_ERR_FLOW_CONTROL; } - if (fr.stream.offset <= rx_offset) { - size_t ncut = (rx_offset - fr.stream.offset); - const uint8_t *data = fr.stream.data + ncut; - size_t datalen = fr.stream.datalen - ncut; + if (fr->stream.offset <= rx_offset) { + size_t ncut = (rx_offset - fr->stream.offset); + const uint8_t *data = fr->stream.data + ncut; + size_t datalen = fr->stream.datalen - ncut; rx_offset += datalen; ngtcp2_rob_remove_prefix(&conn->strm0->rob, rx_offset); @@ -2346,7 +2458,7 @@ static int conn_recv_handshake_pkt(ngtcp2_conn *conn, const uint8_t *pkt, } } } else if (!handshake_failed) { - rv = ngtcp2_strm_recv_reordering(conn->strm0, &fr.stream); + rv = ngtcp2_strm_recv_reordering(conn->strm0, &fr->stream); if (rv != 0) { return rv; } @@ -3004,7 +3116,8 @@ static int conn_recv_pkt(ngtcp2_conn *conn, const uint8_t *pkt, size_t pktlen, int rv = 0; const uint8_t *hdpkt = pkt; ssize_t nread, nwrite; - ngtcp2_frame fr; + ngtcp2_max_frame mfr; + ngtcp2_frame *fr = &mfr.fr; int require_ack = 0; if (pkt[0] & NGTCP2_HEADER_FORM_BIT) { @@ -3104,7 +3217,7 @@ static int conn_recv_pkt(ngtcp2_conn *conn, const uint8_t *pkt, size_t pktlen, conn->flags |= NGTCP2_CONN_FLAG_RECV_PROTECTED_PKT; for (; pktlen;) { - nread = ngtcp2_pkt_decode_frame(&fr, pkt, pktlen); + nread = ngtcp2_pkt_decode_frame(fr, pkt, pktlen); if (nread < 0) { return (int)nread; } @@ -3112,12 +3225,12 @@ static int conn_recv_pkt(ngtcp2_conn *conn, const uint8_t *pkt, size_t pktlen, pkt += nread; pktlen -= (size_t)nread; - rv = conn_call_recv_frame(conn, &hd, &fr); + rv = conn_call_recv_frame(conn, &hd, fr); if (rv != 0) { return rv; } - switch (fr.type) { + switch (fr->type) { case NGTCP2_FRAME_ACK: case NGTCP2_FRAME_PADDING: case NGTCP2_FRAME_CONNECTION_CLOSE: @@ -3126,45 +3239,45 @@ static int conn_recv_pkt(ngtcp2_conn *conn, const uint8_t *pkt, size_t pktlen, require_ack = 1; } - switch (fr.type) { + switch (fr->type) { case NGTCP2_FRAME_ACK: - rv = conn_recv_ack(conn, &fr.ack, 0); + rv = conn_recv_ack(conn, &fr->ack, 0); if (rv != 0) { return rv; } break; case NGTCP2_FRAME_STREAM: - rv = conn_recv_stream(conn, &fr.stream); + rv = conn_recv_stream(conn, &fr->stream); if (rv != 0) { return rv; } break; case NGTCP2_FRAME_RST_STREAM: - rv = conn_recv_rst_stream(conn, &fr.rst_stream); + rv = conn_recv_rst_stream(conn, &fr->rst_stream); if (rv != 0) { return rv; } break; case NGTCP2_FRAME_STOP_SENDING: - rv = conn_recv_stop_sending(conn, &fr.stop_sending); + rv = conn_recv_stop_sending(conn, &fr->stop_sending); if (rv != 0) { return rv; } break; case NGTCP2_FRAME_MAX_STREAM_DATA: - conn_recv_max_stream_data(conn, &fr.max_stream_data); + conn_recv_max_stream_data(conn, &fr->max_stream_data); break; case NGTCP2_FRAME_MAX_DATA: - conn_recv_max_data(conn, &fr.max_data); + conn_recv_max_data(conn, &fr->max_data); break; case NGTCP2_FRAME_MAX_STREAM_ID: - rv = conn_recv_max_stream_id(conn, &fr.max_stream_id); + rv = conn_recv_max_stream_id(conn, &fr->max_stream_id); if (rv != 0) { return rv; } break; case NGTCP2_FRAME_CONNECTION_CLOSE: - conn_recv_connection_close(conn, &fr.connection_close); + conn_recv_connection_close(conn, &fr->connection_close); break; } } diff --git a/lib/ngtcp2_conn.h b/lib/ngtcp2_conn.h index 7ec2b67729ecb0fb9efb23889adb79f42e20f410..0fd490e7292275664547f32b944123979bb0386c 100644 --- a/lib/ngtcp2_conn.h +++ b/lib/ngtcp2_conn.h @@ -88,6 +88,18 @@ struct ngtcp2_pkt_chain { ngtcp2_tstamp ts; }; +/* + * ngtcp2_max_frame is defined so that it covers the largest ACK + * frame. + */ +typedef union { + ngtcp2_frame fr; + struct { + ngtcp2_ack ack; + ngtcp2_ack_blk blks[254]; + } ackfr; +} ngtcp2_max_frame; + /* * ngtcp2_pkt_chain_new allocates ngtcp2_pkt_chain objects, and * assigns its pointer to |*ppc|. The content of buffer pointed by diff --git a/tests/ngtcp2_acktr_test.c b/tests/ngtcp2_acktr_test.c index e8bd87996fc51a0b8d4578aff925cee56e054465..85f2de63998e4caf4f648f314f3e25314e7eb0e7 100644 --- a/tests/ngtcp2_acktr_test.c +++ b/tests/ngtcp2_acktr_test.c @@ -178,11 +178,12 @@ void test_ngtcp2_acktr_recv_ack(void) { ngtcp2_acktr acktr; ngtcp2_mem *mem = ngtcp2_mem_default(); size_t i; - ngtcp2_ack fr; + ngtcp2_ack *fr, ackfr; uint64_t pkt_nums[] = { 4500, 4499, 4497, 4496, 4494, 4493, 4491, 4490, 4488, 4487, }; ngtcp2_acktr_entry *ent; + uint64_t pkt_num; ngtcp2_acktr_init(&acktr, mem); @@ -191,28 +192,30 @@ void test_ngtcp2_acktr_recv_ack(void) { ngtcp2_acktr_add(&acktr, ent, 1); } - fr.type = NGTCP2_FRAME_ACK; - fr.largest_ack = 4500; - fr.ack_delay = 0; - fr.first_ack_blklen = 1; - fr.num_blks = 3; - fr.blks[0].gap = 4; - fr.blks[0].blklen = 2; - fr.blks[1].gap = 1; - fr.blks[1].blklen = 1; - fr.blks[2].gap = 3; - fr.blks[2].blklen = 1; - - ngtcp2_acktr_add_ack(&acktr, 998, &fr, 0); - ngtcp2_acktr_add_ack(&acktr, 999, &fr, 0); - - fr.type = NGTCP2_FRAME_ACK; - fr.largest_ack = 999; - fr.ack_delay = 0; - fr.first_ack_blklen = 0; - fr.num_blks = 0; - - ngtcp2_acktr_recv_ack(&acktr, &fr, 0); + for (pkt_num = 998; pkt_num <= 999; ++pkt_num) { + fr = ngtcp2_mem_malloc(mem, sizeof(ngtcp2_max_frame)); + fr->type = NGTCP2_FRAME_ACK; + fr->largest_ack = 4500; + fr->ack_delay = 0; + fr->first_ack_blklen = 1; + fr->num_blks = 3; + fr->blks[0].gap = 4; + fr->blks[0].blklen = 2; + fr->blks[1].gap = 1; + fr->blks[1].blklen = 1; + fr->blks[2].gap = 3; + fr->blks[2].blklen = 1; + + ngtcp2_acktr_add_ack(&acktr, pkt_num, fr, 0); + } + + ackfr.type = NGTCP2_FRAME_ACK; + ackfr.largest_ack = 999; + ackfr.ack_delay = 0; + ackfr.first_ack_blklen = 0; + ackfr.num_blks = 0; + + ngtcp2_acktr_recv_ack(&acktr, &ackfr, 0); CU_ASSERT(0 == ngtcp2_ringbuf_len(&acktr.acks)); CU_ASSERT(4 == acktr.nack); diff --git a/tests/ngtcp2_pkt_test.c b/tests/ngtcp2_pkt_test.c index 6f12f4871bcb1580aa9cb3ad9451961b4cdf8699..b960196372b04fb6b72df63192586a10ea9e388a 100644 --- a/tests/ngtcp2_pkt_test.c +++ b/tests/ngtcp2_pkt_test.c @@ -461,200 +461,201 @@ void test_ngtcp2_pkt_encode_stream_frame(void) { void test_ngtcp2_pkt_encode_ack_frame(void) { uint8_t buf[256]; - ngtcp2_frame fr, nfr; + ngtcp2_max_frame mfr, nmfr; + ngtcp2_frame *fr = &mfr.fr, *nfr = &nmfr.fr; ssize_t rv; size_t framelen; size_t i; /* 0 Num Blocks */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2f3f4llu; - fr.ack.first_ack_blklen = 0; - fr.ack.ack_delay = 0; - fr.ack.num_blks = 0; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4llu; + fr->ack.first_ack_blklen = 0; + fr->ack.ack_delay = 0; + fr->ack.num_blks = 0; framelen = 1 + 4 + 2 + 1; - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); - CU_ASSERT((NGTCP2_ACK_LL_02_MASK | NGTCP2_ACK_MM_00_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay == nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT((NGTCP2_ACK_LL_02_MASK | NGTCP2_ACK_MM_00_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); /* 2 Num Blocks */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2f3f4llu; - fr.ack.first_ack_blklen = 0xe1e2e3e4llu; - fr.ack.ack_delay = 0xf1f2; - fr.ack.num_blks = 2; - fr.ack.blks[0].gap = 255; - fr.ack.blks[0].blklen = 0xd1d2d3d4llu; - fr.ack.blks[1].gap = 1; - fr.ack.blks[1].blklen = 0xd1d2d3d4llu; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4llu; + fr->ack.first_ack_blklen = 0xe1e2e3e4llu; + fr->ack.ack_delay = 0xf1f2; + fr->ack.num_blks = 2; + fr->ack.blks[0].gap = 255; + fr->ack.blks[0].blklen = 0xd1d2d3d4llu; + fr->ack.blks[1].gap = 1; + fr->ack.blks[1].blklen = 0xd1d2d3d4llu; framelen = 1 + 1 + 4 + 2 + 4 + (1 + 4) * 2; - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr->type == nfr->type); CU_ASSERT((NGTCP2_ACK_N_BIT | NGTCP2_ACK_LL_02_MASK | - NGTCP2_ACK_MM_02_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay = nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); - - for (i = 0; i < fr.ack.num_blks; ++i) { - CU_ASSERT(fr.ack.blks[i].gap == nfr.ack.blks[i].gap); - CU_ASSERT(fr.ack.blks[i].blklen == nfr.ack.blks[i].blklen); + NGTCP2_ACK_MM_02_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay = nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); + + for (i = 0; i < fr->ack.num_blks; ++i) { + CU_ASSERT(fr->ack.blks[i].gap == nfr->ack.blks[i].gap); + CU_ASSERT(fr->ack.blks[i].blklen == nfr->ack.blks[i].blklen); } - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); /* Encode 8 bytes largest ack */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2f3f4f5f6f7f8llu; - fr.ack.first_ack_blklen = 0; - fr.ack.ack_delay = 0; - fr.ack.num_blks = 0; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4f5f6f7f8llu; + fr->ack.first_ack_blklen = 0; + fr->ack.ack_delay = 0; + fr->ack.num_blks = 0; framelen = 1 + 8 + 2 + 1; - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); - CU_ASSERT((NGTCP2_ACK_LL_03_MASK | NGTCP2_ACK_MM_00_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay == nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT((NGTCP2_ACK_LL_03_MASK | NGTCP2_ACK_MM_00_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); /* 8 bytes first ack block length */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2; - fr.ack.first_ack_blklen = 0xf1f2f3f4f5f6f7f8llu; - fr.ack.ack_delay = 0; - fr.ack.num_blks = 0; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2; + fr->ack.first_ack_blklen = 0xf1f2f3f4f5f6f7f8llu; + fr->ack.ack_delay = 0; + fr->ack.num_blks = 0; framelen = 1 + 2 + 2 + 8; - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); - CU_ASSERT((NGTCP2_ACK_LL_01_MASK | NGTCP2_ACK_MM_03_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay == nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT((NGTCP2_ACK_LL_01_MASK | NGTCP2_ACK_MM_03_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); /* 2 bytes first ack block length */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2f3f4u; - fr.ack.first_ack_blklen = 0xf1f2; - fr.ack.ack_delay = 0; - fr.ack.num_blks = 0; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4u; + fr->ack.first_ack_blklen = 0xf1f2; + fr->ack.ack_delay = 0; + fr->ack.num_blks = 0; framelen = 1 + 4 + 2 + 2; - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); - CU_ASSERT((NGTCP2_ACK_LL_02_MASK | NGTCP2_ACK_MM_01_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay == nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); + CU_ASSERT(fr->type == nfr->type); + CU_ASSERT((NGTCP2_ACK_LL_02_MASK | NGTCP2_ACK_MM_01_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); /* 2 bytes ack block length in second ack block */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2f3f4u; - fr.ack.first_ack_blklen = 0xf1; - fr.ack.ack_delay = 0; - fr.ack.num_blks = 1; - fr.ack.blks[0].gap = 255; - fr.ack.blks[0].blklen = 0xd1d2; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4u; + fr->ack.first_ack_blklen = 0xf1; + fr->ack.ack_delay = 0; + fr->ack.num_blks = 1; + fr->ack.blks[0].gap = 255; + fr->ack.blks[0].blklen = 0xd1d2; framelen = 1 + 1 + 4 + 2 + 2 + (1 + 2); - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr->type == nfr->type); CU_ASSERT((NGTCP2_ACK_N_BIT | NGTCP2_ACK_LL_02_MASK | - NGTCP2_ACK_MM_01_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay == nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); + NGTCP2_ACK_MM_01_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); - CU_ASSERT(fr.ack.blks[0].gap == nfr.ack.blks[0].gap); - CU_ASSERT(fr.ack.blks[0].blklen == nfr.ack.blks[0].blklen); + CU_ASSERT(fr->ack.blks[0].gap == nfr->ack.blks[0].gap); + CU_ASSERT(fr->ack.blks[0].blklen == nfr->ack.blks[0].blklen); - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); /* 8 bytes ack block length in second ack block */ - fr.type = NGTCP2_FRAME_ACK; - fr.ack.largest_ack = 0xf1f2f3f4u; - fr.ack.first_ack_blklen = 0xf1; - fr.ack.ack_delay = 0; - fr.ack.num_blks = 1; - fr.ack.blks[0].gap = 255; - fr.ack.blks[0].blklen = 0xd1d2d3d4d5d6f7f8llu; + fr->type = NGTCP2_FRAME_ACK; + fr->ack.largest_ack = 0xf1f2f3f4u; + fr->ack.first_ack_blklen = 0xf1; + fr->ack.ack_delay = 0; + fr->ack.num_blks = 1; + fr->ack.blks[0].gap = 255; + fr->ack.blks[0].blklen = 0xd1d2d3d4d5d6f7f8llu; framelen = 1 + 1 + 4 + 2 + 8 + (1 + 8); - rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr.ack); + rv = ngtcp2_pkt_encode_ack_frame(buf, sizeof(buf), &fr->ack); 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); CU_ASSERT((ssize_t)framelen == rv); - CU_ASSERT(fr.type == nfr.type); + CU_ASSERT(fr->type == nfr->type); CU_ASSERT((NGTCP2_ACK_N_BIT | NGTCP2_ACK_LL_02_MASK | - NGTCP2_ACK_MM_03_MASK) == nfr.ack.flags); - CU_ASSERT(fr.ack.largest_ack == nfr.ack.largest_ack); - CU_ASSERT(fr.ack.ack_delay == nfr.ack.ack_delay); - CU_ASSERT(fr.ack.num_blks == nfr.ack.num_blks); + NGTCP2_ACK_MM_03_MASK) == nfr->ack.flags); + CU_ASSERT(fr->ack.largest_ack == nfr->ack.largest_ack); + CU_ASSERT(fr->ack.ack_delay == nfr->ack.ack_delay); + CU_ASSERT(fr->ack.num_blks == nfr->ack.num_blks); - CU_ASSERT(fr.ack.blks[0].gap == nfr.ack.blks[0].gap); - CU_ASSERT(fr.ack.blks[0].blklen == nfr.ack.blks[0].blklen); + CU_ASSERT(fr->ack.blks[0].gap == nfr->ack.blks[0].gap); + CU_ASSERT(fr->ack.blks[0].blklen == nfr->ack.blks[0].blklen); - memset(&nfr, 0, sizeof(nfr)); + memset(&nmfr, 0, sizeof(nmfr)); } void test_ngtcp2_pkt_encode_rst_stream_frame(void) { diff --git a/tests/ngtcp2_rtb_test.c b/tests/ngtcp2_rtb_test.c index ef38386de8792557155ae6c1a618e23fce23a617..c782e6742631915e8e2dc41fa62d67e270ba46e9 100644 --- a/tests/ngtcp2_rtb_test.c +++ b/tests/ngtcp2_rtb_test.c @@ -135,7 +135,8 @@ static void assert_rtb_entry_not_found(ngtcp2_rtb *rtb, uint64_t pkt_num) { void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb rtb; ngtcp2_mem *mem = ngtcp2_mem_default(); - ngtcp2_ack fr; + ngtcp2_max_frame mfr; + ngtcp2_ack *fr = &mfr.ackfr.ack; /* no ack block */ ngtcp2_rtb_init(&rtb, mem); @@ -143,11 +144,11 @@ void test_ngtcp2_rtb_recv_ack(void) { CU_ASSERT(67 == ngtcp2_pq_size(&rtb.pq)); - fr.largest_ack = 446; - fr.first_ack_blklen = 1; - fr.num_blks = 0; + fr->largest_ack = 446; + fr->first_ack_blklen = 1; + fr->num_blks = 0; - ngtcp2_rtb_recv_ack(&rtb, &fr, 0, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 0, NULL); CU_ASSERT(65 == ngtcp2_pq_size(&rtb.pq)); assert_rtb_entry_not_found(&rtb, 446); @@ -160,16 +161,16 @@ void test_ngtcp2_rtb_recv_ack(void) { setup_rtb_fixture(&rtb, mem); /* 441, 440 */ - fr.largest_ack = 441; - fr.first_ack_blklen = 3; - fr.num_blks = 2; - fr.blks[0].gap = 255; - fr.blks[0].blklen = 0; + fr->largest_ack = 441; + fr->first_ack_blklen = 3; + fr->num_blks = 2; + fr->blks[0].gap = 255; + fr->blks[0].blklen = 0; /* 180 */ - fr.blks[1].gap = 1; - fr.blks[1].blklen = 1; + fr->blks[1].gap = 1; + fr->blks[1].blklen = 1; - ngtcp2_rtb_recv_ack(&rtb, &fr, 0, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 0, NULL); CU_ASSERT(64 == ngtcp2_pq_size(&rtb.pq)); CU_ASSERT(441 == rtb.largest_acked); @@ -183,13 +184,13 @@ void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb_init(&rtb, mem); setup_rtb_fixture(&rtb, mem); - fr.largest_ack = 250; - fr.first_ack_blklen = 0; - fr.num_blks = 1; - fr.blks[0].gap = 250; - fr.blks[0].blklen = 0; + fr->largest_ack = 250; + fr->first_ack_blklen = 0; + fr->num_blks = 1; + fr->blks[0].gap = 250; + fr->blks[0].blklen = 0; - ngtcp2_rtb_recv_ack(&rtb, &fr, 0, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 0, NULL); CU_ASSERT(67 == ngtcp2_pq_size(&rtb.pq)); @@ -199,13 +200,13 @@ void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb_init(&rtb, mem); add_rtb_entry_range(&rtb, 0, 1, mem); - fr.largest_ack = 250; - fr.first_ack_blklen = 0; - fr.num_blks = 1; - fr.blks[0].gap = 249; - fr.blks[0].blklen = 1; + fr->largest_ack = 250; + fr->first_ack_blklen = 0; + fr->num_blks = 1; + fr->blks[0].gap = 249; + fr->blks[0].blklen = 1; - ngtcp2_rtb_recv_ack(&rtb, &fr, 0, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 0, NULL); assert_rtb_entry_not_found(&rtb, 0); @@ -215,13 +216,13 @@ void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb_init(&rtb, mem); add_rtb_entry_range(&rtb, 0, 1, mem); - fr.largest_ack = 0; - fr.first_ack_blklen = 0; - fr.num_blks = 1; - fr.blks[0].gap = 0; - fr.blks[0].blklen = 0; + fr->largest_ack = 0; + fr->first_ack_blklen = 0; + fr->num_blks = 1; + fr->blks[0].gap = 0; + fr->blks[0].blklen = 0; - ngtcp2_rtb_recv_ack(&rtb, &fr, 0, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 0, NULL); assert_rtb_entry_not_found(&rtb, 0); @@ -231,13 +232,13 @@ void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb_init(&rtb, mem); add_rtb_entry_range(&rtb, 0, 1, mem); - fr.largest_ack = 2; - fr.first_ack_blklen = 0; - fr.num_blks = 1; - fr.blks[0].gap = 1; - fr.blks[0].blklen = 1; + fr->largest_ack = 2; + fr->first_ack_blklen = 0; + fr->num_blks = 1; + fr->blks[0].gap = 1; + fr->blks[0].blklen = 1; - ngtcp2_rtb_recv_ack(&rtb, &fr, 0, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 0, NULL); assert_rtb_entry_not_found(&rtb, 0); @@ -247,11 +248,11 @@ void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb_init(&rtb, mem); add_rtb_entry_range(&rtb, 0, 1, mem); - fr.largest_ack = 0; - fr.first_ack_blklen = 0; - fr.num_blks = 0; + fr->largest_ack = 0; + fr->first_ack_blklen = 0; + fr->num_blks = 0; - ngtcp2_rtb_recv_ack(&rtb, &fr, 1, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 1, NULL); CU_ASSERT(1 == ngtcp2_pq_size(&rtb.pq)); @@ -261,13 +262,13 @@ void test_ngtcp2_rtb_recv_ack(void) { ngtcp2_rtb_init(&rtb, mem); add_rtb_entry_range(&rtb, 0, 1, mem); - fr.largest_ack = 3; - fr.first_ack_blklen = 0; - fr.num_blks = 1; - fr.blks[0].gap = 2; - fr.blks[0].blklen = 1; + fr->largest_ack = 3; + fr->first_ack_blklen = 0; + fr->num_blks = 1; + fr->blks[0].gap = 2; + fr->blks[0].blklen = 1; - ngtcp2_rtb_recv_ack(&rtb, &fr, 1, NULL); + ngtcp2_rtb_recv_ack(&rtb, fr, 1, NULL); CU_ASSERT(1 == ngtcp2_pq_size(&rtb.pq));