Added SPDY/3 SETTINGS frame pack/unpack

This commit is contained in:
Tatsuhiro Tsujikawa 2012-03-08 23:49:26 +09:00
parent 643238813d
commit d05d29b507
5 changed files with 73 additions and 28 deletions

View File

@ -901,6 +901,10 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
{ {
ssize_t framelen = SPDYLAY_FRAME_HEAD_LENGTH+frame->hd.length; ssize_t framelen = SPDYLAY_FRAME_HEAD_LENGTH+frame->hd.length;
int i, r; int i, r;
if(frame->hd.version != SPDYLAY_PROTO_SPDY2 &&
frame->hd.version != SPDYLAY_PROTO_SPDY3) {
return SPDYLAY_ERR_UNSUPPORTED_VERSION;
}
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen); r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
if(r != 0) { if(r != 0) {
return r; return r;
@ -908,6 +912,7 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
memset(*buf_ptr, 0, framelen); memset(*buf_ptr, 0, framelen);
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd); spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
spdylay_put_uint32be(&(*buf_ptr)[8], frame->niv); spdylay_put_uint32be(&(*buf_ptr)[8], frame->niv);
if(frame->hd.version == SPDYLAY_PROTO_SPDY2) {
for(i = 0; i < frame->niv; ++i) { for(i = 0; i < frame->niv; ++i) {
int off = i*8; int off = i*8;
/* spdy/2 spec says ID is network byte order, but publicly /* spdy/2 spec says ID is network byte order, but publicly
@ -923,6 +928,14 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
(*buf_ptr)[15+off] = frame->iv[i].flags; (*buf_ptr)[15+off] = frame->iv[i].flags;
spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value); spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value);
} }
} else {
for(i = 0; i < frame->niv; ++i) {
int off = i*8;
spdylay_put_uint32be(&(*buf_ptr)[12+off], frame->iv[i].settings_id);
(*buf_ptr)[12+off] = frame->iv[i].flags;
spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value);
}
}
return framelen; return framelen;
} }
@ -935,6 +948,10 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
return SPDYLAY_ERR_INVALID_FRAME; return SPDYLAY_ERR_INVALID_FRAME;
} }
spdylay_frame_unpack_ctrl_hd(&frame->hd, head); spdylay_frame_unpack_ctrl_hd(&frame->hd, head);
if(frame->hd.version != SPDYLAY_PROTO_SPDY2 &&
frame->hd.version != SPDYLAY_PROTO_SPDY3) {
return SPDYLAY_ERR_UNSUPPORTED_VERSION;
}
frame->niv = spdylay_get_uint32(payload); frame->niv = spdylay_get_uint32(payload);
if(payloadlen != 4+frame->niv*8) { if(payloadlen != 4+frame->niv*8) {
return SPDYLAY_ERR_INVALID_FRAME; return SPDYLAY_ERR_INVALID_FRAME;
@ -943,6 +960,7 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
if(frame->iv == NULL) { if(frame->iv == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
} }
if(frame->hd.version == SPDYLAY_PROTO_SPDY2) {
for(i = 0; i < frame->niv; ++i) { for(i = 0; i < frame->niv; ++i) {
int off = i*8; int off = i*8;
/* ID is little endian. See comments in /* ID is little endian. See comments in
@ -958,6 +976,15 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
frame->iv[i].flags = payload[7+off]; frame->iv[i].flags = payload[7+off];
frame->iv[i].value = spdylay_get_uint32(&payload[8+off]); frame->iv[i].value = spdylay_get_uint32(&payload[8+off]);
} }
} else {
for(i = 0; i < frame->niv; ++i) {
int off = i*8;
frame->iv[i].settings_id = spdylay_get_uint32(&payload[4+off]) &
SPDYLAY_SETTINGS_ID_MASK;
frame->iv[i].flags = payload[4+off];
frame->iv[i].value = spdylay_get_uint32(&payload[8+off]);
}
}
return 0; return 0;
} }

View File

@ -37,6 +37,7 @@
#define SPDYLAY_LENGTH_MASK 0xffffff #define SPDYLAY_LENGTH_MASK 0xffffff
#define SPDYLAY_VERSION_MASK 0x7fff #define SPDYLAY_VERSION_MASK 0x7fff
#define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff #define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff
#define SPDYLAY_SETTINGS_ID_MASK 0xffffff
/* The length of DATA frame payload. */ /* The length of DATA frame payload. */
#define SPDYLAY_DATA_PAYLOAD_LENGTH 4096 #define SPDYLAY_DATA_PAYLOAD_LENGTH 4096
@ -353,6 +354,8 @@ int spdylay_frame_unpack_window_update(spdylay_window_update *frame,
* This function returns the size of packed frame if it succeeds, or * This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes: * returns one of the following negative error codes:
* *
* SPDYLAY_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* SPDYLAY_ERR_NOMEM * SPDYLAY_ERR_NOMEM
* Out of memory. * Out of memory.
*/ */
@ -365,6 +368,8 @@ ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
* 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_UNSUPPORTED_VERSION
* The version is not supported.
* SPDYLAY_ERR_INVALID_FRAME * SPDYLAY_ERR_INVALID_FRAME
* The input data are invalid. * The input data are invalid.
* SPDYLAY_ERR_NOMEM * SPDYLAY_ERR_NOMEM

View File

@ -165,8 +165,10 @@ int main(int argc, char* argv[])
test_spdylay_frame_pack_headers_spdy3) || test_spdylay_frame_pack_headers_spdy3) ||
!CU_add_test(pSuite, "frame_pack_window_update", !CU_add_test(pSuite, "frame_pack_window_update",
test_spdylay_frame_pack_window_update) || test_spdylay_frame_pack_window_update) ||
!CU_add_test(pSuite, "frame_pack_settings", !CU_add_test(pSuite, "frame_pack_settings_spdy2",
test_spdylay_frame_pack_settings) || test_spdylay_frame_pack_settings_spdy2) ||
!CU_add_test(pSuite, "frame_pack_settings_spdy3",
test_spdylay_frame_pack_settings_spdy3) ||
!CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort) || !CU_add_test(pSuite, "frame_nv_sort", test_spdylay_frame_nv_sort) ||
!CU_add_test(pSuite, "frame_nv_downcase", !CU_add_test(pSuite, "frame_nv_downcase",
test_spdylay_frame_nv_downcase) || test_spdylay_frame_nv_downcase) ||

View File

@ -442,7 +442,7 @@ void test_spdylay_frame_pack_window_update()
} }
void test_spdylay_frame_pack_settings() void test_spdylay_frame_pack_settings_version(uint16_t version)
{ {
spdylay_frame frame, oframe; spdylay_frame frame, oframe;
uint8_t *buf = NULL; uint8_t *buf = NULL;
@ -461,7 +461,7 @@ void test_spdylay_frame_pack_settings()
iv[2].value = 65536; iv[2].value = 65536;
spdylay_frame_settings_init spdylay_frame_settings_init
(&frame.settings, SPDYLAY_PROTO_SPDY2, (&frame.settings, version,
SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS, SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS,
spdylay_frame_iv_copy(iv, 3), 3); spdylay_frame_iv_copy(iv, 3), 3);
framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings); framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings);
@ -473,7 +473,7 @@ void test_spdylay_frame_pack_settings()
&buf[SPDYLAY_FRAME_HEAD_LENGTH], &buf[SPDYLAY_FRAME_HEAD_LENGTH],
framelen-SPDYLAY_FRAME_HEAD_LENGTH)); framelen-SPDYLAY_FRAME_HEAD_LENGTH));
CU_ASSERT(SPDYLAY_PROTO_SPDY2 == oframe.settings.hd.version); CU_ASSERT(version == oframe.settings.hd.version);
CU_ASSERT(SPDYLAY_SETTINGS == oframe.settings.hd.type); CU_ASSERT(SPDYLAY_SETTINGS == oframe.settings.hd.type);
CU_ASSERT(SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS == CU_ASSERT(SPDYLAY_FLAG_SETTINGS_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS ==
oframe.settings.hd.flags); oframe.settings.hd.flags);
@ -491,6 +491,16 @@ void test_spdylay_frame_pack_settings()
spdylay_frame_settings_free(&oframe.settings); spdylay_frame_settings_free(&oframe.settings);
} }
void test_spdylay_frame_pack_settings_spdy2()
{
test_spdylay_frame_pack_settings_version(SPDYLAY_PROTO_SPDY2);
}
void test_spdylay_frame_pack_settings_spdy3()
{
test_spdylay_frame_pack_settings_version(SPDYLAY_PROTO_SPDY3);
}
void test_spdylay_frame_nv_sort() void test_spdylay_frame_nv_sort()
{ {
char *nv[7]; char *nv[7];

View File

@ -40,7 +40,8 @@ void test_spdylay_frame_pack_syn_reply_spdy3();
void test_spdylay_frame_pack_headers_spdy2(); void test_spdylay_frame_pack_headers_spdy2();
void test_spdylay_frame_pack_headers_spdy3(); void test_spdylay_frame_pack_headers_spdy3();
void test_spdylay_frame_pack_window_update(); void test_spdylay_frame_pack_window_update();
void test_spdylay_frame_pack_settings(); void test_spdylay_frame_pack_settings_spdy2();
void test_spdylay_frame_pack_settings_spdy3();
void test_spdylay_frame_nv_sort(); void test_spdylay_frame_nv_sort();
void test_spdylay_frame_nv_downcase(); void test_spdylay_frame_nv_downcase();
void test_spdylay_frame_nv_2to3(); void test_spdylay_frame_nv_2to3();