Исходный код TCP ECN

У меня была проблема с пониманием исходного кода Linux для TCP (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 (для "сокета"), а другую для хранения данных и состояния как входящих, так и исходящих пакетов, называемого sk_buff (для "сокета"). бушель и далее эр "). Оба они описаны в этом разделе. Мы также включили краткое описание tcp_opt, структуры, которая является частью структуры sock и используется для поддержания состояния соединения TCP. (из "Карты сетевого кода в ядре Linux 2.4.20")

2 ответа

Решение

TCP_ECN_OK битовый флаг из внутреннего linuxkernel struct tcp_sock как (поле ecn_flags). В нем есть несколько битовых флагов (include/net/tcp.h файл из исходников ядра 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 включают поддержку ECN в Linux), и он останется установленным, если другая сторона сокета также поддерживает ECN.

Как сказано в википедии http://en.wikipedia.org/wiki/Explicit_Congestion_Notification

ECN - это дополнительная функция, которая используется только тогда, когда обе конечные точки поддерживают ее и желают ее использовать.

... перейти в раздел Linux

Ядро Linux поддерживает три режима работы ECN для TCP, настроенных по значению переменной /proc/sys/net/ipv4/tcp_ecn через интерфейс sysctl: [11 - tcp_ecn inDocumentation/networking/ip-sysctl.txt]

  • 0 - отключить ECN и не инициировать и не принимать его
  • 1 - включить ECN при запросе входящих соединений, а также запросить ECN при попытках исходящего соединения
  • 2 - включить ECN при запросе входящих соединений, но не запрашивать ECN для исходящих соединений. // ПО УМОЛЧАНИЮ в 3.14 //

Значение по умолчанию равно 2, что означает, что по умолчанию ECN включается при запросе входящих соединений, но не запрашивается при исходящих соединениях. В любом случае, ECN используется ядром Linux только тогда, когда оба конца TCP-соединения указывают на его поддержку.[11]

Например, когда мы отправляем SYN в начале соединения с исходящим сокетом, и sysctl tcp_ecn включен для исходящих соединений (флаг "sysctl_tcp_ecn" 1), мы устанавливаем бит ECE в заголовке tcp и устанавливаем 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 не было флага заголовка tcp ECE (подробнее о флагах и ECN в RFC3168 "Добавление явного уведомления о перегрузке (ECN) к IP")

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 }

Хорошую ссылку для подробного объяснения исходного кода сети Linux можно найти здесь : Карта сетевого кода в ядре Linux 2.4.20.

Другие вопросы по тегам