From 736502b8cba37cffeda11e2074e1bcff278ff5d8 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Date: Sun, 1 Apr 2018 22:14:17 +0900 Subject: [PATCH] Encode PATH_RESPONSE in resposne to PATH_CHALLENGE --- lib/ngtcp2_conn.c | 60 +++++++++++++++++++++++++++++++------ lib/ngtcp2_ringbuf.c | 5 ++++ lib/ngtcp2_ringbuf.h | 5 ++++ tests/main.c | 2 ++ tests/ngtcp2_ringbuf_test.c | 27 +++++++++++++++++ tests/ngtcp2_ringbuf_test.h | 1 + 6 files changed, 91 insertions(+), 9 deletions(-) diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c index 73e9e6cf..a0447c1a 100644 --- a/lib/ngtcp2_conn.c +++ b/lib/ngtcp2_conn.c @@ -1144,12 +1144,15 @@ 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, *ackfr, paddingfr; + ngtcp2_frame *fr, *ackfr, lfr; size_t nwrite; ssize_t spktlen; ngtcp2_crypto_ctx ctx; ngtcp2_rtb_entry *rtbent; ngtcp2_acktr_ack_entry *ack_ent = NULL; + size_t pclen; + int pr_encoded = 0; + ngtcp2_path_challenge_entry *pc; pfrc = &frc_head; @@ -1189,11 +1192,50 @@ static ssize_t conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest, ack_ent = ngtcp2_acktr_add_ack(&conn->acktr, hd.pkt_num, &ackfr->ack, ts, 1, 0 /* ack_only */); + } + + pclen = ngtcp2_ringbuf_len(&conn->rx_path_challenge); + while (ngtcp2_ringbuf_len(&conn->rx_path_challenge)) { + pc = ngtcp2_ringbuf_get(&conn->rx_path_challenge, 0); + + lfr.type = NGTCP2_FRAME_PATH_RESPONSE; + ngtcp2_cpymem(lfr.path_challenge.data, pc->data, + sizeof(lfr.path_challenge)); - if (ngtcp2_ppe_left(&ppe) < NGTCP2_STREAM_OVERHEAD + 1) { - ++conn->last_tx_pkt_num; - return ngtcp2_ppe_final(&ppe, NULL); + rv = ngtcp2_ppe_encode_frame(&ppe, &lfr); + if (rv != 0) { + if (rv == NGTCP2_ERR_NOBUF) { + break; + } + return rv; } + + ngtcp2_log_tx_fr(&conn->log, &hd, &lfr); + + ngtcp2_ringbuf_pop_front(&conn->rx_path_challenge); + } + + pr_encoded = (pclen != ngtcp2_ringbuf_len(&conn->rx_path_challenge)); + + if (ngtcp2_ppe_left(&ppe) < NGTCP2_STREAM_OVERHEAD + 1) { + spktlen = ngtcp2_ppe_final(&ppe, NULL); + if (spktlen < 0) { + return (int)spktlen; + } + + if (pr_encoded) { + rv = ngtcp2_rtb_entry_new(&rtbent, &hd, NULL, ts, (size_t)spktlen, + NGTCP2_RTB_FLAG_UNPROTECTED, conn->mem); + if (rv != 0) { + return rv; + } + + conn_on_pkt_sent(conn, rtbent); + } + + ++conn->last_tx_pkt_num; + + return spktlen; } } @@ -1237,10 +1279,10 @@ static ssize_t conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest, } if (type == NGTCP2_PKT_INITIAL) { - paddingfr.type = NGTCP2_FRAME_PADDING; - paddingfr.padding.len = ngtcp2_ppe_padding(&ppe); - if (paddingfr.padding.len > 0) { - ngtcp2_log_tx_fr(&conn->log, &hd, &paddingfr); + lfr.type = NGTCP2_FRAME_PADDING; + lfr.padding.len = ngtcp2_ppe_padding(&ppe); + if (lfr.padding.len > 0) { + ngtcp2_log_tx_fr(&conn->log, &hd, &lfr); } } else if (conn->state == NGTCP2_CS_CLIENT_TLS_HANDSHAKE_FAILED || conn->state == NGTCP2_CS_SERVER_TLS_HANDSHAKE_FAILED) { @@ -1273,7 +1315,7 @@ static ssize_t conn_write_handshake_pkt(ngtcp2_conn *conn, uint8_t *dest, goto fail; } - if (frc_head) { + if (frc_head || pr_encoded) { rv = ngtcp2_rtb_entry_new(&rtbent, &hd, frc_head, ts, (size_t)spktlen, NGTCP2_RTB_FLAG_UNPROTECTED, conn->mem); if (rv != 0) { diff --git a/lib/ngtcp2_ringbuf.c b/lib/ngtcp2_ringbuf.c index d7ee2eb2..a5754dba 100644 --- a/lib/ngtcp2_ringbuf.c +++ b/lib/ngtcp2_ringbuf.c @@ -61,6 +61,11 @@ void *ngtcp2_ringbuf_push_front(ngtcp2_ringbuf *rb) { return (void *)&rb->buf[rb->first * rb->size]; } +void ngtcp2_ringbuf_pop_front(ngtcp2_ringbuf *rb) { + rb->first = (rb->first + 1) & (rb->nmemb - 1); + --rb->len; +} + void ngtcp2_ringbuf_resize(ngtcp2_ringbuf *rb, size_t len) { assert(len <= rb->nmemb); rb->len = len; diff --git a/lib/ngtcp2_ringbuf.h b/lib/ngtcp2_ringbuf.h index 56c53d9f..260c5a82 100644 --- a/lib/ngtcp2_ringbuf.h +++ b/lib/ngtcp2_ringbuf.h @@ -75,6 +75,11 @@ void ngtcp2_ringbuf_free(ngtcp2_ringbuf *rb); element is silently overwritten, and rb->len remains unchanged. */ void *ngtcp2_ringbuf_push_front(ngtcp2_ringbuf *rb); +/* + * ngtcp2_ringbuf_pop_front removes first element in |rb|. + */ +void ngtcp2_ringbuf_pop_front(ngtcp2_ringbuf *rb); + /* ngtcp2_ringbuf_resize changes the number of elements stored. This does not change the capacity of the underlying buffer. */ void ngtcp2_ringbuf_resize(ngtcp2_ringbuf *rb, size_t len); diff --git a/tests/main.c b/tests/main.c index 31603ead..b172a843 100644 --- a/tests/main.c +++ b/tests/main.c @@ -135,6 +135,8 @@ int main() { !CU_add_test(pSuite, "idtr_open", test_ngtcp2_idtr_open) || !CU_add_test(pSuite, "ringbuf_push_front", test_ngtcp2_ringbuf_push_front) || + !CU_add_test(pSuite, "ringbuf_pop_front", + test_ngtcp2_ringbuf_pop_front) || !CU_add_test(pSuite, "conn_stream_open_close", test_ngtcp2_conn_stream_open_close) || !CU_add_test(pSuite, "conn_stream_rx_flow_control", diff --git a/tests/ngtcp2_ringbuf_test.c b/tests/ngtcp2_ringbuf_test.c index d7f41535..6bebb786 100644 --- a/tests/ngtcp2_ringbuf_test.c +++ b/tests/ngtcp2_ringbuf_test.c @@ -62,3 +62,30 @@ void test_ngtcp2_ringbuf_push_front(void) { ngtcp2_ringbuf_free(&rb); } + +void test_ngtcp2_ringbuf_pop_front(void) { + ngtcp2_ringbuf rb; + ngtcp2_mem *mem = ngtcp2_mem_default(); + size_t i; + + ngtcp2_ringbuf_init(&rb, 4, sizeof(ints), mem); + + for (i = 0; i < 5; ++i) { + ints *p = ngtcp2_ringbuf_push_front(&rb); + p->a = (int32_t)i; + } + + CU_ASSERT(4 == ngtcp2_ringbuf_len(&rb)); + + for (i = 4; i >= 1; --i) { + ints *p = ngtcp2_ringbuf_get(&rb, 0); + + CU_ASSERT((int32_t)i == p->a); + + ngtcp2_ringbuf_pop_front(&rb); + } + + CU_ASSERT(0 == ngtcp2_ringbuf_len(&rb)); + + ngtcp2_ringbuf_free(&rb); +} diff --git a/tests/ngtcp2_ringbuf_test.h b/tests/ngtcp2_ringbuf_test.h index 6c8a1aef..8cae526e 100644 --- a/tests/ngtcp2_ringbuf_test.h +++ b/tests/ngtcp2_ringbuf_test.h @@ -30,5 +30,6 @@ #endif /* HAVE_CONFIG_H */ void test_ngtcp2_ringbuf_push_front(void); +void test_ngtcp2_ringbuf_pop_front(void); #endif /* NGTCP2_RINGBUF_TEST_H */ -- GitLab