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
|
||||
* 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);
|
||||
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;
|
||||
}
|
||||
if(state_reserved_remote(session, stream)) {
|
||||
|
@ -2430,10 +2450,19 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
|
|||
nghttp2_frame *frame)
|
||||
{
|
||||
int rv;
|
||||
nghttp2_stream *stream;
|
||||
if(frame->hd.stream_id == 0) {
|
||||
return nghttp2_session_handle_invalid_connection(session, frame,
|
||||
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);
|
||||
if(rv != 0) {
|
||||
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);
|
||||
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
|
||||
(session, frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_REFUSED_STREAM);
|
||||
|
@ -3062,6 +3097,10 @@ static int session_on_stream_window_update_received
|
|||
nghttp2_stream *stream;
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
if(!stream) {
|
||||
if(session_detect_idle_stream(session, stream_id)) {
|
||||
goto fail;
|
||||
}
|
||||
return NGHTTP2_ERR_IGN_PAYLOAD;
|
||||
}
|
||||
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;
|
||||
fail:
|
||||
rv = nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
|
||||
if(rv != 0) {
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
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.frame_recv_cb_called);
|
||||
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. */
|
||||
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
|
||||
DATA. Additional 4 DATA frames, connection flow control will kick
|
||||
in. */
|
||||
for(i = 0; i < 4; ++i) {
|
||||
for(i = 0; i < 5; ++i) {
|
||||
rv = nghttp2_session_mem_recv(session, data, 8+4096);
|
||||
CU_ASSERT(8+4096 == rv);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue