tcp 拥塞控制字段解析

tcp的struct 解释https://www.cnblogs.com/codestack/p/15578849.html

 

1、tcp_sock 成员

  1.  tp->undo_retrans  ;//标记是否发生过真正的重传。如果此标记为 0,则表示没有实际的重传。

在进入 disorder或者recover的时候 ;调用tcp_init_undo初始化,此时一般值设置为-1;

static inline void tcp_init_undo(struct tcp_sock *tp)
{
    tp->undo_marker = tp->snd_una;
    /* Retransmission still in flight may cause DSACKs later. */
    tp->undo_retrans = tp->retrans_out ? : -1;
}

 然后重传skb的时候 如果此值为-1;则赋值为0; 然后加上重传的skb 段数

int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
{

    /* Save stamp of the first (attempted) retransmit. */
    if (!tp->retrans_stamp)
        tp->retrans_stamp = tcp_skb_timestamp(skb);

    if (tp->undo_retrans < 0)
        tp->undo_retrans = 0;
    tp->undo_retrans += tcp_skb_pcount(skb);
    return err;
}

 

 如果有重传的包被sack确认,因此减少撤销重传的计数。

/* Mark the given newly-SACKed range as such, adjusting counters and hints. */
static u8 tcp_sacktag_one(struct sock *sk,
{
    struct tcp_sock *tp = tcp_sk(sk);

    /* Account D-SACK for retransmitted packet. */
    if (dup_sack && (sacked & TCPCB_RETRANS)) {
        if (tp->undo_marker && tp->undo_retrans > 0 &&
            after(end_seq, tp->undo_marker))// 表明对端接收到了原始报文和拥塞之后发送的重传报文,将undo_retrans递减一 dup-seg
            tp->undo_retrans--;
        if ((sacked & TCPCB_SACKED_ACKED) &&
            before(start_seq, state->reord))
                state->reord = start_seq;
    }

 

 

  • tp->undo_marker 使用F-RTO算法进行发送超时处理,或进入 Recovery 进行重传,或进入 Loss 开始慢启动时,记录当时 SND.UNA, 标记重传起始点

 

posted @ 2024-10-29 17:27  codestacklinuxer  阅读(38)  评论(0)    收藏  举报