Skip to content

【BBR】【delay ack】BBR算法,delay ack,间隔几个报文再回复ack报文,存在逻辑bug #1065

@honglingjinol

Description

@honglingjinol

当前代码实现

当前默认配置,每收到2个包,强制回复一个ack报文。
`static int
bbr_init(struct tcpcb *tp)
{

if (V_tcp_delack_enabled == 1) 
    tp->t_delayed_ack = 2;
else if (V_tcp_delack_enabled == 0)
tp->t_delayed_ack = 0;
else if (V_tcp_delack_enabled < 100)
    tp->t_delayed_ack = V_tcp_delack_enabled;
else
tp->t_delayed_ack = 2;

}
可以通过配置文件配置参数:
[freebsd.sysctl]

net.inet.tcp.delayed_ack=5
`

配置每收到5个包回复1个ACK报文后,效果仍然为每收到2个报文回复一个ACK报文。

关键实现代码bbr.c
`

#define DELAY_ACK(tp, bbr, nsegs)
(((tp->t_flags & TF_RXWIN0SENT) == 0) &&
((tp->t_flags & TF_DELACK) == 0) &&
((bbr->bbr_segs_rcvd + nsegs) < tp->t_delayed_ack) &&
(tp->t_delayed_ack || (tp->t_flags & TF_NEEDSYN)))

static int
bbr_do_fastnewdata(struct mbuf *m, struct tcphdr *th, struct socket *so,
struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
uint32_t tiwin, int32_t nxt_pkt)
{

xxx
if (DELAY_ACK(tp, bbr, nsegs)) {
bbr->bbr_segs_rcvd += max(1, nsegs);
tp->t_flags |= TF_DELACK;
bbr_timer_cancel(bbr, __LINE__, bbr->r_ctl.rc_rcvtime);
} else {
bbr->r_wanted_output = 1;
tp->t_flags |= TF_ACKNOW;
}

xxx

}
`
如果配置收到5个包才回复一个ACK,那么:tp->t_delayed_ack = 5

收到第1个数据包后,bbr->bbr_segs_rcvd = 1。bbr_do_fastnewdata函数中,会把t_flags置上TF_DELACK标记。

收到第2个数据包时,在宏代码执行DELAY_ACK时,因为(tp->t_flags & TF_DELACK) == 0)条件不满足,会进入bbr_do_fastnewdata函数的8625行执行。立即发送ACK报文。

根因:DELAY_ACK中判断tp->t_flags & TF_DELACK逻辑不合理。我认为应该删除tp->t_flags & TF_DELACK的判断逻辑,即TF_DELACK宏代码修改为:
#define DELAY_ACK(tp, bbr, nsegs) \ (((tp->t_flags & TF_RXWIN0SENT) == 0) && \ ((bbr->bbr_segs_rcvd + nsegs) < tp->t_delayed_ack) && \ (tp->t_delayed_ack || (tp->t_flags & TF_NEEDSYN)))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions