WireShark 会假设数据包是 DUP 还是重传?

网络工程 包分析 线鲨
2021-07-20 22:44:50

我在两个不同的交换机端口上有一个 SPAN,它们将进入同一个嗅探器。主机 A 的连接端口是 SPAN 的,主机 B 的连接端口也是 SPAN 的。因为它是一个棒状配置的路由器,我希望在从应用程序日志报告通信故障期间,我可以在双方寻找一个特定的数据包。我在我的跟踪中看到有大量的重传,我很好奇 Wireshark 的逻辑是否将任何东西标记为重传,如果它看到两次?

有没有人在追踪这样的事情时有任何提示?

谢谢

1个回答

Wireshark 存储给定 TCP 流的序列号。如果新数据包没有提前序列号,则将其标记为重传。

这是实际的Wireshark 代码epan/dissectors/packet-tcp.c(包含在下面)。

请查看tcp_analyze_sequence_number()函数,更具体地说是从第 822 行开始的块。


epan/dissectors/packet-tcp.c(修订版 33861)的第 822 行

/* RETRANSMISSION/FAST RETRANSMISSION/OUT-OF-ORDER
 * If the segments contains data and if it does not advance
 * sequence number it must be either 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
&&  tcpd->fwd->nextseq
&&  (LT_SEQ(seq, tcpd->fwd->nextseq)) ){
    guint64 t;

    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->fd->abs_ts.secs-tcpd->rev->lastacktime.secs)*1000000000;
    t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->rev->lastacktime.nsecs;


    if( tcpd->rev->dupacknum>=2
    &&  tcpd->rev->lastack==seq
    &&  t<20000000 ){
        if(!tcpd->ta){
            tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
        }
        tcpd->ta->flags|=TCP_A_FAST_RETRANSMISSION;
        goto finished_checking_retransmission_type;
    }

    /* If the segment came <3ms since the segment with the highest
     * seen sequence number, then it is an OUT-OF-ORDER segment.
     *   (3ms is an arbitrary number)
     */
    t=(pinfo->fd->abs_ts.secs-tcpd->fwd->nextseqtime.secs)*1000000000;
    t=t+(pinfo->fd->abs_ts.nsecs)-tcpd->fwd->nextseqtime.nsecs;
    if( t<3000000 ){
        if(!tcpd->ta){
            tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
        }
        tcpd->ta->flags|=TCP_A_OUT_OF_ORDER;
        goto finished_checking_retransmission_type;
    }

    /* Then it has to be a generic retransmission */
    if(!tcpd->ta){
        tcp_analyze_get_acked_struct(pinfo->fd->num, TRUE, tcpd);
    }
    tcpd->ta->flags|=TCP_A_RETRANSMISSION;
    nstime_delta(&tcpd->ta->rto_ts, &pinfo->fd->abs_ts, &tcpd->fwd->nextseqtime);
    tcpd->ta->rto_frame=tcpd->fwd->nextseqframe;
}