Added handling of received PING
This commit is contained in:
parent
9461147968
commit
d1c4c59aad
|
@ -51,6 +51,8 @@ AC_CHECK_LIB([cunit], [CU_initialize_registry],
|
||||||
[have_cunit=yes], [have_cunit=no])
|
[have_cunit=yes], [have_cunit=no])
|
||||||
AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
|
AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
|
||||||
|
|
||||||
|
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_CHECK_HEADERS([ \
|
AC_CHECK_HEADERS([ \
|
||||||
arpa/inet.h \
|
arpa/inet.h \
|
||||||
|
@ -58,6 +60,7 @@ AC_CHECK_HEADERS([ \
|
||||||
stdint.h \
|
stdint.h \
|
||||||
stdlib.h \
|
stdlib.h \
|
||||||
string.h \
|
string.h \
|
||||||
|
time.h \
|
||||||
unistd.h \
|
unistd.h \
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -179,11 +179,18 @@ typedef void (*spdylay_on_invalid_ctrl_recv_callback)
|
||||||
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
|
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback function invoked when PING reply is received from peer.
|
||||||
|
*/
|
||||||
|
typedef void (*spdylay_on_ping_recv_callback)
|
||||||
|
(spdylay_session *session, const struct timespec *rtt, void *user_data);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spdylay_send_callback send_callback;
|
spdylay_send_callback send_callback;
|
||||||
spdylay_recv_callback recv_callback;
|
spdylay_recv_callback recv_callback;
|
||||||
spdylay_on_ctrl_recv_callback on_ctrl_recv_callback;
|
spdylay_on_ctrl_recv_callback on_ctrl_recv_callback;
|
||||||
spdylay_on_invalid_ctrl_recv_callback on_invalid_ctrl_recv_callback;
|
spdylay_on_invalid_ctrl_recv_callback on_invalid_ctrl_recv_callback;
|
||||||
|
spdylay_on_ping_recv_callback on_ping_recv_callback;
|
||||||
} spdylay_session_callbacks;
|
} spdylay_session_callbacks;
|
||||||
|
|
||||||
int spdylay_session_client_new(spdylay_session **session_ptr,
|
int spdylay_session_client_new(spdylay_session **session_ptr,
|
||||||
|
@ -215,6 +222,8 @@ int spdylay_reply_submit(spdylay_session *session,
|
||||||
int32_t stream_id, const char **nv,
|
int32_t stream_id, const char **nv,
|
||||||
spdylay_data_provider *data_prd);
|
spdylay_data_provider *data_prd);
|
||||||
|
|
||||||
|
int spdylay_submit_ping(spdylay_session *session);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,8 +71,14 @@ int spdylay_session_client_new(spdylay_session **session_ptr,
|
||||||
return SPDYLAY_ERR_NOMEM;
|
return SPDYLAY_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
memset(*session_ptr, 0, sizeof(spdylay_session));
|
memset(*session_ptr, 0, sizeof(spdylay_session));
|
||||||
|
|
||||||
|
/* IDs for use in client */
|
||||||
(*session_ptr)->next_stream_id = 1;
|
(*session_ptr)->next_stream_id = 1;
|
||||||
(*session_ptr)->last_recv_stream_id = 0;
|
(*session_ptr)->last_recv_stream_id = 0;
|
||||||
|
(*session_ptr)->next_unique_id = 1;
|
||||||
|
|
||||||
|
(*session_ptr)->last_ping_unique_id = 0;
|
||||||
|
memset(&(*session_ptr)->last_ping_time, 0, sizeof(struct timespec));
|
||||||
|
|
||||||
r = spdylay_zlib_deflate_hd_init(&(*session_ptr)->hd_deflater);
|
r = spdylay_zlib_deflate_hd_init(&(*session_ptr)->hd_deflater);
|
||||||
if(r != 0) {
|
if(r != 0) {
|
||||||
|
@ -131,10 +137,12 @@ static void spdylay_outbound_item_free(spdylay_outbound_item *item)
|
||||||
case SPDYLAY_RST_STREAM:
|
case SPDYLAY_RST_STREAM:
|
||||||
spdylay_frame_rst_stream_free(&item->frame->rst_stream);
|
spdylay_frame_rst_stream_free(&item->frame->rst_stream);
|
||||||
break;
|
break;
|
||||||
|
case SPDYLAY_PING:
|
||||||
|
spdylay_frame_ping_free(&item->frame->ping);
|
||||||
|
break;
|
||||||
case SPDYLAY_HEADERS:
|
case SPDYLAY_HEADERS:
|
||||||
/* Currently we don't have any API to send HEADERS frame, so this
|
spdylay_frame_headers_free(&item->frame->headers);
|
||||||
is unreachable. */
|
break;
|
||||||
abort();
|
|
||||||
case SPDYLAY_DATA:
|
case SPDYLAY_DATA:
|
||||||
spdylay_frame_data_free(&item->frame->data);
|
spdylay_frame_data_free(&item->frame->data);
|
||||||
break;
|
break;
|
||||||
|
@ -195,6 +203,10 @@ int spdylay_session_add_frame(spdylay_session *session,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPDYLAY_PING:
|
||||||
|
/* Ping has "height" priority. Give it -1. */
|
||||||
|
item->pri = -1;
|
||||||
|
break;
|
||||||
case SPDYLAY_HEADERS:
|
case SPDYLAY_HEADERS:
|
||||||
/* Currently we don't have any API to send HEADERS frame, so this
|
/* Currently we don't have any API to send HEADERS frame, so this
|
||||||
is unreachable. */
|
is unreachable. */
|
||||||
|
@ -339,6 +351,12 @@ ssize_t spdylay_session_prep_frame(spdylay_session *session,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPDYLAY_PING:
|
||||||
|
framebuflen = spdylay_frame_pack_ping(&framebuf, &item->frame->ping);
|
||||||
|
if(framebuflen < 0) {
|
||||||
|
return framebuflen;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SPDYLAY_HEADERS:
|
case SPDYLAY_HEADERS:
|
||||||
/* Currently we don't have any API to send HEADERS frame, so this
|
/* Currently we don't have any API to send HEADERS frame, so this
|
||||||
is unreachable. */
|
is unreachable. */
|
||||||
|
@ -370,7 +388,7 @@ static void spdylay_active_outbound_item_reset
|
||||||
memset(aob, 0, sizeof(spdylay_active_outbound_item));
|
memset(aob, 0, sizeof(spdylay_active_outbound_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
static spdylay_outbound_item* spdylay_session_get_ob_pq_top
|
spdylay_outbound_item* spdylay_session_get_ob_pq_top
|
||||||
(spdylay_session *session)
|
(spdylay_session *session)
|
||||||
{
|
{
|
||||||
return (spdylay_outbound_item*)spdylay_pq_top(&session->ob_pq);
|
return (spdylay_outbound_item*)spdylay_pq_top(&session->ob_pq);
|
||||||
|
@ -401,6 +419,13 @@ static int spdylay_session_after_frame_sent(spdylay_session *session)
|
||||||
case SPDYLAY_RST_STREAM:
|
case SPDYLAY_RST_STREAM:
|
||||||
spdylay_session_close_stream(session, frame->rst_stream.stream_id);
|
spdylay_session_close_stream(session, frame->rst_stream.stream_id);
|
||||||
break;
|
break;
|
||||||
|
case SPDYLAY_PING:
|
||||||
|
/* We record the time now and show application code RTT when
|
||||||
|
reply PING is received. */
|
||||||
|
session->last_ping_unique_id = frame->ping.unique_id;
|
||||||
|
/* TODO If clock_gettime() fails, what should we do? */
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &session->last_ping_time);
|
||||||
|
break;
|
||||||
case SPDYLAY_HEADERS:
|
case SPDYLAY_HEADERS:
|
||||||
/* Currently we don't have any API to send HEADERS frame, so this
|
/* Currently we don't have any API to send HEADERS frame, so this
|
||||||
is unreachable. */
|
is unreachable. */
|
||||||
|
@ -688,6 +713,39 @@ int spdylay_session_on_syn_reply_received(spdylay_session *session,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spdylay_session_on_ping_received(spdylay_session *session,
|
||||||
|
spdylay_frame *frame)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
if(frame->ping.unique_id != 0) {
|
||||||
|
if(session->last_ping_unique_id == frame->ping.unique_id) {
|
||||||
|
/* This is ping reply from peer */
|
||||||
|
struct timespec rtt;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &rtt);
|
||||||
|
rtt.tv_nsec -= session->last_ping_time.tv_nsec;
|
||||||
|
if(rtt.tv_nsec < 0) {
|
||||||
|
rtt.tv_nsec += 1000000000;
|
||||||
|
--rtt.tv_sec;
|
||||||
|
}
|
||||||
|
rtt.tv_sec -= session->last_ping_time.tv_sec;
|
||||||
|
/* Assign 0 to last_ping_unique_id so that we can ignore same
|
||||||
|
ID. */
|
||||||
|
session->last_ping_unique_id = 0;
|
||||||
|
if(session->callbacks.on_ping_recv_callback) {
|
||||||
|
session->callbacks.on_ping_recv_callback(session, &rtt,
|
||||||
|
session->user_data);
|
||||||
|
}
|
||||||
|
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_PING, frame);
|
||||||
|
} else if((session->server && frame->ping.unique_id % 2 == 1) ||
|
||||||
|
(!session->server && frame->ping.unique_id % 2 == 0)) {
|
||||||
|
/* Peer sent ping, so ping it back */
|
||||||
|
r = spdylay_session_add_ping(session, frame->ping.unique_id);
|
||||||
|
spdylay_session_call_on_ctrl_frame_received(session, SPDYLAY_PING, frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int spdylay_session_on_headers_received(spdylay_session *session,
|
int spdylay_session_on_headers_received(spdylay_session *session,
|
||||||
spdylay_frame *frame)
|
spdylay_frame *frame)
|
||||||
{
|
{
|
||||||
|
@ -770,6 +828,17 @@ int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SPDYLAY_PING:
|
||||||
|
r = spdylay_frame_unpack_ping(&frame.ping,
|
||||||
|
session->iframe.headbuf,
|
||||||
|
sizeof(session->iframe.headbuf),
|
||||||
|
session->iframe.buf,
|
||||||
|
session->iframe.len);
|
||||||
|
if(r == 0) {
|
||||||
|
r = spdylay_session_on_ping_received(session, &frame);
|
||||||
|
spdylay_frame_ping_free(&frame.ping);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SPDYLAY_HEADERS:
|
case SPDYLAY_HEADERS:
|
||||||
r = spdylay_frame_unpack_headers(&frame.headers,
|
r = spdylay_frame_unpack_headers(&frame.headers,
|
||||||
session->iframe.headbuf,
|
session->iframe.headbuf,
|
||||||
|
@ -890,13 +959,35 @@ int spdylay_session_want_write(spdylay_session *session)
|
||||||
return session->aob.item != NULL || !spdylay_pq_empty(&session->ob_pq);
|
return session->aob.item != NULL || !spdylay_pq_empty(&session->ob_pq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int spdylay_session_add_ping(spdylay_session *session, uint32_t unique_id)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
spdylay_frame *frame;
|
||||||
|
frame = malloc(sizeof(spdylay_frame));
|
||||||
|
if(frame == NULL) {
|
||||||
|
return SPDYLAY_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
spdylay_frame_ping_init(&frame->ping, unique_id);
|
||||||
|
r = spdylay_session_add_frame(session, SPDYLAY_PING, frame);
|
||||||
|
if(r != 0) {
|
||||||
|
spdylay_frame_ping_free(&frame->ping);
|
||||||
|
free(frame);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spdylay_submit_ping(spdylay_session *session)
|
||||||
|
{
|
||||||
|
return spdylay_session_add_ping(session,
|
||||||
|
spdylay_session_get_next_unique_id(session));
|
||||||
|
}
|
||||||
|
|
||||||
int spdylay_reply_submit(spdylay_session *session,
|
int spdylay_reply_submit(spdylay_session *session,
|
||||||
int32_t stream_id, const char **nv,
|
int32_t stream_id, const char **nv,
|
||||||
spdylay_data_provider *data_prd)
|
spdylay_data_provider *data_prd)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
spdylay_frame *frame;
|
spdylay_frame *frame;
|
||||||
spdylay_frame *data_frame = NULL;
|
|
||||||
char **nv_copy;
|
char **nv_copy;
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
frame = malloc(sizeof(spdylay_frame));
|
frame = malloc(sizeof(spdylay_frame));
|
||||||
|
@ -920,6 +1011,7 @@ int spdylay_reply_submit(spdylay_session *session,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
if(data_prd != NULL) {
|
if(data_prd != NULL) {
|
||||||
|
spdylay_frame *data_frame;
|
||||||
/* TODO If error is not FATAL, we should add RST_STREAM frame to
|
/* TODO If error is not FATAL, we should add RST_STREAM frame to
|
||||||
cancel this stream. */
|
cancel this stream. */
|
||||||
data_frame = malloc(sizeof(spdylay_frame));
|
data_frame = malloc(sizeof(spdylay_frame));
|
||||||
|
@ -1001,3 +1093,15 @@ ssize_t spdylay_session_pack_data_overwrite(spdylay_session *session,
|
||||||
frame->flags = flags;
|
frame->flags = flags;
|
||||||
return r+8;
|
return r+8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t spdylay_session_get_next_unique_id(spdylay_session *session)
|
||||||
|
{
|
||||||
|
if(session->next_unique_id > SPDYLAY_MAX_UNIQUE_ID) {
|
||||||
|
if(session->server) {
|
||||||
|
session->next_unique_id = 2;
|
||||||
|
} else {
|
||||||
|
session->next_unique_id = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return session->next_unique_id++;
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include <spdylay/spdylay.h>
|
#include <spdylay/spdylay.h>
|
||||||
#include "spdylay_pq.h"
|
#include "spdylay_pq.h"
|
||||||
#include "spdylay_map.h"
|
#include "spdylay_map.h"
|
||||||
|
@ -62,6 +64,10 @@ typedef enum {
|
||||||
|
|
||||||
#define SPDYLAY_HEAD_LEN 8
|
#define SPDYLAY_HEAD_LEN 8
|
||||||
|
|
||||||
|
/* Maximum unique ID in use for PING. If unique ID exeeds this number,
|
||||||
|
it wraps to 1 (client) or 2 (server) */
|
||||||
|
#define SPDYLAY_MAX_UNIQUE_ID ((1u << 31)-1)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
spdylay_inbound_state state;
|
spdylay_inbound_state state;
|
||||||
uint8_t headbuf[SPDYLAY_HEAD_LEN];
|
uint8_t headbuf[SPDYLAY_HEAD_LEN];
|
||||||
|
@ -77,6 +83,9 @@ typedef struct spdylay_session {
|
||||||
uint8_t server;
|
uint8_t server;
|
||||||
int32_t next_stream_id;
|
int32_t next_stream_id;
|
||||||
int32_t last_recv_stream_id;
|
int32_t last_recv_stream_id;
|
||||||
|
/* Counter of unique ID of PING. Wraps when it exceeds
|
||||||
|
SPDYLAY_MAX_UNIQUE_ID */
|
||||||
|
uint32_t next_unique_id;
|
||||||
|
|
||||||
spdylay_map /* <spdylay_stream*> */ streams;
|
spdylay_map /* <spdylay_stream*> */ streams;
|
||||||
spdylay_pq /* <spdylay_outbound_item*> */ ob_pq;
|
spdylay_pq /* <spdylay_outbound_item*> */ ob_pq;
|
||||||
|
@ -89,6 +98,11 @@ typedef struct spdylay_session {
|
||||||
spdylay_zlib hd_deflater;
|
spdylay_zlib hd_deflater;
|
||||||
spdylay_zlib hd_inflater;
|
spdylay_zlib hd_inflater;
|
||||||
|
|
||||||
|
/* The last unique ID sent to the peer. */
|
||||||
|
uint32_t last_ping_unique_id;
|
||||||
|
/* Time stamp when last ping is sent. */
|
||||||
|
struct timespec last_ping_time;
|
||||||
|
|
||||||
spdylay_session_callbacks callbacks;
|
spdylay_session_callbacks callbacks;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
} spdylay_session;
|
} spdylay_session;
|
||||||
|
@ -102,6 +116,8 @@ int spdylay_session_add_frame(spdylay_session *session,
|
||||||
int spdylay_session_add_rst_stream(spdylay_session *session,
|
int spdylay_session_add_rst_stream(spdylay_session *session,
|
||||||
int32_t stream_id, uint32_t status_code);
|
int32_t stream_id, uint32_t status_code);
|
||||||
|
|
||||||
|
int spdylay_session_add_ping(spdylay_session *session, uint32_t unique_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates new stream in |session| with stream ID |stream_id|,
|
* Creates new stream in |session| with stream ID |stream_id|,
|
||||||
* priority |pri| and flags |flags|. Currently, |flags| &
|
* priority |pri| and flags |flags|. Currently, |flags| &
|
||||||
|
@ -173,4 +189,15 @@ ssize_t spdylay_session_pack_data_overwrite(spdylay_session *session,
|
||||||
uint8_t *buf, size_t len,
|
uint8_t *buf, size_t len,
|
||||||
spdylay_data *frame);
|
spdylay_data *frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns next unique ID which can be used with PING.
|
||||||
|
*/
|
||||||
|
uint32_t spdylay_session_get_next_unique_id(spdylay_session *session);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns top of outbound frame queue. This function returns NULL if
|
||||||
|
* queue is empty.
|
||||||
|
*/
|
||||||
|
spdylay_outbound_item* spdylay_session_get_ob_pq_top(spdylay_session *session);
|
||||||
|
|
||||||
#endif /* SPDYLAY_SESSION_H */
|
#endif /* SPDYLAY_SESSION_H */
|
||||||
|
|
|
@ -84,6 +84,8 @@ int main()
|
||||||
test_spdylay_session_reply_fail) ||
|
test_spdylay_session_reply_fail) ||
|
||||||
!CU_add_test(pSuite, "session_on_headers_received",
|
!CU_add_test(pSuite, "session_on_headers_received",
|
||||||
test_spdylay_session_on_headers_received) ||
|
test_spdylay_session_on_headers_received) ||
|
||||||
|
!CU_add_test(pSuite, "session_on_ping_received",
|
||||||
|
test_spdylay_session_on_ping_received) ||
|
||||||
!CU_add_test(pSuite, "frame_unpack_nv", test_spdylay_frame_unpack_nv) ||
|
!CU_add_test(pSuite, "frame_unpack_nv", test_spdylay_frame_unpack_nv) ||
|
||||||
!CU_add_test(pSuite, "frame_count_nv_space",
|
!CU_add_test(pSuite, "frame_count_nv_space",
|
||||||
test_spdylay_frame_count_nv_space) ||
|
test_spdylay_frame_count_nv_space) ||
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
accumulator *acc;
|
accumulator *acc;
|
||||||
scripted_data_feed *df;
|
scripted_data_feed *df;
|
||||||
int valid, invalid;
|
int valid, invalid, ping_recv;
|
||||||
size_t data_source_length;
|
size_t data_source_length;
|
||||||
} my_user_data;
|
} my_user_data;
|
||||||
|
|
||||||
|
@ -122,6 +122,14 @@ static void on_invalid_ctrl_recv_callback(spdylay_session *session,
|
||||||
++ud->invalid;
|
++ud->invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_ping_recv_callback(spdylay_session *session,
|
||||||
|
const struct timespec *rtt,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
my_user_data *ud = (my_user_data*)user_data;
|
||||||
|
++ud->ping_recv;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t fixed_length_data_source_read_callback
|
static ssize_t fixed_length_data_source_read_callback
|
||||||
(spdylay_session *session, uint8_t *buf, size_t len, int *eof,
|
(spdylay_session *session, uint8_t *buf, size_t len, int *eof,
|
||||||
spdylay_data_source *source, void *user_data)
|
spdylay_data_source *source, void *user_data)
|
||||||
|
@ -533,3 +541,44 @@ void test_spdylay_session_on_headers_received()
|
||||||
spdylay_frame_headers_free(&frame.headers);
|
spdylay_frame_headers_free(&frame.headers);
|
||||||
spdylay_session_del(session);
|
spdylay_session_del(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_spdylay_session_on_ping_received()
|
||||||
|
{
|
||||||
|
spdylay_session *session;
|
||||||
|
spdylay_session_callbacks callbacks = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
on_ctrl_recv_callback,
|
||||||
|
on_invalid_ctrl_recv_callback,
|
||||||
|
on_ping_recv_callback
|
||||||
|
};
|
||||||
|
my_user_data user_data;
|
||||||
|
const char *nv[] = { NULL };
|
||||||
|
spdylay_frame frame;
|
||||||
|
spdylay_outbound_item *top;
|
||||||
|
uint32_t unique_id;
|
||||||
|
user_data.valid = 0;
|
||||||
|
user_data.invalid = 0;
|
||||||
|
user_data.ping_recv = 0;
|
||||||
|
|
||||||
|
spdylay_session_client_new(&session, &callbacks, &user_data);
|
||||||
|
unique_id = 2;
|
||||||
|
spdylay_frame_ping_init(&frame.ping, unique_id);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_ping_received(session, &frame));
|
||||||
|
CU_ASSERT(1 == user_data.valid);
|
||||||
|
CU_ASSERT(0 == user_data.ping_recv);
|
||||||
|
top = spdylay_session_get_ob_pq_top(session);
|
||||||
|
CU_ASSERT(SPDYLAY_PING == top->frame_type);
|
||||||
|
CU_ASSERT(unique_id == top->frame->ping.unique_id);
|
||||||
|
|
||||||
|
session->last_ping_unique_id = 1;
|
||||||
|
frame.ping.unique_id = 1;
|
||||||
|
|
||||||
|
CU_ASSERT(0 == spdylay_session_on_ping_received(session, &frame));
|
||||||
|
CU_ASSERT(2 == user_data.valid);
|
||||||
|
CU_ASSERT(1 == user_data.ping_recv);
|
||||||
|
|
||||||
|
spdylay_frame_ping_free(&frame.ping);
|
||||||
|
spdylay_session_del(session);
|
||||||
|
}
|
||||||
|
|
|
@ -35,5 +35,6 @@ void test_spdylay_session_send_syn_reply();
|
||||||
void test_spdylay_reply_submit();
|
void test_spdylay_reply_submit();
|
||||||
void test_spdylay_session_reply_fail();
|
void test_spdylay_session_reply_fail();
|
||||||
void test_spdylay_session_on_headers_received();
|
void test_spdylay_session_on_headers_received();
|
||||||
|
void test_spdylay_session_on_ping_received();
|
||||||
|
|
||||||
#endif // SPDYLAY_SESSION_TEST_H
|
#endif // SPDYLAY_SESSION_TEST_H
|
||||||
|
|
Loading…
Reference in New Issue