Исходный код 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 in
Documentation/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.