【问题标题】:TCP ECN source codeTCP ECN源代码
【发布时间】:2015-07-15 01:38:17
【问题描述】:

我无法理解 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(用于“套接字缓冲区”)。这两个都在本节中描述。我们还包括对 tcp_opt 的简要描述,该结构是 sock 结构的一部分,用于维护 TCP 连接状态。 (来自“Linux Kernel 2.4.20 中的网络代码图”

【问题讨论】:

  • 对于“请在 socket、sock、tcp_sock、sk_buff 之间进行解释。”部分问题 - 这太宽泛,无法在单一答案中解释。请阅读一些关于 linux 网络子系统的书籍/文章(例如 linuxfoundation.org/collaborate/workgroups/networking/group),并询问比“太阳地球和木星之间”更具体的问题。

标签: linux tcp linux-kernel


【解决方案1】:

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

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_ECN_OK位在tcp套接字打开时设置(如果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 中的默认设置 //

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

例如,当我们在传出套接字连接开始时发送 SYN,并且为传出连接启用 sysctl tcp_ecn(“sysctl_tcp_ecn”标志为1),我们在 tcp 头中设置 ECE 位并设置 TCP_ECN_OK。 net/ipv4/tcp_output.c315号线

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.c246号线

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 }

【讨论】:

  • 谢谢osgx,我当然理解运营商,我怀疑它的意思。可能 TCP_ECN_OK 会呈现一个表示 ECN 已启用的状态。
  • 对不起,谢谢您的信息。我会尝试通过搜索这个位的用法来找到意义lxr.free-electrons.com/ident?i=TCP_ECN_OK
  • 你真是个天才。太感谢了。你是不是主修这个东西——ECN、TCP拥塞控制?
  • 我只看 ECN 文档 2 小时。只是有点谷歌搜索(tcp ecn linux)
【解决方案2】:

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

【讨论】:

  • ECN 逻辑在第 24-25 页的“6.5 ECN”部分。但是没有关于TCP_ECN_OK位的确切信息,只是ECN逻辑的概述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多