当前代码实现
当前默认配置,每收到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)))
当前代码实现
当前默认配置,每收到2个包,强制回复一个ack报文。
`static int
bbr_init(struct tcpcb *tp)
{
}
可以通过配置文件配置参数:[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)
{
}
`
如果配置收到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)))