TCP发送窗口更新tcp_ack_update_window
2021-05-18 02:29
标签:red int const 设置 hdr UNC 更新窗口 wro eve 在tcp_ack接收ACK处理函数中,如果确认当前走慢速路径,那么会调用tcp_ack_update_window函数检查窗口是否需要更新并更新之,并且更新未确认数据的位置,即更新窗口左边沿; tcp_ack_update_window执行窗口更新主流程,函数首先根据窗口扩大因子计算实际的窗口大小,然后判断是否需要更新窗口,若需要则对窗口进行更新,注意,只有当窗口不相等的情况下才会实际更新窗口,否则只更新最后一次窗口更新ack序号;窗口更新需要更新窗口,同步MSS,检查是否开启快速路径等;函数最后还将设置未确认数据位置,即窗口左边沿; tcp_may_update_window用于判断窗口是否需要更新,满足以下条件之一则更新: (1) ACK确认了新的数据; (2) 未满足(1),ACK未确认数据,通过上面snd_una
(3) 未满足(1)(2),未确认数据,ack需要也未更新,但是窗口有所改变,则说明单单发送了一个窗口更新通知; TCP发送窗口更新tcp_ack_update_window 标签:red int const 设置 hdr UNC 更新窗口 wro eve 原文地址:https://www.cnblogs.com/wanpengcoder/p/11750676.html 1 static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
2 {
3 /* 快速路径&& ack确认了新数据 */
4 if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
5 ;
6 }
7 /* 慢速路径 */
8 else {
9 /* 更新发送窗口 */
10 flag |= tcp_ack_update_window(sk, skb, ack, ack_seq);
11 }
12 }
1 /* Update our send window.
2 *
3 * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2
4 * and in FreeBSD. NetBSD‘s one is even worse.) is wrong.
5 */
6 static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32 ack,
7 u32 ack_seq)
8 {
9 struct tcp_sock *tp = tcp_sk(sk);
10 int flag = 0;
11 u32 nwin = ntohs(tcp_hdr(skb)->window);
12
13 /* 根据扩大因子计算窗口大小 */
14 if (likely(!tcp_hdr(skb)->syn))
15 nwin rx_opt.snd_wscale;
16
17 /* 需要更新窗口的话 */
18 if (tcp_may_update_window(tp, ack, ack_seq, nwin)) {
19 /* 窗口更新标记 */
20 flag |= FLAG_WIN_UPDATE;
21
22 /* 记录窗口更新的ack序号 */
23 tcp_update_wl(tp, ack_seq);
24
25
26 /* 发送窗口与通告窗口不等时 */
27 if (tp->snd_wnd != nwin) {
28
29 /* 更新发送窗口*/
30 tp->snd_wnd = nwin;
31
32 /* Note, it is the only place, where
33 * fast path is recovered for sending TCP.
34 */
35 /* 判断是否开启快路标志 */
36 tp->pred_flags = 0;
37 tcp_fast_path_check(sk);
38
39 /* 有数据要发送 */
40 if (tcp_send_head(sk))
41 tcp_slow_start_after_idle_check(sk);
42
43 /* 窗口大于以前记录的最大窗口 */
44 if (nwin > tp->max_window) {
45 /* 更新最大窗口 */
46 tp->max_window = nwin;
47 /* 更新mss */
48 tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie);
49 }
50 }
51 }
52
53 /* 更新未确认的数据位置,即窗口左边沿 */
54 tcp_snd_una_update(tp, ack);
55
56 return flag;
57 }
1 /* Check that window update is acceptable.
2 * The function assumes that snd_una 3 */
4 static inline bool tcp_may_update_window(const struct tcp_sock *tp,
5 const u32 ack, const u32 ack_seq,
6 const u32 nwin)
7 {
8 /*
9 更新条件
10 ack确认序号确认了数据,意味着窗口要收缩
11 ack确认序号未确认新数据,ack序号比上一个更新窗口ack序号要新
12 ack序号与上一个更新装ack序号一致,但是窗口比以前的窗口大
13 */
14 return after(ack, tp->snd_una) ||
15 after(ack_seq, tp->snd_wl1) ||
16 (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd);
17 }
文章标题:TCP发送窗口更新tcp_ack_update_window
文章链接:http://soscw.com/index.php/essay/86988.html