Commit 08ff95d4 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

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.
parent 2402b46c
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment