TCP ECN源代码

Tai*_*yen 3 linux tcp linux-kernel

我在include/net/tcp.h中了解TCP源代码(net/ipv4/tcp_input.c)时遇到了问题,它已经定义了TCP_ECN_OK = 1但实际意味着什么

tp->ecn_flags & TCP_ECN_OK
Run Code Online (Sandbox Code Playgroud)

另外,请在socket,sock,tcp_sock,sk_buff之间解释.

是否有任何参考资料更详细地解释或更清楚.

谢谢.

更新:

内核的网络部分主要使用两种数据结构:一种用于保持连接状态,称为sock(用于"套接字"),另一种用于保持数据以及传入和传出数据包的状态,称为sk_buff(用于"套接字") BU FF ER").本节将介绍它们.我们还包括tcp_opt的简要描述,这是一种结构,它是sock结构的一部分,用于维护TCP连接状态.(摘自"Linux Kernel 2.4.20中的网络代码图")

osg*_*sgx 7

TCP_ECN_OK是从Linux内核的内部位标记struct tcp_sock(字段ecn_flags).其中有几个位标志(来自linux内核源代码的include/net/tcp.h文件):

398 #define TCP_ECN_OK              1
399 #define TCP_ECN_QUEUE_CWR       2
400 #define TCP_ECN_DEMAND_CWR      4
401 #define TCP_ECN_SEEN            8
Run Code Online (Sandbox Code Playgroud)

表达式tp->ecn_flags & TCP_ECN_OK是逻辑测试,是否仍然设置TCP_ECN_OK.

更新:我认为TCP_ECN_OK在tcp套接字打开时设置该位(如果sysctl的当前设置在Linux中启用了ECN支持),如果套接字的另一端也支持ECN,它将保持设置状态.

如维基百科http://en.wikipedia.org/wiki/Explicit_Congestion_Notification中所述

ECN是一项可选功能,仅在两个端点都支持并愿意使用它时使用.

...跳到Linux部分

Linux内核通过sysctl接口支持TCP的ECN的三种工作模式,由/ proc/sys/net/ipv4/tcp_ecn变量的值配置:[11 - tcp_ecn inDocumentation/networking/ip-sysctl.txt ]

  • 0 - 禁用ECN,既不启动也不接受它
  • 1 - 在传入连接请求时启用ECN,并在传出连接尝试时请求ECN
  • 2 - 在传入连接请求时启用ECN,但不在传出连接上请求ECN.// 3.14中的DEFAULT //

默认值为2,这意味着默认情况下,ECN在传入连接请求时启用,但在传出连接上不会请求.无论如何,只有当TCP连接的两端都表明支持时,Linux内核才会使用ECN.[11]

例如,当我们在传出套接字连接开始时发送SYN,并且tcp_ecn为传出连接启用sysctl ("sysctl_tcp_ecn"flag is 1)时,我们在tcp头中设置ECE位并设置TCP_ECN_OK.net/ipv4/tcp_output.c第315行

315 /* Packet ECN state for a SYN.  */
316 static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
....
320         tp->ecn_flags = 0;
321         if (sock_net(sk)->ipv4.sysctl_tcp_ecn == 1) {
322                 TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR;
323                 tp->ecn_flags = TCP_ECN_OK;
324         }
Run Code Online (Sandbox Code Playgroud)

稍后,如果连接的另一端不支持ECN或禁用,我们将取消设置TCP_ECN_OK标志. net/ipv4/tcp_input.c第246行

246 static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th)
247 {
248         if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || th->cwr))
249                 tp->ecn_flags &= ~TCP_ECN_OK;
250 }
Run Code Online (Sandbox Code Playgroud)

对于传入连接,我们取消设置TCP_ECN_OK,如果在传入SYN中没有ECE tcp头标志(更多关于RFC3168中的标志和ECN " 向IP添加显式拥塞通知(ECN) ")

252 static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th)
253 {
254         if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || !th->cwr))
255                 tp->ecn_flags &= ~TCP_ECN_OK;
256 }
Run Code Online (Sandbox Code Playgroud)