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
0b75800c
Commit
0b75800c
authored
Feb 01, 2012
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added SETTINGS frame and its pack/unpack functions.
parent
49096387
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
197 additions
and
0 deletions
+197
-0
lib/includes/spdylay/spdylay.h
lib/includes/spdylay/spdylay.h
+35
-0
lib/spdylay_frame.c
lib/spdylay_frame.c
+78
-0
lib/spdylay_frame.h
lib/spdylay_frame.h
+33
-0
tests/main.c
tests/main.c
+2
-0
tests/spdylay_frame_test.c
tests/spdylay_frame_test.c
+48
-0
tests/spdylay_frame_test.h
tests/spdylay_frame_test.h
+1
-0
No files found.
lib/includes/spdylay/spdylay.h
View file @
0b75800c
...
...
@@ -78,6 +78,27 @@ typedef enum {
SPDYLAY_FLAG_UNIDIRECTIONAL
=
2
}
spdylay_flag
;
typedef
enum
{
SPDYLAY_FLAG_SETTINGS_NONE
=
0
,
SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS
=
1
}
spdylay_settings_flag
;
typedef
enum
{
SPDYLAY_ID_FLAG_SETTINGS_NONE
=
0
,
SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE
=
1
,
SPDYLAY_ID_FLAG_SETTINGS_PERSISTED
=
2
}
spdylay_settings_id_flag
;
typedef
enum
{
SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH
=
1
,
SPDYLAY_SETTINGS_DOWNLOAD_BANDWIDTH
=
2
,
SPDYLAY_SETTINGS_ROUND_TRIP_TIME
=
3
,
SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS
=
4
,
SPDYLAY_SETTINGS_CURRENT_CWND
=
5
,
SPDYLAY_SETTINGS_DOWNLOAD_RETRANS_RATE
=
6
,
SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE
=
7
}
spdylay_settings_id
;
typedef
enum
{
SPDYLAY_OK
=
0
,
SPDYLAY_PROTOCOL_ERROR
=
1
,
...
...
@@ -123,6 +144,19 @@ typedef struct {
uint32_t
status_code
;
}
spdylay_rst_stream
;
typedef
struct
{
int32_t
settings_id
;
uint8_t
flags
;
uint32_t
value
;
}
spdylay_settings_entry
;
typedef
struct
{
spdylay_ctrl_hd
hd
;
/* Number of entries in |iv| */
size_t
niv
;
spdylay_settings_entry
*
iv
;
}
spdylay_settings
;
typedef
struct
{
spdylay_ctrl_hd
hd
;
uint32_t
unique_id
;
...
...
@@ -158,6 +192,7 @@ typedef union {
spdylay_syn_stream
syn_stream
;
spdylay_syn_reply
syn_reply
;
spdylay_rst_stream
rst_stream
;
spdylay_settings
settings
;
spdylay_ping
ping
;
spdylay_goaway
goaway
;
spdylay_headers
headers
;
...
...
lib/spdylay_frame.c
View file @
0b75800c
...
...
@@ -444,6 +444,23 @@ void spdylay_frame_rst_stream_init(spdylay_rst_stream *frame,
void
spdylay_frame_rst_stream_free
(
spdylay_rst_stream
*
frame
)
{}
void
spdylay_frame_settings_init
(
spdylay_settings
*
frame
,
uint8_t
flags
,
spdylay_settings_entry
*
iv
,
size_t
niv
)
{
memset
(
frame
,
0
,
sizeof
(
spdylay_settings
));
frame
->
hd
.
version
=
SPDYLAY_PROTO_VERSION
;
frame
->
hd
.
type
=
SPDYLAY_SETTINGS
;
frame
->
hd
.
flags
=
flags
;
frame
->
hd
.
length
=
4
+
niv
*
8
;
frame
->
niv
=
niv
;
frame
->
iv
=
iv
;
}
void
spdylay_frame_settings_free
(
spdylay_settings
*
frame
)
{
free
(
frame
->
iv
);
}
void
spdylay_frame_data_init
(
spdylay_data
*
frame
,
int32_t
stream_id
,
spdylay_data_provider
*
data_prd
)
{
...
...
@@ -658,3 +675,64 @@ int spdylay_frame_unpack_rst_stream(spdylay_rst_stream *frame,
frame
->
status_code
=
spdylay_get_uint32
(
payload
+
4
);
return
0
;
}
ssize_t
spdylay_frame_pack_settings
(
uint8_t
**
buf_ptr
,
spdylay_settings
*
frame
)
{
uint8_t
*
framebuf
;
ssize_t
framelen
=
SPDYLAY_FRAME_HEAD_LENGTH
+
frame
->
hd
.
length
;
int
i
;
framebuf
=
malloc
(
framelen
);
if
(
framebuf
==
NULL
)
{
return
SPDYLAY_ERR_NOMEM
;
}
memset
(
framebuf
,
0
,
framelen
);
spdylay_frame_pack_ctrl_hd
(
framebuf
,
&
frame
->
hd
);
spdylay_put_uint32be
(
&
framebuf
[
8
],
frame
->
niv
);
for
(
i
=
0
;
i
<
frame
->
niv
;
++
i
)
{
int
off
=
i
*
8
;
spdylay_put_uint32be
(
&
framebuf
[
12
+
off
],
frame
->
iv
[
i
].
settings_id
<<
8
);
framebuf
[
15
+
off
]
=
frame
->
iv
[
i
].
flags
;
spdylay_put_uint32be
(
&
framebuf
[
16
+
off
],
frame
->
iv
[
i
].
value
);
}
*
buf_ptr
=
framebuf
;
return
framelen
;
}
int
spdylay_frame_unpack_settings
(
spdylay_settings
*
frame
,
const
uint8_t
*
head
,
size_t
headlen
,
const
uint8_t
*
payload
,
size_t
payloadlen
)
{
int
i
;
if
(
payloadlen
<
4
)
{
return
SPDYLAY_ERR_INVALID_FRAME
;
}
spdylay_frame_unpack_ctrl_hd
(
&
frame
->
hd
,
head
);
frame
->
niv
=
spdylay_get_uint32
(
payload
);
if
(
payloadlen
!=
4
+
frame
->
niv
*
8
)
{
return
SPDYLAY_ERR_INVALID_FRAME
;
}
frame
->
iv
=
malloc
(
frame
->
niv
*
sizeof
(
spdylay_settings_entry
));
if
(
frame
->
iv
==
NULL
)
{
return
SPDYLAY_ERR_NOMEM
;
}
for
(
i
=
0
;
i
<
frame
->
niv
;
++
i
)
{
int
off
=
i
*
8
;
frame
->
iv
[
i
].
settings_id
=
(
spdylay_get_uint32
(
&
payload
[
4
+
off
])
>>
8
);
frame
->
iv
[
i
].
flags
=
payload
[
7
+
off
];
frame
->
iv
[
i
].
value
=
spdylay_get_uint32
(
&
payload
[
8
+
off
]);
}
return
0
;
}
spdylay_settings_entry
*
spdylay_frame_iv_copy
(
const
spdylay_settings_entry
*
iv
,
size_t
niv
)
{
spdylay_settings_entry
*
iv_copy
;
size_t
len
=
niv
*
sizeof
(
spdylay_settings_entry
);
iv_copy
=
malloc
(
len
);
if
(
iv_copy
==
NULL
)
{
return
NULL
;
}
memcpy
(
iv_copy
,
iv
,
len
);
return
iv_copy
;
}
lib/spdylay_frame.h
View file @
0b75800c
...
...
@@ -155,6 +155,22 @@ int spdylay_frame_unpack_rst_stream(spdylay_rst_stream *frame,
const
uint8_t
*
head
,
size_t
headlen
,
const
uint8_t
*
payload
,
size_t
payloadlen
);
/*
* Packs SETTINGS frame |frame| in wire format and store it in
* |*buf_ptr|. This function allocates enough memory to store given
* frame in |*buf_ptr|. This function returns the size of packed frame
* if it succeeds, or negative error code.
*/
ssize_t
spdylay_frame_pack_settings
(
uint8_t
**
buf_ptr
,
spdylay_settings
*
frame
);
/*
* Unpacks SETTINGS wire format into |frame|. This function returns 0
* if it succeeds, or negative error code.
*/
int
spdylay_frame_unpack_settings
(
spdylay_settings
*
frame
,
const
uint8_t
*
head
,
size_t
headlen
,
const
uint8_t
*
payload
,
size_t
payloadlen
);
/*
* Returns number of bytes to pack name/value pairs |nv|. This
* function expects |nv| is sorted in ascending order of key. This
...
...
@@ -212,6 +228,15 @@ void spdylay_frame_rst_stream_init(spdylay_rst_stream *frame,
void
spdylay_frame_rst_stream_free
(
spdylay_rst_stream
*
frame
);
/*
* Initializes SETTINGS frame |frame| with given values. |frame| takes
* ownership of |iv|, so caller must not free it.
*/
void
spdylay_frame_settings_init
(
spdylay_settings
*
frame
,
uint8_t
flags
,
spdylay_settings_entry
*
iv
,
size_t
niv
);
void
spdylay_frame_settings_free
(
spdylay_settings
*
frame
);
void
spdylay_frame_data_init
(
spdylay_data
*
frame
,
int32_t
stream_id
,
spdylay_data_provider
*
data_prd
);
...
...
@@ -239,4 +264,12 @@ char** spdylay_frame_nv_copy(const char **nv);
*/
void
spdylay_frame_nv_sort
(
char
**
nv
);
/*
* Makes copy of |iv| and return the copy. The |niv| is the number of
* entries in |iv|. This function returns the pointer to the copy if
* it succeeds, or NULL.
*/
spdylay_settings_entry
*
spdylay_frame_iv_copy
(
const
spdylay_settings_entry
*
iv
,
size_t
niv
);
#endif
/* SPDYLAY_FRAME_H */
tests/main.c
View file @
0b75800c
...
...
@@ -100,6 +100,8 @@ int main()
test_spdylay_frame_pack_goaway
)
||
!
CU_add_test
(
pSuite
,
"frame_pack_headers"
,
test_spdylay_frame_pack_headers
)
||
!
CU_add_test
(
pSuite
,
"frame_pack_settings"
,
test_spdylay_frame_pack_settings
)
||
!
CU_add_test
(
pSuite
,
"frame_nv_sort"
,
test_spdylay_frame_nv_sort
))
{
CU_cleanup_registry
();
return
CU_get_error
();
...
...
tests/spdylay_frame_test.c
View file @
0b75800c
...
...
@@ -125,6 +125,54 @@ void test_spdylay_frame_pack_headers()
spdylay_zlib_deflate_free
(
&
deflater
);
}
void
test_spdylay_frame_pack_settings
()
{
spdylay_frame
frame
,
oframe
;
uint8_t
*
buf
;
ssize_t
buflen
;
int
i
;
spdylay_settings_entry
iv
[
3
];
iv
[
0
].
settings_id
=
SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH
;
iv
[
0
].
flags
=
SPDYLAY_ID_FLAG_SETTINGS_PERSIST_VALUE
;
iv
[
0
].
value
=
256
;
iv
[
1
].
settings_id
=
SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS
;
iv
[
1
].
flags
=
SPDYLAY_ID_FLAG_SETTINGS_NONE
;
iv
[
1
].
value
=
100
;
iv
[
2
].
settings_id
=
SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE
;
iv
[
2
].
flags
=
SPDYLAY_ID_FLAG_SETTINGS_NONE
;
iv
[
2
].
value
=
65536
;
spdylay_frame_settings_init
(
&
frame
.
settings
,
SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS
,
spdylay_frame_iv_copy
(
iv
,
3
),
3
);
buflen
=
spdylay_frame_pack_settings
(
&
buf
,
&
frame
.
settings
);
CU_ASSERT
(
8
+
4
+
3
*
8
==
buflen
);
CU_ASSERT
(
0
==
spdylay_frame_unpack_settings
(
&
oframe
.
settings
,
&
buf
[
0
],
SPDYLAY_FRAME_HEAD_LENGTH
,
&
buf
[
SPDYLAY_FRAME_HEAD_LENGTH
],
buflen
-
SPDYLAY_FRAME_HEAD_LENGTH
));
CU_ASSERT
(
SPDYLAY_PROTO_VERSION
==
oframe
.
settings
.
hd
.
version
);
CU_ASSERT
(
SPDYLAY_SETTINGS
==
oframe
.
settings
.
hd
.
type
);
CU_ASSERT
(
SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS
==
oframe
.
settings
.
hd
.
flags
);
CU_ASSERT
(
buflen
-
SPDYLAY_FRAME_HEAD_LENGTH
==
oframe
.
settings
.
hd
.
length
);
CU_ASSERT
(
3
==
oframe
.
settings
.
niv
);
for
(
i
=
0
;
i
<
3
;
++
i
)
{
CU_ASSERT
(
iv
[
i
].
settings_id
==
oframe
.
settings
.
iv
[
i
].
settings_id
);
CU_ASSERT
(
iv
[
i
].
flags
==
oframe
.
settings
.
iv
[
i
].
flags
);
CU_ASSERT
(
iv
[
i
].
value
==
oframe
.
settings
.
iv
[
i
].
value
);
}
free
(
buf
);
spdylay_frame_settings_free
(
&
frame
.
settings
);
spdylay_frame_settings_free
(
&
oframe
.
settings
);
}
void
test_spdylay_frame_nv_sort
()
{
char
*
nv
[
7
];
...
...
tests/spdylay_frame_test.h
View file @
0b75800c
...
...
@@ -30,6 +30,7 @@ void test_spdylay_frame_count_nv_space();
void
test_spdylay_frame_pack_ping
();
void
test_spdylay_frame_pack_goaway
();
void
test_spdylay_frame_pack_headers
();
void
test_spdylay_frame_pack_settings
();
void
test_spdylay_frame_nv_sort
();
#endif
/* SPDYLAY_FRAME_TEST_H */
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