From d966c0dd5e7e66fd06fac0c07d496f5090d7d220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig=20Bj=C3=B8rlykke?= Date: Mon, 26 Aug 2019 10:38:06 +0200 Subject: coap: Improve request/response tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use both Token and Message ID in request/response tracking and retransmission detection. The token is the same when using observables but the message id is increasing. Change-Id: I545416ce139328e6a8eb67258d7b51bddb6b278e Reviewed-on: https://code.wireshark.org/review/34367 Petri-Dish: Stig Bjørlykke Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- epan/dissectors/packet-coap.c | 63 +++++++++++++++++++++++++++++-------------- epan/dissectors/packet-coap.h | 10 ++++--- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/epan/dissectors/packet-coap.c b/epan/dissectors/packet-coap.c index 56695cbc2b..3acff1a913 100644 --- a/epan/dissectors/packet-coap.c +++ b/epan/dissectors/packet-coap.c @@ -1037,13 +1037,14 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, guint32 token_len; guint8 code; guint8 code_class; - guint32 mid; + guint32 mid = 0; gint coap_length; gchar *coap_token_str; coap_info *coinfo; conversation_t *conversation; coap_conv_info *ccinfo; coap_transaction *coap_trans = NULL; + coap_request_response *coap_req_rsp = NULL; // TODO support TCP/WebSocket/TCP with more than one PDU per packet. // These probably require a unique coinfo for each. @@ -1173,9 +1174,7 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, if ((!PINFO_FD_VISITED(pinfo)) && (code_class == 0)) { /* New request - log it */ coap_trans = wmem_new0(wmem_file_scope(), coap_transaction); - coap_trans->req_frame = pinfo->num; - coap_trans->rsp_frame = 0; - coap_trans->req_time = pinfo->abs_ts; + coap_trans->req_rsp = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); if (coinfo->uri_str_strbuf) { /* Store the URI into CoAP transaction info */ coap_trans->uri_str_strbuf = wmem_strbuf_new(wmem_file_scope(), wmem_strbuf_get_str(coinfo->uri_str_strbuf)); @@ -1196,12 +1195,6 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, } } else { if ((code_class >= 2) && (code_class <= 5)) { - if (!PINFO_FD_VISITED(pinfo)) { - if (coap_trans->rsp_frame == 0) { - /* Log the first matching response frame */ - coap_trans->rsp_frame = pinfo->num; - } - } if (coap_trans->uri_str_strbuf) { /* Copy the URI stored in matching transaction info into CoAP packet info */ coinfo->uri_str_strbuf = wmem_strbuf_new(wmem_packet_scope(), wmem_strbuf_get_str(coap_trans->uri_str_strbuf)); @@ -1232,6 +1225,30 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, } } } + + if (coap_trans) { + coap_req_rsp = (coap_request_response *)wmem_map_lookup(coap_trans->req_rsp, GINT_TO_POINTER(mid)); + if (!PINFO_FD_VISITED(pinfo)) { + if (!coap_req_rsp) { + coap_req_rsp = wmem_new0(wmem_file_scope(), coap_request_response); + wmem_map_insert(coap_trans->req_rsp, GINT_TO_POINTER(mid), (void *)coap_req_rsp); + } + if (code_class == 0) { + /* This is a request */ + if (coap_req_rsp->req_frame == 0) { + /* Log the first request frame */ + coap_req_rsp->req_frame = pinfo->num; + coap_req_rsp->req_time = pinfo->abs_ts; + } + } else if ((code_class >= 2) && (code_class <= 5)) { + /* This is a reply */ + if (coap_req_rsp->rsp_frame == 0) { + /* Log the first matching response frame */ + coap_req_rsp->rsp_frame = pinfo->num; + } + } + } + } } } @@ -1250,45 +1267,51 @@ dissect_coap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, if (wmem_strbuf_get_len(coinfo->uri_query_strbuf) > 0) col_append_str(pinfo->cinfo, COL_INFO, wmem_strbuf_get_str(coinfo->uri_query_strbuf)); - if (coap_trans != NULL) { + if (coap_req_rsp != NULL) { /* Print state tracking in the tree */ if (code_class == 0) { /* This is a request */ - if (coap_trans->rsp_frame) { + if (coap_req_rsp->rsp_frame) { proto_item *it; it = proto_tree_add_uint(coap_tree, hf_coap_response_in, - tvb, 0, 0, coap_trans->rsp_frame); + tvb, 0, 0, coap_req_rsp->rsp_frame); proto_item_set_generated(it); } - if (coap_trans->req_frame != pinfo->num) { + if (coap_req_rsp->req_frame != pinfo->num) { col_append_str(pinfo->cinfo, COL_INFO, " [Retransmission]"); proto_item *it = proto_tree_add_uint(coap_tree, hf_coap_request_resend_in, - tvb, 0, 0, coap_trans->req_frame); + tvb, 0, 0, coap_req_rsp->req_frame); proto_item_set_generated(it); expert_add_info(pinfo, it, &ei_retransmitted); } } else if ((code_class >= 2) && (code_class <= 5)) { /* This is a reply */ - if (coap_trans->req_frame) { + if (coap_req_rsp->req_frame) { proto_item *it; nstime_t ns; it = proto_tree_add_uint(coap_tree, hf_coap_response_to, - tvb, 0, 0, coap_trans->req_frame); + tvb, 0, 0, coap_req_rsp->req_frame); proto_item_set_generated(it); - nstime_delta(&ns, &pinfo->abs_ts, &coap_trans->req_time); + nstime_delta(&ns, &pinfo->abs_ts, &coap_req_rsp->req_time); it = proto_tree_add_time(coap_tree, hf_coap_response_time, tvb, 0, 0, &ns); proto_item_set_generated(it); } - if (coap_trans->rsp_frame != pinfo->num) { + if (coap_req_rsp->rsp_frame != pinfo->num) { col_append_str(pinfo->cinfo, COL_INFO, " [Retransmission]"); proto_item *it = proto_tree_add_uint(coap_tree, hf_coap_response_resend_in, - tvb, 0, 0, coap_trans->rsp_frame); + tvb, 0, 0, coap_req_rsp->rsp_frame); proto_item_set_generated(it); expert_add_info(pinfo, it, &ei_retransmitted); } + } + } + + if (coap_trans != NULL) { + if ((code_class >= 2) && (code_class <= 5)) { + /* This is a reply */ if (coinfo->object_security && coap_trans->oscore_info) { proto_item *it; diff --git a/epan/dissectors/packet-coap.h b/epan/dissectors/packet-coap.h index 8e1e06441b..b8783c7ce2 100644 --- a/epan/dissectors/packet-coap.h +++ b/epan/dissectors/packet-coap.h @@ -44,13 +44,17 @@ typedef struct { /* CoAP Transaction tracking information */ typedef struct { - guint32 req_frame; - guint32 rsp_frame; - nstime_t req_time; + wmem_map_t *req_rsp; wmem_strbuf_t *uri_str_strbuf; oscore_info_t *oscore_info; /* OSCORE transaction to decrypt response */ } coap_transaction; +typedef struct { + guint32 req_frame; + guint32 rsp_frame; + nstime_t req_time; +} coap_request_response; + /* common header fields, subtrees and expert info for SSL and DTLS dissectors */ typedef struct coap_common_dissect { struct { -- cgit v1.2.3