spdylay_submit_syn_stream: Return SPDYLAY_ERR_INVALID_ARGUMENT if even
Associated-To-Stream-ID is specified. Check the Associated-To-Stream is active before sending SYN_STREAM.
This commit is contained in:
parent
bee873712a
commit
8284746163
|
@ -663,7 +663,8 @@ void* spdylay_session_get_stream_user_data(spdylay_session *session,
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
*
|
*
|
||||||
* SPDYLAY_ERR_INVALID_ARGUMENT
|
* SPDYLAY_ERR_INVALID_ARGUMENT
|
||||||
* |pri| is invalid.
|
* The |pri| is invalid; or the Associated-To-Stream-ID is
|
||||||
|
* invalid.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
@ -722,14 +723,15 @@ int spdylay_submit_response(spdylay_session *session,
|
||||||
* data which is associated to the stream this frame will open.
|
* data which is associated to the stream this frame will open.
|
||||||
*
|
*
|
||||||
* This function is low-level in a sense that the application code can
|
* This function is low-level in a sense that the application code can
|
||||||
* specify flags and assoc-stream-ID directly. For usual HTTP request,
|
* specify flags and the Associated-To-Stream-ID directly. For usual
|
||||||
* spdylay_submit_request() is useful.
|
* HTTP request, spdylay_submit_request() is useful.
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
*
|
*
|
||||||
* SPDYLAY_ERR_INVALID_ARGUMENT
|
* SPDYLAY_ERR_INVALID_ARGUMENT
|
||||||
* |pri| is invalid.
|
* The |pri| is invalid; or the Associated-To-Stream-ID is
|
||||||
|
* invalid.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -478,6 +478,45 @@ static int spdylay_predicate_stream_for_send(spdylay_stream *stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function checks SYN_STREAM frame |frame| can be sent at this
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* SPDYLAY_ERR_STREAM_CLOSED
|
||||||
|
* The Associated-To-Stream is already closed or does not exist.
|
||||||
|
* SPDYLAY_ERR_STREAM_ID_NOT_AVAILABLE
|
||||||
|
* Stream ID has reached maximum value. Therefore no stream ID is
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
static int spdylay_session_predicate_syn_stream_send
|
||||||
|
(spdylay_session *session,
|
||||||
|
spdylay_syn_stream *frame)
|
||||||
|
{
|
||||||
|
if(session->goaway_flags) {
|
||||||
|
/* When GOAWAY is sent or received, peer must not send new
|
||||||
|
SYN_STREAM. */
|
||||||
|
return SPDYLAY_ERR_SYN_STREAM_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
/* All 32bit signed stream IDs are spent. */
|
||||||
|
if(session->next_stream_id > INT32_MAX) {
|
||||||
|
return SPDYLAY_ERR_STREAM_ID_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
if(frame->assoc_stream_id != 0) {
|
||||||
|
/* Check associated stream is active. */
|
||||||
|
/* We assume here that if frame->assoc_stream_id != 0,
|
||||||
|
session->server is always 1 and frame->assoc_stream_id is
|
||||||
|
odd. */
|
||||||
|
if(spdylay_session_get_stream(session, frame->assoc_stream_id) ==
|
||||||
|
NULL) {
|
||||||
|
return SPDYLAY_ERR_STREAM_CLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function checks SYN_REPLY with the stream ID |stream_id| can
|
* This function checks SYN_REPLY with the stream ID |stream_id| can
|
||||||
* be sent at this time.
|
* be sent at this time.
|
||||||
|
@ -673,21 +712,16 @@ static int spdylay_session_predicate_data_send(spdylay_session *session,
|
||||||
static ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
static ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
spdylay_outbound_item *item)
|
spdylay_outbound_item *item)
|
||||||
{
|
{
|
||||||
/* TODO Get or validate stream ID here */
|
|
||||||
/* TODO Validate assoc_stream_id here */
|
|
||||||
ssize_t framebuflen;
|
ssize_t framebuflen;
|
||||||
switch(item->frame_type) {
|
switch(item->frame_type) {
|
||||||
case SPDYLAY_SYN_STREAM: {
|
case SPDYLAY_SYN_STREAM: {
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
spdylay_syn_stream_aux_data *aux_data;
|
spdylay_syn_stream_aux_data *aux_data;
|
||||||
if(session->goaway_flags) {
|
int r;
|
||||||
/* When GOAWAY is sent or received, peer must not send new
|
r = spdylay_session_predicate_syn_stream_send(session,
|
||||||
SYN_STREAM. */
|
&item->frame->syn_stream);
|
||||||
return SPDYLAY_ERR_SYN_STREAM_NOT_ALLOWED;
|
if(r != 0) {
|
||||||
}
|
return r;
|
||||||
/* All 32bit signed stream IDs are spent. */
|
|
||||||
if(session->next_stream_id > INT32_MAX) {
|
|
||||||
return SPDYLAY_ERR_STREAM_ID_NOT_AVAILABLE;
|
|
||||||
}
|
}
|
||||||
stream_id = session->next_stream_id;
|
stream_id = session->next_stream_id;
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,12 @@ static int spdylay_submit_syn_stream_shared
|
||||||
if(pri > spdylay_session_get_pri_lowest(session)) {
|
if(pri > spdylay_session_get_pri_lowest(session)) {
|
||||||
return SPDYLAY_ERR_INVALID_ARGUMENT;
|
return SPDYLAY_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
if(assoc_stream_id != 0) {
|
||||||
if(session->server == 0) {
|
if(session->server == 0) {
|
||||||
assoc_stream_id = 0;
|
assoc_stream_id = 0;
|
||||||
|
} else if(spdylay_session_is_my_stream_id(session, assoc_stream_id)) {
|
||||||
|
return SPDYLAY_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(data_prd != NULL && data_prd->read_callback != NULL) {
|
if(data_prd != NULL && data_prd->read_callback != NULL) {
|
||||||
data_prd_copy = malloc(sizeof(spdylay_data_provider));
|
data_prd_copy = malloc(sizeof(spdylay_data_provider));
|
||||||
|
|
|
@ -730,6 +730,11 @@ void test_spdylay_submit_syn_stream()
|
||||||
CU_ASSERT(1 == item->frame->syn_stream.assoc_stream_id);
|
CU_ASSERT(1 == item->frame->syn_stream.assoc_stream_id);
|
||||||
CU_ASSERT(3 == item->frame->syn_stream.pri);
|
CU_ASSERT(3 == item->frame->syn_stream.pri);
|
||||||
|
|
||||||
|
/* Invalid assoc-stream-ID */
|
||||||
|
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
|
||||||
|
spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_FIN, 2, 3,
|
||||||
|
nv, NULL));
|
||||||
|
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1738,9 +1743,21 @@ void test_spdylay_session_on_ctrl_not_send()
|
||||||
stream = spdylay_session_open_stream(session, 1,
|
stream = spdylay_session_open_stream(session, 1,
|
||||||
SPDYLAY_CTRL_FLAG_NONE,
|
SPDYLAY_CTRL_FLAG_NONE,
|
||||||
3, SPDYLAY_STREAM_OPENED, &user_data);
|
3, SPDYLAY_STREAM_OPENED, &user_data);
|
||||||
|
/* Check SYN_STREAM */
|
||||||
|
CU_ASSERT(0 == spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_FIN, 3, 3,
|
||||||
|
nv, NULL));
|
||||||
|
|
||||||
|
user_data.ctrl_not_send_cb_called = 0;
|
||||||
|
/* Associated stream closed */
|
||||||
|
CU_ASSERT(0 == spdylay_session_send(session));
|
||||||
|
CU_ASSERT(1 == user_data.ctrl_not_send_cb_called);
|
||||||
|
CU_ASSERT(SPDYLAY_SYN_STREAM == user_data.not_sent_frame_type);
|
||||||
|
CU_ASSERT(SPDYLAY_ERR_STREAM_CLOSED == user_data.not_sent_error);
|
||||||
|
|
||||||
/* Check SYN_REPLY */
|
/* Check SYN_REPLY */
|
||||||
CU_ASSERT(0 ==
|
CU_ASSERT(0 ==
|
||||||
spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_FIN, 1, nv));
|
spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_FIN, 1, nv));
|
||||||
|
user_data.ctrl_not_send_cb_called = 0;
|
||||||
CU_ASSERT(0 == spdylay_session_send(session));
|
CU_ASSERT(0 == spdylay_session_send(session));
|
||||||
CU_ASSERT(1 == user_data.ctrl_not_send_cb_called);
|
CU_ASSERT(1 == user_data.ctrl_not_send_cb_called);
|
||||||
CU_ASSERT(SPDYLAY_SYN_REPLY == user_data.not_sent_frame_type);
|
CU_ASSERT(SPDYLAY_SYN_REPLY == user_data.not_sent_frame_type);
|
||||||
|
|
Loading…
Reference in New Issue