diff --git a/lib/ngtcp2_acktr.c b/lib/ngtcp2_acktr.c index 568f86750bec2b9991a4e398c0ae636c6ec1c789..e4c658a2c228d95e47c3dc14733108e41e3430b6 100644 --- a/lib/ngtcp2_acktr.c +++ b/lib/ngtcp2_acktr.c @@ -36,8 +36,6 @@ int ngtcp2_acktr_entry_new(ngtcp2_acktr_entry **ent, uint64_t pkt_num, return NGTCP2_ERR_NOMEM; } - (*ent)->next = NULL; - (*ent)->pprev = NULL; (*ent)->pkt_num = pkt_num; (*ent)->tstamp = tstamp; @@ -48,6 +46,8 @@ void ngtcp2_acktr_entry_del(ngtcp2_acktr_entry *ent, ngtcp2_mem *mem) { ngtcp2_mem_free(mem, ent); } +static int greater(int64_t lhs, int64_t rhs) { return lhs > rhs; } + int ngtcp2_acktr_init(ngtcp2_acktr *acktr, int delayed_ack, ngtcp2_log *log, ngtcp2_mem *mem) { int rv; @@ -58,11 +58,14 @@ int ngtcp2_acktr_init(ngtcp2_acktr *acktr, int delayed_ack, ngtcp2_log *log, return rv; } - acktr->ent = NULL; - acktr->tail = NULL; + rv = ngtcp2_ksl_init(&acktr->ent, greater, -1, mem); + if (rv != 0) { + ngtcp2_ringbuf_free(&acktr->acks); + return rv; + } + acktr->log = log; acktr->mem = mem; - acktr->nack = 0; acktr->flags = delayed_ack ? NGTCP2_ACKTR_FLAG_DELAYED_ACK : NGTCP2_ACKTR_FLAG_NONE; acktr->first_unacked_ts = UINT64_MAX; @@ -71,51 +74,44 @@ int ngtcp2_acktr_init(ngtcp2_acktr *acktr, int delayed_ack, ngtcp2_log *log, } void ngtcp2_acktr_free(ngtcp2_acktr *acktr) { - ngtcp2_acktr_entry *ent, *next; ngtcp2_acktr_ack_entry *ack_ent; size_t i; + ngtcp2_ksl_it it; if (acktr == NULL) { return; } + for (it = ngtcp2_ksl_begin(&acktr->ent); !ngtcp2_ksl_it_end(&it); + ngtcp2_ksl_it_next(&it)) { + ngtcp2_acktr_entry_del(ngtcp2_ksl_it_get(&it), acktr->mem); + } + ngtcp2_ksl_free(&acktr->ent); + 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;) { - next = ent->next; - ngtcp2_acktr_entry_del(ent, acktr->mem); - ent = next; - } } int ngtcp2_acktr_add(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent, int active_ack, ngtcp2_tstamp ts) { - ngtcp2_acktr_entry **pent; - ngtcp2_acktr_entry *tail; + ngtcp2_ksl_it it; + ngtcp2_acktr_entry *delent; + int rv; - for (pent = &acktr->ent; *pent; pent = &(*pent)->next) { - if ((*pent)->pkt_num > ent->pkt_num) { - continue; - } + it = ngtcp2_ksl_lower_bound(&acktr->ent, (int64_t)ent->pkt_num); + if (!ngtcp2_ksl_it_end(&it) && + ngtcp2_ksl_it_key(&it) == (int64_t)ent->pkt_num) { /* TODO What to do if we receive duplicated packet number? */ - if ((*pent)->pkt_num == ent->pkt_num) { - return NGTCP2_ERR_INVALID_ARGUMENT; - } - break; + return NGTCP2_ERR_INVALID_ARGUMENT; } - ent->next = *pent; - ent->pprev = pent; - if (ent->next) { - ent->next->pprev = &ent->next; - } else { - acktr->tail = ent; + rv = ngtcp2_ksl_insert(&acktr->ent, NULL, (int64_t)ent->pkt_num, ent); + if (rv != 0) { + return rv; } - *pent = ent; if (active_ack) { acktr->flags |= NGTCP2_ACKTR_FLAG_ACTIVE_ACK; @@ -124,57 +120,38 @@ int ngtcp2_acktr_add(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent, } } - if (++acktr->nack > NGTCP2_ACKTR_MAX_ENT) { - assert(acktr->tail); - - tail = acktr->tail; - *tail->pprev = NULL; - - acktr->tail = ngtcp2_struct_of(tail->pprev, ngtcp2_acktr_entry, next); - - ngtcp2_acktr_entry_del(tail, acktr->mem); - --acktr->nack; + if (ngtcp2_ksl_len(&acktr->ent) > NGTCP2_ACKTR_MAX_ENT) { + it = ngtcp2_ksl_end(&acktr->ent); + ngtcp2_ksl_it_prev(&it); + delent = ngtcp2_ksl_it_get(&it); + ngtcp2_ksl_remove(&acktr->ent, NULL, (int64_t)delent->pkt_num); + ngtcp2_acktr_entry_del(delent, acktr->mem); } return 0; } -void ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent) { - ngtcp2_acktr_entry *next; +int ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent) { + ngtcp2_ksl_it it; + int rv; - if (ent->pprev != &acktr->ent) { - *ent->pprev = NULL; - acktr->tail = ngtcp2_struct_of(ent->pprev, ngtcp2_acktr_entry, next); - } else { - acktr->ent = acktr->tail = NULL; - } + it = ngtcp2_ksl_lower_bound(&acktr->ent, (int64_t)ent->pkt_num); + assert(ngtcp2_ksl_it_key(&it) == (int64_t)ent->pkt_num); - for (; ent;) { - next = ent->next; + for (; !ngtcp2_ksl_it_end(&it);) { + ent = ngtcp2_ksl_it_get(&it); + rv = ngtcp2_ksl_remove(&acktr->ent, &it, (int64_t)ent->pkt_num); + if (rv != 0) { + return rv; + } ngtcp2_acktr_entry_del(ent, acktr->mem); - ent = next; - --acktr->nack; } -} -ngtcp2_acktr_entry **ngtcp2_acktr_get(ngtcp2_acktr *acktr) { - return &acktr->ent; + return 0; } -void ngtcp2_acktr_pop(ngtcp2_acktr *acktr) { - ngtcp2_acktr_entry *ent = acktr->ent; - - assert(acktr->ent); - - --acktr->nack; - acktr->ent = acktr->ent->next; - if (acktr->ent) { - acktr->ent->pprev = &acktr->ent; - } else { - acktr->tail = NULL; - } - - ngtcp2_acktr_entry_del(ent, acktr->mem); +ngtcp2_ksl_it ngtcp2_acktr_get(ngtcp2_acktr *acktr) { + return ngtcp2_ksl_begin(&acktr->ent); } ngtcp2_acktr_ack_entry *ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, @@ -197,78 +174,91 @@ ngtcp2_acktr_ack_entry *ngtcp2_acktr_add_ack(ngtcp2_acktr *acktr, return ent; } -static void acktr_remove(ngtcp2_acktr *acktr, ngtcp2_acktr_entry **pent) { - ngtcp2_acktr_entry *ent; +/* + * acktr_remove removes |ent| from |acktr|. The iterator which points + * to the entry next to |ent| is assigned to |it|. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * NGTCP2_ERR_NOMEM + * Out of memory. + */ +static int acktr_remove(ngtcp2_acktr *acktr, ngtcp2_ksl_it *it, + ngtcp2_acktr_entry *ent) { + int rv; - ent = *pent; - *pent = (*pent)->next; - if (*pent) { - (*pent)->pprev = pent; - } else { - acktr->tail = ngtcp2_struct_of(pent, ngtcp2_acktr_entry, next); + rv = ngtcp2_ksl_remove(&acktr->ent, it, (int64_t)ent->pkt_num); + if (rv != 0) { + return rv; } ngtcp2_acktr_entry_del(ent, acktr->mem); - --acktr->nack; + return 0; } -static void acktr_on_ack(ngtcp2_acktr *acktr, ngtcp2_ringbuf *rb, - size_t ack_ent_offset) { - ngtcp2_acktr_ack_entry *ent; +static int acktr_on_ack(ngtcp2_acktr *acktr, ngtcp2_ringbuf *rb, + size_t ack_ent_offset) { + ngtcp2_acktr_ack_entry *ack_ent; + ngtcp2_acktr_entry *ent; ngtcp2_ack *fr; - ngtcp2_acktr_entry **pent; uint64_t largest_ack, min_ack; size_t i; + ngtcp2_ksl_it it; + int rv; - ent = ngtcp2_ringbuf_get(rb, ack_ent_offset); - fr = ent->ack; + ack_ent = ngtcp2_ringbuf_get(rb, ack_ent_offset); + fr = ack_ent->ack; largest_ack = fr->largest_ack; + min_ack = largest_ack - fr->first_ack_blklen; /* Assume that ngtcp2_pkt_validate_ack(fr) returns 0 */ - for (pent = &acktr->ent; *pent; pent = &(*pent)->next) { - if (largest_ack >= (*pent)->pkt_num) { - break; - } - } - if (*pent == NULL) { + it = ngtcp2_ksl_lower_bound(&acktr->ent, (int64_t)largest_ack); + if (ngtcp2_ksl_it_end(&it)) { goto fin; } - min_ack = largest_ack - fr->first_ack_blklen; - - for (; *pent;) { - if (min_ack <= (*pent)->pkt_num && (*pent)->pkt_num <= largest_ack) { - acktr_remove(acktr, pent); - continue; + for (; !ngtcp2_ksl_it_end(&it);) { + ent = ngtcp2_ksl_it_get(&it); + if (ent->pkt_num < min_ack) { + break; + } + rv = acktr_remove(acktr, &it, ent); + if (rv != 0) { + return rv; } - break; } - for (i = 0; i < fr->num_blks && *pent;) { + for (i = 0; i < fr->num_blks && !ngtcp2_ksl_it_end(&it); ++i) { largest_ack = min_ack - fr->blks[i].gap - 2; min_ack = largest_ack - fr->blks[i].blklen; - for (; *pent;) { - if ((*pent)->pkt_num > largest_ack) { - pent = &(*pent)->next; - continue; - } - if ((*pent)->pkt_num < min_ack) { + it = ngtcp2_ksl_lower_bound(&acktr->ent, (int64_t)largest_ack); + if (ngtcp2_ksl_it_end(&it)) { + break; + } + + for (; !ngtcp2_ksl_it_end(&it);) { + ent = ngtcp2_ksl_it_get(&it); + if (ent->pkt_num < min_ack) { break; } - acktr_remove(acktr, pent); + rv = acktr_remove(acktr, &it, ent); + if (rv != 0) { + return rv; + } } - - ++i; } fin: for (i = ack_ent_offset; i < rb->len; ++i) { - ent = ngtcp2_ringbuf_get(rb, i); - ngtcp2_mem_free(acktr->mem, ent->ack); + ack_ent = ngtcp2_ringbuf_get(rb, i); + ngtcp2_mem_free(acktr->mem, ack_ent->ack); } ngtcp2_ringbuf_resize(rb, ack_ent_offset); + + return 0; } int ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr, @@ -278,6 +268,7 @@ int ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr, size_t i, j; ngtcp2_ringbuf *rb = &acktr->acks; size_t nacks = ngtcp2_ringbuf_len(rb); + int rv; /* Assume that ngtcp2_pkt_validate_ack(fr) returns 0 */ for (j = 0; j < nacks; ++j) { @@ -294,7 +285,10 @@ int ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr, for (;;) { if (min_ack <= ent->pkt_num && ent->pkt_num <= largest_ack) { - acktr_on_ack(acktr, rb, j); + rv = acktr_on_ack(acktr, rb, j); + if (rv != 0) { + return rv; + } if (conn && largest_ack == ent->pkt_num && ent->ack_only) { ngtcp2_conn_update_rtt(conn, ts - ent->ts, fr->ack_delay_unscaled, ent->ack_only); @@ -304,7 +298,7 @@ int ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr, break; } - for (i = 0; i < fr->num_blks && j < nacks;) { + for (i = 0; i < fr->num_blks && j < nacks; ++i) { largest_ack = min_ack - fr->blks[i].gap - 2; min_ack = largest_ack - fr->blks[i].blklen; @@ -320,11 +314,8 @@ int ngtcp2_acktr_recv_ack(ngtcp2_acktr *acktr, const ngtcp2_ack *fr, if (ent->pkt_num < min_ack) { break; } - acktr_on_ack(acktr, rb, j); - return 0; + return acktr_on_ack(acktr, rb, j); } - - ++i; } return 0; diff --git a/lib/ngtcp2_acktr.h b/lib/ngtcp2_acktr.h index 1394a97edd0f9b643cd80093abe8acc6110f162e..b2d41abd5d625db9f21f886b2e505a63ab44a607 100644 --- a/lib/ngtcp2_acktr.h +++ b/lib/ngtcp2_acktr.h @@ -33,6 +33,7 @@ #include "ngtcp2_mem.h" #include "ngtcp2_ringbuf.h" +#include "ngtcp2_ksl.h" /* NGTCP2_ACKTR_MAX_ENT is the maximum number of ngtcp2_acktr_entry which ngtcp2_acktr stores. */ @@ -54,7 +55,6 @@ typedef struct ngtcp2_log ngtcp2_log; * ngtcp2_acktr_entry is a single packet which needs to be acked. */ struct ngtcp2_acktr_entry { - ngtcp2_acktr_entry **pprev, *next; uint64_t pkt_num; ngtcp2_tstamp tstamp; }; @@ -105,12 +105,11 @@ typedef enum { */ typedef struct { ngtcp2_ringbuf acks; - /* ent points to the head of list which is ordered by the decreasing - order of packet number. */ - ngtcp2_acktr_entry *ent, *tail; + /* ent includes ngtcp2_acktr_entry sorted by decreasing order of + packet number. */ + ngtcp2_ksl ent; ngtcp2_log *log; ngtcp2_mem *mem; - size_t nack; /* flags is bitwise OR of zero, or more of ngtcp2_ack_flag. */ uint16_t flags; /* first_unacked_ts is timestamp when ngtcp2_acktr_entry is added @@ -151,24 +150,24 @@ int ngtcp2_acktr_add(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent, int active_ack, ngtcp2_tstamp ts); /* - * ngtcp2_acktr_forget removes all entries from |ent| to the end of - * the list. This function assumes that |ent| is linked directly, or - * indirectly from acktr->ent. + * ngtcp2_acktr_forget removes all entries which have the packet + * number that is equal to or less than ent->pkt_num. This function + * assumes that |acktr| includes |ent|. + * + * This function returns 0 if it succeeds, or one of the following + * negative error codes: + * + * NGTCP2_ERR_NOMEM + * Out of memory. */ -void ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent); +int ngtcp2_acktr_forget(ngtcp2_acktr *acktr, ngtcp2_acktr_entry *ent); /* * ngtcp2_acktr_get returns the pointer to pointer to the entry which * has the largest packet number to be acked. If there is no entry, - * this function returns a pointer which includes NULL on dereference. - */ -ngtcp2_acktr_entry **ngtcp2_acktr_get(ngtcp2_acktr *acktr); - -/* - * ngtcp2_acktr_removes and frees the head of entries, which has the - * largest packet number. + * returned value satisfies ngtcp2_ksl_it_end(&it) != 0. */ -void ngtcp2_acktr_pop(ngtcp2_acktr *acktr); +ngtcp2_ksl_it ngtcp2_acktr_get(ngtcp2_acktr *acktr); /* * ngtcp2_acktr_add_ack adds the outgoing ACK frame |fr| to |acktr|. diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c index 773467eb64709294e873362aeab9c139ca78df07..1a08b6f5bcd0c6b66251724a0ec1fa60e6e0d145 100644 --- a/lib/ngtcp2_conn.c +++ b/lib/ngtcp2_conn.c @@ -487,7 +487,8 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr, ngtcp2_ack_blk *blk; int initial = 1; uint64_t gap; - ngtcp2_acktr_entry **prpkt; + ngtcp2_ksl_it it; + ngtcp2_acktr_entry *rpkt; ngtcp2_frame *fr; ngtcp2_ack *ack; /* TODO Measure an actual size of ACK bloks to find the best default @@ -503,8 +504,8 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr, return 0; } - prpkt = ngtcp2_acktr_get(acktr); - if (*prpkt == NULL) { + it = ngtcp2_acktr_get(acktr); + if (ngtcp2_ksl_it_end(&it)) { ngtcp2_acktr_commit_ack(acktr); return 0; } @@ -517,19 +518,21 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr, ack = &fr->ack; - first_pkt_num = last_pkt_num = (*prpkt)->pkt_num; + rpkt = ngtcp2_ksl_it_get(&it); + first_pkt_num = last_pkt_num = rpkt->pkt_num; ack->type = NGTCP2_FRAME_ACK; ack->largest_ack = first_pkt_num; - ack->ack_delay_unscaled = ts - (*prpkt)->tstamp; + ack->ack_delay_unscaled = ts - rpkt->tstamp; ack->ack_delay = (ack->ack_delay_unscaled / 1000) >> ack_delay_exponent; ack->num_blks = 0; - prpkt = &(*prpkt)->next; + ngtcp2_ksl_it_next(&it); - for (; *prpkt; prpkt = &(*prpkt)->next) { - if ((*prpkt)->pkt_num + 1 == last_pkt_num) { - last_pkt_num = (*prpkt)->pkt_num; + for (; !ngtcp2_ksl_it_end(&it); ngtcp2_ksl_it_next(&it)) { + rpkt = ngtcp2_ksl_it_get(&it); + if (rpkt->pkt_num + 1 == last_pkt_num) { + last_pkt_num = rpkt->pkt_num; continue; } @@ -549,10 +552,10 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr, blk->blklen = first_pkt_num - last_pkt_num; } - gap = last_pkt_num - (*prpkt)->pkt_num - 2; - first_pkt_num = last_pkt_num = (*prpkt)->pkt_num; + gap = last_pkt_num - rpkt->pkt_num - 2; + first_pkt_num = last_pkt_num = rpkt->pkt_num; - if (ack->num_blks == NGTCP2_MAX_ACK_BLKS) { + if (ack->num_blks == NGTCP2_MAX_ACK_BLKS - 1) { break; } } @@ -572,10 +575,13 @@ static int conn_create_ack_frame(ngtcp2_conn *conn, ngtcp2_frame **pfr, blk->blklen = first_pkt_num - last_pkt_num; } - /* TODO Just remove entries which cannot be fit into a single ACK - frame for now. */ - if (*prpkt) { - ngtcp2_acktr_forget(acktr, *prpkt); + /* TODO Just remove entries which cannot fit into a single ACK frame + for now. */ + if (!ngtcp2_ksl_it_end(&it)) { + rv = ngtcp2_acktr_forget(acktr, ngtcp2_ksl_it_get(&it)); + if (rv != 0) { + return rv; + } } *pfr = fr; @@ -1583,10 +1589,12 @@ static ssize_t conn_write_server_handshake(ngtcp2_conn *conn, uint8_t *dest, ngtcp2_crypto_data *cdata; ssize_t nwrite; ssize_t res = 0; + ngtcp2_ksl_it it; for (;;) { if (ngtcp2_ringbuf_len(rb) == 0) { - if (conn->early_ckm && *ngtcp2_acktr_get(&conn->pktns.acktr)) { + it = ngtcp2_acktr_get(&conn->pktns.acktr); + if (conn->early_ckm && !ngtcp2_ksl_it_end(&it)) { assert(conn->pktns.tx_ckm); nwrite = conn_write_protected_ack_pkt(conn, dest, destlen, ts); diff --git a/tests/ngtcp2_acktr_test.c b/tests/ngtcp2_acktr_test.c index c1be61c6ff159ff335466aece8aa5e5d7c1a097d..c42d43fd339fb97f34764bee12372858072a6372 100644 --- a/tests/ngtcp2_acktr_test.c +++ b/tests/ngtcp2_acktr_test.c @@ -33,7 +33,8 @@ void test_ngtcp2_acktr_add(void) { ngtcp2_acktr acktr; ngtcp2_acktr_entry *ents[7]; uint64_t max_pkt_num[] = {1, 5, 7, 7, 7, 7, 7}; - ngtcp2_acktr_entry **pent; + ngtcp2_acktr_entry *ent; + ngtcp2_ksl_it it; size_t i; int rv; ngtcp2_mem *mem = ngtcp2_mem_default(); @@ -55,20 +56,26 @@ void test_ngtcp2_acktr_add(void) { CU_ASSERT(0 == rv); - pent = ngtcp2_acktr_get(&acktr); + it = ngtcp2_acktr_get(&acktr); + ent = ngtcp2_ksl_it_get(&it); - CU_ASSERT(max_pkt_num[i] == (*pent)->pkt_num); + CU_ASSERT(max_pkt_num[i] == ent->pkt_num); } for (i = 0; i < arraylen(ents); ++i) { - ngtcp2_acktr_pop(&acktr); + it = ngtcp2_acktr_get(&acktr); + ent = ngtcp2_ksl_it_get(&it); + ngtcp2_ksl_remove(&acktr.ent, NULL, (int64_t)ent->pkt_num); + ngtcp2_acktr_entry_del(ent, mem); - pent = ngtcp2_acktr_get(&acktr); + it = ngtcp2_acktr_get(&acktr); if (i != arraylen(ents) - 1) { - CU_ASSERT(arraylen(ents) - i - 1 == (*pent)->pkt_num); + ent = ngtcp2_ksl_it_get(&it); + + CU_ASSERT(arraylen(ents) - i - 1 == ent->pkt_num); } else { - CU_ASSERT(NULL == *pent); + CU_ASSERT(ngtcp2_ksl_it_end(&it)); } } @@ -93,9 +100,10 @@ void test_ngtcp2_acktr_eviction(void) { ngtcp2_acktr acktr; ngtcp2_mem *mem = ngtcp2_mem_default(); size_t i; - ngtcp2_acktr_entry *ent, *next; + ngtcp2_acktr_entry *ent; const size_t extra = 17; ngtcp2_log log; + ngtcp2_ksl_it it; ngtcp2_log_init(&log, NULL, NULL, 0, NULL); ngtcp2_acktr_init(&acktr, 0 /* delayed_ack */, &log, mem); @@ -105,19 +113,13 @@ void test_ngtcp2_acktr_eviction(void) { ngtcp2_acktr_add(&acktr, ent, 1, 999 + i); } - CU_ASSERT(NGTCP2_ACKTR_MAX_ENT == acktr.nack); - CU_ASSERT(NULL != acktr.ent); + CU_ASSERT(NGTCP2_ACKTR_MAX_ENT == ngtcp2_ksl_len(&acktr.ent)); - for (ent = acktr.ent; ent; ent = ent->next) { - CU_ASSERT(ent == *ent->pprev); - } - - for (i = 0, ent = acktr.ent; ent; ++i) { - next = ent->next; + for (i = 0, it = ngtcp2_acktr_get(&acktr); !ngtcp2_ksl_it_end(&it); + ++i, ngtcp2_ksl_it_next(&it)) { + ent = ngtcp2_ksl_it_get(&it); CU_ASSERT(NGTCP2_ACKTR_MAX_ENT + extra - i - 1 == ent->pkt_num); - - ent = next; } ngtcp2_acktr_free(&acktr); @@ -130,19 +132,13 @@ void test_ngtcp2_acktr_eviction(void) { ngtcp2_acktr_add(&acktr, ent, 1, 999 + i); } - CU_ASSERT(NGTCP2_ACKTR_MAX_ENT == acktr.nack); - CU_ASSERT(NULL != acktr.ent); + CU_ASSERT(NGTCP2_ACKTR_MAX_ENT == ngtcp2_ksl_len(&acktr.ent)); - for (ent = acktr.ent; ent; ent = ent->next) { - CU_ASSERT(ent == *ent->pprev); - } - - for (i = 0, ent = acktr.ent; ent; ++i) { - next = ent->next; + for (i = 0, it = ngtcp2_acktr_get(&acktr); !ngtcp2_ksl_it_end(&it); + ++i, ngtcp2_ksl_it_next(&it)) { + ent = ngtcp2_ksl_it_get(&it); CU_ASSERT(NGTCP2_ACKTR_MAX_ENT + extra - i - 1 == ent->pkt_num); - - ent = next; } ngtcp2_acktr_free(&acktr); @@ -154,6 +150,7 @@ void test_ngtcp2_acktr_forget(void) { size_t i; ngtcp2_acktr_entry *ent; ngtcp2_log log; + ngtcp2_ksl_it it; ngtcp2_log_init(&log, NULL, NULL, 0, NULL); ngtcp2_acktr_init(&acktr, 0 /* delayed_ack */, &log, mem); @@ -163,19 +160,38 @@ void test_ngtcp2_acktr_forget(void) { ngtcp2_acktr_add(&acktr, ent, 1, 999 + i); } - CU_ASSERT(7 == acktr.nack); + CU_ASSERT(7 == ngtcp2_ksl_len(&acktr.ent)); + + it = ngtcp2_acktr_get(&acktr); + ngtcp2_ksl_it_next(&it); + ngtcp2_ksl_it_next(&it); + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); + ngtcp2_acktr_forget(&acktr, ent); + + CU_ASSERT(3 == ngtcp2_ksl_len(&acktr.ent)); + + it = ngtcp2_acktr_get(&acktr); + ent = ngtcp2_ksl_it_get(&it); - ngtcp2_acktr_forget(&acktr, acktr.ent->next->next->next); + CU_ASSERT(6 == ent->pkt_num); - CU_ASSERT(3 == acktr.nack); - CU_ASSERT(NULL == acktr.ent->next->next->next); - CU_ASSERT(acktr.ent->next->next == acktr.tail); + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); - ngtcp2_acktr_forget(&acktr, acktr.ent); + CU_ASSERT(5 == ent->pkt_num); - CU_ASSERT(0 == acktr.nack); - CU_ASSERT(NULL == acktr.ent); - CU_ASSERT(NULL == acktr.tail); + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); + + CU_ASSERT(4 == ent->pkt_num); + + it = ngtcp2_acktr_get(&acktr); + ent = ngtcp2_ksl_it_get(&it); + + ngtcp2_acktr_forget(&acktr, ent); + + CU_ASSERT(0 == ngtcp2_ksl_len(&acktr.ent)); ngtcp2_acktr_free(&acktr); } @@ -192,6 +208,7 @@ void test_ngtcp2_acktr_recv_ack(void) { uint64_t pkt_num; ngtcp2_ack_blk *blks; ngtcp2_log log; + ngtcp2_ksl_it it; ngtcp2_log_init(&log, NULL, NULL, 0, NULL); ngtcp2_acktr_init(&acktr, 0 /* delayed_ack */, &log, mem); @@ -228,20 +245,32 @@ void test_ngtcp2_acktr_recv_ack(void) { ngtcp2_acktr_recv_ack(&acktr, &ackfr, NULL, 1000000009); CU_ASSERT(0 == ngtcp2_ringbuf_len(&acktr.acks)); - CU_ASSERT(5 == acktr.nack); + CU_ASSERT(5 == ngtcp2_ksl_len(&acktr.ent)); - ent = acktr.ent; + it = ngtcp2_acktr_get(&acktr); + ent = ngtcp2_ksl_it_get(&it); CU_ASSERT(4497 == ent->pkt_num); - ent = ent->next; + + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); + CU_ASSERT(4496 == ent->pkt_num); - ent = ent->next; + + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); + CU_ASSERT(4494 == ent->pkt_num); - ent = ent->next; + + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); + CU_ASSERT(4490 == ent->pkt_num); - ent = ent->next; + + ngtcp2_ksl_it_next(&it); + ent = ngtcp2_ksl_it_get(&it); + CU_ASSERT(4483 == ent->pkt_num); - CU_ASSERT(ent == acktr.tail); ngtcp2_acktr_free(&acktr); } diff --git a/tests/ngtcp2_conn_test.c b/tests/ngtcp2_conn_test.c index 74fc7803334c30bf533a2317d39b34f1a3983d51..2843b600da0d22bc077de297d54414ab66a243c5 100644 --- a/tests/ngtcp2_conn_test.c +++ b/tests/ngtcp2_conn_test.c @@ -1801,7 +1801,7 @@ void test_ngtcp2_conn_recv_delayed_handshake_pkt(void) { rv = ngtcp2_conn_recv(conn, buf, pktlen, 1); CU_ASSERT(0 == rv); - CU_ASSERT(1 == conn->hs_pktns.acktr.nack); + CU_ASSERT(1 == ngtcp2_ksl_len(&conn->hs_pktns.acktr.ent)); CU_ASSERT(conn->hs_pktns.acktr.flags & NGTCP2_ACKTR_FLAG_ACTIVE_ACK); ngtcp2_conn_del(conn); @@ -1845,7 +1845,7 @@ void test_ngtcp2_conn_recv_delayed_handshake_pkt(void) { rv = ngtcp2_conn_recv(conn, buf, pktlen, 1); CU_ASSERT(0 == rv); - CU_ASSERT(1 == conn->hs_pktns.acktr.nack); + CU_ASSERT(1 == ngtcp2_ksl_len(&conn->hs_pktns.acktr.ent)); CU_ASSERT(!conn->hs_pktns.acktr.flags); ngtcp2_conn_del(conn); @@ -2875,6 +2875,7 @@ void test_ngtcp2_conn_recv_compound_pkt(void) { ngtcp2_tstamp t = 0; ngtcp2_acktr_entry *ackent; int rv; + ngtcp2_ksl_it it; /* 2 QUIC long packets in one UDP packet */ setup_handshake_server(&conn); @@ -2897,11 +2898,13 @@ void test_ngtcp2_conn_recv_compound_pkt(void) { CU_ASSERT(spktlen > 0); - ackent = conn->in_pktns.acktr.ent; + it = ngtcp2_acktr_get(&conn->in_pktns.acktr); + ackent = ngtcp2_ksl_it_get(&it); CU_ASSERT(ackent->pkt_num == pkt_num); - ackent = ackent->next; + ngtcp2_ksl_it_next(&it); + ackent = ngtcp2_ksl_it_get(&it); CU_ASSERT(ackent->pkt_num == pkt_num - 1); @@ -2931,11 +2934,13 @@ void test_ngtcp2_conn_recv_compound_pkt(void) { CU_ASSERT(0 == rv); - ackent = conn->pktns.acktr.ent; + it = ngtcp2_acktr_get(&conn->pktns.acktr); + ackent = ngtcp2_ksl_it_get(&it); CU_ASSERT(ackent->pkt_num == pkt_num); - ackent = conn->hs_pktns.acktr.ent; + it = ngtcp2_acktr_get(&conn->hs_pktns.acktr); + ackent = ngtcp2_ksl_it_get(&it); CU_ASSERT(ackent->pkt_num == pkt_num - 1); @@ -2973,7 +2978,7 @@ void test_ngtcp2_conn_pkt_payloadlen(void) { spktlen = ngtcp2_conn_handshake(conn, buf, sizeof(buf), buf, pktlen, ++t); CU_ASSERT(spktlen == 0); - CU_ASSERT(NULL == conn->in_pktns.acktr.ent); + CU_ASSERT(0 == ngtcp2_ksl_len(&conn->in_pktns.acktr.ent)); ngtcp2_conn_del(conn); }