Skip to content

Instantly share code, notes, and snippets.

@netbrain
Created February 8, 2018 10:54
Show Gist options
  • Save netbrain/74662f336e06a83d13c8b3ac15d58e83 to your computer and use it in GitHub Desktop.
Save netbrain/74662f336e06a83d13c8b3ac15d58e83 to your computer and use it in GitHub Desktop.
retrans notes
/* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
* If the segment contains data (or is a SYN or a FIN) and
* if it does not advance the sequence number, it must be one
* of these three.
* Only test for this if we know what the seq number should be
* (tcpd->fwd->nextseq)
*
* Note that a simple KeepAlive is not a retransmission
*/
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->ta && (tcpd->ta->flags&TCP_A_KEEP_ALIVE) ) {
goto finished_checking_retransmission_type;
}
/* If there were >=2 duplicate ACKs in the reverse direction
* (there might be duplicate acks missing from the trace)
* and if this sequence number matches those ACKs
* and if the packet occurs within 20ms of the last
* duplicate ack
* then this is a fast retransmission
*/
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( seq_not_advanced
&& tcpd->rev->tcp_analyze_seq_info->dupacknum>=2
&& tcpd->rev->tcp_analyze_seq_info->lastack==seq
&& t<20000000 ) {
if(!tcpd->ta) {
tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd);
}
tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
goto finished_checking_retransmission_type;
}
/* If the segment came relatively close since the segment with the highest
* seen sequence number and it doesn't look like a retransmission
* then it is an OUT-OF-ORDER segment.
*/
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 (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);
}
tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
goto finished_checking_retransmission_type;
}
/* Check for spurious retransmission. If the current seq + segment length
* is less than or equal to the current lastack, the packet contains
* duplicate data and may be considered spurious.
*/
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);
}
tcpd->ta->flags|=TCP_A_SPURIOUS_RETRANSMISSION;
goto finished_checking_retransmission_type;
}
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment