forked from osmocom/wireshark
http2: Reduce the number of times calling find_or_create_conversation()
Change-Id: Ic55b228c52d0935c7cde859b3b49b861fc21f4f7 Reviewed-on: https://code.wireshark.org/review/36848 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
9f7e4fda0b
commit
9a6a64726a
|
@ -1136,20 +1136,17 @@ get_stream_info(http2_session_t *http2_session)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static http2_session_t*
|
static http2_session_t*
|
||||||
get_http2_session(packet_info *pinfo)
|
get_http2_session(packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
conversation_t *conversation;
|
|
||||||
http2_session_t *h2session;
|
http2_session_t *h2session;
|
||||||
|
|
||||||
conversation = find_or_create_conversation(pinfo);
|
|
||||||
|
|
||||||
h2session = (http2_session_t*)conversation_get_proto_data(conversation,
|
h2session = (http2_session_t*)conversation_get_proto_data(conversation,
|
||||||
proto_http2);
|
proto_http2);
|
||||||
|
|
||||||
if(!h2session) {
|
if(!h2session) {
|
||||||
struct tcp_analysis *tcpd;
|
struct tcp_analysis *tcpd;
|
||||||
|
|
||||||
tcpd = get_tcp_conversation_data(NULL, pinfo);
|
tcpd = get_tcp_conversation_data(conversation, pinfo);
|
||||||
|
|
||||||
h2session = wmem_new0(wmem_file_scope(), http2_session_t);
|
h2session = wmem_new0(wmem_file_scope(), http2_session_t);
|
||||||
|
|
||||||
|
@ -1242,9 +1239,9 @@ get_http2_frame_num(tvbuff_t *tvb, packet_info *pinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
static http2_oneway_stream_info_t*
|
static http2_oneway_stream_info_t*
|
||||||
get_oneway_stream_info(packet_info *pinfo, gboolean the_other_direction)
|
get_oneway_stream_info(packet_info *pinfo, conversation_t* conversation, gboolean the_other_direction)
|
||||||
{
|
{
|
||||||
http2_session_t *http2_session = get_http2_session(pinfo);
|
http2_session_t *http2_session = get_http2_session(pinfo, conversation);
|
||||||
http2_stream_info_t *http2_stream_info = get_stream_info(http2_session);
|
http2_stream_info_t *http2_stream_info = get_stream_info(http2_session);
|
||||||
guint32 flow_index = select_http2_flow_index(pinfo, http2_session);
|
guint32 flow_index = select_http2_flow_index(pinfo, http2_session);
|
||||||
if (the_other_direction) {
|
if (the_other_direction) {
|
||||||
|
@ -1257,22 +1254,22 @@ get_oneway_stream_info(packet_info *pinfo, gboolean the_other_direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
static http2_data_stream_body_info_t*
|
static http2_data_stream_body_info_t*
|
||||||
get_data_stream_body_info(packet_info *pinfo)
|
get_data_stream_body_info(packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
return &(get_oneway_stream_info(pinfo, FALSE)->data_stream_body_info);
|
return &(get_oneway_stream_info(pinfo, conversation, FALSE)->data_stream_body_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static http2_data_stream_reassembly_info_t*
|
static http2_data_stream_reassembly_info_t*
|
||||||
get_data_reassembly_info(packet_info *pinfo)
|
get_data_reassembly_info(packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
return &(get_oneway_stream_info(pinfo, FALSE)->data_stream_reassembly_info);
|
return &(get_oneway_stream_info(pinfo, conversation, FALSE)->data_stream_reassembly_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static http2_header_stream_info_t*
|
static http2_header_stream_info_t*
|
||||||
get_header_stream_info(packet_info *pinfo, gboolean the_other_direction)
|
get_header_stream_info(packet_info *pinfo, conversation_t* conversation, gboolean the_other_direction)
|
||||||
{
|
{
|
||||||
return &(get_oneway_stream_info(pinfo, the_other_direction)->header_stream_info);
|
return &(get_oneway_stream_info(pinfo, conversation, the_other_direction)->header_stream_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1483,9 +1480,9 @@ static gboolean http2_hdrcache_equal(gconstpointer lhs, gconstpointer rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_in_header_context(tvbuff_t *tvb, packet_info *pinfo)
|
is_in_header_context(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, FALSE);
|
http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, conversation, FALSE);
|
||||||
if (get_http2_frame_num(tvb, pinfo) >= stream_info->header_start_in) {
|
if (get_http2_frame_num(tvb, pinfo) >= stream_info->header_start_in) {
|
||||||
/* We either haven't established the frame that the headers end in so we are currently in the HEADERS context,
|
/* We either haven't established the frame that the headers end in so we are currently in the HEADERS context,
|
||||||
* or if we have, it should be equal or less that the current frame number */
|
* or if we have, it should be equal or less that the current frame number */
|
||||||
|
@ -1552,12 +1549,12 @@ get_content_type_parameters_only(const gchar *content_type, int content_type_str
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t *h2session, int header_value_length,
|
populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation, http2_session_t *h2session, int header_value_length,
|
||||||
const gchar *header_name, const gchar *header_value)
|
const gchar *header_name, const gchar *header_value)
|
||||||
{
|
{
|
||||||
/* Populate the content encoding used so we can uncompress the body later if required */
|
/* Populate the content encoding used so we can uncompress the body later if required */
|
||||||
if (strcmp(header_name, HTTP2_HEADER_CONTENT_ENCODING) == 0) {
|
if (strcmp(header_name, HTTP2_HEADER_CONTENT_ENCODING) == 0) {
|
||||||
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo);
|
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, conversation);
|
||||||
if (body_info->content_encoding == NULL) {
|
if (body_info->content_encoding == NULL) {
|
||||||
body_info->content_encoding = wmem_strndup(wmem_file_scope(), header_value, header_value_length);
|
body_info->content_encoding = wmem_strndup(wmem_file_scope(), header_value, header_value_length);
|
||||||
}
|
}
|
||||||
|
@ -1566,14 +1563,14 @@ populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t
|
||||||
/* Is this a partial content? */
|
/* Is this a partial content? */
|
||||||
if (strcmp(header_name, HTTP2_HEADER_STATUS) == 0 &&
|
if (strcmp(header_name, HTTP2_HEADER_STATUS) == 0 &&
|
||||||
strcmp(header_value, HTTP2_HEADER_STATUS_PARTIAL_CONTENT) == 0) {
|
strcmp(header_value, HTTP2_HEADER_STATUS_PARTIAL_CONTENT) == 0) {
|
||||||
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo);
|
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, conversation);
|
||||||
body_info->is_partial_content = TRUE;
|
body_info->is_partial_content = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Was this header used to initiate transfer of data frames? We'll use this later for reassembly */
|
/* Was this header used to initiate transfer of data frames? We'll use this later for reassembly */
|
||||||
if (strcmp(header_name, HTTP2_HEADER_STATUS) == 0 ||
|
if (strcmp(header_name, HTTP2_HEADER_STATUS) == 0 ||
|
||||||
strcmp(header_name, HTTP2_HEADER_METHOD) == 0) {
|
strcmp(header_name, HTTP2_HEADER_METHOD) == 0) {
|
||||||
http2_data_stream_reassembly_info_t *reassembly_info = get_data_reassembly_info(pinfo);
|
http2_data_stream_reassembly_info_t *reassembly_info = get_data_reassembly_info(pinfo, conversation);
|
||||||
if (reassembly_info->data_initiated_in == 0) {
|
if (reassembly_info->data_initiated_in == 0) {
|
||||||
reassembly_info->data_initiated_in = get_http2_frame_num(tvb, pinfo);
|
reassembly_info->data_initiated_in = get_http2_frame_num(tvb, pinfo);
|
||||||
}
|
}
|
||||||
|
@ -1581,7 +1578,7 @@ populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t
|
||||||
|
|
||||||
/* Do we have transfer encoding of bodies? We don't support reassembling these so mark it as such. */
|
/* Do we have transfer encoding of bodies? We don't support reassembling these so mark it as such. */
|
||||||
if (strcmp(header_name, HTTP2_HEADER_TRANSFER_ENCODING) == 0) {
|
if (strcmp(header_name, HTTP2_HEADER_TRANSFER_ENCODING) == 0) {
|
||||||
http2_data_stream_reassembly_info_t *reassembly_info = get_data_reassembly_info(pinfo);
|
http2_data_stream_reassembly_info_t *reassembly_info = get_data_reassembly_info(pinfo, conversation);
|
||||||
reassembly_info->has_transfer_encoded_body = TRUE;
|
reassembly_info->has_transfer_encoded_body = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1594,7 +1591,7 @@ populate_http_header_tracking(tvbuff_t *tvb, packet_info *pinfo, http2_session_t
|
||||||
|
|
||||||
/* Populate the content type so we can dissect the body later */
|
/* Populate the content type so we can dissect the body later */
|
||||||
if (strcmp(header_name, HTTP2_HEADER_CONTENT_TYPE) == 0) {
|
if (strcmp(header_name, HTTP2_HEADER_CONTENT_TYPE) == 0) {
|
||||||
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo);
|
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, conversation);
|
||||||
if (body_info->content_type == NULL) {
|
if (body_info->content_type == NULL) {
|
||||||
http2_stream_info_t *stream_info = get_stream_info(h2session);
|
http2_stream_info_t *stream_info = get_stream_info(h2session);
|
||||||
body_info->content_type = get_content_type_only(header_value, header_value_length);
|
body_info->content_type = get_content_type_only(header_value, header_value_length);
|
||||||
|
@ -1648,8 +1645,8 @@ try_add_named_header_field(proto_tree *tree, tvbuff_t *tvb, int offset, guint32
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation,
|
||||||
proto_tree *tree, guint headlen,
|
guint offset, proto_tree *tree, guint headlen,
|
||||||
http2_session_t *h2session, guint8 flags)
|
http2_session_t *h2session, guint8 flags)
|
||||||
{
|
{
|
||||||
guint8 *headbuf;
|
guint8 *headbuf;
|
||||||
|
@ -1796,7 +1793,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add this packet headers to stream header list */
|
/* add this packet headers to stream header list */
|
||||||
header_stream_info = get_header_stream_info(pinfo, FALSE);
|
header_stream_info = get_header_stream_info(pinfo, conversation, FALSE);
|
||||||
if (header_stream_info) {
|
if (header_stream_info) {
|
||||||
wmem_list_append(header_stream_info->stream_header_list, headers);
|
wmem_list_append(header_stream_info->stream_header_list, headers);
|
||||||
}
|
}
|
||||||
|
@ -1904,8 +1901,8 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset,
|
||||||
/* Only track HEADER and CONTINUATION frames part there of. Don't look at PUSH_PROMISE and trailing CONTINUATION.
|
/* Only track HEADER and CONTINUATION frames part there of. Don't look at PUSH_PROMISE and trailing CONTINUATION.
|
||||||
* Only do it for the first pass in case the current layer changes, altering where the headers frame number,
|
* Only do it for the first pass in case the current layer changes, altering where the headers frame number,
|
||||||
* http2_frame_num_t points to. */
|
* http2_frame_num_t points to. */
|
||||||
if (is_in_header_context(tvb, pinfo) && !PINFO_FD_VISITED(pinfo)) {
|
if (is_in_header_context(tvb, pinfo, conversation) && !PINFO_FD_VISITED(pinfo)) {
|
||||||
populate_http_header_tracking(tvb, pinfo, h2session, header_value_length, header_name, header_value);
|
populate_http_header_tracking(tvb, pinfo, conversation, h2session, header_value_length, header_name, header_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add encoding representation */
|
/* Add encoding representation */
|
||||||
|
@ -1956,12 +1953,13 @@ http2_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream)
|
||||||
{
|
{
|
||||||
http2_session_t *h2session;
|
http2_session_t *h2session;
|
||||||
struct tcp_analysis *tcpd;
|
struct tcp_analysis *tcpd;
|
||||||
|
conversation_t* conversation = find_or_create_conversation(pinfo);
|
||||||
|
|
||||||
if( ((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) ||
|
if( ((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) ||
|
||||||
(pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6)))
|
(pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6)))
|
||||||
{
|
{
|
||||||
h2session = get_http2_session(pinfo);
|
h2session = get_http2_session(pinfo, conversation);
|
||||||
tcpd = get_tcp_conversation_data(NULL, pinfo);
|
tcpd = get_tcp_conversation_data(conversation, pinfo);
|
||||||
|
|
||||||
if (tcpd == NULL)
|
if (tcpd == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2165,9 +2163,9 @@ enum body_uncompression {
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum body_uncompression
|
static enum body_uncompression
|
||||||
get_body_uncompression_info(packet_info *pinfo)
|
get_body_uncompression_info(packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo);
|
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, conversation);
|
||||||
gchar *content_encoding = body_info->content_encoding;
|
gchar *content_encoding = body_info->content_encoding;
|
||||||
|
|
||||||
/* Check we have a content-encoding header appropriate as well as checking if this is partial content.
|
/* Check we have a content-encoding header appropriate as well as checking if this is partial content.
|
||||||
|
@ -2198,17 +2196,17 @@ create_streaming_reassembly_id(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static http2_streaming_reassembly_info_t*
|
static http2_streaming_reassembly_info_t*
|
||||||
get_streaming_reassembly_info(packet_info *pinfo)
|
get_streaming_reassembly_info(packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
return &(get_oneway_stream_info(pinfo, FALSE)->data_stream_reassembly_info.streaming_reassembly_info);
|
return &(get_oneway_stream_info(pinfo, conversation, FALSE)->data_stream_reassembly_info.streaming_reassembly_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to dissect reassembled http2.data.data according to content_type. */
|
/* Try to dissect reassembled http2.data.data according to content_type. */
|
||||||
static void
|
static void
|
||||||
dissect_body_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
|
dissect_body_data(proto_tree *tree, packet_info *pinfo, conversation_t* conversation, tvbuff_t *tvb,
|
||||||
const gint start, gint length, const guint encoding, gboolean streaming_mode)
|
const gint start, gint length, const guint encoding, gboolean streaming_mode)
|
||||||
{
|
{
|
||||||
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo);
|
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, conversation);
|
||||||
gchar *content_type = body_info->content_type;
|
gchar *content_type = body_info->content_type;
|
||||||
http_message_info_t metadata_used_for_media_type_handle = { HTTP_OTHERS, body_info->content_type_parameters, NULL, NULL };
|
http_message_info_t metadata_used_for_media_type_handle = { HTTP_OTHERS, body_info->content_type_parameters, NULL, NULL };
|
||||||
|
|
||||||
|
@ -2225,7 +2223,7 @@ dissect_body_data(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree)
|
dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation, proto_tree *http2_tree)
|
||||||
{
|
{
|
||||||
if (!tvb) {
|
if (!tvb) {
|
||||||
return;
|
return;
|
||||||
|
@ -2233,7 +2231,7 @@ dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http
|
||||||
|
|
||||||
gint datalen = tvb_reported_length(tvb);
|
gint datalen = tvb_reported_length(tvb);
|
||||||
|
|
||||||
enum body_uncompression uncompression = get_body_uncompression_info(pinfo);
|
enum body_uncompression uncompression = get_body_uncompression_info(pinfo, conversation);
|
||||||
if (uncompression != BODY_UNCOMPRESSION_NONE) {
|
if (uncompression != BODY_UNCOMPRESSION_NONE) {
|
||||||
proto_item *compressed_proto_item = NULL;
|
proto_item *compressed_proto_item = NULL;
|
||||||
|
|
||||||
|
@ -2244,7 +2242,7 @@ dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http
|
||||||
uncompressed_tvb = tvb_child_uncompress_brotli(tvb, tvb, 0, datalen);
|
uncompressed_tvb = tvb_child_uncompress_brotli(tvb, tvb, 0, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo);
|
http2_data_stream_body_info_t *body_info = get_data_stream_body_info(pinfo, conversation);
|
||||||
gchar *compression_method = body_info->content_encoding;
|
gchar *compression_method = body_info->content_encoding;
|
||||||
|
|
||||||
proto_tree *compressed_entity_tree = proto_tree_add_subtree_format(http2_tree, tvb, 0, datalen, ett_http2_encoded_entity,
|
proto_tree *compressed_entity_tree = proto_tree_add_subtree_format(http2_tree, tvb, 0, datalen, ett_http2_encoded_entity,
|
||||||
|
@ -2256,20 +2254,20 @@ dissect_http2_data_full_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http
|
||||||
guint uncompressed_length = tvb_captured_length(uncompressed_tvb);
|
guint uncompressed_length = tvb_captured_length(uncompressed_tvb);
|
||||||
add_new_data_source(pinfo, uncompressed_tvb, "Uncompressed entity body");
|
add_new_data_source(pinfo, uncompressed_tvb, "Uncompressed entity body");
|
||||||
proto_item_append_text(compressed_proto_item, " -> %u bytes", uncompressed_length);
|
proto_item_append_text(compressed_proto_item, " -> %u bytes", uncompressed_length);
|
||||||
dissect_body_data(compressed_entity_tree, pinfo, uncompressed_tvb, 0, uncompressed_length, ENC_NA, FALSE);
|
dissect_body_data(compressed_entity_tree, pinfo, conversation, uncompressed_tvb, 0, uncompressed_length, ENC_NA, FALSE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
proto_tree_add_expert(compressed_entity_tree, pinfo, &ei_http2_body_decompression_failed, tvb, 0, datalen);
|
proto_tree_add_expert(compressed_entity_tree, pinfo, &ei_http2_body_decompression_failed, tvb, 0, datalen);
|
||||||
dissect_body_data(compressed_entity_tree, pinfo, tvb, 0, datalen, ENC_NA, FALSE);
|
dissect_body_data(compressed_entity_tree, pinfo, conversation, tvb, 0, datalen, ENC_NA, FALSE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dissect_body_data(http2_tree, pinfo, tvb, 0, datalen, ENC_NA, FALSE);
|
dissect_body_data(http2_tree, pinfo, conversation, tvb, 0, datalen, ENC_NA, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
should_attempt_to_reassemble_data_frame(http2_data_stream_reassembly_info_t *reassembly, packet_info *pinfo)
|
should_attempt_to_reassemble_data_frame(http2_data_stream_reassembly_info_t *reassembly, packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
/* If we haven't captured the header frame with the request/response we don't know how many data
|
/* If we haven't captured the header frame with the request/response we don't know how many data
|
||||||
* frames we might have lost before processing */
|
* frames we might have lost before processing */
|
||||||
|
@ -2286,7 +2284,7 @@ should_attempt_to_reassemble_data_frame(http2_data_stream_reassembly_info_t *rea
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this data frame part of an established tunnel? Don't try to reassemble the data if that is the case */
|
/* Is this data frame part of an established tunnel? Don't try to reassemble the data if that is the case */
|
||||||
http2_stream_info_t *stream_info = get_stream_info(get_http2_session(pinfo));
|
http2_stream_info_t *stream_info = get_stream_info(get_http2_session(pinfo, conversation));
|
||||||
if (stream_info->is_stream_http_connect) {
|
if (stream_info->is_stream_http_connect) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2295,9 +2293,9 @@ should_attempt_to_reassemble_data_frame(http2_data_stream_reassembly_info_t *rea
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint32
|
static guint32
|
||||||
get_reassembly_id_from_stream(packet_info *pinfo)
|
get_reassembly_id_from_stream(packet_info *pinfo, conversation_t* conversation)
|
||||||
{
|
{
|
||||||
http2_session_t *session = get_http2_session(pinfo);
|
http2_session_t *session = get_http2_session(pinfo, conversation);
|
||||||
http2_stream_info_t *stream_info = get_stream_info(session);
|
http2_stream_info_t *stream_info = get_stream_info(session);
|
||||||
guint32 flow_index = select_http2_flow_index(pinfo, session);
|
guint32 flow_index = select_http2_flow_index(pinfo, session);
|
||||||
|
|
||||||
|
@ -2307,18 +2305,18 @@ get_reassembly_id_from_stream(packet_info *pinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
static tvbuff_t*
|
static tvbuff_t*
|
||||||
reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree, guint offset,
|
reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation, proto_tree *http2_tree, guint offset,
|
||||||
guint8 flags, guint datalen)
|
guint8 flags, guint datalen)
|
||||||
{
|
{
|
||||||
http2_data_stream_reassembly_info_t *reassembly = get_data_reassembly_info(pinfo);
|
http2_data_stream_reassembly_info_t *reassembly = get_data_reassembly_info(pinfo, conversation);
|
||||||
|
|
||||||
/* There are a number of conditions as to why we may not want to reassemble DATA frames */
|
/* There are a number of conditions as to why we may not want to reassemble DATA frames */
|
||||||
if (!should_attempt_to_reassemble_data_frame(reassembly, pinfo)) {
|
if (!should_attempt_to_reassemble_data_frame(reassembly, pinfo, conversation)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Continue to add fragments, checking if we have any more fragments */
|
/* Continue to add fragments, checking if we have any more fragments */
|
||||||
guint32 reassembly_id = get_reassembly_id_from_stream(pinfo);
|
guint32 reassembly_id = get_reassembly_id_from_stream(pinfo, conversation);
|
||||||
fragment_head *head = NULL;
|
fragment_head *head = NULL;
|
||||||
if (IS_HTTP2_END_STREAM(flags) && datalen == 0) {
|
if (IS_HTTP2_END_STREAM(flags) && datalen == 0) {
|
||||||
/* Workaround displaying "[Frame: N (no data)]" for a HTTP2 frame that contains no data but ends the stream */
|
/* Workaround displaying "[Frame: N (no data)]" for a HTTP2 frame that contains no data but ends the stream */
|
||||||
|
@ -2349,10 +2347,10 @@ reassemble_http2_data_into_full_frame(tvbuff_t *tvb, packet_info *pinfo, proto_t
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree, guint offset, gint length,
|
dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation, proto_tree *http2_tree, guint offset, gint length,
|
||||||
guint8 flags)
|
guint8 flags)
|
||||||
{
|
{
|
||||||
http2_data_stream_reassembly_info_t *reassembly = get_data_reassembly_info(pinfo);
|
http2_data_stream_reassembly_info_t *reassembly = get_data_reassembly_info(pinfo, conversation);
|
||||||
|
|
||||||
/* Is the frame part of a body that is going to be reassembled? */
|
/* Is the frame part of a body that is going to be reassembled? */
|
||||||
if(!IS_HTTP2_END_STREAM(flags)) {
|
if(!IS_HTTP2_END_STREAM(flags)) {
|
||||||
|
@ -2365,7 +2363,7 @@ dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *h
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this part of a tunneled connection? */
|
/* Is this part of a tunneled connection? */
|
||||||
http2_stream_info_t *stream_info = get_stream_info(get_http2_session(pinfo));
|
http2_stream_info_t *stream_info = get_stream_info(get_http2_session(pinfo, conversation));
|
||||||
if (stream_info->is_stream_http_connect) {
|
if (stream_info->is_stream_http_connect) {
|
||||||
proto_item_append_text(http2_tree, " (tunneled data)");
|
proto_item_append_text(http2_tree, " (tunneled data)");
|
||||||
}
|
}
|
||||||
|
@ -2436,8 +2434,8 @@ dissect_http2_data_partial_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *h
|
||||||
* pinfo->desegment_len to DESEGMENT_ONE_MORE_SEGMENT.
|
* pinfo->desegment_len to DESEGMENT_ONE_MORE_SEGMENT.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
reassemble_http2_data_according_to_subdissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
reassemble_http2_data_according_to_subdissector(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation,
|
||||||
guint offset, guint8 flags _U_, gint length)
|
proto_tree *http2_tree,guint offset, guint8 flags _U_, gint length)
|
||||||
{
|
{
|
||||||
guint orig_offset = offset;
|
guint orig_offset = offset;
|
||||||
gint orig_length = length;
|
gint orig_length = length;
|
||||||
|
@ -2448,7 +2446,7 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t *tvb, packet_info *pinf
|
||||||
fragment_head *head = NULL;
|
fragment_head *head = NULL;
|
||||||
gboolean need_more = FALSE;
|
gboolean need_more = FALSE;
|
||||||
http2_multisegment_pdu_t *cur_msp = NULL, *prev_msp = NULL;
|
http2_multisegment_pdu_t *cur_msp = NULL, *prev_msp = NULL;
|
||||||
http2_streaming_reassembly_info_t* reassembly_info = get_streaming_reassembly_info(pinfo);
|
http2_streaming_reassembly_info_t* reassembly_info = get_streaming_reassembly_info(pinfo, conversation);
|
||||||
http2_frame_num_t cur_frame_num = get_http2_frame_num(tvb, pinfo);
|
http2_frame_num_t cur_frame_num = get_http2_frame_num(tvb, pinfo);
|
||||||
guint16 save_can_desegment;
|
guint16 save_can_desegment;
|
||||||
int save_desegment_offset;
|
int save_desegment_offset;
|
||||||
|
@ -2549,7 +2547,7 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t *tvb, packet_info *pinf
|
||||||
datalen = tvb_reported_length(reassembled_tvb);
|
datalen = tvb_reported_length(reassembled_tvb);
|
||||||
|
|
||||||
/* normally, this stage will dissect one or more completed pdus */
|
/* normally, this stage will dissect one or more completed pdus */
|
||||||
dissect_body_data(http2_tree, pinfo, reassembled_tvb, 0, datalen, ENC_NA, TRUE);
|
dissect_body_data(http2_tree, pinfo, conversation, reassembled_tvb, 0, datalen, ENC_NA, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += bytes_belong_to_prev_msp;
|
offset += bytes_belong_to_prev_msp;
|
||||||
|
@ -2612,7 +2610,7 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t *tvb, packet_info *pinf
|
||||||
pinfo->desegment_offset = 0;
|
pinfo->desegment_offset = 0;
|
||||||
pinfo->desegment_len = 0;
|
pinfo->desegment_len = 0;
|
||||||
|
|
||||||
dissect_body_data(http2_tree, pinfo, tvb, offset, datalen, ENC_NA, TRUE);
|
dissect_body_data(http2_tree, pinfo, conversation, tvb, offset, datalen, ENC_NA, TRUE);
|
||||||
|
|
||||||
if (pinfo->desegment_len) {
|
if (pinfo->desegment_len) {
|
||||||
/* only happen during first scan */
|
/* only happen during first scan */
|
||||||
|
@ -2677,20 +2675,20 @@ reassemble_http2_data_according_to_subdissector(tvbuff_t *tvb, packet_info *pinf
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree, guint offset, guint8 flags, gint length)
|
dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation, proto_tree *http2_tree, guint offset, guint8 flags, gint length)
|
||||||
{
|
{
|
||||||
http2_stream_info_t *stream_info = get_stream_info(get_http2_session(pinfo));
|
http2_stream_info_t *stream_info = get_stream_info(get_http2_session(pinfo, conversation));
|
||||||
if (stream_info->reassembly_mode == HTTP2_DATA_REASSEMBLY_MODE_STREAMING) {
|
if (stream_info->reassembly_mode == HTTP2_DATA_REASSEMBLY_MODE_STREAMING) {
|
||||||
reassemble_http2_data_according_to_subdissector(tvb, pinfo, http2_tree, offset, flags, length);
|
reassemble_http2_data_according_to_subdissector(tvb, pinfo, conversation, http2_tree, offset, flags, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tvbuff_t *data_tvb = reassemble_http2_data_into_full_frame(tvb, pinfo, http2_tree, offset, flags, length);
|
tvbuff_t *data_tvb = reassemble_http2_data_into_full_frame(tvb, pinfo, conversation, http2_tree, offset, flags, length);
|
||||||
|
|
||||||
if (data_tvb != NULL) {
|
if (data_tvb != NULL) {
|
||||||
dissect_http2_data_full_body(data_tvb, pinfo, http2_tree);
|
dissect_http2_data_full_body(data_tvb, pinfo, conversation, http2_tree);
|
||||||
} else {
|
} else {
|
||||||
dissect_http2_data_partial_body(tvb, pinfo, http2_tree, offset, length, flags);
|
dissect_http2_data_partial_body(tvb, pinfo, conversation, http2_tree, offset, length, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2707,7 +2705,8 @@ http2_get_header_value(packet_info *pinfo, const gchar* name, gboolean the_other
|
||||||
http2_header_t *hdr;
|
http2_header_t *hdr;
|
||||||
gchar* data;
|
gchar* data;
|
||||||
|
|
||||||
header_stream_info = get_header_stream_info(pinfo, the_other_direction);
|
conversation_t* conversation = find_or_create_conversation(pinfo);
|
||||||
|
header_stream_info = get_header_stream_info(pinfo, conversation, the_other_direction);
|
||||||
if (!header_stream_info) {
|
if (!header_stream_info) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2752,7 +2751,7 @@ http2_get_header_value(packet_info *pinfo, const gchar* name, gboolean the_other
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void
|
static void
|
||||||
dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags _U_, gint datalen)
|
dissect_http2_data_body(tvbuff_t *tvb, packet_info *pinfo _U_, conversation_t * conversation _U_, proto_tree *http2_tree, guint offset, guint8 flags _U_, gint datalen)
|
||||||
{
|
{
|
||||||
proto_tree_add_item(http2_tree, hf_http2_data_data, tvb, offset, datalen, ENC_NA);
|
proto_tree_add_item(http2_tree, hf_http2_data_data, tvb, offset, datalen, ENC_NA);
|
||||||
}
|
}
|
||||||
|
@ -2766,7 +2765,7 @@ http2_get_header_value(packet_info *pinfo _U_, const gchar* name _U_, gboolean t
|
||||||
|
|
||||||
/* Data (0) */
|
/* Data (0) */
|
||||||
static int
|
static int
|
||||||
dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation,proto_tree *http2_tree,
|
||||||
guint offset, guint8 flags)
|
guint offset, guint8 flags)
|
||||||
{
|
{
|
||||||
guint16 padding;
|
guint16 padding;
|
||||||
|
@ -2775,7 +2774,7 @@ dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
||||||
offset = dissect_frame_padding(tvb, &padding, http2_tree, offset, flags);
|
offset = dissect_frame_padding(tvb, &padding, http2_tree, offset, flags);
|
||||||
datalen = tvb_reported_length_remaining(tvb, offset) - padding;
|
datalen = tvb_reported_length_remaining(tvb, offset) - padding;
|
||||||
|
|
||||||
dissect_http2_data_body(tvb, pinfo, http2_tree, offset, flags, datalen);
|
dissect_http2_data_body(tvb, pinfo, conversation, http2_tree, offset, flags, datalen);
|
||||||
|
|
||||||
offset += datalen;
|
offset += datalen;
|
||||||
|
|
||||||
|
@ -2789,7 +2788,7 @@ dissect_http2_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
||||||
|
|
||||||
/* Headers */
|
/* Headers */
|
||||||
static int
|
static int
|
||||||
dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, conversation_t* conversation,proto_tree *http2_tree,
|
||||||
guint offset, guint8 flags)
|
guint offset, guint8 flags)
|
||||||
{
|
{
|
||||||
guint16 padding;
|
guint16 padding;
|
||||||
|
@ -2800,7 +2799,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
||||||
http2_stream_info_t *info;
|
http2_stream_info_t *info;
|
||||||
http2_streaming_reassembly_info_t *reassembly_info;
|
http2_streaming_reassembly_info_t *reassembly_info;
|
||||||
|
|
||||||
h2session = get_http2_session(pinfo);
|
h2session = get_http2_session(pinfo, conversation);
|
||||||
|
|
||||||
/* Trailing headers coming after a DATA stream should have END_STREAM set. DATA should be complete
|
/* Trailing headers coming after a DATA stream should have END_STREAM set. DATA should be complete
|
||||||
* so try to reassemble DATA fragments if that is the case */
|
* so try to reassemble DATA fragments if that is the case */
|
||||||
|
@ -2808,16 +2807,16 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
||||||
info = get_stream_info(h2session);
|
info = get_stream_info(h2session);
|
||||||
switch (info->reassembly_mode) {
|
switch (info->reassembly_mode) {
|
||||||
case HTTP2_DATA_REASSEMBLY_MODE_END_STREAM:
|
case HTTP2_DATA_REASSEMBLY_MODE_END_STREAM:
|
||||||
head = fragment_end_seq_next(&http2_body_reassembly_table, pinfo, get_reassembly_id_from_stream(pinfo), NULL);
|
head = fragment_end_seq_next(&http2_body_reassembly_table, pinfo, get_reassembly_id_from_stream(pinfo, conversation), NULL);
|
||||||
if(head) {
|
if(head) {
|
||||||
tvbuff_t *reassembled_data = process_reassembled_data(tvb, 0, pinfo, "Reassembled body", head,
|
tvbuff_t *reassembled_data = process_reassembled_data(tvb, 0, pinfo, "Reassembled body", head,
|
||||||
&http2_body_fragment_items, NULL, http2_tree);
|
&http2_body_fragment_items, NULL, http2_tree);
|
||||||
dissect_http2_data_full_body(reassembled_data, pinfo, http2_tree);
|
dissect_http2_data_full_body(reassembled_data, pinfo, conversation, http2_tree);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_DATA_REASSEMBLY_MODE_STREAMING:
|
case HTTP2_DATA_REASSEMBLY_MODE_STREAMING:
|
||||||
reassembly_info = get_streaming_reassembly_info(pinfo);
|
reassembly_info = get_streaming_reassembly_info(pinfo, conversation);
|
||||||
if (reassembly_info->prev_deseg_len) {
|
if (reassembly_info->prev_deseg_len) {
|
||||||
proto_tree_add_expert_format(http2_tree, pinfo, &ei_http2_reassembly_error, tvb, offset, tvb_reported_length(tvb),
|
proto_tree_add_expert_format(http2_tree, pinfo, &ei_http2_reassembly_error, tvb, offset, tvb_reported_length(tvb),
|
||||||
"Reassembling HTTP2 body for subdissector failed, %d bytes are missing before END_STREAM.",
|
"Reassembling HTTP2 body for subdissector failed, %d bytes are missing before END_STREAM.",
|
||||||
|
@ -2834,7 +2833,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
||||||
/* Mark this frame as the first header frame seen and last if the END_HEADERS flag
|
/* Mark this frame as the first header frame seen and last if the END_HEADERS flag
|
||||||
* is set. We use this to ensure when we read header values, we are not reading ones
|
* is set. We use this to ensure when we read header values, we are not reading ones
|
||||||
* that have come from a PUSH_PROMISE header (and associated CONTINUATION frames) */
|
* that have come from a PUSH_PROMISE header (and associated CONTINUATION frames) */
|
||||||
http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, FALSE);
|
http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, conversation, FALSE);
|
||||||
if (stream_info->header_start_in == 0) {
|
if (stream_info->header_start_in == 0) {
|
||||||
stream_info->header_start_in = get_http2_frame_num(tvb, pinfo);
|
stream_info->header_start_in = get_http2_frame_num(tvb, pinfo);
|
||||||
}
|
}
|
||||||
|
@ -2856,7 +2855,7 @@ dissect_http2_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *http2_tree,
|
||||||
|
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
/* decompress the header block */
|
/* decompress the header block */
|
||||||
inflate_http2_header_block(tvb, pinfo, offset, http2_tree, headlen, h2session, flags);
|
inflate_http2_header_block(tvb, pinfo, conversation, offset, http2_tree, headlen, h2session, flags);
|
||||||
#else
|
#else
|
||||||
proto_tree_add_expert_format(http2_tree, pinfo, &ei_http2_header_size, tvb, offset, headlen,
|
proto_tree_add_expert_format(http2_tree, pinfo, &ei_http2_header_size, tvb, offset, headlen,
|
||||||
"Wireshark must be built with nghttp2 for HTTP/2 HEADERS support");
|
"Wireshark must be built with nghttp2 for HTTP/2 HEADERS support");
|
||||||
|
@ -2898,9 +2897,9 @@ dissect_http2_rst_stream(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http
|
||||||
/* Settings */
|
/* Settings */
|
||||||
static int
|
static int
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags)
|
dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, conversation_t* conversation _U_,proto_tree *http2_tree, guint offset, guint8 flags)
|
||||||
#else
|
#else
|
||||||
dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags _U_)
|
dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, conversation_t* conversation, proto_tree *http2_tree, guint offset, guint8 flags _U_)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
guint32 settingsid;
|
guint32 settingsid;
|
||||||
|
@ -2966,7 +2965,7 @@ dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_
|
||||||
|
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
if(!PINFO_FD_VISITED(pinfo)) {
|
if(!PINFO_FD_VISITED(pinfo)) {
|
||||||
h2session = get_http2_session(pinfo);
|
h2session = get_http2_session(pinfo, conversation);
|
||||||
|
|
||||||
if(flags & HTTP2_FLAGS_ACK) {
|
if(flags & HTTP2_FLAGS_ACK) {
|
||||||
apply_and_pop_settings(pinfo, h2session);
|
apply_and_pop_settings(pinfo, h2session);
|
||||||
|
@ -2989,7 +2988,7 @@ dissect_http2_settings(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_
|
||||||
|
|
||||||
/* Push Promise */
|
/* Push Promise */
|
||||||
static int
|
static int
|
||||||
dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree,
|
dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, conversation_t* conversation, proto_tree *http2_tree,
|
||||||
guint offset, guint8 flags _U_)
|
guint offset, guint8 flags _U_)
|
||||||
{
|
{
|
||||||
guint16 padding;
|
guint16 padding;
|
||||||
|
@ -2997,7 +2996,7 @@ dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ht
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
http2_session_t *h2session;
|
http2_session_t *h2session;
|
||||||
|
|
||||||
h2session = get_http2_session(pinfo);
|
h2session = get_http2_session(pinfo, conversation);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
offset = dissect_frame_padding(tvb, &padding, http2_tree, offset, flags);
|
offset = dissect_frame_padding(tvb, &padding, http2_tree, offset, flags);
|
||||||
|
@ -3017,7 +3016,7 @@ dissect_http2_push_promise(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ht
|
||||||
ENC_NA);
|
ENC_NA);
|
||||||
|
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
inflate_http2_header_block(tvb, pinfo, offset, http2_tree, headlen, h2session, flags);
|
inflate_http2_header_block(tvb, pinfo, conversation, offset, http2_tree, headlen, h2session, flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
offset += headlen;
|
offset += headlen;
|
||||||
|
@ -3081,19 +3080,19 @@ dissect_http2_window_update(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *h
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *http2_tree, guint offset, guint8 flags)
|
dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, conversation_t* conversation, proto_tree *http2_tree, guint offset, guint8 flags)
|
||||||
{
|
{
|
||||||
guint16 padding;
|
guint16 padding;
|
||||||
gint headlen;
|
gint headlen;
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
http2_session_t *h2session;
|
http2_session_t *h2session;
|
||||||
|
|
||||||
h2session = get_http2_session(pinfo);
|
h2session = get_http2_session(pinfo, conversation);
|
||||||
|
|
||||||
/* Mark this as the last CONTINUATION frame for a HEADERS frame. This is used to know the context when we read
|
/* Mark this as the last CONTINUATION frame for a HEADERS frame. This is used to know the context when we read
|
||||||
* header (is the source a HEADER frame or a PUSH_PROMISE frame?) */
|
* header (is the source a HEADER frame or a PUSH_PROMISE frame?) */
|
||||||
if (flags & HTTP2_FLAGS_END_HEADERS) {
|
if (flags & HTTP2_FLAGS_END_HEADERS) {
|
||||||
http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, FALSE);
|
http2_header_stream_info_t *stream_info = get_header_stream_info(pinfo, conversation, FALSE);
|
||||||
if (stream_info->header_start_in != 0 && stream_info->header_end_in == 0) {
|
if (stream_info->header_start_in != 0 && stream_info->header_end_in == 0) {
|
||||||
stream_info->header_end_in = get_http2_frame_num(tvb, pinfo);
|
stream_info->header_end_in = get_http2_frame_num(tvb, pinfo);
|
||||||
}
|
}
|
||||||
|
@ -3112,7 +3111,7 @@ dissect_http2_continuation(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ht
|
||||||
proto_tree_add_item(http2_tree, hf_http2_continuation_header, tvb, offset, headlen, ENC_ASCII|ENC_NA);
|
proto_tree_add_item(http2_tree, hf_http2_continuation_header, tvb, offset, headlen, ENC_ASCII|ENC_NA);
|
||||||
|
|
||||||
#ifdef HAVE_NGHTTP2
|
#ifdef HAVE_NGHTTP2
|
||||||
inflate_http2_header_block(tvb, pinfo, offset, http2_tree, headlen, h2session, flags);
|
inflate_http2_header_block(tvb, pinfo, conversation, offset, http2_tree, headlen, h2session, flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
offset += headlen;
|
offset += headlen;
|
||||||
|
@ -3163,6 +3162,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
|
||||||
struct HTTP2Tap *http2_stats;
|
struct HTTP2Tap *http2_stats;
|
||||||
GHashTable* entry;
|
GHashTable* entry;
|
||||||
struct tcp_analysis* tcpd;
|
struct tcp_analysis* tcpd;
|
||||||
|
conversation_t* conversation = find_or_create_conversation(pinfo);
|
||||||
|
|
||||||
if(!p_get_proto_data(wmem_file_scope(), pinfo, proto_http2, 0)) {
|
if(!p_get_proto_data(wmem_file_scope(), pinfo, proto_http2, 0)) {
|
||||||
http2_header_data_t *header_data;
|
http2_header_data_t *header_data;
|
||||||
|
@ -3241,7 +3241,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
|
||||||
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s[%u]", type_str, streamid);
|
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s[%u]", type_str, streamid);
|
||||||
|
|
||||||
/* fill hash table with stream ids and skip all unknown frames */
|
/* fill hash table with stream ids and skip all unknown frames */
|
||||||
tcpd = get_tcp_conversation_data(NULL, pinfo);
|
tcpd = get_tcp_conversation_data(conversation, pinfo);
|
||||||
if (tcpd != NULL && type_idx != -1) {
|
if (tcpd != NULL && type_idx != -1) {
|
||||||
entry = (GHashTable*)g_hash_table_lookup(streamid_hash, GUINT_TO_POINTER(tcpd->stream));
|
entry = (GHashTable*)g_hash_table_lookup(streamid_hash, GUINT_TO_POINTER(tcpd->stream));
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
|
@ -3253,7 +3253,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the current stream, used for per-stream processing later in the dissection */
|
/* Mark the current stream, used for per-stream processing later in the dissection */
|
||||||
http2_session_t *http2_session = get_http2_session(pinfo);
|
http2_session_t *http2_session = get_http2_session(pinfo, conversation);
|
||||||
http2_session->current_stream_id = streamid;
|
http2_session->current_stream_id = streamid;
|
||||||
|
|
||||||
/* Collect stats */
|
/* Collect stats */
|
||||||
|
@ -3262,11 +3262,11 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
|
||||||
|
|
||||||
switch(type){
|
switch(type){
|
||||||
case HTTP2_DATA: /* Data (0) */
|
case HTTP2_DATA: /* Data (0) */
|
||||||
dissect_http2_data(tvb, pinfo, http2_tree, offset, flags);
|
dissect_http2_data(tvb, pinfo, conversation, http2_tree, offset, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_HEADERS: /* Headers (1) */
|
case HTTP2_HEADERS: /* Headers (1) */
|
||||||
dissect_http2_headers(tvb, pinfo, http2_tree, offset, flags);
|
dissect_http2_headers(tvb, pinfo, conversation, http2_tree, offset, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_PRIORITY: /* Priority (2) */
|
case HTTP2_PRIORITY: /* Priority (2) */
|
||||||
|
@ -3278,11 +3278,11 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_SETTINGS: /* Settings (4) */
|
case HTTP2_SETTINGS: /* Settings (4) */
|
||||||
dissect_http2_settings(tvb, pinfo, http2_tree, offset, flags);
|
dissect_http2_settings(tvb, pinfo, conversation, http2_tree, offset, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_PUSH_PROMISE: /* PUSH Promise (5) */
|
case HTTP2_PUSH_PROMISE: /* PUSH Promise (5) */
|
||||||
dissect_http2_push_promise(tvb, pinfo, http2_tree, offset, flags);
|
dissect_http2_push_promise(tvb, pinfo, conversation, http2_tree, offset, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_PING: /* Ping (6) */
|
case HTTP2_PING: /* Ping (6) */
|
||||||
|
@ -3298,7 +3298,7 @@ dissect_http2_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_CONTINUATION: /* Continuation (9) */
|
case HTTP2_CONTINUATION: /* Continuation (9) */
|
||||||
dissect_http2_continuation(tvb, pinfo, http2_tree, offset, flags);
|
dissect_http2_continuation(tvb, pinfo, conversation, http2_tree, offset, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HTTP2_ALTSVC: /* ALTSVC (10) */
|
case HTTP2_ALTSVC: /* ALTSVC (10) */
|
||||||
|
@ -3374,7 +3374,7 @@ dissect_http2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *da
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember http2 conversation. */
|
/* Remember http2 conversation. */
|
||||||
get_http2_session(pinfo);
|
get_http2_session(pinfo, conversation);
|
||||||
dissect_http2(tvb, pinfo, tree, data);
|
dissect_http2(tvb, pinfo, tree, data);
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
|
|
Loading…
Reference in New Issue