TCP ECN源代码

时间:2014-04-26 17:14:59

标签: linux tcp linux-kernel

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

tp->ecn_flags & TCP_ECN_OK

此外,请在socket,sock,tcp_sock,sk_buff之间解释。

是否有任何参考资料更详细或更清楚。

谢谢。

更新

内核的网络部分主要使用两种数据结构:一种用于保持连接状态,名为 sock (用于" socket"),另一种用于保存数据以及 sk_buff 的传入和传出数据包的状态(对于" socket buffer")。本节将介绍它们。我们还包括tcp_opt的简要描述,这是一种结构,它是sock结构的一部分,用于维护TCP连接状态。 ( from" Linux Kernel 2.4.20" 中的网络代码映射)

2 个答案:

答案 0 :(得分:6)

TCP_ECN_OK是来自linuxkernel的内部struct tcp_sock as(字段ecn_flags)的位标志。其中有几个位标志(来自Linux内核源代码include/net/tcp.h file):

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

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

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

正如维基百科http://en.wikipedia.org/wiki/Explicit_Congestion_Notification

所述
  

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

     

...跳到Linux部分

     

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

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

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

例如,当我们在传出套接字连接开始时发送SYN,并且为传出连接启用了sysctl tcp_ecn(“sysctl_tcp_ecn”标志为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         }

稍后,如果连接的另一端不支持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 }

对于传入连接,我们取消设置TCP_ECN_OK,如果在传入SYN中没有ECE tcp头标志(在RFC3168 "The Addition of Explicit Congestion Notification (ECN) to 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 }

答案 1 :(得分:0)

详细解释Linux网络源代码的一个很好的参考资料可以在A Map of the Networking Code in Linux Kernel 2.4.20

找到