Reuse buffers when packing frames.
Temporal name/value buffer will be shared by unpacking frame.
This commit is contained in:
parent
e4ad446261
commit
050f33e8f9
|
@ -63,27 +63,35 @@ static void spdylay_frame_unpack_ctrl_hd(spdylay_ctrl_hd *hd,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t spdylay_frame_alloc_pack_nv(uint8_t **buf_ptr,
|
static ssize_t spdylay_frame_alloc_pack_nv(uint8_t **buf_ptr,
|
||||||
|
size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr,
|
||||||
|
size_t *nvbuflen_ptr,
|
||||||
char **nv, size_t nv_offset,
|
char **nv, size_t nv_offset,
|
||||||
spdylay_zlib *deflater)
|
spdylay_zlib *deflater)
|
||||||
{
|
{
|
||||||
size_t nvbuflen = spdylay_frame_count_nv_space(nv);
|
size_t nvspace;
|
||||||
uint8_t *nvbuf = malloc(nvbuflen);
|
size_t maxframelen;
|
||||||
size_t maxframelen = nv_offset+
|
|
||||||
spdylay_zlib_deflate_hd_bound(deflater, nvbuflen);
|
|
||||||
uint8_t *framebuf = malloc(maxframelen);
|
|
||||||
ssize_t framelen;
|
ssize_t framelen;
|
||||||
spdylay_frame_pack_nv(nvbuf, nv);
|
int r;
|
||||||
|
nvspace = spdylay_frame_count_nv_space(nv);
|
||||||
|
r = spdylay_reserve_buffer(nvbuf_ptr, nvbuflen_ptr, nvspace);
|
||||||
|
if(r != 0) {
|
||||||
|
return SPDYLAY_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
maxframelen = nv_offset+spdylay_zlib_deflate_hd_bound(deflater, nvspace);
|
||||||
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, maxframelen);
|
||||||
|
if(r != 0) {
|
||||||
|
return SPDYLAY_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
spdylay_frame_pack_nv(*nvbuf_ptr, nv);
|
||||||
framelen = spdylay_zlib_deflate_hd(deflater,
|
framelen = spdylay_zlib_deflate_hd(deflater,
|
||||||
framebuf+nv_offset,
|
(*buf_ptr)+nv_offset,
|
||||||
maxframelen-nv_offset,
|
maxframelen-nv_offset,
|
||||||
nvbuf, nvbuflen);
|
*nvbuf_ptr, nvspace);
|
||||||
free(nvbuf);
|
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
free(framebuf);
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
framelen += nv_offset;
|
framelen += nv_offset;
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,26 +459,28 @@ void spdylay_frame_data_free(spdylay_data *frame)
|
||||||
#define SPDYLAY_SYN_STREAM_NV_OFFSET 18
|
#define SPDYLAY_SYN_STREAM_NV_OFFSET 18
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
|
||||||
|
size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr,
|
||||||
|
size_t *nvbuflen_ptr,
|
||||||
spdylay_syn_stream *frame,
|
spdylay_syn_stream *frame,
|
||||||
spdylay_zlib *deflater)
|
spdylay_zlib *deflater)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf = NULL;
|
|
||||||
ssize_t framelen;
|
ssize_t framelen;
|
||||||
framelen = spdylay_frame_alloc_pack_nv(&framebuf, frame->nv,
|
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
||||||
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
|
frame->nv,
|
||||||
SPDYLAY_SYN_STREAM_NV_OFFSET,
|
SPDYLAY_SYN_STREAM_NV_OFFSET,
|
||||||
deflater);
|
deflater);
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
|
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
|
||||||
memset(framebuf, 0, SPDYLAY_SYN_STREAM_NV_OFFSET);
|
memset(*buf_ptr, 0, SPDYLAY_SYN_STREAM_NV_OFFSET);
|
||||||
/* pack ctrl header after length is determined */
|
/* pack ctrl header after length is determined */
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->stream_id);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id);
|
||||||
spdylay_put_uint32be(&framebuf[12], frame->assoc_stream_id);
|
spdylay_put_uint32be(&(*buf_ptr)[12], frame->assoc_stream_id);
|
||||||
framebuf[16] = (frame->pri << 6);
|
(*buf_ptr)[16] = (frame->pri << 6);
|
||||||
|
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,21 +506,24 @@ int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame,
|
||||||
#define SPDYLAY_SYN_REPLY_NV_OFFSET 14
|
#define SPDYLAY_SYN_REPLY_NV_OFFSET 14
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
|
||||||
|
size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr,
|
||||||
|
size_t *nvbuflen_ptr,
|
||||||
spdylay_syn_reply *frame,
|
spdylay_syn_reply *frame,
|
||||||
spdylay_zlib *deflater)
|
spdylay_zlib *deflater)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf = NULL;
|
|
||||||
ssize_t framelen;
|
ssize_t framelen;
|
||||||
framelen = spdylay_frame_alloc_pack_nv(&framebuf, frame->nv,
|
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
||||||
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
|
frame->nv,
|
||||||
SPDYLAY_SYN_REPLY_NV_OFFSET, deflater);
|
SPDYLAY_SYN_REPLY_NV_OFFSET, deflater);
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
|
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
|
||||||
memset(framebuf, 0, SPDYLAY_SYN_REPLY_NV_OFFSET);
|
memset(*buf_ptr, 0, SPDYLAY_SYN_REPLY_NV_OFFSET);
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->stream_id);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id);
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,18 +543,18 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_ping(uint8_t **buf_ptr, spdylay_ping *frame)
|
ssize_t spdylay_frame_pack_ping(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_ping *frame)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf = NULL;
|
|
||||||
ssize_t framelen = 12;
|
ssize_t framelen = 12;
|
||||||
framebuf = malloc(framelen);
|
int r;
|
||||||
if(framebuf == NULL) {
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||||
return SPDYLAY_ERR_NOMEM;
|
if(r != 0) {
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
memset(framebuf, 0, framelen);
|
memset(*buf_ptr, 0, framelen);
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->unique_id);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->unique_id);
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,18 +570,18 @@ int spdylay_frame_unpack_ping(spdylay_ping *frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, spdylay_goaway *frame)
|
ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_goaway *frame)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf = NULL;
|
|
||||||
ssize_t framelen = 12;
|
ssize_t framelen = 12;
|
||||||
framebuf = malloc(framelen);
|
int r;
|
||||||
if(framebuf == NULL) {
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||||
return SPDYLAY_ERR_NOMEM;
|
if(r != 0) {
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
memset(framebuf, 0, framelen);
|
memset(*buf_ptr, 0, framelen);
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->last_good_stream_id);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->last_good_stream_id);
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,22 +600,23 @@ int spdylay_frame_unpack_goaway(spdylay_goaway *frame,
|
||||||
|
|
||||||
#define SPDYLAY_HEADERS_NV_OFFSET 14
|
#define SPDYLAY_HEADERS_NV_OFFSET 14
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr, size_t *nvbuflen_ptr,
|
||||||
spdylay_headers *frame,
|
spdylay_headers *frame,
|
||||||
spdylay_zlib *deflater)
|
spdylay_zlib *deflater)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf = NULL;
|
|
||||||
ssize_t framelen;
|
ssize_t framelen;
|
||||||
framelen = spdylay_frame_alloc_pack_nv(&framebuf, frame->nv,
|
framelen = spdylay_frame_alloc_pack_nv(buf_ptr, buflen_ptr,
|
||||||
|
nvbuf_ptr, nvbuflen_ptr,
|
||||||
|
frame->nv,
|
||||||
SPDYLAY_HEADERS_NV_OFFSET, deflater);
|
SPDYLAY_HEADERS_NV_OFFSET, deflater);
|
||||||
if(framelen < 0) {
|
if(framelen < 0) {
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
|
frame->hd.length = framelen-SPDYLAY_FRAME_HEAD_LENGTH;
|
||||||
memset(framebuf, 0, SPDYLAY_HEADERS_NV_OFFSET);
|
memset(*buf_ptr, 0, SPDYLAY_HEADERS_NV_OFFSET);
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->stream_id);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id);
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,20 +636,19 @@ int spdylay_frame_unpack_headers(spdylay_headers *frame,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_rst_stream(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_rst_stream(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
spdylay_rst_stream *frame)
|
spdylay_rst_stream *frame)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf;
|
|
||||||
ssize_t framelen = 16;
|
ssize_t framelen = 16;
|
||||||
framebuf = malloc(framelen);
|
int r;
|
||||||
if(framebuf == NULL) {
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||||
return SPDYLAY_ERR_NOMEM;
|
if(r != 0) {
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
memset(framebuf, 0, framelen);
|
memset(*buf_ptr, 0, framelen);
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->stream_id);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->stream_id);
|
||||||
spdylay_put_uint32be(&framebuf[12], frame->status_code);
|
spdylay_put_uint32be(&(*buf_ptr)[12], frame->status_code);
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,34 +665,33 @@ int spdylay_frame_unpack_rst_stream(spdylay_rst_stream *frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, spdylay_settings *frame)
|
ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_settings *frame)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf;
|
|
||||||
ssize_t framelen = SPDYLAY_FRAME_HEAD_LENGTH+frame->hd.length;
|
ssize_t framelen = SPDYLAY_FRAME_HEAD_LENGTH+frame->hd.length;
|
||||||
int i;
|
int i, r;
|
||||||
framebuf = malloc(framelen);
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||||
if(framebuf == NULL) {
|
if(r != 0) {
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return r;
|
||||||
}
|
}
|
||||||
memset(framebuf, 0, framelen);
|
memset(*buf_ptr, 0, framelen);
|
||||||
spdylay_frame_pack_ctrl_hd(framebuf, &frame->hd);
|
spdylay_frame_pack_ctrl_hd(*buf_ptr, &frame->hd);
|
||||||
spdylay_put_uint32be(&framebuf[8], frame->niv);
|
spdylay_put_uint32be(&(*buf_ptr)[8], frame->niv);
|
||||||
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
|
||||||
deployed server sends little endian host byte order. */
|
deployed server sends little endian host byte order. */
|
||||||
char *id_ptr = (char*)(&frame->iv[i].settings_id);
|
char *id_ptr = (char*)(&frame->iv[i].settings_id);
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
framebuf[12+off] = id_ptr[3];
|
(*buf_ptr)[12+off] = id_ptr[3];
|
||||||
framebuf[12+off+1] = id_ptr[2];
|
(*buf_ptr)[12+off+1] = id_ptr[2];
|
||||||
framebuf[12+off+2] = id_ptr[1];
|
(*buf_ptr)[12+off+2] = id_ptr[1];
|
||||||
#else /* !WORDS_BIGENDIAN */
|
#else /* !WORDS_BIGENDIAN */
|
||||||
memcpy(&framebuf[12+off], id_ptr, 3);
|
memcpy(&(*buf_ptr)[12+off], id_ptr, 3);
|
||||||
#endif /* !WORDS_BIGENDIAN */
|
#endif /* !WORDS_BIGENDIAN */
|
||||||
framebuf[15+off] = frame->iv[i].flags;
|
(*buf_ptr)[15+off] = frame->iv[i].flags;
|
||||||
spdylay_put_uint32be(&framebuf[16+off], frame->iv[i].value);
|
spdylay_put_uint32be(&(*buf_ptr)[16+off], frame->iv[i].value);
|
||||||
}
|
}
|
||||||
*buf_ptr = framebuf;
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,25 @@
|
||||||
#define SPDYLAY_FRAME_HEAD_LENGTH 8
|
#define SPDYLAY_FRAME_HEAD_LENGTH 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs SYN_STREAM frame |frame| in wire frame format and store it in
|
* Packs SYN_STREAM frame |frame| in wire format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory to store given
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr| bytes.
|
||||||
* frame in |*buf_ptr|. This function returns the size of packed
|
* The |*nvbuf_ptr| is used to store inflated name/value pairs in wire
|
||||||
* frame if it succeeds, or returns negative error
|
* format temporarily. Its length is |*nvbuflen_ptr| bytes. This
|
||||||
|
* function expands |*buf_ptr| and |*nvbuf_ptr| as necessary to store
|
||||||
|
* frame and name/value pairs. When expansion occurred, memory
|
||||||
|
* previously pointed by |*buf_ptr| and |*nvbuf_ptr| is freed.
|
||||||
|
* |*buf_ptr|, |*buflen_ptr|, |*nvbuf_ptr| and |*nvbuflen_ptr| are
|
||||||
|
* updated accordingly.
|
||||||
|
*
|
||||||
|
* This function returns the size of
|
||||||
|
* packed frame if it succeeds, or returns negative error
|
||||||
* code. frame->hd.length is assigned after length is determined
|
* code. frame->hd.length is assigned after length is determined
|
||||||
* during packing process.
|
* during packing process.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_syn_stream(uint8_t **buf_ptr,
|
||||||
|
size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr,
|
||||||
|
size_t *nvbuflen_ptr,
|
||||||
spdylay_syn_stream *frame,
|
spdylay_syn_stream *frame,
|
||||||
spdylay_zlib *deflater);
|
spdylay_zlib *deflater);
|
||||||
|
|
||||||
|
@ -68,12 +79,22 @@ int spdylay_frame_unpack_syn_stream(spdylay_syn_stream *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs SYN_REPLY frame |frame| in wire frame format and store it in
|
* Packs SYN_REPLY frame |frame| in wire frame format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory to store given
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr| bytes.
|
||||||
* frame in |*buf_ptr|. This function returns the size of packed frame
|
* The |*nvbuf_ptr| is used to store inflated name/value pairs in wire
|
||||||
* it it succeeds, or returns negative error code. frame->hd.length is
|
* format temporarily. Its length is |*nvbuflen_ptr| bytes. This
|
||||||
* assigned after length is determined during packing process.
|
* function expands |*buf_ptr| and |*nvbuf_ptr| as necessary to store
|
||||||
|
* frame and name/value pairs. When expansion occurred, memory
|
||||||
|
* previously pointed by |*buf_ptr| and |*nvbuf_ptr| is freed.
|
||||||
|
* |*buf_ptr|, |*buflen_ptr|, |*nvbuf_ptr| and |*nvbuflen_ptr| are
|
||||||
|
* updated accordingly. This function returns the size of packed
|
||||||
|
* frame it it succeeds, or returns negative error
|
||||||
|
* code. frame->hd.length is assigned after length is determined
|
||||||
|
* during packing process.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_syn_reply(uint8_t **buf_ptr,
|
||||||
|
size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr,
|
||||||
|
size_t *nvbuflen_ptr,
|
||||||
spdylay_syn_reply *frame,
|
spdylay_syn_reply *frame,
|
||||||
spdylay_zlib *deflater);
|
spdylay_zlib *deflater);
|
||||||
|
|
||||||
|
@ -88,11 +109,13 @@ int spdylay_frame_unpack_syn_reply(spdylay_syn_reply *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs PING frame |frame| in wire format and store it in
|
* Packs PING frame |frame| in wire format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory in |*buf_ptr| to
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||||
* store given |frame|. This function returns the size of packed frame
|
* length. This function expands |*buf_ptr| as necessary to store
|
||||||
* if it succeeds, or negative error code.
|
* given |frame|. This function returns the size of packed frame if it
|
||||||
|
* succeeds, or negative error code.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_ping(uint8_t **buf_ptr, spdylay_ping *frame);
|
ssize_t spdylay_frame_pack_ping(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_ping *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpacks PING wire format into |frame|. This function returns 0 if
|
* Unpacks PING wire format into |frame|. This function returns 0 if
|
||||||
|
@ -104,11 +127,13 @@ int spdylay_frame_unpack_ping(spdylay_ping *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs GOAWAY frame |frame | in wire format and store it in
|
* Packs GOAWAY frame |frame | in wire format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory in |*buf_ptr| to
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||||
* store given |frame|. This function returns the size of packed frame
|
* length. This function expands |*buf_ptr| as necessary to store
|
||||||
* if it succeeds, or negative error code.
|
* given |frame|. This function returns the size of packed frame if it
|
||||||
|
* succeeds, or negative error code.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, spdylay_goaway *frame);
|
ssize_t spdylay_frame_pack_goaway(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_goaway *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpacks GOAWAY wire format into |frame|. This function returns 0 if
|
* Unpacks GOAWAY wire format into |frame|. This function returns 0 if
|
||||||
|
@ -120,12 +145,20 @@ int spdylay_frame_unpack_goaway(spdylay_goaway *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs HEADERS frame |frame| in wire format and store it in
|
* Packs HEADERS frame |frame| in wire format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory in |*buf_ptr| to
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr| bytes.
|
||||||
* store given |frame|. This function returns the size of packed frame
|
* The |*nvbuf_ptr| is used to store inflated name/value pairs in wire
|
||||||
* it it succeeds, or returns negative error code. frame->hd.length is
|
* format temporarily. Its length is |*nvbuflen_ptr| bytes. This
|
||||||
* assigned after length is determined during packing process.
|
* function expands |*buf_ptr| and |*nvbuf_ptr| as necessary to store
|
||||||
|
* frame and name/value pairs. When expansion occurred, memory
|
||||||
|
* previously pointed by |*buf_ptr| and |*nvbuf_ptr| is freed.
|
||||||
|
* |*buf_ptr|, |*buflen_ptr|, |*nvbuf_ptr| and |*nvbuflen_ptr| are
|
||||||
|
* updated accordingly. This function returns the size of packed
|
||||||
|
* frame it it succeeds, or returns negative error
|
||||||
|
* code. frame->hd.length is assigned after length is determined
|
||||||
|
* during packing process.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
uint8_t **nvbuf_ptr, size_t *nvbuflen_ptr,
|
||||||
spdylay_headers *frame,
|
spdylay_headers *frame,
|
||||||
spdylay_zlib *deflater);
|
spdylay_zlib *deflater);
|
||||||
|
|
||||||
|
@ -140,12 +173,13 @@ int spdylay_frame_unpack_headers(spdylay_headers *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs RST_STREAM frame |frame| in wire frame format and store it in
|
* Packs RST_STREAM frame |frame| in wire frame format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory to store given
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||||
* frame in |*buf_ptr|. In spdy/2 spc, RST_STREAM wire format is
|
* length. This function expands |*buf_ptr| as necessary to store
|
||||||
* always 16 bytes long. This function returns the size of packed
|
* given |frame|. In spdy/2 spc, RST_STREAM wire format is always 16
|
||||||
* frame if it succeeds, or negative error code.
|
* bytes long. This function returns the size of packed frame if it
|
||||||
|
* succeeds, or negative error code.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_frame_pack_rst_stream(uint8_t **buf_ptr,
|
ssize_t spdylay_frame_pack_rst_stream(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
spdylay_rst_stream *frame);
|
spdylay_rst_stream *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -158,11 +192,13 @@ int spdylay_frame_unpack_rst_stream(spdylay_rst_stream *frame,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs SETTINGS frame |frame| in wire format and store it in
|
* Packs SETTINGS frame |frame| in wire format and store it in
|
||||||
* |*buf_ptr|. This function allocates enough memory to store given
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||||
* frame in |*buf_ptr|. This function returns the size of packed frame
|
* length. This function expands |*buf_ptr| as necessary to store
|
||||||
* if it succeeds, or negative error code.
|
* given |frame|. 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);
|
ssize_t spdylay_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_settings *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpacks SETTINGS wire format into |frame|. This function returns 0
|
* Unpacks SETTINGS wire format into |frame|. This function returns 0
|
||||||
|
|
|
@ -52,3 +52,19 @@ uint32_t spdylay_get_uint32(const uint8_t *data)
|
||||||
memcpy(&n, data, sizeof(uint32_t));
|
memcpy(&n, data, sizeof(uint32_t));
|
||||||
return ntohl(n);
|
return ntohl(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spdylay_reserve_buffer(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
size_t min_length)
|
||||||
|
{
|
||||||
|
if(min_length > *buflen_ptr) {
|
||||||
|
uint8_t *temp = malloc(min_length);
|
||||||
|
if(temp == NULL) {
|
||||||
|
return SPDYLAY_ERR_NOMEM;
|
||||||
|
} else {
|
||||||
|
free(*buf_ptr);
|
||||||
|
*buf_ptr = temp;
|
||||||
|
*buflen_ptr = min_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -55,4 +55,18 @@ uint16_t spdylay_get_uint16(const uint8_t *data);
|
||||||
*/
|
*/
|
||||||
uint32_t spdylay_get_uint32(const uint8_t *data);
|
uint32_t spdylay_get_uint32(const uint8_t *data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensures that buffer |*buf_ptr| with |*buflen_ptr| length has at
|
||||||
|
* least |min_length| bytes. If |min_length| > |*buflen_ptr|,
|
||||||
|
* allocates new buffer having at least |min_length| bytes and assigns
|
||||||
|
* its pointer to |*buf_ptr| and allocated number of bytes to
|
||||||
|
* |*buflen_ptr|. The memory pointed by |*buf_ptr| previously is
|
||||||
|
* freed. No memory copy is done between old and new buffer. This
|
||||||
|
* function returns 0 if it succeeds, or negative error code.
|
||||||
|
* |*buf_ptr| and |*buflen_ptr| are only updated iff this function
|
||||||
|
* succeeds.
|
||||||
|
*/
|
||||||
|
int spdylay_reserve_buffer(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
size_t min_length);
|
||||||
|
|
||||||
#endif /* SPDYLAY_HELPER_H */
|
#endif /* SPDYLAY_HELPER_H */
|
||||||
|
|
|
@ -130,6 +130,31 @@ static int spdylay_session_new(spdylay_session **session_ptr,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*session_ptr)->aob.framebuf = malloc(SPDYLAY_INITIAL_OUTBOUND_BUFFER_LENGTH);
|
||||||
|
if((*session_ptr)->aob.framebuf == NULL) {
|
||||||
|
spdylay_pq_free(&(*session_ptr)->ob_ss_pq);
|
||||||
|
spdylay_pq_free(&(*session_ptr)->ob_pq);
|
||||||
|
spdylay_map_free(&(*session_ptr)->streams);
|
||||||
|
spdylay_zlib_inflate_free(&(*session_ptr)->hd_inflater);
|
||||||
|
spdylay_zlib_deflate_free(&(*session_ptr)->hd_deflater);
|
||||||
|
free(*session_ptr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
(*session_ptr)->aob.framebufmax = SPDYLAY_INITIAL_OUTBOUND_BUFFER_LENGTH;
|
||||||
|
|
||||||
|
(*session_ptr)->nvbuf = malloc(SPDYLAY_INITIAL_NV_BUFFER_LENGTH);
|
||||||
|
if((*session_ptr)->nvbuf == NULL) {
|
||||||
|
free((*session_ptr)->aob.framebuf);
|
||||||
|
spdylay_pq_free(&(*session_ptr)->ob_ss_pq);
|
||||||
|
spdylay_pq_free(&(*session_ptr)->ob_pq);
|
||||||
|
spdylay_map_free(&(*session_ptr)->streams);
|
||||||
|
spdylay_zlib_inflate_free(&(*session_ptr)->hd_inflater);
|
||||||
|
spdylay_zlib_deflate_free(&(*session_ptr)->hd_deflater);
|
||||||
|
free(*session_ptr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
(*session_ptr)->nvbuflen = SPDYLAY_INITIAL_NV_BUFFER_LENGTH;
|
||||||
|
|
||||||
memset((*session_ptr)->settings, 0, sizeof((*session_ptr)->settings));
|
memset((*session_ptr)->settings, 0, sizeof((*session_ptr)->settings));
|
||||||
(*session_ptr)->settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] =
|
(*session_ptr)->settings[SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS] =
|
||||||
SPDYLAY_CONCURRENT_STREAMS_MAX;
|
SPDYLAY_CONCURRENT_STREAMS_MAX;
|
||||||
|
@ -244,6 +269,8 @@ void spdylay_session_del(spdylay_session *session)
|
||||||
spdylay_zlib_deflate_free(&session->hd_deflater);
|
spdylay_zlib_deflate_free(&session->hd_deflater);
|
||||||
spdylay_zlib_inflate_free(&session->hd_inflater);
|
spdylay_zlib_inflate_free(&session->hd_inflater);
|
||||||
free(session->iframe.buf);
|
free(session->iframe.buf);
|
||||||
|
free(session->aob.framebuf);
|
||||||
|
free(session->nvbuf);
|
||||||
free(session);
|
free(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,12 +481,10 @@ static int spdylay_session_is_data_allowed(spdylay_session *session,
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
spdylay_outbound_item *item,
|
spdylay_outbound_item *item)
|
||||||
uint8_t **framebuf_ptr)
|
|
||||||
{
|
{
|
||||||
/* TODO Get or validate stream ID here */
|
/* TODO Get or validate stream ID here */
|
||||||
/* TODO Validate assoc_stream_id here */
|
/* TODO Validate assoc_stream_id here */
|
||||||
uint8_t *framebuf;
|
|
||||||
ssize_t framebuflen;
|
ssize_t framebuflen;
|
||||||
switch(item->frame_type) {
|
switch(item->frame_type) {
|
||||||
case SPDYLAY_SYN_STREAM: {
|
case SPDYLAY_SYN_STREAM: {
|
||||||
|
@ -473,7 +498,10 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
stream_id = session->next_stream_id;
|
stream_id = session->next_stream_id;
|
||||||
item->frame->syn_stream.stream_id = stream_id;
|
item->frame->syn_stream.stream_id = stream_id;
|
||||||
session->next_stream_id += 2;
|
session->next_stream_id += 2;
|
||||||
framebuflen = spdylay_frame_pack_syn_stream(&framebuf,
|
framebuflen = spdylay_frame_pack_syn_stream(&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
|
&session->nvbuf,
|
||||||
|
&session->nvbuflen,
|
||||||
&item->frame->syn_stream,
|
&item->frame->syn_stream,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
|
@ -485,7 +513,6 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
item->frame->syn_stream.pri,
|
item->frame->syn_stream.pri,
|
||||||
SPDYLAY_STREAM_INITIAL,
|
SPDYLAY_STREAM_INITIAL,
|
||||||
aux_data->stream_user_data) == NULL) {
|
aux_data->stream_user_data) == NULL) {
|
||||||
free(framebuf);
|
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -495,7 +522,10 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
item->frame->syn_reply.stream_id)) {
|
item->frame->syn_reply.stream_id)) {
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
framebuflen = spdylay_frame_pack_syn_reply(&framebuf,
|
framebuflen = spdylay_frame_pack_syn_reply(&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
|
&session->nvbuf,
|
||||||
|
&session->nvbuflen,
|
||||||
&item->frame->syn_reply,
|
&item->frame->syn_reply,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
|
@ -504,14 +534,16 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPDYLAY_RST_STREAM:
|
case SPDYLAY_RST_STREAM:
|
||||||
framebuflen = spdylay_frame_pack_rst_stream(&framebuf,
|
framebuflen = spdylay_frame_pack_rst_stream(&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
&item->frame->rst_stream);
|
&item->frame->rst_stream);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPDYLAY_SETTINGS:
|
case SPDYLAY_SETTINGS:
|
||||||
framebuflen = spdylay_frame_pack_settings(&framebuf,
|
framebuflen = spdylay_frame_pack_settings(&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
&item->frame->settings);
|
&item->frame->settings);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
|
@ -522,7 +554,9 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
unreachable. */
|
unreachable. */
|
||||||
abort();
|
abort();
|
||||||
case SPDYLAY_PING:
|
case SPDYLAY_PING:
|
||||||
framebuflen = spdylay_frame_pack_ping(&framebuf, &item->frame->ping);
|
framebuflen = spdylay_frame_pack_ping(&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
|
&item->frame->ping);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +573,9 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
last-good-stream-id. */
|
last-good-stream-id. */
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
framebuflen = spdylay_frame_pack_goaway(&framebuf, &item->frame->goaway);
|
framebuflen = spdylay_frame_pack_goaway(&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
|
&item->frame->goaway);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +584,9 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
if(!spdylay_session_is_data_allowed(session, item->frame->data.stream_id)) {
|
if(!spdylay_session_is_data_allowed(session, item->frame->data.stream_id)) {
|
||||||
return SPDYLAY_ERR_INVALID_FRAME;
|
return SPDYLAY_ERR_INVALID_FRAME;
|
||||||
}
|
}
|
||||||
framebuflen = spdylay_session_pack_data(session, &framebuf,
|
framebuflen = spdylay_session_pack_data(session,
|
||||||
|
&session->aob.framebuf,
|
||||||
|
&session->aob.framebufmax,
|
||||||
&item->frame->data);
|
&item->frame->data);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
|
@ -558,7 +596,6 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
default:
|
default:
|
||||||
framebuflen = SPDYLAY_ERR_INVALID_ARGUMENT;
|
framebuflen = SPDYLAY_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
*framebuf_ptr = framebuf;
|
|
||||||
return framebuflen;
|
return framebuflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,8 +604,8 @@ static void spdylay_active_outbound_item_reset
|
||||||
{
|
{
|
||||||
spdylay_outbound_item_free(aob->item);
|
spdylay_outbound_item_free(aob->item);
|
||||||
free(aob->item);
|
free(aob->item);
|
||||||
free(aob->framebuf);
|
aob->item = NULL;
|
||||||
memset(aob, 0, sizeof(spdylay_active_outbound_item));
|
aob->framebuflen = aob->framebufoff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdylay_outbound_item* spdylay_session_get_ob_pq_top
|
spdylay_outbound_item* spdylay_session_get_ob_pq_top
|
||||||
|
@ -815,13 +852,12 @@ int spdylay_session_send(spdylay_session *session)
|
||||||
ssize_t sentlen;
|
ssize_t sentlen;
|
||||||
if(session->aob.item == NULL) {
|
if(session->aob.item == NULL) {
|
||||||
spdylay_outbound_item *item;
|
spdylay_outbound_item *item;
|
||||||
uint8_t *framebuf;
|
|
||||||
ssize_t framebuflen;
|
ssize_t framebuflen;
|
||||||
item = spdylay_session_pop_next_ob_item(session);
|
item = spdylay_session_pop_next_ob_item(session);
|
||||||
if(item == NULL) {
|
if(item == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
framebuflen = spdylay_session_prep_frame(session, item, &framebuf);
|
framebuflen = spdylay_session_prep_frame(session, item);
|
||||||
if(framebuflen < 0) {
|
if(framebuflen < 0) {
|
||||||
/* TODO Call error callback? */
|
/* TODO Call error callback? */
|
||||||
spdylay_outbound_item_free(item);
|
spdylay_outbound_item_free(item);
|
||||||
|
@ -833,7 +869,6 @@ int spdylay_session_send(spdylay_session *session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session->aob.item = item;
|
session->aob.item = item;
|
||||||
session->aob.framebuf = framebuf;
|
|
||||||
session->aob.framebuflen = framebuflen;
|
session->aob.framebuflen = framebuflen;
|
||||||
/* Call before_send callback */
|
/* Call before_send callback */
|
||||||
if(item->frame_type != SPDYLAY_DATA &&
|
if(item->frame_type != SPDYLAY_DATA &&
|
||||||
|
@ -1582,21 +1617,17 @@ int spdylay_session_add_goaway(spdylay_session *session,
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t spdylay_session_pack_data(spdylay_session *session,
|
ssize_t spdylay_session_pack_data(spdylay_session *session,
|
||||||
uint8_t **buf_ptr, spdylay_data *frame)
|
uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_data *frame)
|
||||||
{
|
{
|
||||||
uint8_t *framebuf;
|
|
||||||
ssize_t framelen = SPDYLAY_DATA_FRAME_LENGTH;
|
ssize_t framelen = SPDYLAY_DATA_FRAME_LENGTH;
|
||||||
framebuf = malloc(framelen);
|
int r;
|
||||||
if(framebuf == NULL) {
|
r = spdylay_reserve_buffer(buf_ptr, buflen_ptr, framelen);
|
||||||
return SPDYLAY_ERR_NOMEM;
|
if(r != 0) {
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
framelen = spdylay_session_pack_data_overwrite(session, framebuf, framelen,
|
framelen = spdylay_session_pack_data_overwrite(session, *buf_ptr, framelen,
|
||||||
frame);
|
frame);
|
||||||
if(framelen < 0) {
|
|
||||||
free(framebuf);
|
|
||||||
} else {
|
|
||||||
*buf_ptr = framebuf;
|
|
||||||
}
|
|
||||||
return framelen;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,16 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spdylay_outbound_item *item;
|
spdylay_outbound_item *item;
|
||||||
|
/* Buffer for outbound frames. Used to pack one frame. The memory
|
||||||
|
pointed by framebuf is initially allocated by
|
||||||
|
spdylay_session_{client,server}_new() and deallocated by
|
||||||
|
spdylay_session_del() */
|
||||||
uint8_t *framebuf;
|
uint8_t *framebuf;
|
||||||
|
/* The capacity of framebuf in bytes */
|
||||||
|
size_t framebufmax;
|
||||||
|
/* The length of the frame stored in framebuf */
|
||||||
size_t framebuflen;
|
size_t framebuflen;
|
||||||
|
/* The number of bytes has been sent */
|
||||||
size_t framebufoff;
|
size_t framebufoff;
|
||||||
} spdylay_active_outbound_item;
|
} spdylay_active_outbound_item;
|
||||||
|
|
||||||
|
@ -55,6 +63,9 @@ typedef struct {
|
||||||
message block of SSLv3/TLSv1 */
|
message block of SSLv3/TLSv1 */
|
||||||
#define SPDYLAY_INBOUND_BUFFER_LENGTH 16384
|
#define SPDYLAY_INBOUND_BUFFER_LENGTH 16384
|
||||||
|
|
||||||
|
#define SPDYLAY_INITIAL_OUTBOUND_BUFFER_LENGTH SPDYLAY_DATA_FRAME_LENGTH
|
||||||
|
#define SPDYLAY_INITIAL_NV_BUFFER_LENGTH 4096
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t buf[SPDYLAY_INBOUND_BUFFER_LENGTH];
|
uint8_t buf[SPDYLAY_INBOUND_BUFFER_LENGTH];
|
||||||
uint8_t *mark;
|
uint8_t *mark;
|
||||||
|
@ -114,6 +125,12 @@ struct spdylay_session {
|
||||||
spdylay_inbound_buffer ibuf;
|
spdylay_inbound_buffer ibuf;
|
||||||
spdylay_inbound_frame iframe;
|
spdylay_inbound_frame iframe;
|
||||||
|
|
||||||
|
/* Buffer used to store inflated name/value pairs in wire format
|
||||||
|
temporarily on pack/unpack. */
|
||||||
|
uint8_t *nvbuf;
|
||||||
|
/* The number of bytes allocated for nvbuf */
|
||||||
|
size_t nvbuflen;
|
||||||
|
|
||||||
spdylay_zlib hd_deflater;
|
spdylay_zlib hd_deflater;
|
||||||
spdylay_zlib hd_inflater;
|
spdylay_zlib hd_inflater;
|
||||||
|
|
||||||
|
@ -274,14 +291,15 @@ spdylay_stream* spdylay_session_get_stream(spdylay_session *session,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs DATA frame |frame| in wire frame format and store it in
|
* Packs DATA frame |frame| in wire frame format and store it in
|
||||||
* |*buf_ptr|. This function always allocates
|
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
|
||||||
* 8+SPDYLAY_DATA_CHUNK_LENGTH bytes. It packs header in first 8
|
* length. This function expands |*buf_ptr| as necessary to store
|
||||||
* bytes. Remaining bytes are filled using frame->data_prd. This
|
* given |frame|. It packs header in first 8 bytes. Remaining bytes
|
||||||
* function returns the size of packed frame if it succeeds, or
|
* are filled using frame->data_prd. This function returns the size
|
||||||
* negative error code.
|
* of packed frame if it succeeds, or negative error code.
|
||||||
*/
|
*/
|
||||||
ssize_t spdylay_session_pack_data(spdylay_session *session,
|
ssize_t spdylay_session_pack_data(spdylay_session *session,
|
||||||
uint8_t **buf_ptr, spdylay_data *frame);
|
uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
spdylay_data *frame);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packs DATA frame |frame| in wire frame format and store it in
|
* Packs DATA frame |frame| in wire frame format and store it in
|
||||||
|
|
|
@ -95,15 +95,16 @@ void test_spdylay_frame_count_unpack_nv_space()
|
||||||
void test_spdylay_frame_pack_ping()
|
void test_spdylay_frame_pack_ping()
|
||||||
{
|
{
|
||||||
spdylay_frame frame, oframe;
|
spdylay_frame frame, oframe;
|
||||||
uint8_t *buf;
|
uint8_t *buf = NULL;
|
||||||
ssize_t buflen;
|
size_t buflen = 0;
|
||||||
|
ssize_t framelen;
|
||||||
spdylay_frame_ping_init(&frame.ping, 1);
|
spdylay_frame_ping_init(&frame.ping, 1);
|
||||||
buflen = spdylay_frame_pack_ping(&buf, &frame.ping);
|
framelen = spdylay_frame_pack_ping(&buf, &buflen, &frame.ping);
|
||||||
CU_ASSERT(0 == spdylay_frame_unpack_ping
|
CU_ASSERT(0 == spdylay_frame_unpack_ping
|
||||||
(&oframe.ping,
|
(&oframe.ping,
|
||||||
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
||||||
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
||||||
buflen-SPDYLAY_FRAME_HEAD_LENGTH));
|
framelen-SPDYLAY_FRAME_HEAD_LENGTH));
|
||||||
CU_ASSERT(1 == oframe.ping.unique_id);
|
CU_ASSERT(1 == oframe.ping.unique_id);
|
||||||
free(buf);
|
free(buf);
|
||||||
spdylay_frame_ping_free(&oframe.ping);
|
spdylay_frame_ping_free(&oframe.ping);
|
||||||
|
@ -113,20 +114,21 @@ void test_spdylay_frame_pack_ping()
|
||||||
void test_spdylay_frame_pack_goaway()
|
void test_spdylay_frame_pack_goaway()
|
||||||
{
|
{
|
||||||
spdylay_frame frame, oframe;
|
spdylay_frame frame, oframe;
|
||||||
uint8_t *buf;
|
uint8_t *buf = NULL;
|
||||||
ssize_t buflen;
|
size_t buflen = 0;
|
||||||
|
ssize_t framelen;
|
||||||
spdylay_frame_goaway_init(&frame.goaway, 1000000007);
|
spdylay_frame_goaway_init(&frame.goaway, 1000000007);
|
||||||
buflen = spdylay_frame_pack_goaway(&buf, &frame.goaway);
|
framelen = spdylay_frame_pack_goaway(&buf, &buflen, &frame.goaway);
|
||||||
CU_ASSERT(0 == spdylay_frame_unpack_goaway
|
CU_ASSERT(0 == spdylay_frame_unpack_goaway
|
||||||
(&oframe.goaway,
|
(&oframe.goaway,
|
||||||
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
||||||
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
||||||
buflen-SPDYLAY_FRAME_HEAD_LENGTH));
|
framelen-SPDYLAY_FRAME_HEAD_LENGTH));
|
||||||
CU_ASSERT(1000000007 == oframe.goaway.last_good_stream_id);
|
CU_ASSERT(1000000007 == oframe.goaway.last_good_stream_id);
|
||||||
CU_ASSERT(SPDYLAY_PROTO_VERSION == oframe.headers.hd.version);
|
CU_ASSERT(SPDYLAY_PROTO_VERSION == oframe.headers.hd.version);
|
||||||
CU_ASSERT(SPDYLAY_GOAWAY == oframe.headers.hd.type);
|
CU_ASSERT(SPDYLAY_GOAWAY == oframe.headers.hd.type);
|
||||||
CU_ASSERT(SPDYLAY_FLAG_NONE == oframe.headers.hd.flags);
|
CU_ASSERT(SPDYLAY_FLAG_NONE == oframe.headers.hd.flags);
|
||||||
CU_ASSERT(buflen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length);
|
CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length);
|
||||||
free(buf);
|
free(buf);
|
||||||
spdylay_frame_goaway_free(&oframe.goaway);
|
spdylay_frame_goaway_free(&oframe.goaway);
|
||||||
spdylay_frame_goaway_free(&frame.goaway);
|
spdylay_frame_goaway_free(&frame.goaway);
|
||||||
|
@ -136,28 +138,32 @@ void test_spdylay_frame_pack_headers()
|
||||||
{
|
{
|
||||||
spdylay_zlib deflater, inflater;
|
spdylay_zlib deflater, inflater;
|
||||||
spdylay_frame frame, oframe;
|
spdylay_frame frame, oframe;
|
||||||
uint8_t *buf;
|
uint8_t *buf = NULL, *nvbuf = NULL;
|
||||||
ssize_t buflen;
|
size_t buflen = 0, nvbuflen = 0;
|
||||||
|
ssize_t framelen;
|
||||||
spdylay_zlib_deflate_hd_init(&deflater);
|
spdylay_zlib_deflate_hd_init(&deflater);
|
||||||
spdylay_zlib_inflate_hd_init(&inflater);
|
spdylay_zlib_inflate_hd_init(&inflater);
|
||||||
spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_FIN, 3,
|
spdylay_frame_headers_init(&frame.headers, SPDYLAY_FLAG_FIN, 3,
|
||||||
spdylay_frame_nv_copy(headers));
|
spdylay_frame_nv_copy(headers));
|
||||||
buflen = spdylay_frame_pack_headers(&buf, &frame.headers, &deflater);
|
framelen = spdylay_frame_pack_headers(&buf, &buflen,
|
||||||
|
&nvbuf, &nvbuflen,
|
||||||
|
&frame.headers, &deflater);
|
||||||
CU_ASSERT(0 == spdylay_frame_unpack_headers
|
CU_ASSERT(0 == spdylay_frame_unpack_headers
|
||||||
(&oframe.headers,
|
(&oframe.headers,
|
||||||
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
||||||
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
||||||
buflen-SPDYLAY_FRAME_HEAD_LENGTH,
|
framelen-SPDYLAY_FRAME_HEAD_LENGTH,
|
||||||
&inflater));
|
&inflater));
|
||||||
CU_ASSERT(3 == oframe.headers.stream_id);
|
CU_ASSERT(3 == oframe.headers.stream_id);
|
||||||
CU_ASSERT(SPDYLAY_PROTO_VERSION == oframe.headers.hd.version);
|
CU_ASSERT(SPDYLAY_PROTO_VERSION == oframe.headers.hd.version);
|
||||||
CU_ASSERT(SPDYLAY_HEADERS == oframe.headers.hd.type);
|
CU_ASSERT(SPDYLAY_HEADERS == oframe.headers.hd.type);
|
||||||
CU_ASSERT(SPDYLAY_FLAG_FIN == oframe.headers.hd.flags);
|
CU_ASSERT(SPDYLAY_FLAG_FIN == oframe.headers.hd.flags);
|
||||||
CU_ASSERT(buflen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length);
|
CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.ping.hd.length);
|
||||||
CU_ASSERT(strcmp("method", oframe.headers.nv[0]) == 0);
|
CU_ASSERT(strcmp("method", oframe.headers.nv[0]) == 0);
|
||||||
CU_ASSERT(strcmp("GET", oframe.headers.nv[1]) == 0);
|
CU_ASSERT(strcmp("GET", oframe.headers.nv[1]) == 0);
|
||||||
CU_ASSERT(NULL == oframe.headers.nv[12]);
|
CU_ASSERT(NULL == oframe.headers.nv[12]);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
free(nvbuf);
|
||||||
spdylay_frame_headers_free(&oframe.headers);
|
spdylay_frame_headers_free(&oframe.headers);
|
||||||
spdylay_frame_headers_free(&frame.headers);
|
spdylay_frame_headers_free(&frame.headers);
|
||||||
spdylay_zlib_inflate_free(&inflater);
|
spdylay_zlib_inflate_free(&inflater);
|
||||||
|
@ -167,8 +173,9 @@ void test_spdylay_frame_pack_headers()
|
||||||
void test_spdylay_frame_pack_settings()
|
void test_spdylay_frame_pack_settings()
|
||||||
{
|
{
|
||||||
spdylay_frame frame, oframe;
|
spdylay_frame frame, oframe;
|
||||||
uint8_t *buf;
|
uint8_t *buf = NULL;
|
||||||
ssize_t buflen;
|
size_t buflen = 0;
|
||||||
|
ssize_t framelen;
|
||||||
int i;
|
int i;
|
||||||
spdylay_settings_entry iv[3];
|
spdylay_settings_entry iv[3];
|
||||||
iv[0].settings_id = SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH;
|
iv[0].settings_id = SPDYLAY_SETTINGS_UPLOAD_BANDWIDTH;
|
||||||
|
@ -185,20 +192,20 @@ void test_spdylay_frame_pack_settings()
|
||||||
(&frame.settings,
|
(&frame.settings,
|
||||||
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);
|
||||||
buflen = spdylay_frame_pack_settings(&buf, &frame.settings);
|
framelen = spdylay_frame_pack_settings(&buf, &buflen, &frame.settings);
|
||||||
CU_ASSERT(8+4+3*8 == buflen);
|
CU_ASSERT(8+4+3*8 == framelen);
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_frame_unpack_settings
|
CU_ASSERT(0 == spdylay_frame_unpack_settings
|
||||||
(&oframe.settings,
|
(&oframe.settings,
|
||||||
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
&buf[0], SPDYLAY_FRAME_HEAD_LENGTH,
|
||||||
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
&buf[SPDYLAY_FRAME_HEAD_LENGTH],
|
||||||
buflen-SPDYLAY_FRAME_HEAD_LENGTH));
|
framelen-SPDYLAY_FRAME_HEAD_LENGTH));
|
||||||
|
|
||||||
CU_ASSERT(SPDYLAY_PROTO_VERSION == oframe.settings.hd.version);
|
CU_ASSERT(SPDYLAY_PROTO_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);
|
||||||
CU_ASSERT(buflen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.settings.hd.length);
|
CU_ASSERT(framelen-SPDYLAY_FRAME_HEAD_LENGTH == oframe.settings.hd.length);
|
||||||
|
|
||||||
CU_ASSERT(3 == oframe.settings.niv);
|
CU_ASSERT(3 == oframe.settings.niv);
|
||||||
for(i = 0; i < 3; ++i) {
|
for(i = 0; i < 3; ++i) {
|
||||||
|
|
|
@ -190,18 +190,22 @@ void test_spdylay_session_recv()
|
||||||
const char *nv[] = {
|
const char *nv[] = {
|
||||||
"url", "/", NULL
|
"url", "/", NULL
|
||||||
};
|
};
|
||||||
uint8_t *framedata;
|
uint8_t *framedata = NULL, *nvbuf = NULL;
|
||||||
size_t framelen;
|
size_t framedatalen = 0, nvbuflen = 0;
|
||||||
|
ssize_t framelen;
|
||||||
spdylay_frame frame;
|
spdylay_frame frame;
|
||||||
|
|
||||||
user_data.df = &df;
|
user_data.df = &df;
|
||||||
spdylay_session_client_new(&session, &callbacks, &user_data);
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 0, 0, 3,
|
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 0, 0, 3,
|
||||||
dup_nv(nv));
|
dup_nv(nv));
|
||||||
framelen = spdylay_frame_pack_syn_stream(&framedata, &frame.syn_stream,
|
framelen = spdylay_frame_pack_syn_stream(&framedata, &framedatalen,
|
||||||
|
&nvbuf, &nvbuflen,
|
||||||
|
&frame.syn_stream,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
scripted_data_feed_init(&df, framedata, framelen);
|
scripted_data_feed_init(&df, framedata, framelen);
|
||||||
free(framedata);
|
free(framedata);
|
||||||
|
free(nvbuf);
|
||||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_session_recv(session));
|
CU_ASSERT(0 == spdylay_session_recv(session));
|
||||||
|
@ -272,8 +276,9 @@ void test_spdylay_session_recv_invalid_stream_id()
|
||||||
scripted_data_feed df;
|
scripted_data_feed df;
|
||||||
my_user_data user_data;
|
my_user_data user_data;
|
||||||
const char *nv[] = { NULL };
|
const char *nv[] = { NULL };
|
||||||
uint8_t *framedata;
|
uint8_t *framedata = NULL, *nvbuf = NULL;
|
||||||
size_t framelen;
|
size_t framedatalen = 0, nvbuflen = 0;
|
||||||
|
ssize_t framelen;
|
||||||
spdylay_frame frame;
|
spdylay_frame frame;
|
||||||
|
|
||||||
user_data.df = &df;
|
user_data.df = &df;
|
||||||
|
@ -281,10 +286,11 @@ void test_spdylay_session_recv_invalid_stream_id()
|
||||||
spdylay_session_client_new(&session, &callbacks, &user_data);
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 1, 0, 3,
|
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_FLAG_NONE, 1, 0, 3,
|
||||||
dup_nv(nv));
|
dup_nv(nv));
|
||||||
framelen = spdylay_frame_pack_syn_stream(&framedata, &frame.syn_stream,
|
framelen = spdylay_frame_pack_syn_stream(&framedata, &framedatalen,
|
||||||
|
&nvbuf, &nvbuflen,
|
||||||
|
&frame.syn_stream,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
scripted_data_feed_init(&df, framedata, framelen);
|
scripted_data_feed_init(&df, framedata, framelen);
|
||||||
free(framedata);
|
|
||||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_session_recv(session));
|
CU_ASSERT(0 == spdylay_session_recv(session));
|
||||||
|
@ -292,15 +298,18 @@ void test_spdylay_session_recv_invalid_stream_id()
|
||||||
|
|
||||||
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 100,
|
spdylay_frame_syn_reply_init(&frame.syn_reply, SPDYLAY_FLAG_NONE, 100,
|
||||||
dup_nv(nv));
|
dup_nv(nv));
|
||||||
framelen = spdylay_frame_pack_syn_reply(&framedata, &frame.syn_reply,
|
framelen = spdylay_frame_pack_syn_reply(&framedata, &framedatalen,
|
||||||
|
&nvbuf, &nvbuflen,
|
||||||
|
&frame.syn_reply,
|
||||||
&session->hd_deflater);
|
&session->hd_deflater);
|
||||||
scripted_data_feed_init(&df, framedata, framelen);
|
scripted_data_feed_init(&df, framedata, framelen);
|
||||||
free(framedata);
|
|
||||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||||
|
|
||||||
CU_ASSERT(0 == spdylay_session_recv(session));
|
CU_ASSERT(0 == spdylay_session_recv(session));
|
||||||
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
CU_ASSERT(2 == user_data.invalid_ctrl_recv_cb_called);
|
||||||
|
|
||||||
|
free(framedata);
|
||||||
|
free(nvbuf);
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue