TCP: Some protocols running ontop of TCP needs the PDUs to be delivered in order. for example decryption of DCERPCoverHTTP.

For such protocols, hte state gets out of sync of for example the same PDU is invoked twice in a row, which sometimes can happen if there is tcp retransmission and we see the same PDU twice. First for hte original segment and a second time for the tcp retransmission.
These protocols might lack an easy way to detect that a PDU is seen twice or out of order.

To handle this a little better, offer a TCP option that defaults to being disabled but when enabled skips invoking any subdissector for retransmitted or out of order packets.
(For some virtualization environments it sometimes becomes VERY common to see false tcp retransmissions due to segments being captured twice making this even worse)


We dont want this option to default to ON because for most cases we do want the current behaviour where the subdissector is called twice, or more, for any PDU that is retrasnmitted on the TPC layer.
For example, assume a SMB response packet is retransmitted on the TCP level.
This may result in a capture file that looks like
1 -> SMB request
2 <- SMB response to 1  
... 1 second ...
3 <- SMB response to 1   TCP retransmission

For this case we definitely want packet 3 to be passed to the SMB layer so that 
the request/respons ematching will detect that the response time for this transaction was > 1.0 second
We want smb.time to indicate the delta betwenn packets 1 and 3
as well as the SMB Service Response Time to indicate that this command took very long.





svn path=/trunk/; revision=42774
This commit is contained in:
Ronnie Sahlberg 2012-05-22 07:51:12 +00:00
parent 7e0c167eb0
commit 2a2dc8c5f3
1 changed files with 28 additions and 0 deletions

View File

@ -274,6 +274,15 @@ static gint ett_tcp_opt_rvbd_probe_flags = -1;
static gint ett_tcp_opt_rvbd_trpy = -1;
static gint ett_tcp_opt_rvbd_trpy_flags = -1;
/* Some protocols such as encrypted DCE/RPCoverHTTP have dependencies
* from one PDU to the next PDU and require that they are called in sequence.
* These protocols would not be able to handle PDUs coming out of order
* or for example when a PDU is seen twice, like for retransmissions.
* This preference can be set for such protocols to make sure that we dont invoke
* the subdissectors for retransmitted or out-of-order segments.
*/
static gboolean tcp_no_subdissector_on_error = FALSE;
/*
* TCP option
*/
@ -3793,6 +3802,13 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
next_tvb = tvb_new_subset_remaining(tvb, offset);
if (tcp_no_subdissector_on_error && tcpd->ta && tcpd->ta->flags & (TCP_A_RETRANSMISSION | TCP_A_OUT_OF_ORDER)) {
/* Don't try to dissect a retransmission high chance that it will mess
* subdissectors for protocols that require in-order delivery of the
* PDUs. (i.e. DCE/RPCoverHTTP and encryption)
*/
return FALSE;
}
/* determine if this packet is part of a conversation and call dissector */
/* for the conversation if available */
@ -3851,6 +3867,13 @@ decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
low_port = src_port;
high_port = dst_port;
}
if (tcp_no_subdissector_on_error && tcpd->ta && tcpd->ta->flags & (TCP_A_RETRANSMISSION | TCP_A_OUT_OF_ORDER)) {
/* Don't try to dissect a retransmission high chance that it will mess
* subdissectors for protocols that require in-order delivery of the
* PDUs. (i.e. DCE/RPCoverHTTP and encryption)
*/
return FALSE;
}
if (low_port != 0 &&
dissector_try_uint(subdissector_table, low_port, next_tvb, pinfo, tree)){
pinfo->want_pdu_tracking -= !!(pinfo->want_pdu_tracking);
@ -5573,6 +5596,11 @@ proto_register_tcp(void)
"Do not place the TCP Timestamps in the summary line",
&tcp_ignore_timestamps);
prefs_register_bool_preference(tcp_module, "no_subdissector_on_error",
"Do not call subdissectors for error packets",
"Do not call any subdissectors for Retransmitted or OutOfOrder segments",
&tcp_no_subdissector_on_error);
register_init_routine(tcp_init);
}