Detect frame reception for idle stream and make it connection error
Only stream ID which larger than currently used stream ID is detected as idle.
This commit is contained in:
parent
2402b46cf3
commit
08ff95d402
|
@ -1893,6 +1893,22 @@ static int nghttp2_session_is_new_peer_stream_id(nghttp2_session *session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int session_detect_idle_stream(nghttp2_session *session,
|
||||||
|
int32_t stream_id)
|
||||||
|
{
|
||||||
|
/* Assume that stream object with stream_id does not exist */
|
||||||
|
if(nghttp2_session_is_my_stream_id(session, stream_id)) {
|
||||||
|
if(session->next_stream_id >= (uint32_t)stream_id) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(nghttp2_session_is_new_peer_stream_id(session, stream_id)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validates received HEADERS frame |frame| with NGHTTP2_HCAT_REQUEST
|
* Validates received HEADERS frame |frame| with NGHTTP2_HCAT_REQUEST
|
||||||
* or NGHTTP2_HCAT_PUSH_RESPONSE category, which both opens new
|
* or NGHTTP2_HCAT_PUSH_RESPONSE category, which both opens new
|
||||||
|
@ -2397,6 +2413,10 @@ int nghttp2_session_on_priority_received(nghttp2_session *session,
|
||||||
}
|
}
|
||||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
if(!stream) {
|
if(!stream) {
|
||||||
|
if(session_detect_idle_stream(session, frame->hd.stream_id)) {
|
||||||
|
return nghttp2_session_handle_invalid_connection(session, frame,
|
||||||
|
NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(state_reserved_remote(session, stream)) {
|
if(state_reserved_remote(session, stream)) {
|
||||||
|
@ -2430,10 +2450,19 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
|
||||||
nghttp2_frame *frame)
|
nghttp2_frame *frame)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
nghttp2_stream *stream;
|
||||||
if(frame->hd.stream_id == 0) {
|
if(frame->hd.stream_id == 0) {
|
||||||
return nghttp2_session_handle_invalid_connection(session, frame,
|
return nghttp2_session_handle_invalid_connection(session, frame,
|
||||||
NGHTTP2_PROTOCOL_ERROR);
|
NGHTTP2_PROTOCOL_ERROR);
|
||||||
}
|
}
|
||||||
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
|
if(!stream) {
|
||||||
|
if(session_detect_idle_stream(session, frame->hd.stream_id)) {
|
||||||
|
return nghttp2_session_handle_invalid_connection(session, frame,
|
||||||
|
NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rv = nghttp2_session_call_on_frame_received(session, frame);
|
rv = nghttp2_session_call_on_frame_received(session, frame);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -2883,6 +2912,12 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
|
||||||
}
|
}
|
||||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
if(!stream || stream->state == NGHTTP2_STREAM_CLOSING) {
|
if(!stream || stream->state == NGHTTP2_STREAM_CLOSING) {
|
||||||
|
if(!stream) {
|
||||||
|
if(session_detect_idle_stream(session, frame->hd.stream_id)) {
|
||||||
|
return nghttp2_session_handle_invalid_connection
|
||||||
|
(session, frame, NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
rv = nghttp2_session_add_rst_stream
|
rv = nghttp2_session_add_rst_stream
|
||||||
(session, frame->push_promise.promised_stream_id,
|
(session, frame->push_promise.promised_stream_id,
|
||||||
NGHTTP2_REFUSED_STREAM);
|
NGHTTP2_REFUSED_STREAM);
|
||||||
|
@ -3062,6 +3097,10 @@ static int session_on_stream_window_update_received
|
||||||
nghttp2_stream *stream;
|
nghttp2_stream *stream;
|
||||||
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
||||||
if(!stream) {
|
if(!stream) {
|
||||||
|
if(session_detect_idle_stream(session, frame->hd.stream_id)) {
|
||||||
|
return nghttp2_session_handle_invalid_connection(session, frame,
|
||||||
|
NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(stream->state == NGHTTP2_STREAM_RESERVED) {
|
if(stream->state == NGHTTP2_STREAM_RESERVED) {
|
||||||
|
@ -3307,6 +3346,9 @@ static int nghttp2_session_on_data_received_fail_fast(nghttp2_session *session)
|
||||||
}
|
}
|
||||||
stream = nghttp2_session_get_stream(session, stream_id);
|
stream = nghttp2_session_get_stream(session, stream_id);
|
||||||
if(!stream) {
|
if(!stream) {
|
||||||
|
if(session_detect_idle_stream(session, stream_id)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
return NGHTTP2_ERR_IGN_PAYLOAD;
|
return NGHTTP2_ERR_IGN_PAYLOAD;
|
||||||
}
|
}
|
||||||
if(stream->shut_flags & NGHTTP2_SHUT_RD) {
|
if(stream->shut_flags & NGHTTP2_SHUT_RD) {
|
||||||
|
@ -3330,7 +3372,7 @@ static int nghttp2_session_on_data_received_fail_fast(nghttp2_session *session)
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
rv = nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
|
rv = nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
|
||||||
if(rv != 0) {
|
if(nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
return NGHTTP2_ERR_IGN_PAYLOAD;
|
return NGHTTP2_ERR_IGN_PAYLOAD;
|
||||||
|
|
|
@ -555,7 +555,11 @@ void test_nghttp2_session_recv_data(void)
|
||||||
CU_ASSERT(0 == ud.data_chunk_recv_cb_called);
|
CU_ASSERT(0 == ud.data_chunk_recv_cb_called);
|
||||||
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
CU_ASSERT(0 == ud.frame_recv_cb_called);
|
||||||
item = nghttp2_session_get_next_ob_item(session);
|
item = nghttp2_session_get_next_ob_item(session);
|
||||||
CU_ASSERT(NULL == item);
|
CU_ASSERT(NGHTTP2_GOAWAY == OB_CTRL_TYPE(item));
|
||||||
|
|
||||||
|
nghttp2_session_del(session);
|
||||||
|
|
||||||
|
nghttp2_session_client_new(&session, &callbacks, &ud);
|
||||||
|
|
||||||
/* Create stream 1 with CLOSING state. DATA is ignored. */
|
/* Create stream 1 with CLOSING state. DATA is ignored. */
|
||||||
stream = nghttp2_session_open_stream(session, 1,
|
stream = nghttp2_session_open_stream(session, 1,
|
||||||
|
@ -610,7 +614,7 @@ void test_nghttp2_session_recv_data(void)
|
||||||
in the error condition. We have received 4096 * 4 bytes of
|
in the error condition. We have received 4096 * 4 bytes of
|
||||||
DATA. Additional 4 DATA frames, connection flow control will kick
|
DATA. Additional 4 DATA frames, connection flow control will kick
|
||||||
in. */
|
in. */
|
||||||
for(i = 0; i < 4; ++i) {
|
for(i = 0; i < 5; ++i) {
|
||||||
rv = nghttp2_session_mem_recv(session, data, 8+4096);
|
rv = nghttp2_session_mem_recv(session, data, 8+4096);
|
||||||
CU_ASSERT(8+4096 == rv);
|
CU_ASSERT(8+4096 == rv);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue