Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
ce6dc130
Commit
ce6dc130
authored
Mar 11, 2012
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue session error with PROTOCOL_ERROR if SYN_STREAM with a stream ID
which is less than any previously received SYN_STREAM.
parent
82847461
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
56 additions
and
24 deletions
+56
-24
lib/spdylay_session.c
lib/spdylay_session.c
+35
-18
tests/spdylay_session_test.c
tests/spdylay_session_test.c
+21
-6
No files found.
lib/spdylay_session.c
View file @
ce6dc130
...
...
@@ -63,6 +63,18 @@ static int spdylay_is_fatal(int error)
return
error
<
SPDYLAY_ERR_FATAL
;
}
/*
* This function should be called when the session wants to drop
* connection after sending GOAWAY. These cases are called as the
* session error. For example, when it receives bad zlib data.
*/
static
int
spdylay_session_fail_session
(
spdylay_session
*
session
,
uint32_t
status_code
)
{
session
->
goaway_flags
|=
SPDYLAY_GOAWAY_FAIL_ON_SEND
;
return
spdylay_submit_goaway
(
session
,
status_code
);
}
int
spdylay_session_is_my_stream_id
(
spdylay_session
*
session
,
int32_t
stream_id
)
{
...
...
@@ -1376,9 +1388,6 @@ static int spdylay_session_check_nv(char **nv)
static
int
spdylay_session_validate_syn_stream
(
spdylay_session
*
session
,
spdylay_syn_stream
*
frame
)
{
if
(
!
spdylay_session_is_new_peer_stream_id
(
session
,
frame
->
stream_id
))
{
return
SPDYLAY_PROTOCOL_ERROR
;
}
if
(
!
spdylay_session_check_version
(
session
,
frame
->
hd
.
version
))
{
return
SPDYLAY_UNSUPPORTED_VERSION
;
}
...
...
@@ -1443,8 +1452,29 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
/* We don't accept SYN_STREAM after GOAWAY is sent or received. */
return
0
;
}
status_code
=
spdylay_session_validate_syn_stream
(
session
,
&
frame
->
syn_stream
);
if
(
session
->
last_recv_stream_id
==
frame
->
syn_stream
.
stream_id
)
{
/* SPDY/3 spec says if an endpoint receives same stream ID twice,
it MUST issue a stream error with status code
PROTOCOL_ERROR. */
status_code
=
SPDYLAY_PROTOCOL_ERROR
;
}
else
if
(
!
spdylay_session_is_new_peer_stream_id
(
session
,
frame
->
syn_stream
.
stream_id
))
{
/* SPDY/3 spec says if an endpoint receives a SYN_STREAM with a
stream ID which is less than any previously received
SYN_STREAM, it MUST issue a session error with status
PROTOCOL_ERROR */
if
(
session
->
callbacks
.
on_invalid_ctrl_recv_callback
)
{
session
->
callbacks
.
on_invalid_ctrl_recv_callback
(
session
,
SPDYLAY_SYN_STREAM
,
frame
,
session
->
user_data
);
}
return
spdylay_session_fail_session
(
session
,
SPDYLAY_GOAWAY_PROTOCOL_ERROR
);
}
else
{
session
->
last_recv_stream_id
=
frame
->
syn_stream
.
stream_id
;
status_code
=
spdylay_session_validate_syn_stream
(
session
,
&
frame
->
syn_stream
);
}
if
(
status_code
==
0
)
{
uint8_t
flags
=
frame
->
syn_stream
.
hd
.
flags
;
if
((
flags
&
SPDYLAY_CTRL_FLAG_FIN
)
&&
...
...
@@ -1471,7 +1501,6 @@ int spdylay_session_on_syn_stream_received(spdylay_session *session,
SPDYLAY_CTRL_FLAG_UNIDIRECTIONAL is not set here. */
}
}
session
->
last_recv_stream_id
=
frame
->
syn_stream
.
stream_id
;
spdylay_session_call_on_ctrl_frame_received
(
session
,
SPDYLAY_SYN_STREAM
,
frame
);
if
(
flags
&
SPDYLAY_CTRL_FLAG_FIN
)
{
...
...
@@ -1749,18 +1778,6 @@ int spdylay_session_on_headers_received(spdylay_session *session,
return
r
;
}
/*
* This function should be called when the session wants to drop
* connection after sending GOAWAY. These cases are called as the
* session error. For example, when it receives bad zlib data.
*/
static
int
spdylay_session_fail_session
(
spdylay_session
*
session
,
uint32_t
status_code
)
{
session
->
goaway_flags
|=
SPDYLAY_GOAWAY_FAIL_ON_SEND
;
return
spdylay_submit_goaway
(
session
,
status_code
);
}
/* For errors, this function only returns FATAL error. */
static
int
spdylay_session_process_ctrl_frame
(
spdylay_session
*
session
)
{
...
...
tests/spdylay_session_test.c
View file @
ce6dc130
...
...
@@ -377,25 +377,40 @@ void test_spdylay_session_on_syn_stream_received()
CU_ASSERT
(
SPDYLAY_STREAM_OPENING
==
stream
->
state
);
CU_ASSERT
(
pri
==
stream
->
pri
);
/* Same stream ID twice leads stream closing */
/* Same stream ID twice leads stream error */
user_data
.
invalid_ctrl_recv_cb_called
=
0
;
CU_ASSERT
(
0
==
spdylay_session_on_syn_stream_received
(
session
,
&
frame
));
CU_ASSERT
(
1
==
user_data
.
invalid_ctrl_recv_cb_called
);
CU_ASSERT
(
SPDYLAY_STREAM_CLOSING
==
spdylay_session_get_stream
(
session
,
stream_id
)
->
state
);
CU_ASSERT
(
SPDYLAY_STREAM_CLOSING
==
stream
->
state
);
/* assoc_stream_id != 0 from client is invalid. */
frame
.
syn_stream
.
stream_id
=
3
;
frame
.
syn_stream
.
assoc_stream_id
=
1
;
user_data
.
invalid_ctrl_recv_cb_called
=
0
;
CU_ASSERT
(
0
==
spdylay_session_on_syn_stream_received
(
session
,
&
frame
));
CU_ASSERT
(
2
==
user_data
.
invalid_ctrl_recv_cb_called
);
CU_ASSERT
(
1
==
user_data
.
invalid_ctrl_recv_cb_called
);
spdylay_frame_syn_stream_free
(
&
frame
.
syn_stream
);
/* Upper cased name/value pairs */
spdylay_frame_syn_stream_init
(
&
frame
.
syn_stream
,
SPDYLAY_PROTO_SPDY2
,
SPDYLAY_CTRL_FLAG_NONE
,
3
,
0
,
3
,
dup_nv
(
upcase_nv
));
5
,
0
,
3
,
dup_nv
(
upcase_nv
));
user_data
.
invalid_ctrl_recv_cb_called
=
0
;
CU_ASSERT
(
0
==
spdylay_session_on_syn_stream_received
(
session
,
&
frame
));
CU_ASSERT
(
3
==
user_data
.
invalid_ctrl_recv_cb_called
);
CU_ASSERT
(
1
==
user_data
.
invalid_ctrl_recv_cb_called
);
spdylay_frame_syn_stream_free
(
&
frame
.
syn_stream
);
/* Stream ID less than previouly received SYN_STREAM leads session
error */
spdylay_frame_syn_stream_init
(
&
frame
.
syn_stream
,
SPDYLAY_PROTO_SPDY2
,
SPDYLAY_CTRL_FLAG_NONE
,
3
,
0
,
3
,
dup_nv
(
nv
));
user_data
.
invalid_ctrl_recv_cb_called
=
0
;
CU_ASSERT
(
0
==
spdylay_session_on_syn_stream_received
(
session
,
&
frame
));
CU_ASSERT
(
1
==
user_data
.
invalid_ctrl_recv_cb_called
);
CU_ASSERT
(
session
->
goaway_flags
&
SPDYLAY_GOAWAY_FAIL_ON_SEND
);
spdylay_frame_syn_stream_free
(
&
frame
.
syn_stream
);
spdylay_session_del
(
session
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment