Added spdylay_on_unknown_ctrl_recv_callback.

This callback function is invoked when the unknown frame type is received.
Added debug output using this callback to spdycat.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-05-09 22:41:08 +09:00
parent 171bede1fa
commit c68a0b5e6d
5 changed files with 72 additions and 7 deletions

View File

@ -350,6 +350,7 @@ int run(char **uris, int n)
callbacks.on_ctrl_send_callback = on_ctrl_send_callback3; callbacks.on_ctrl_send_callback = on_ctrl_send_callback3;
callbacks.on_ctrl_recv_parse_error_callback = callbacks.on_ctrl_recv_parse_error_callback =
on_ctrl_recv_parse_error_callback; on_ctrl_recv_parse_error_callback;
callbacks.on_unknown_ctrl_recv_callback = on_unknown_ctrl_recv_callback;
} else { } else {
callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback2; callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback2;
callbacks.on_ctrl_send_callback = on_ctrl_send_callback2; callbacks.on_ctrl_send_callback = on_ctrl_send_callback2;

View File

@ -414,6 +414,19 @@ const char* spdylay_strerror(int error_code)
}; };
} // namespace } // namespace
namespace {
void dump_header(const uint8_t *head, size_t headlen)
{
size_t i;
print_frame_attr_indent();
printf("Header dump: ");
for(i = 0; i < headlen; ++i) {
printf("%02X ", head[i]);
}
printf("\n");
}
} // namespace
void on_ctrl_recv_parse_error_callback(spdylay_session *session, void on_ctrl_recv_parse_error_callback(spdylay_session *session,
spdylay_frame_type type, spdylay_frame_type type,
const uint8_t *head, const uint8_t *head,
@ -422,16 +435,23 @@ void on_ctrl_recv_parse_error_callback(spdylay_session *session,
size_t payloadlen, size_t payloadlen,
int error_code, void *user_data) int error_code, void *user_data)
{ {
size_t i;
print_timer(); print_timer();
printf(" recv %s frame: Parse error [%s]\n", ctrl_names[type-1], printf(" recv %s frame: Parse error [%s]\n", ctrl_names[type-1],
spdylay_strerror(error_code)); spdylay_strerror(error_code));
print_frame_attr_indent(); dump_header(head, headlen);
printf("Header dump: "); fflush(stdout);
for(i = 0; i < headlen; ++i) { }
printf("%02X ", head[i]);
} void on_unknown_ctrl_recv_callback(spdylay_session *session,
printf("\n"); const uint8_t *head,
size_t headlen,
const uint8_t *payload,
size_t payloadlen,
void *user_data)
{
print_timer();
printf(" recv unknown frame\n");
dump_header(head, headlen);
fflush(stdout); fflush(stdout);
} }

View File

@ -93,6 +93,13 @@ void on_ctrl_recv_parse_error_callback(spdylay_session *session,
size_t payloadlen, size_t payloadlen,
int error_code, void *user_data); int error_code, void *user_data);
void on_unknown_ctrl_recv_callback(spdylay_session *session,
const uint8_t *head,
size_t headlen,
const uint8_t *payload,
size_t payloadlen,
void *user_data);
void on_ctrl_send_callback void on_ctrl_send_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);

View File

@ -978,6 +978,24 @@ typedef void (*spdylay_on_ctrl_recv_parse_error_callback)
const uint8_t *payload, size_t payloadlen, const uint8_t *payload, size_t payloadlen,
int error_code, void *user_data); int error_code, void *user_data);
/**
* @functypedef
*
* Callback function invoked when the received control frame type is
* unknown. The |head| is the pointer to the header of the received
* frame. The |headlen| is the length of the |head|. According to the
* SPDY spec, the |headlen| is always 8. In other words, the |head| is
* the first 8 bytes of the received frame. The |payload| is the
* pointer to the data portion of the received frame. The
* |payloadlen| is the length of the |payload|. This is the data after
* the length field.
*/
typedef void (*spdylay_on_unknown_ctrl_recv_callback)
(spdylay_session *session,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
void *user_data);
#define SPDYLAY_MAX_SCHEME 255 #define SPDYLAY_MAX_SCHEME 255
#define SPDYLAY_MAX_HOSTNAME 255 #define SPDYLAY_MAX_HOSTNAME 255
@ -1143,6 +1161,11 @@ typedef struct {
* could not be parsed correctly. * could not be parsed correctly.
*/ */
spdylay_on_ctrl_recv_parse_error_callback on_ctrl_recv_parse_error_callback; spdylay_on_ctrl_recv_parse_error_callback on_ctrl_recv_parse_error_callback;
/**
* Callback function invoked when the received control frame type is
* unknown.
*/
spdylay_on_unknown_ctrl_recv_callback on_unknown_ctrl_recv_callback;
} spdylay_session_callbacks; } spdylay_session_callbacks;
/** /**
@ -1404,6 +1427,9 @@ int spdylay_session_send(spdylay_session *session);
* 3.4. If the received frame could not be unpacked correctly, * 3.4. If the received frame could not be unpacked correctly,
* :member:`spdylay_session_callbacks.on_ctrl_recv_parse_error_callback` * :member:`spdylay_session_callbacks.on_ctrl_recv_parse_error_callback`
* is invoked. * is invoked.
* 3.5. If the received frame type is unknown,
* :member:`spdylay_session_callbacks.on_unknown_ctrl_recv_callback`
* is invoked.
* *
* 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:

View File

@ -2199,6 +2199,17 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR); r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
} }
break; break;
default:
/* Unknown frame */
if(session->callbacks.on_unknown_ctrl_recv_callback) {
session->callbacks.on_unknown_ctrl_recv_callback
(session,
session->iframe.headbuf,
sizeof(session->iframe.headbuf),
session->iframe.buf,
session->iframe.len,
session->user_data);
}
} }
if(spdylay_is_fatal(r)) { if(spdylay_is_fatal(r)) {
return r; return r;