Fail nghttp2_submit_settings if there is pending SETTINGS frame in-flight
pending_local_max_concurrent_stream is now set in nghttp2_session_add_settings, rather than after frame was sent.
This commit is contained in:
parent
74daa16a1c
commit
21d5986157
|
@ -2259,6 +2259,10 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
|
||||||
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
|
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
|
||||||
* The |iv| contains invalid value (e.g., initial window size
|
* The |iv| contains invalid value (e.g., initial window size
|
||||||
* strictly greater than (1 << 31) - 1.
|
* strictly greater than (1 << 31) - 1.
|
||||||
|
* :enum:`NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS`
|
||||||
|
* There is already another in-flight SETTINGS. Note that the
|
||||||
|
* current implementation only allows 1 in-flight SETTINGS frame
|
||||||
|
* without ACK flag set.
|
||||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1315,21 +1315,11 @@ static int nghttp2_session_predicate_window_update_send
|
||||||
/*
|
/*
|
||||||
* This function checks SETTINGS can be sent at this time.
|
* This function checks SETTINGS can be sent at this time.
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* Currently this function always returns 0.
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS
|
|
||||||
* There is already another in-flight SETTINGS. Note that the
|
|
||||||
* current implementation only allows 1 in-flight SETTINGS frame
|
|
||||||
* without ACK flag set.
|
|
||||||
*/
|
*/
|
||||||
static int nghttp2_session_predicate_settings_send(nghttp2_session *session,
|
static int nghttp2_session_predicate_settings_send(nghttp2_session *session,
|
||||||
nghttp2_frame *frame)
|
nghttp2_frame *frame)
|
||||||
{
|
{
|
||||||
if((frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 &&
|
|
||||||
session->inflight_niv != -1) {
|
|
||||||
return NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2024,28 +2014,9 @@ static int nghttp2_session_after_frame_sent(nghttp2_session *session)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_SETTINGS: {
|
case NGHTTP2_SETTINGS:
|
||||||
size_t i;
|
/* nothing to do */
|
||||||
if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
/* Extract NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS here and use
|
|
||||||
it to refuse the incoming streams with RST_STREAM. */
|
|
||||||
for(i = frame->settings.niv; i > 0; --i) {
|
|
||||||
if(frame->settings.iv[i - 1].settings_id ==
|
|
||||||
NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS) {
|
|
||||||
session->pending_local_max_concurrent_stream =
|
|
||||||
frame->settings.iv[i - 1].value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(session->inflight_niv == -1);
|
|
||||||
session->inflight_iv = frame->settings.iv;
|
|
||||||
session->inflight_niv = frame->settings.niv;
|
|
||||||
frame->settings.iv = NULL;
|
|
||||||
frame->settings.niv = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NGHTTP2_PUSH_PROMISE:
|
case NGHTTP2_PUSH_PROMISE:
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
break;
|
break;
|
||||||
|
@ -5204,7 +5175,17 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
|
||||||
{
|
{
|
||||||
nghttp2_frame *frame;
|
nghttp2_frame *frame;
|
||||||
nghttp2_settings_entry *iv_copy;
|
nghttp2_settings_entry *iv_copy;
|
||||||
|
size_t i;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
if(flags & NGHTTP2_FLAG_ACK) {
|
||||||
|
if(niv != 0) {
|
||||||
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
} else if(session->inflight_niv != -1) {
|
||||||
|
return NGHTTP2_ERR_TOO_MANY_INFLIGHT_SETTINGS;
|
||||||
|
}
|
||||||
|
|
||||||
if(!nghttp2_iv_check(iv, niv)) {
|
if(!nghttp2_iv_check(iv, niv)) {
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
@ -5217,15 +5198,50 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
|
||||||
free(frame);
|
free(frame);
|
||||||
return NGHTTP2_ERR_NOMEM;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((flags & NGHTTP2_FLAG_ACK) == 0) {
|
||||||
|
if(niv > 0) {
|
||||||
|
session->inflight_iv = nghttp2_frame_iv_copy(iv, niv);
|
||||||
|
|
||||||
|
if(session->inflight_iv == NULL) {
|
||||||
|
free(iv_copy);
|
||||||
|
free(frame);
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
session->inflight_iv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->inflight_niv = niv;
|
||||||
|
}
|
||||||
|
|
||||||
nghttp2_frame_settings_init(&frame->settings, flags, iv_copy, niv);
|
nghttp2_frame_settings_init(&frame->settings, flags, iv_copy, niv);
|
||||||
rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL);
|
rv = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
/* The only expected error is fatal one */
|
/* The only expected error is fatal one */
|
||||||
assert(nghttp2_is_fatal(rv));
|
assert(nghttp2_is_fatal(rv));
|
||||||
|
|
||||||
|
if((flags & NGHTTP2_FLAG_ACK) == 0) {
|
||||||
|
free(session->inflight_iv);
|
||||||
|
session->inflight_iv = NULL;
|
||||||
|
session->inflight_niv = -1;
|
||||||
|
}
|
||||||
|
|
||||||
nghttp2_frame_settings_free(&frame->settings);
|
nghttp2_frame_settings_free(&frame->settings);
|
||||||
free(frame);
|
free(frame);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extract NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS here and use
|
||||||
|
it to refuse the incoming streams with RST_STREAM. */
|
||||||
|
for(i = niv; i > 0; --i) {
|
||||||
|
if(iv[i - 1].settings_id == NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS) {
|
||||||
|
session->pending_local_max_concurrent_stream = iv[i - 1].value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5355,8 +5355,6 @@ void test_nghttp2_session_keep_closed_stream(void)
|
||||||
|
|
||||||
nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, &iv, 1);
|
nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, &iv, 1);
|
||||||
|
|
||||||
nghttp2_session_send(session);
|
|
||||||
|
|
||||||
for(i = 0; i < max_concurrent_streams; ++i) {
|
for(i = 0; i < max_concurrent_streams; ++i) {
|
||||||
open_stream(session, i * 2 + 1);
|
open_stream(session, i * 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue