Add nghttp2_session_handle_invalid_connction to simply code

This commit is contained in:
Tatsuhiro Tsujikawa 2013-07-21 18:20:23 +09:00
parent 3e72fb84f4
commit d96da77412
1 changed files with 36 additions and 52 deletions

View File

@ -1381,6 +1381,21 @@ static int nghttp2_session_handle_invalid_stream
return 0; return 0;
} }
/*
* Handles invalid frame which causes connection error.
*/
static int nghttp2_session_handle_invalid_connection
(nghttp2_session *session,
nghttp2_frame *frame,
nghttp2_error_code error_code)
{
if(session->callbacks.on_invalid_frame_recv_callback) {
session->callbacks.on_invalid_frame_recv_callback
(session, frame, error_code, session->user_data);
}
return nghttp2_session_fail_session(session, error_code);
}
int nghttp2_session_on_syn_stream_received(nghttp2_session *session, int nghttp2_session_on_syn_stream_received(nghttp2_session *session,
nghttp2_frame *frame) nghttp2_frame *frame)
{ {
@ -1390,16 +1405,12 @@ int nghttp2_session_on_syn_stream_received(nghttp2_session *session,
/* We don't accept new stream after GOAWAY is sent or received. */ /* We don't accept new stream after GOAWAY is sent or received. */
return 0; return 0;
} }
if(!nghttp2_session_is_new_peer_stream_id if(!nghttp2_session_is_new_peer_stream_id(session, frame->hd.stream_id)) {
(session, frame->hd.stream_id)) {
/* The spec says if an endpoint receives a HEADERS with invalid /* The spec says if an endpoint receives a HEADERS with invalid
stream ID, it MUST issue connection error with error code stream ID, it MUST issue connection error with error code
PROTOCOL_ERROR */ PROTOCOL_ERROR */
if(session->callbacks.on_invalid_frame_recv_callback) { return nghttp2_session_handle_invalid_connection
session->callbacks.on_invalid_frame_recv_callback (session, frame, NGHTTP2_PROTOCOL_ERROR);
(session, frame, NGHTTP2_PROTOCOL_ERROR, session->user_data);
}
return nghttp2_session_fail_session(session, NGHTTP2_PROTOCOL_ERROR);
} else { } else {
session->last_recv_stream_id = frame->hd.stream_id; session->last_recv_stream_id = frame->hd.stream_id;
error_code = nghttp2_session_validate_syn_stream(session, &frame->headers); error_code = nghttp2_session_validate_syn_stream(session, &frame->headers);
@ -1439,34 +1450,18 @@ int nghttp2_session_on_syn_reply_received(nghttp2_session *session,
nghttp2_error_code error_code = NGHTTP2_PROTOCOL_ERROR; nghttp2_error_code error_code = NGHTTP2_PROTOCOL_ERROR;
if((stream->shut_flags & NGHTTP2_SHUT_RD) == 0) { if((stream->shut_flags & NGHTTP2_SHUT_RD) == 0) {
if(nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { if(nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
if(stream->state == NGHTTP2_STREAM_OPENING) { /* This function is only called if stream->state ==
valid = 1; NGHTTP2_STREAM_OPENING. If server push is implemented, it may
stream->state = NGHTTP2_STREAM_OPENED; be called on reserved state. */
nghttp2_session_call_on_frame_received(session, frame); assert(stream->state == NGHTTP2_STREAM_OPENING);
if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { valid = 1;
/* This is the last frame of this stream, so disallow stream->state = NGHTTP2_STREAM_OPENED;
further receptions. */ nghttp2_session_call_on_frame_received(session, frame);
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
nghttp2_session_close_stream_if_shut_rdwr(session, stream); /* This is the last frame of this stream, so disallow
} further receptions. */
} else if(stream->state == NGHTTP2_STREAM_CLOSING) { nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
/* This is race condition. NGHTTP2_STREAM_CLOSING indicates nghttp2_session_close_stream_if_shut_rdwr(session, stream);
that we queued RST_STREAM but it has not been sent. It will
eventually sent, so we just ignore this frame. */
valid = 1;
} else {
/* It seems that the spec does not say what to do if multiple
HEADERS for the same active stream ID are receives. The
SPDY/3 spec says it should be treated as stream error with
error code STREAM_IN_USE. The spec does not such code
anymore. It would be safer to reject those broken client at
the moment. Do you accept the web server which responds
with multiple response headers? */
if(session->callbacks.on_invalid_frame_recv_callback) {
session->callbacks.on_invalid_frame_recv_callback
(session, frame, NGHTTP2_PROTOCOL_ERROR, session->user_data);
}
return nghttp2_session_fail_session(session, NGHTTP2_PROTOCOL_ERROR);
} }
} }
} else { } else {
@ -1675,11 +1670,8 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
return rv; return rv;
} }
} else { } else {
if(session->callbacks.on_invalid_frame_recv_callback) { return nghttp2_session_handle_invalid_connection
session->callbacks.on_invalid_frame_recv_callback (session, frame, NGHTTP2_PROTOCOL_ERROR);
(session, frame, NGHTTP2_PROTOCOL_ERROR, session->user_data);
}
return nghttp2_session_fail_session(session, NGHTTP2_PROTOCOL_ERROR);
} }
break; break;
case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS: case NGHTTP2_SETTINGS_FLOW_CONTROL_OPTIONS:
@ -1693,12 +1685,8 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
} else if(session->remote_settings[entry->settings_id] == 1) { } else if(session->remote_settings[entry->settings_id] == 1) {
/* Re-enabling flow control is subject to connection-level /* Re-enabling flow control is subject to connection-level
error(?) */ error(?) */
if(session->callbacks.on_invalid_frame_recv_callback) { return nghttp2_session_handle_invalid_connection
session->callbacks.on_invalid_frame_recv_callback (session, frame, NGHTTP2_FLOW_CONTROL_ERROR);
(session, frame, NGHTTP2_PROTOCOL_ERROR, session->user_data);
}
return nghttp2_session_fail_session(session,
NGHTTP2_FLOW_CONTROL_ERROR);
} }
break; break;
} }
@ -1791,12 +1779,8 @@ int nghttp2_session_on_window_update_received(nghttp2_session *session,
} }
if(INT32_MAX - frame->window_update.window_size_increment < if(INT32_MAX - frame->window_update.window_size_increment <
session->window_size) { session->window_size) {
if(session->callbacks.on_invalid_frame_recv_callback) { return nghttp2_session_handle_invalid_connection
session->callbacks.on_invalid_frame_recv_callback (session, frame, NGHTTP2_FLOW_CONTROL_ERROR);
(session, frame, NGHTTP2_FLOW_CONTROL_ERROR, session->user_data);
}
return nghttp2_session_fail_session
(session, NGHTTP2_FLOW_CONTROL_ERROR);
} }
session->window_size += frame->window_update.window_size_increment; session->window_size += frame->window_update.window_size_increment;
nghttp2_session_call_on_frame_received(session, frame); nghttp2_session_call_on_frame_received(session, frame);