Disable local flow control on FLOW_CONTROL_OPTIONS = 1
This commit is contained in:
parent
49519a06b3
commit
8033152e80
|
@ -1908,8 +1908,8 @@ static int nghttp2_session_update_initial_window_size
|
||||||
&arg);
|
&arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nghttp2_disable_flow_control_func(nghttp2_map_entry *entry,
|
static int nghttp2_disable_remote_flow_control_func(nghttp2_map_entry *entry,
|
||||||
void *ptr)
|
void *ptr)
|
||||||
{
|
{
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_stream *stream;
|
nghttp2_stream *stream;
|
||||||
|
@ -1934,14 +1934,38 @@ static int nghttp2_disable_flow_control_func(nghttp2_map_entry *entry,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable connection-level flow control and stream-level flow control
|
* Disable remote side connection-level flow control and stream-level
|
||||||
* of existing streams.
|
* flow control of existing streams.
|
||||||
*/
|
*/
|
||||||
static int nghttp2_session_disable_flow_control(nghttp2_session *session)
|
static int nghttp2_session_disable_remote_flow_control
|
||||||
|
(nghttp2_session *session)
|
||||||
{
|
{
|
||||||
session->remote_flow_control = 0;
|
session->remote_flow_control = 0;
|
||||||
return nghttp2_map_each(&session->streams,
|
return nghttp2_map_each(&session->streams,
|
||||||
nghttp2_disable_flow_control_func, session);
|
nghttp2_disable_remote_flow_control_func, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nghttp2_disable_local_flow_control_func(nghttp2_map_entry *entry,
|
||||||
|
void *ptr)
|
||||||
|
{
|
||||||
|
nghttp2_stream *stream;
|
||||||
|
stream = (nghttp2_stream*)entry;
|
||||||
|
stream->local_flow_control = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable stream-level flow control in local side of existing
|
||||||
|
* streams.
|
||||||
|
*/
|
||||||
|
static void nghttp2_session_disable_local_flow_control
|
||||||
|
(nghttp2_session *session)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
session->local_flow_control = 0;
|
||||||
|
rv = nghttp2_map_each(&session->streams,
|
||||||
|
nghttp2_disable_local_flow_control_func, NULL);
|
||||||
|
assert(rv == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_session_update_local_settings(nghttp2_session *session,
|
void nghttp2_session_update_local_settings(nghttp2_session *session,
|
||||||
|
@ -1949,10 +1973,17 @@ void nghttp2_session_update_local_settings(nghttp2_session *session,
|
||||||
size_t niv)
|
size_t niv)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
uint8_t old_flow_control =
|
||||||
|
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS];
|
||||||
|
|
||||||
for(i = 0; i < niv; ++i) {
|
for(i = 0; i < niv; ++i) {
|
||||||
assert(iv[i].settings_id > 0 && iv[i].settings_id <= NGHTTP2_SETTINGS_MAX);
|
assert(iv[i].settings_id > 0 && iv[i].settings_id <= NGHTTP2_SETTINGS_MAX);
|
||||||
session->local_settings[iv[i].settings_id] = iv[i].value;
|
session->local_settings[iv[i].settings_id] = iv[i].value;
|
||||||
}
|
}
|
||||||
|
if(old_flow_control == 0 &&
|
||||||
|
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]) {
|
||||||
|
nghttp2_session_disable_local_flow_control(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_session_on_settings_received(nghttp2_session *session,
|
int nghttp2_session_on_settings_received(nghttp2_session *session,
|
||||||
|
@ -1993,7 +2024,7 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
|
||||||
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
|
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
|
||||||
if(entry->value & 0x1) {
|
if(entry->value & 0x1) {
|
||||||
if(session->remote_settings[entry->settings_id] == 0) {
|
if(session->remote_settings[entry->settings_id] == 0) {
|
||||||
rv = nghttp2_session_disable_flow_control(session);
|
rv = nghttp2_session_disable_remote_flow_control(session);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,8 +165,10 @@ int main(int argc, char* argv[])
|
||||||
test_nghttp2_session_defer_data) ||
|
test_nghttp2_session_defer_data) ||
|
||||||
!CU_add_test(pSuite, "session_flow_control",
|
!CU_add_test(pSuite, "session_flow_control",
|
||||||
test_nghttp2_session_flow_control) ||
|
test_nghttp2_session_flow_control) ||
|
||||||
!CU_add_test(pSuite, "session_flow_control_disable",
|
!CU_add_test(pSuite, "session_flow_control_disable_remote",
|
||||||
test_nghttp2_session_flow_control_disable) ||
|
test_nghttp2_session_flow_control_disable_remote) ||
|
||||||
|
!CU_add_test(pSuite, "session_flow_control_disable_local",
|
||||||
|
test_nghttp2_session_flow_control_disable_local) ||
|
||||||
!CU_add_test(pSuite, "session_data_read_temporal_failure",
|
!CU_add_test(pSuite, "session_data_read_temporal_failure",
|
||||||
test_nghttp2_session_data_read_temporal_failure) ||
|
test_nghttp2_session_data_read_temporal_failure) ||
|
||||||
!CU_add_test(pSuite, "session_on_request_recv_callback",
|
!CU_add_test(pSuite, "session_on_request_recv_callback",
|
||||||
|
|
|
@ -1770,7 +1770,7 @@ void test_nghttp2_submit_settings(void)
|
||||||
my_user_data ud;
|
my_user_data ud;
|
||||||
nghttp2_outbound_item *item;
|
nghttp2_outbound_item *item;
|
||||||
nghttp2_frame *frame;
|
nghttp2_frame *frame;
|
||||||
nghttp2_settings_entry iv[3];
|
nghttp2_settings_entry iv[4];
|
||||||
|
|
||||||
iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
iv[0].value = 50;
|
iv[0].value = 50;
|
||||||
|
@ -1778,9 +1778,12 @@ void test_nghttp2_submit_settings(void)
|
||||||
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||||
iv[1].value = 16*1024;
|
iv[1].value = 16*1024;
|
||||||
|
|
||||||
|
iv[2].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
|
||||||
|
iv[2].value = 1;
|
||||||
|
|
||||||
/* This is duplicate entry */
|
/* This is duplicate entry */
|
||||||
iv[2].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
iv[3].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
iv[2].value = 150;
|
iv[3].value = 150;
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||||
callbacks.send_callback = null_send_callback;
|
callbacks.send_callback = null_send_callback;
|
||||||
|
@ -1788,29 +1791,34 @@ void test_nghttp2_submit_settings(void)
|
||||||
nghttp2_session_server_new(&session, &callbacks, &ud);
|
nghttp2_session_server_new(&session, &callbacks, &ud);
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
||||||
nghttp2_submit_settings(session, iv, 3));
|
nghttp2_submit_settings(session, iv, 4));
|
||||||
|
|
||||||
/* Make sure that local settings are not changed */
|
/* Make sure that local settings are not changed */
|
||||||
CU_ASSERT(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS ==
|
CU_ASSERT(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS ==
|
||||||
session->local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
|
session->local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
|
||||||
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE ==
|
CU_ASSERT(NGHTTP2_INITIAL_WINDOW_SIZE ==
|
||||||
session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
|
session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
|
||||||
|
CU_ASSERT(0 ==
|
||||||
|
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]);
|
||||||
|
|
||||||
/* Now sends without 3rd one */
|
/* Now sends without 4th one */
|
||||||
CU_ASSERT(0 == nghttp2_submit_settings(session, iv, 2));
|
CU_ASSERT(0 == nghttp2_submit_settings(session, iv, 3));
|
||||||
|
|
||||||
/* Make sure that local settings are changed */
|
/* Make sure that local settings are changed */
|
||||||
CU_ASSERT(50 ==
|
CU_ASSERT(50 ==
|
||||||
session->local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
|
session->local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
|
||||||
CU_ASSERT(16*1024 ==
|
CU_ASSERT(16*1024 ==
|
||||||
session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
|
session->local_settings[NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
|
||||||
|
CU_ASSERT(1 ==
|
||||||
|
session->local_settings[NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS]);
|
||||||
|
CU_ASSERT(0 == session->local_flow_control);
|
||||||
|
|
||||||
item = nghttp2_session_get_next_ob_item(session);
|
item = nghttp2_session_get_next_ob_item(session);
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_SETTINGS == OB_CTRL_TYPE(item));
|
CU_ASSERT(NGHTTP2_SETTINGS == OB_CTRL_TYPE(item));
|
||||||
|
|
||||||
frame = item->frame;
|
frame = item->frame;
|
||||||
CU_ASSERT(2 == frame->settings.niv);
|
CU_ASSERT(3 == frame->settings.niv);
|
||||||
CU_ASSERT(50 == frame->settings.iv[0].value);
|
CU_ASSERT(50 == frame->settings.iv[0].value);
|
||||||
CU_ASSERT(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS ==
|
CU_ASSERT(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS ==
|
||||||
frame->settings.iv[0].settings_id);
|
frame->settings.iv[0].settings_id);
|
||||||
|
@ -2433,7 +2441,7 @@ void test_nghttp2_session_flow_control(void)
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_flow_control_disable(void)
|
void test_nghttp2_session_flow_control_disable_remote(void)
|
||||||
{
|
{
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
|
@ -2487,6 +2495,33 @@ void test_nghttp2_session_flow_control_disable(void)
|
||||||
nghttp2_session_del(session);
|
nghttp2_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_session_flow_control_disable_local(void)
|
||||||
|
{
|
||||||
|
nghttp2_session *session;
|
||||||
|
nghttp2_session_callbacks callbacks;
|
||||||
|
nghttp2_stream *stream;
|
||||||
|
nghttp2_settings_entry iv[1];
|
||||||
|
|
||||||
|
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||||
|
callbacks.send_callback = null_send_callback;
|
||||||
|
|
||||||
|
nghttp2_session_client_new(&session, &callbacks, NULL);
|
||||||
|
|
||||||
|
stream = nghttp2_session_open_stream(session, 1, NGHTTP2_FLAG_NONE,
|
||||||
|
NGHTTP2_PRI_DEFAULT,
|
||||||
|
NGHTTP2_STREAM_OPENING, NULL);
|
||||||
|
|
||||||
|
iv[0].settings_id = NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS;
|
||||||
|
iv[0].value = 1;
|
||||||
|
|
||||||
|
CU_ASSERT(0 == nghttp2_submit_settings(session, iv,
|
||||||
|
sizeof(iv)/sizeof(iv[0])));
|
||||||
|
CU_ASSERT(0 == stream->local_flow_control);
|
||||||
|
CU_ASSERT(0 == session->local_flow_control);
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
}
|
||||||
|
|
||||||
void test_nghttp2_session_data_read_temporal_failure(void)
|
void test_nghttp2_session_data_read_temporal_failure(void)
|
||||||
{
|
{
|
||||||
nghttp2_session *session;
|
nghttp2_session *session;
|
||||||
|
|
|
@ -73,7 +73,8 @@ void test_nghttp2_session_stream_close_on_headers_push(void);
|
||||||
void test_nghttp2_session_stop_data_with_rst_stream(void);
|
void test_nghttp2_session_stop_data_with_rst_stream(void);
|
||||||
void test_nghttp2_session_defer_data(void);
|
void test_nghttp2_session_defer_data(void);
|
||||||
void test_nghttp2_session_flow_control(void);
|
void test_nghttp2_session_flow_control(void);
|
||||||
void test_nghttp2_session_flow_control_disable(void);
|
void test_nghttp2_session_flow_control_disable_remote(void);
|
||||||
|
void test_nghttp2_session_flow_control_disable_local(void);
|
||||||
void test_nghttp2_session_data_read_temporal_failure(void);
|
void test_nghttp2_session_data_read_temporal_failure(void);
|
||||||
void test_nghttp2_session_on_request_recv_callback(void);
|
void test_nghttp2_session_on_request_recv_callback(void);
|
||||||
void test_nghttp2_session_on_stream_close(void);
|
void test_nghttp2_session_on_stream_close(void);
|
||||||
|
|
Loading…
Reference in New Issue