iSCSI: handle repetition of InitiatorTaskTag fore request / response tracking

Use a red-black tree instead of a hash map so as to take he current frame number into account
Only insert entries in the red-black tree on first pass

Bug: 11250
Change-Id: Ic6e4a5e4f3cd4a22c2df0b8851c6651695648fa8
Reviewed-on: https://code.wireshark.org/review/8763
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
Pascal Quantin 2015-06-04 21:54:44 +02:00 committed by Alexis La Goutte
parent 509eb46981
commit 5061da3f96
1 changed files with 60 additions and 20 deletions

View File

@ -211,7 +211,7 @@ enum iscsi_digest {
typedef struct _iscsi_session_t {
enum iscsi_digest header_digest;
enum iscsi_digest data_digest;
wmem_map_t *itlq; /* indexed by ITT */
wmem_tree_t *itlq; /* indexed by ITT */
wmem_map_t *itl; /* indexed by LUN */
} iscsi_session_t;
@ -505,6 +505,7 @@ static const value_string iscsi_reject_reasons[] = {
typedef struct _iscsi_conv_data {
guint32 data_in_frame;
guint32 data_out_frame;
guint32 itt;
itlq_nexus_t itlq;
} iscsi_conv_data_t;
@ -732,6 +733,8 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
guint ahs_cdb_length=0;
guint ahs_cdb_offset=0;
guint32 data_offset=0;
wmem_tree_key_t key[3];
guint32 itt;
if(paddedDataSegmentLength & 3)
paddedDataSegmentLength += 4 - (paddedDataSegmentLength & 3);
@ -739,25 +742,62 @@ dissect_iscsi_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint off
/* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "iSCSI");
/* XXX we need a way to handle replayed iscsi itt here */
cdata=(iscsi_conv_data_t *)wmem_map_lookup(iscsi_session->itlq, GUINT_TO_POINTER(tvb_get_ntohl(tvb, offset+16)));
if(!cdata){
cdata = wmem_new(wmem_file_scope(), iscsi_conv_data_t);
cdata->itlq.lun=0xffff;
cdata->itlq.scsi_opcode=0xffff;
cdata->itlq.task_flags=0;
cdata->itlq.data_length=0;
cdata->itlq.bidir_data_length=0;
cdata->itlq.fc_time = pinfo->fd->abs_ts;
cdata->itlq.first_exchange_frame=0;
cdata->itlq.last_exchange_frame=0;
cdata->itlq.flags=0;
cdata->itlq.alloc_len=0;
cdata->itlq.extra_data=NULL;
cdata->data_in_frame=0;
cdata->data_out_frame=0;
itt = tvb_get_ntohl(tvb, offset+16);
key[0].length = 1;
key[0].key = &itt;
key[1].length = 1;
key[1].key = &pinfo->fd->num;
key[2].length = 0;
key[2].key = NULL;
wmem_map_insert(iscsi_session->itlq, GUINT_TO_POINTER(tvb_get_ntohl(tvb, offset+16)), cdata);
if (!PINFO_FD_VISITED(pinfo)) {
if (opcode == ISCSI_OPCODE_SCSI_COMMAND) {
cdata = wmem_new(wmem_file_scope(), iscsi_conv_data_t);
cdata->itlq.lun = 0xffff;
cdata->itlq.scsi_opcode = 0xffff;
cdata->itlq.task_flags = 0;
cdata->itlq.data_length = 0;
cdata->itlq.bidir_data_length = 0;
cdata->itlq.fc_time = pinfo->fd->abs_ts;
cdata->itlq.first_exchange_frame = 0;
cdata->itlq.last_exchange_frame = 0;
cdata->itlq.flags = 0;
cdata->itlq.alloc_len = 0;
cdata->itlq.extra_data = NULL;
cdata->data_in_frame = 0;
cdata->data_out_frame = 0;
cdata->itt = itt;
wmem_tree_insert32_array(iscsi_session->itlq, key, (void *)cdata);
} else {
cdata = (iscsi_conv_data_t *)wmem_tree_lookup32_array_le(iscsi_session->itlq, key);
if (cdata && (cdata->itt != itt)) {
cdata = NULL;
}
}
} else {
cdata = (iscsi_conv_data_t *)wmem_tree_lookup32_array_le(iscsi_session->itlq, key);
if (cdata && (cdata->itt != itt)) {
cdata = NULL;
}
}
if(!cdata) {
/* Create a fake temporary structure */
cdata = wmem_new(wmem_packet_scope(), iscsi_conv_data_t);
cdata->itlq.lun = 0xffff;
cdata->itlq.scsi_opcode = 0xffff;
cdata->itlq.task_flags = 0;
cdata->itlq.data_length = 0;
cdata->itlq.bidir_data_length = 0;
cdata->itlq.fc_time = pinfo->fd->abs_ts;
cdata->itlq.first_exchange_frame = 0;
cdata->itlq.last_exchange_frame = 0;
cdata->itlq.flags = 0;
cdata->itlq.alloc_len = 0;
cdata->itlq.extra_data = NULL;
cdata->data_in_frame = 0;
cdata->data_out_frame = 0;
cdata->itt = itt;
}
if (opcode == ISCSI_OPCODE_SCSI_RESPONSE ||
@ -2353,7 +2393,7 @@ dissect_iscsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean chec
iscsi_session = wmem_new(wmem_file_scope(), iscsi_session_t);
iscsi_session->header_digest = ISCSI_DIGEST_AUTO;
iscsi_session->data_digest = ISCSI_DIGEST_AUTO;
iscsi_session->itlq = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
iscsi_session->itlq = wmem_tree_new(wmem_file_scope());
iscsi_session->itl = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
conversation_add_proto_data(conversation, proto_iscsi, iscsi_session);