我在理解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" 中的网络代码映射)
答案 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
找到