aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-tcp.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2017-05-26 15:10:48 -0700
committerAnders Broman <a.broman58@gmail.com>2017-06-15 04:13:28 +0000
commit01fe854fa00e780e2eb7f9b18a11a09ff0dc1c11 (patch)
tree3def25e466f972ebebf95b1908127c2ecf487a6d /epan/dissectors/packet-tcp.c
parent86fceac9ad52531b723ce179a46931d9312a33b8 (diff)
TCP Analysis: Update the spurious retransmission check.
The spurious retransmission check operates on the last-seen acknowledgment in the reverse direction. Adjust the analysis logic so that it is checked independently of the forward sequence number. Update the documentation accordingly. Change-Id: I3714f44398501a581f967c61e119fe95f90209b1 Reviewed-on: https://code.wireshark.org/review/21769 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-tcp.c')
-rw-r--r--epan/dissectors/packet-tcp.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 1e29f63896..68a0fa6aa2 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -1752,10 +1752,10 @@ tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint3
#if 0
printf("\nanalyze_sequence numbers frame:%u\n",pinfo->num);
- printf("FWD list lastflags:0x%04x base_seq:%u: nextseq:%u\n",tcpd->fwd->lastsegmentflags,tcpd->fwd->base_seq,tcpd->fwd->tcp_analyze_seq_info->nextseq);
+ printf("FWD list lastflags:0x%04x base_seq:%u: nextseq:%u lastack:%u\n",tcpd->fwd->lastsegmentflags,tcpd->fwd->base_seq,tcpd->fwd->tcp_analyze_seq_info->nextseq,tcpd->rev->tcp_analyze_seq_info->lastack);
for(ual=tcpd->fwd->tcp_analyze_seq_info->segments; ual; ual=ual->next)
printf("Frame:%d Seq:%u Nextseq:%u\n",ual->frame,ual->seq,ual->nextseq);
- printf("REV list lastflags:0x%04x base_seq:%u nextseq:%u\n",tcpd->rev->lastsegmentflags,tcpd->rev->base_seq,tcpd->rev->tcp_analyze_seq_info->nextseq);
+ printf("REV list lastflags:0x%04x base_seq:%u nextseq:%u lastack:%u\n",tcpd->rev->lastsegmentflags,tcpd->rev->base_seq,tcpd->rev->tcp_analyze_seq_info->nextseq,tcpd->fwd->tcp_analyze_seq_info->lastack);
for(ual=tcpd->rev->tcp_analyze_seq_info->segments; ual; ual=ual->next)
printf("Frame:%d Seq:%u Nextseq:%u\n",ual->frame,ual->seq,ual->nextseq);
#endif
@@ -2003,15 +2003,12 @@ finished_fwd:
*
* Note that a simple KeepAlive is not a retransmission
*/
- if( (seglen>0 || flags&(TH_SYN|TH_FIN))
- && tcpd->fwd->tcp_analyze_seq_info->nextseq
- && (LT_SEQ(seq, tcpd->fwd->tcp_analyze_seq_info->nextseq)) ) {
+ if (seglen>0 || flags&(TH_SYN|TH_FIN)) {
+ gboolean seq_not_advanced = tcpd->fwd->tcp_analyze_seq_info->nextseq
+ && (LT_SEQ(seq, tcpd->fwd->tcp_analyze_seq_info->nextseq));
+
guint64 t;
guint64 ooo_thres;
- if (tcpd->ts_first_rtt.nsecs == 0 && tcpd->ts_first_rtt.secs == 0)
- ooo_thres = 3000000;
- else
- ooo_thres = tcpd->ts_first_rtt.nsecs + tcpd->ts_first_rtt.secs*1000000000;
if(tcpd->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ) {
goto finished_checking_retransmission_type;
@@ -2026,7 +2023,8 @@ finished_fwd:
*/
t=(pinfo->abs_ts.secs-tcpd->rev->tcp_analyze_seq_info->lastacktime.secs)*1000000000;
t=t+(pinfo->abs_ts.nsecs)-tcpd->rev->tcp_analyze_seq_info->lastacktime.nsecs;
- if( tcpd->rev->tcp_analyze_seq_info->dupacknum>=2
+ if( seq_not_advanced
+ && tcpd->rev->tcp_analyze_seq_info->dupacknum>=2
&& tcpd->rev->tcp_analyze_seq_info->lastack==seq
&& t<20000000 ) {
if(!tcpd->ta) {
@@ -2042,7 +2040,14 @@ finished_fwd:
*/
t=(pinfo->abs_ts.secs-tcpd->fwd->tcp_analyze_seq_info->nextseqtime.secs)*1000000000;
t=t+(pinfo->abs_ts.nsecs)-tcpd->fwd->tcp_analyze_seq_info->nextseqtime.nsecs;
- if( t < ooo_thres
+ if (tcpd->ts_first_rtt.nsecs == 0 && tcpd->ts_first_rtt.secs == 0) {
+ ooo_thres = 3000000;
+ } else {
+ ooo_thres = tcpd->ts_first_rtt.nsecs + tcpd->ts_first_rtt.secs*1000000000;
+ }
+
+ if( seq_not_advanced // XXX is this neccessary?
+ && t < ooo_thres
&& tcpd->fwd->tcp_analyze_seq_info->nextseq != seq + seglen ) {
if(!tcpd->ta) {
tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
@@ -2052,10 +2057,12 @@ finished_fwd:
}
/* Check for spurious retransmission. If the current seq + segment length
- * is less than or equal to the receiver's lastack, the packet contains
+ * is less than or equal to the current lastack, the packet contains
* duplicate data and may be considered spurious.
*/
- if ( seq + seglen <= tcpd->rev->tcp_analyze_seq_info->lastack ) {
+ if ( seglen > 0
+ && tcpd->rev->tcp_analyze_seq_info->lastack
+ && LE_SEQ(seq + seglen, tcpd->rev->tcp_analyze_seq_info->lastack) ) {
if(!tcpd->ta){
tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
}
@@ -2063,13 +2070,15 @@ finished_fwd:
goto finished_checking_retransmission_type;
}
- /* Then it has to be a generic retransmission */
- if(!tcpd->ta) {
- tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
+ if (seq_not_advanced) {
+ /* Then it has to be a generic retransmission */
+ if(!tcpd->ta) {
+ tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
+ }
+ tcpd->ta->flags|=TCP_A_RETRANSMISSION;
+ nstime_delta(&tcpd->ta->rto_ts, &pinfo->abs_ts, &tcpd->fwd->tcp_analyze_seq_info->nextseqtime);
+ tcpd->ta->rto_frame=tcpd->fwd->tcp_analyze_seq_info->nextseqframe;
}
- tcpd->ta->flags|=TCP_A_RETRANSMISSION;
- nstime_delta(&tcpd->ta->rto_ts, &pinfo->abs_ts, &tcpd->fwd->tcp_analyze_seq_info->nextseqtime);
- tcpd->ta->rto_frame=tcpd->fwd->tcp_analyze_seq_info->nextseqframe;
}
finished_checking_retransmission_type: