From cdd26098c525b23714c111ae3db11da84079b786 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Date: Sun, 24 Mar 2019 22:15:52 +0900 Subject: [PATCH] Fix broken stream ID counting issue --- examples/client.cc | 4 +- examples/server.cc | 4 +- lib/includes/ngtcp2/ngtcp2.h | 28 ++---- lib/ngtcp2_conn.c | 190 +++++++++++++++-------------------- lib/ngtcp2_conn.h | 35 ++++--- lib/ngtcp2_conv.c | 4 + lib/ngtcp2_conv.h | 5 + tests/ngtcp2_conn_test.c | 28 ++---- 8 files changed, 131 insertions(+), 167 deletions(-) diff --git a/examples/client.cc b/examples/client.cc index 6f6f5fad..d6aa4833 100644 --- a/examples/client.cc +++ b/examples/client.cc @@ -931,8 +931,8 @@ int Client::init(int fd, const Address &local_addr, const Address &remote_addr, path_validation, ::select_preferred_address, nullptr, // stream_reset - nullptr, // max_remote_stream_id_bidi, - nullptr, // max_remote_stream_id_uni, + nullptr, // extend_max_remote_streams_bidi, + nullptr, // extend_max_remote_streams_uni, }; auto dis = std::uniform_int_distribution<uint8_t>( diff --git a/examples/server.cc b/examples/server.cc index 67aa4dae..9009fd07 100644 --- a/examples/server.cc +++ b/examples/server.cc @@ -1066,8 +1066,8 @@ int Handler::init(const Endpoint &ep, const sockaddr *sa, socklen_t salen, path_validation, nullptr, // select_preferred_addr nullptr, // stream_reset - nullptr, // max_remote_stream_id_bidi, - nullptr, // max_remote_stream_id_uni, + nullptr, // extend_max_remote_streams_bidi, + nullptr, // extend_max_remote_streams_uni, }; ngtcp2_settings settings; diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h index 8fe27627..e04fad32 100644 --- a/lib/includes/ngtcp2/ngtcp2.h +++ b/lib/includes/ngtcp2/ngtcp2.h @@ -1336,8 +1336,8 @@ typedef int (*ngtcp2_recv_stateless_reset)(ngtcp2_conn *conn, * * :type:`ngtcp2_extend_max_streams` is a callback function which is * called every time max stream ID is strictly extended. - * |max_streams| is the cumulative number of streams which a local - * endpoint can open. + * |max_streams| is the cumulative number of streams which an endpoint + * can open. * * The callback function must return 0 if it succeeds. Returning * :enum:`NGTCP2_ERR_CALLBACK_FAILURE` makes the library call return @@ -1451,22 +1451,6 @@ typedef int (*ngtcp2_select_preferred_addr)(ngtcp2_conn *conn, const ngtcp2_preferred_addr *paddr, void *user_data); -/** - * @functypedef - * - * :type:`ngtcp2_max_remote_stream_id` is a callback function which is - * invoked when the maximum stream ID which remote endpoint can open - * is extended. |max_stream_id| is the maximum stream ID which remote - * endpoint can initiate. - * - * The callback function must return 0 if it succeeds. Returning - * :enum:`NGTCP2_ERR_CALLBACK_FAILURE` makes the library call return - * immediately. - */ -typedef int (*ngtcp2_max_remote_stream_id)(ngtcp2_conn *conn, - int64_t max_stream_id, - void *user_data); - typedef struct { ngtcp2_client_initial client_initial; ngtcp2_recv_client_initial recv_client_initial; @@ -1510,8 +1494,8 @@ typedef struct { ngtcp2_stream_close stream_close; ngtcp2_recv_stateless_reset recv_stateless_reset; ngtcp2_recv_retry recv_retry; - ngtcp2_extend_max_streams extend_max_streams_bidi; - ngtcp2_extend_max_streams extend_max_streams_uni; + ngtcp2_extend_max_streams extend_max_local_streams_bidi; + ngtcp2_extend_max_streams extend_max_local_streams_uni; ngtcp2_rand rand; ngtcp2_get_new_connection_id get_new_connection_id; ngtcp2_remove_connection_id remove_connection_id; @@ -1519,8 +1503,8 @@ typedef struct { ngtcp2_path_validation path_validation; ngtcp2_select_preferred_addr select_preferred_addr; ngtcp2_stream_reset stream_reset; - ngtcp2_max_remote_stream_id max_remote_stream_id_bidi; - ngtcp2_max_remote_stream_id max_remote_stream_id_uni; + ngtcp2_extend_max_streams extend_max_remote_streams_bidi; + ngtcp2_extend_max_streams extend_max_remote_streams_uni; } ngtcp2_conn_callbacks; /* diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c index 2367f754..10269f71 100644 --- a/lib/ngtcp2_conn.c +++ b/lib/ngtcp2_conn.c @@ -169,16 +169,16 @@ static int conn_call_stream_reset(ngtcp2_conn *conn, int64_t stream_id, return 0; } -static int conn_call_extend_max_streams_bidi(ngtcp2_conn *conn, - uint64_t max_streams) { +static int conn_call_extend_max_local_streams_bidi(ngtcp2_conn *conn, + uint64_t max_streams) { int rv; - if (!conn->callbacks.extend_max_streams_bidi) { + if (!conn->callbacks.extend_max_local_streams_bidi) { return 0; } - rv = conn->callbacks.extend_max_streams_bidi(conn, max_streams, - conn->user_data); + rv = conn->callbacks.extend_max_local_streams_bidi(conn, max_streams, + conn->user_data); if (rv != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -186,16 +186,16 @@ static int conn_call_extend_max_streams_bidi(ngtcp2_conn *conn, return 0; } -static int conn_call_extend_max_streams_uni(ngtcp2_conn *conn, - uint64_t max_streams) { +static int conn_call_extend_max_local_streams_uni(ngtcp2_conn *conn, + uint64_t max_streams) { int rv; - if (!conn->callbacks.extend_max_streams_uni) { + if (!conn->callbacks.extend_max_local_streams_uni) { return 0; } - rv = conn->callbacks.extend_max_streams_uni(conn, max_streams, - conn->user_data); + rv = conn->callbacks.extend_max_local_streams_uni(conn, max_streams, + conn->user_data); if (rv != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -266,16 +266,16 @@ static int conn_call_select_preferred_addr(ngtcp2_conn *conn, return 0; } -static int conn_call_max_remote_stream_id_bidi(ngtcp2_conn *conn, - int64_t max_stream_id) { +static int conn_call_extend_max_remote_streams_bidi(ngtcp2_conn *conn, + uint64_t max_streams) { int rv; - if (!conn->callbacks.max_remote_stream_id_bidi) { + if (!conn->callbacks.extend_max_remote_streams_bidi) { return 0; } - rv = conn->callbacks.max_remote_stream_id_bidi(conn, max_stream_id, - conn->user_data); + rv = conn->callbacks.extend_max_remote_streams_bidi(conn, max_streams, + conn->user_data); if (rv != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -283,16 +283,16 @@ static int conn_call_max_remote_stream_id_bidi(ngtcp2_conn *conn, return 0; } -static int conn_call_max_remote_stream_id_uni(ngtcp2_conn *conn, - int64_t max_stream_id) { +static int conn_call_extend_max_remote_streams_uni(ngtcp2_conn *conn, + uint64_t max_streams) { int rv; - if (!conn->callbacks.max_remote_stream_id_uni) { + if (!conn->callbacks.extend_max_remote_streams_uni) { return 0; } - rv = conn->callbacks.max_remote_stream_id_uni(conn, max_stream_id, - conn->user_data); + rv = conn->callbacks.extend_max_remote_streams_uni(conn, max_streams, + conn->user_data); if (rv != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -639,13 +639,11 @@ int ngtcp2_conn_client_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid, return rv; } (*pconn)->rcid = *dcid; - (*pconn)->remote.bidi.unsent_max_stream_id = - (*pconn)->remote.bidi.max_stream_id = - ngtcp2_nth_server_bidi_id(settings->max_streams_bidi); + (*pconn)->remote.bidi.unsent_max_streams = (*pconn)->remote.bidi.max_streams = + settings->max_streams_bidi; - (*pconn)->remote.uni.unsent_max_stream_id = - (*pconn)->remote.uni.max_stream_id = - ngtcp2_nth_server_uni_id(settings->max_streams_uni); + (*pconn)->remote.uni.unsent_max_streams = (*pconn)->remote.uni.max_streams = + settings->max_streams_uni; (*pconn)->state = NGTCP2_CS_CLIENT_INITIAL; (*pconn)->local.bidi.next_stream_id = 0; @@ -665,13 +663,11 @@ int ngtcp2_conn_server_new(ngtcp2_conn **pconn, const ngtcp2_cid *dcid, return rv; } (*pconn)->server = 1; - (*pconn)->remote.bidi.unsent_max_stream_id = - (*pconn)->remote.bidi.max_stream_id = - ngtcp2_nth_client_bidi_id(settings->max_streams_bidi); + (*pconn)->remote.bidi.unsent_max_streams = (*pconn)->remote.bidi.max_streams = + settings->max_streams_bidi; - (*pconn)->remote.uni.unsent_max_stream_id = - (*pconn)->remote.uni.max_stream_id = - ngtcp2_nth_client_uni_id(settings->max_streams_uni); + (*pconn)->remote.uni.unsent_max_streams = (*pconn)->remote.uni.max_streams = + settings->max_streams_uni; (*pconn)->state = NGTCP2_CS_SERVER_INITIAL; (*pconn)->local.bidi.next_stream_id = 1; @@ -2171,8 +2167,7 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, assert(0); break; case NGTCP2_FRAME_MAX_STREAMS_BIDI: - if ((*pfrc)->fr.max_streams.max_streams < - (uint64_t)(conn->remote.bidi.max_stream_id >> 2)) { + if ((*pfrc)->fr.max_streams.max_streams < conn->remote.bidi.max_streams) { frc = *pfrc; *pfrc = (*pfrc)->next; ngtcp2_frame_chain_del(frc, conn->mem); @@ -2180,8 +2175,7 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, } break; case NGTCP2_FRAME_MAX_STREAMS_UNI: - if ((*pfrc)->fr.max_streams.max_streams < - (uint64_t)(conn->remote.uni.max_stream_id >> 2)) { + if ((*pfrc)->fr.max_streams.max_streams < conn->remote.uni.max_streams) { frc = *pfrc; *pfrc = (*pfrc)->next; ngtcp2_frame_chain_del(frc, conn->mem); @@ -2261,10 +2255,9 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, /* Write MAX_STREAM_ID after RESET_STREAM so that we can extend stream ID space in one packet. */ if (rv != NGTCP2_ERR_NOBUF && *pfrc == NULL && - conn->remote.bidi.unsent_max_stream_id > - conn->remote.bidi.max_stream_id) { - rv = conn_call_max_remote_stream_id_bidi( - conn, conn->remote.bidi.unsent_max_stream_id); + conn->remote.bidi.unsent_max_streams > conn->remote.bidi.max_streams) { + rv = conn_call_extend_max_remote_streams_bidi( + conn, conn->remote.bidi.unsent_max_streams); if (rv != 0) { assert(ngtcp2_err_is_fatal(rv)); return rv; @@ -2276,11 +2269,10 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, return rv; } nfrc->fr.type = NGTCP2_FRAME_MAX_STREAMS_BIDI; - nfrc->fr.max_streams.max_streams = - (uint64_t)(conn->remote.bidi.unsent_max_stream_id >> 2); + nfrc->fr.max_streams.max_streams = conn->remote.bidi.unsent_max_streams; *pfrc = nfrc; - conn->remote.bidi.max_stream_id = conn->remote.bidi.unsent_max_stream_id; + conn->remote.bidi.max_streams = conn->remote.bidi.unsent_max_streams; rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, &(*pfrc)->fr); if (rv != 0) { @@ -2293,10 +2285,9 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, } if (rv != NGTCP2_ERR_NOBUF && *pfrc == NULL) { - if (conn->remote.uni.unsent_max_stream_id > - conn->remote.uni.max_stream_id) { - rv = conn_call_max_remote_stream_id_uni( - conn, conn->remote.uni.unsent_max_stream_id); + if (conn->remote.uni.unsent_max_streams > conn->remote.uni.max_streams) { + rv = conn_call_extend_max_remote_streams_uni( + conn, conn->remote.uni.unsent_max_streams); if (rv != 0) { assert(ngtcp2_err_is_fatal(rv)); return rv; @@ -2308,11 +2299,10 @@ static ssize_t conn_write_pkt(ngtcp2_conn *conn, uint8_t *dest, size_t destlen, return rv; } nfrc->fr.type = NGTCP2_FRAME_MAX_STREAMS_UNI; - nfrc->fr.max_streams.max_streams = - (uint64_t)(conn->remote.uni.unsent_max_stream_id >> 2); + nfrc->fr.max_streams.max_streams = conn->remote.uni.unsent_max_streams; *pfrc = nfrc; - conn->remote.uni.max_stream_id = conn->remote.uni.unsent_max_stream_id; + conn->remote.uni.max_streams = conn->remote.uni.unsent_max_streams; rv = conn_ppe_write_frame_hd_log(conn, &ppe, &hd_logged, &hd, &(*pfrc)->fr); @@ -3654,7 +3644,8 @@ static int conn_recv_max_stream_data(ngtcp2_conn *conn, if (conn->local.bidi.next_stream_id <= fr->stream_id) { return NGTCP2_ERR_STREAM_STATE; } - } else if (conn->remote.bidi.max_stream_id < fr->stream_id) { + } else if (conn->remote.bidi.max_streams < + ngtcp2_ord_stream_id(fr->stream_id)) { return NGTCP2_ERR_STREAM_LIMIT; } @@ -4868,7 +4859,8 @@ static int conn_recv_stream(ngtcp2_conn *conn, const ngtcp2_stream *fr) { if (conn->local.bidi.next_stream_id <= fr->stream_id) { return NGTCP2_ERR_STREAM_STATE; } - } else if (conn->remote.bidi.max_stream_id < fr->stream_id) { + } else if (conn->remote.bidi.max_streams < + ngtcp2_ord_stream_id(fr->stream_id)) { return NGTCP2_ERR_STREAM_LIMIT; } @@ -4877,7 +4869,7 @@ static int conn_recv_stream(ngtcp2_conn *conn, const ngtcp2_stream *fr) { if (local_stream) { return NGTCP2_ERR_STREAM_STATE; } - if (conn->remote.uni.max_stream_id < fr->stream_id) { + if (conn->remote.uni.max_streams < ngtcp2_ord_stream_id(fr->stream_id)) { return NGTCP2_ERR_STREAM_LIMIT; } @@ -5099,13 +5091,13 @@ static int conn_stop_sending(ngtcp2_conn *conn, ngtcp2_strm *strm, } /* - * handle_remote_stream_id_extension extends - * |*punsent_max_remote_stream_id| if a condition allows it. + * handle_max_remote_streams_extension extends + * |*punsent_max_remote_streams| if a condition allows it. */ static void -handle_remote_stream_id_extension(int64_t *punsent_max_remote_stream_id) { - if (*punsent_max_remote_stream_id <= (int64_t)(NGTCP2_MAX_VARINT - 4)) { - *punsent_max_remote_stream_id += 4; +handle_max_remote_streams_extension(uint64_t *punsent_max_remote_streams) { + if (*punsent_max_remote_streams < NGTCP2_MAX_STREAMS) { + ++(*punsent_max_remote_streams); } } @@ -5149,7 +5141,8 @@ static int conn_recv_reset_stream(ngtcp2_conn *conn, if (conn->local.bidi.next_stream_id <= fr->stream_id) { return NGTCP2_ERR_STREAM_STATE; } - } else if (fr->stream_id > conn->remote.bidi.max_stream_id) { + } else if (conn->remote.bidi.max_streams < + ngtcp2_ord_stream_id(fr->stream_id)) { return NGTCP2_ERR_STREAM_LIMIT; } @@ -5158,7 +5151,7 @@ static int conn_recv_reset_stream(ngtcp2_conn *conn, if (local_stream) { return NGTCP2_ERR_PROTO; } - if (fr->stream_id > conn->remote.uni.max_stream_id) { + if (conn->remote.uni.max_streams < ngtcp2_ord_stream_id(fr->stream_id)) { return NGTCP2_ERR_STREAM_LIMIT; } @@ -5197,10 +5190,10 @@ static int conn_recv_reset_stream(ngtcp2_conn *conn, RESET_STREAM and don't write stream data any further. This effectively allows another new stream for peer. */ if (bidi) { - handle_remote_stream_id_extension( - &conn->remote.bidi.unsent_max_stream_id); + handle_max_remote_streams_extension( + &conn->remote.bidi.unsent_max_streams); } else { - handle_remote_stream_id_extension(&conn->remote.uni.unsent_max_stream_id); + handle_max_remote_streams_extension(&conn->remote.uni.unsent_max_streams); } return 0; @@ -5268,7 +5261,8 @@ static int conn_recv_stop_sending(ngtcp2_conn *conn, if (conn->local.bidi.next_stream_id <= fr->stream_id) { return NGTCP2_ERR_STREAM_STATE; } - } else if (fr->stream_id > conn->remote.bidi.max_stream_id) { + } else if (conn->remote.bidi.max_streams < + ngtcp2_ord_stream_id(fr->stream_id)) { return NGTCP2_ERR_STREAM_LIMIT; } @@ -5513,32 +5507,19 @@ static int conn_recv_delayed_handshake_pkt(ngtcp2_conn *conn, */ static int conn_recv_max_streams(ngtcp2_conn *conn, const ngtcp2_max_streams *fr) { - int64_t n; + uint64_t n = ngtcp2_min(fr->max_streams, NGTCP2_MAX_STREAMS); + if (fr->type == NGTCP2_FRAME_MAX_STREAMS_BIDI) { - if (conn->server) { - n = ngtcp2_nth_server_bidi_id(fr->max_streams); - n = ngtcp2_min(n, NGTCP2_MAX_SERVER_STREAM_ID_BIDI); - } else { - n = ngtcp2_nth_client_bidi_id(fr->max_streams); - n = ngtcp2_min(n, NGTCP2_MAX_CLIENT_STREAM_ID_BIDI); - } - if (n > conn->local.bidi.max_stream_id) { - conn->local.bidi.max_stream_id = n; - return conn_call_extend_max_streams_bidi(conn, (uint64_t)(n >> 2)); + if (conn->local.bidi.max_streams < n) { + conn->local.bidi.max_streams = n; + return conn_call_extend_max_local_streams_bidi(conn, n); } return 0; } - if (conn->server) { - n = ngtcp2_nth_server_uni_id(fr->max_streams); - n = ngtcp2_min(n, NGTCP2_MAX_SERVER_STREAM_ID_UNI); - } else { - n = ngtcp2_nth_client_uni_id(fr->max_streams); - n = ngtcp2_min(n, NGTCP2_MAX_CLIENT_STREAM_ID_UNI); - } - if (n > conn->local.uni.max_stream_id) { - conn->local.uni.max_stream_id = n; - return conn_call_extend_max_streams_uni(conn, (uint64_t)(n >> 2)); + if (conn->local.uni.max_streams < n) { + conn->local.uni.max_streams = n; + return conn_call_extend_max_local_streams_uni(conn, n); } return 0; } @@ -6417,16 +6398,16 @@ static int conn_handshake_completed(ngtcp2_conn *conn) { return rv; } - if (conn->local.bidi.max_stream_id > 0) { - rv = conn_call_extend_max_streams_bidi( - conn, (uint64_t)(conn->local.bidi.max_stream_id >> 2)); + if (conn->local.bidi.max_streams > 0) { + rv = conn_call_extend_max_local_streams_bidi(conn, + conn->local.bidi.max_streams); if (rv != 0) { return rv; } } - if (conn->local.uni.max_stream_id > 0) { - rv = conn_call_extend_max_streams_uni( - conn, (uint64_t)(conn->local.uni.max_stream_id >> 2)); + if (conn->local.uni.max_streams > 0) { + rv = conn_call_extend_max_local_streams_uni(conn, + conn->local.uni.max_streams); if (rv != 0) { return rv; } @@ -7617,19 +7598,8 @@ conn_client_validate_transport_params(ngtcp2_conn *conn, } static void conn_sync_stream_id_limit(ngtcp2_conn *conn) { - if (conn->server) { - conn->local.bidi.max_stream_id = - ngtcp2_nth_server_bidi_id(conn->remote.settings.max_streams_bidi); - - conn->local.uni.max_stream_id = - ngtcp2_nth_server_uni_id(conn->remote.settings.max_streams_uni); - } else { - conn->local.bidi.max_stream_id = - ngtcp2_nth_client_bidi_id(conn->remote.settings.max_streams_bidi); - - conn->local.uni.max_stream_id = - ngtcp2_nth_client_uni_id(conn->remote.settings.max_streams_uni); - } + conn->local.bidi.max_streams = conn->remote.settings.max_streams_bidi; + conn->local.uni.max_streams = conn->remote.settings.max_streams_uni; } int ngtcp2_conn_set_remote_transport_params( @@ -7723,7 +7693,8 @@ int ngtcp2_conn_open_bidi_stream(ngtcp2_conn *conn, int64_t *pstream_id, int rv; ngtcp2_strm *strm; - if (conn->local.bidi.next_stream_id > conn->local.bidi.max_stream_id) { + if (ngtcp2_ord_stream_id(conn->local.bidi.next_stream_id) > + conn->local.bidi.max_streams) { return NGTCP2_ERR_STREAM_ID_BLOCKED; } @@ -7750,7 +7721,8 @@ int ngtcp2_conn_open_uni_stream(ngtcp2_conn *conn, int64_t *pstream_id, int rv; ngtcp2_strm *strm; - if (conn->local.uni.next_stream_id > conn->local.uni.max_stream_id) { + if (ngtcp2_ord_stream_id(conn->local.uni.next_stream_id) > + conn->local.uni.max_streams) { return NGTCP2_ERR_STREAM_ID_BLOCKED; } @@ -8043,10 +8015,10 @@ int ngtcp2_conn_close_stream(ngtcp2_conn *conn, ngtcp2_strm *strm, if (!conn_local_stream(conn, strm->stream_id)) { if (bidi_stream(strm->stream_id)) { - handle_remote_stream_id_extension( - &conn->remote.bidi.unsent_max_stream_id); + handle_max_remote_streams_extension( + &conn->remote.bidi.unsent_max_streams); } else { - handle_remote_stream_id_extension(&conn->remote.uni.unsent_max_stream_id); + handle_max_remote_streams_extension(&conn->remote.uni.unsent_max_streams); } } diff --git a/lib/ngtcp2_conn.h b/lib/ngtcp2_conn.h index 1ff6af99..31674bf0 100644 --- a/lib/ngtcp2_conn.h +++ b/lib/ngtcp2_conn.h @@ -62,6 +62,9 @@ typedef enum { NGTCP2_CS_DRAINING, } ngtcp2_conn_state; +/* NGTCP2_MAX_STREAMS is the maximum number of streams. */ +#define NGTCP2_MAX_STREAMS (((1LL << 60) - 1) << 2) + /* NGTCP2_MAX_NUM_BUFFED_RX_PKTS is the maximum number of buffered reordered packets. */ #define NGTCP2_MAX_NUM_BUFFED_RX_PKTS 16 @@ -356,18 +359,18 @@ struct ngtcp2_conn { struct { ngtcp2_settings settings; struct { - /* max_stream_id is the maximum bidirectional stream ID which + /* max_streams is the maximum number of bidirectional streams which the local endpoint can open. */ - int64_t max_stream_id; + uint64_t max_streams; /* next_stream_id is the bidirectional stream ID which the local endpoint opens next. */ int64_t next_stream_id; } bidi; struct { - /* max_stream_id is the maximum unidirectional stream ID which - the local endpoint can open. */ - int64_t max_stream_id; + /* max_streams is the maximum number of unidirectional streams + which the local endpoint can open. */ + uint64_t max_streams; /* next_stream_id is the unidirectional stream ID which the local endpoint opens next. */ int64_t next_stream_id; @@ -378,26 +381,28 @@ struct ngtcp2_conn { ngtcp2_settings settings; struct { ngtcp2_idtr idtr; - /* unsent_max_stream_id is the maximum stream ID of peer + /* unsent_max_streams is the maximum number of streams of peer initiated bidirectional stream which the local endpoint can accept. This limit is not yet notified to the remote endpoint. */ - int64_t unsent_max_stream_id; - /* max_stream_id is the maximum stream ID of peer initiated - bidirectional stream which the local endpoint can accept. */ - int64_t max_stream_id; + uint64_t unsent_max_streams; + /* max_streams is the maximum number of streams of peer + initiated bidirectional stream which the local endpoint can + accept. */ + uint64_t max_streams; } bidi; struct { ngtcp2_idtr idtr; - /* unsent_max_stream_id is the maximum stream ID of peer + /* unsent_max_streams is the maximum number of streams of peer initiated unidirectional stream which the local endpoint can accept. This limit is not yet notified to the remote endpoint. */ - int64_t unsent_max_stream_id; - /* max_stream_id is the maximum stream ID of peer initiated - unidirectional stream which the local endpoint can accept. */ - int64_t max_stream_id; + uint64_t unsent_max_streams; + /* max_streams is the maximum number of streams of peer + initiated unidirectional stream which the local endpoint can + accept. */ + uint64_t max_streams; } uni; } remote; diff --git a/lib/ngtcp2_conv.c b/lib/ngtcp2_conv.c index 89c0a1d0..319dd14a 100644 --- a/lib/ngtcp2_conv.c +++ b/lib/ngtcp2_conv.c @@ -246,3 +246,7 @@ int64_t ngtcp2_nth_client_uni_id(uint64_t n) { return (int64_t)(((n - 1) << 2) | 0x02); } + +uint64_t ngtcp2_ord_stream_id(int64_t stream_id) { + return (uint64_t)(stream_id >> 2) + 1; +} diff --git a/lib/ngtcp2_conv.h b/lib/ngtcp2_conv.h index e421cd2f..c70d42cf 100644 --- a/lib/ngtcp2_conv.h +++ b/lib/ngtcp2_conv.h @@ -189,4 +189,9 @@ int64_t ngtcp2_nth_server_uni_id(uint64_t n); */ int64_t ngtcp2_nth_client_uni_id(uint64_t n); +/* + * ngtcp2_ord_stream_id returns the ordinal number of |stream_id|. + */ +uint64_t ngtcp2_ord_stream_id(int64_t stream_id); + #endif /* NGTCP2_CONV_H */ diff --git a/tests/ngtcp2_conn_test.c b/tests/ngtcp2_conn_test.c index 2d33de6f..af6408f8 100644 --- a/tests/ngtcp2_conn_test.c +++ b/tests/ngtcp2_conn_test.c @@ -388,10 +388,8 @@ static void setup_default_server(ngtcp2_conn **pconn) { (*pconn)->remote.settings.max_streams_bidi = 0; (*pconn)->remote.settings.max_streams_uni = 1; (*pconn)->remote.settings.max_data = 64 * 1024; - (*pconn)->local.bidi.max_stream_id = - ngtcp2_nth_server_bidi_id((*pconn)->remote.settings.max_streams_bidi); - (*pconn)->local.uni.max_stream_id = - ngtcp2_nth_server_uni_id((*pconn)->remote.settings.max_streams_uni); + (*pconn)->local.bidi.max_streams = (*pconn)->remote.settings.max_streams_bidi; + (*pconn)->local.uni.max_streams = (*pconn)->remote.settings.max_streams_uni; (*pconn)->tx.max_offset = (*pconn)->remote.settings.max_data; (*pconn)->odcid = dcid; } @@ -439,10 +437,8 @@ static void setup_default_client(ngtcp2_conn **pconn) { (*pconn)->remote.settings.max_streams_bidi = 1; (*pconn)->remote.settings.max_streams_uni = 1; (*pconn)->remote.settings.max_data = 64 * 1024; - (*pconn)->local.bidi.max_stream_id = - ngtcp2_nth_client_bidi_id((*pconn)->remote.settings.max_streams_bidi); - (*pconn)->local.uni.max_stream_id = - ngtcp2_nth_client_uni_id((*pconn)->remote.settings.max_streams_uni); + (*pconn)->local.bidi.max_streams = (*pconn)->remote.settings.max_streams_bidi; + (*pconn)->local.uni.max_streams = (*pconn)->remote.settings.max_streams_uni; (*pconn)->tx.max_offset = (*pconn)->remote.settings.max_data; (*pconn)->odcid = dcid; } @@ -547,10 +543,8 @@ static void setup_early_server(ngtcp2_conn **pconn) { (*pconn)->remote.settings.max_streams_bidi = 0; (*pconn)->remote.settings.max_streams_uni = 1; (*pconn)->remote.settings.max_data = 64 * 1024; - (*pconn)->local.bidi.max_stream_id = - ngtcp2_nth_server_bidi_id((*pconn)->remote.settings.max_streams_bidi); - (*pconn)->local.uni.max_stream_id = - ngtcp2_nth_server_uni_id((*pconn)->remote.settings.max_streams_uni); + (*pconn)->local.bidi.max_streams = (*pconn)->remote.settings.max_streams_bidi; + (*pconn)->local.uni.max_streams = (*pconn)->remote.settings.max_streams_uni; (*pconn)->tx.max_offset = (*pconn)->remote.settings.max_data; } @@ -1434,7 +1428,7 @@ void test_ngtcp2_conn_recv_reset_stream(void) { CU_ASSERT(0 == rv); CU_ASSERT(NULL == ngtcp2_conn_find_stream(conn, 0)); - CU_ASSERT(12 == conn->remote.bidi.unsent_max_stream_id); + CU_ASSERT(4 == conn->remote.bidi.unsent_max_streams); ngtcp2_conn_del(conn); @@ -2301,7 +2295,7 @@ void test_ngtcp2_conn_recv_max_streams(void) { rv = ngtcp2_conn_read_pkt(conn, &null_path, buf, pktlen, 1); CU_ASSERT(0 == rv); - CU_ASSERT(((999 - 1) << 2) + 0x02 == conn->local.uni.max_stream_id); + CU_ASSERT(999 == conn->local.uni.max_streams); fr.type = NGTCP2_FRAME_MAX_STREAMS_BIDI; fr.max_streams.max_streams = 997; @@ -2310,7 +2304,7 @@ void test_ngtcp2_conn_recv_max_streams(void) { rv = ngtcp2_conn_read_pkt(conn, &null_path, buf, pktlen, 2); CU_ASSERT(0 == rv); - CU_ASSERT(((997 - 1) << 2) == conn->local.bidi.max_stream_id); + CU_ASSERT(997 == conn->local.bidi.max_streams); ngtcp2_conn_del(conn); } @@ -2526,7 +2520,7 @@ void test_ngtcp2_conn_retransmit_protected(void) { /* Retransmission takes place per frame basis. */ setup_default_client(&conn); - conn->local.bidi.max_stream_id = 8; + conn->local.bidi.max_streams = 3; ngtcp2_conn_open_bidi_stream(conn, &stream_id_a, NULL); ngtcp2_conn_open_bidi_stream(conn, &stream_id_b, NULL); @@ -2914,7 +2908,7 @@ void test_ngtcp2_conn_recv_stream_data(void) { /* Receive an unidirectional stream which is beyond the limit. */ setup_default_server(&conn); conn->callbacks.recv_stream_data = recv_stream_data; - conn->remote.uni.max_stream_id = 0; + conn->remote.uni.max_streams = 0; conn->user_data = &ud; fr.type = NGTCP2_FRAME_STREAM; -- GitLab