aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-dns.c
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2014-11-03 23:32:47 +0100
committerEvan Huus <eapache@gmail.com>2014-11-05 02:40:07 +0000
commitaae48be5a54a7992ecfda525a24465dbf102d11a (patch)
tree3ae440e54903f9dd2dcaeb79d9ee05bfd86afe13 /epan/dissectors/packet-dns.c
parent2bd15c7cefcf87aa6b2d9d53477f0ece897ba620 (diff)
DNS: replace hash map by red-black tree to fix request/response tracking when transaction id is reused
Bug: 10657 Change-Id: Id4356dcd6802da40b4a3e2e2095cc9d2932c2c68 Reviewed-on: https://code.wireshark.org/review/5100 Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-dns.c')
-rw-r--r--epan/dissectors/packet-dns.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/epan/dissectors/packet-dns.c b/epan/dissectors/packet-dns.c
index 40bfa41466..268595102f 100644
--- a/epan/dissectors/packet-dns.c
+++ b/epan/dissectors/packet-dns.c
@@ -373,11 +373,12 @@ typedef struct _dns_transaction_t {
guint32 req_frame;
guint32 rep_frame;
nstime_t req_time;
+ guint id;
} dns_transaction_t;
/* Structure containing conversation specific information */
typedef struct _dns_conv_info_t {
- wmem_map_t *pdus;
+ wmem_tree_t *pdus;
} dns_conv_info_t;
/* DNS structs and definitions */
@@ -3579,6 +3580,7 @@ dissect_dns_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
conversation_t *conversation;
dns_conv_info_t *dns_info;
dns_transaction_t *dns_trans;
+ wmem_tree_key_t key[3];
dns_data_offset = offset;
@@ -3633,9 +3635,17 @@ dissect_dns_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
* it to the list of information structures.
*/
dns_info = wmem_new(wmem_file_scope(), dns_conv_info_t);
- dns_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
+ dns_info->pdus=wmem_tree_new(wmem_file_scope());
conversation_add_proto_data(conversation, proto_dns, dns_info);
}
+
+ key[0].length = 1;
+ key[0].key = &id;
+ key[1].length = 1;
+ key[1].key = &pinfo->fd->num;
+ key[2].length = 0;
+ key[2].key = NULL;
+
if (!pinfo->fd->flags.visited) {
if (!(flags&F_RESPONSE)) {
/* This is a request */
@@ -3643,15 +3653,23 @@ dissect_dns_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
dns_trans->req_frame=pinfo->fd->num;
dns_trans->rep_frame=0;
dns_trans->req_time=pinfo->fd->abs_ts;
- wmem_map_insert(dns_info->pdus, GUINT_TO_POINTER(id), (void *)dns_trans);
+ dns_trans->id = id;
+ wmem_tree_insert32_array(dns_info->pdus, key, (void *)dns_trans);
} else {
- dns_trans=(dns_transaction_t *)wmem_map_lookup(dns_info->pdus, GUINT_TO_POINTER(id));
+ dns_trans=(dns_transaction_t *)wmem_tree_lookup32_array_le(dns_info->pdus, key);
if (dns_trans) {
- dns_trans->rep_frame=pinfo->fd->num;
+ if (dns_trans->id != id) {
+ dns_trans = NULL;
+ } else {
+ dns_trans->rep_frame=pinfo->fd->num;
+ }
}
}
} else {
- dns_trans=(dns_transaction_t *)wmem_map_lookup(dns_info->pdus, GUINT_TO_POINTER(id));
+ dns_trans=(dns_transaction_t *)wmem_tree_lookup32_array_le(dns_info->pdus, key);
+ if (dns_trans && dns_trans->id != id) {
+ dns_trans = NULL;
+ }
}
if (!dns_trans) {
/* create a "fake" pana_trans structure */