сетевая ОС Linux

sergey_m

Наверное, я уже заебал. Но не могу не порадовать вас новыми открытиями в области одной из самых популярных т.н. сетевых ОС.
Когда Linux 2.4.x (кто может проверить на 2.6.x?!) высылает ICMP или UDP датаграмму превышающую MTU, то он конечно же её фрагментирует. Интересным является то, что фрагменты высылаются в обратном порядке:


[xxx root]# tcpdump -vvnpi eth0 icmp
tcpdump: listening on eth0
14:28:23.671556 192.168.254.28 > 192.168.254.252: (frag 46097:2960) (ttl 64, len 168)
14:28:23.671561 192.168.254.28 > 192.168.254.252: (frag 46097:1480+) (ttl 64, len 1500)
14:28:23.671563 192.168.254.28 > 192.168.254.252: icmp: echo request (frag 46097:0+) (ttl 64, len 1500)

krishtaf

а чего тут такого ?
все равно ручками пакет собирать нужно при получении.

sergey_m

Это оптимально по твоему? Это создает дополнительную нагрузку на собирающий хост.

krishtaf

почему ?
с жопы собирать должно быть легче

sergey_m

> с жопы собирать должно быть легче
С какого хуя?

krishtaf

ну скажем по другому: не сложнее
сувать в стек.

Chupa

2.4.27-rc2


14:51:36.816054 > 172.16.12.128 > 172.16.12.1: icmp: echo request (frag 13910:0+)
14:51:36.816068 > 172.16.12.128 > 172.16.12.1: (frag 13910:1480+)
14:51:36.816071 > 172.16.12.128 > 172.16.12.1: (frag 13910:2960)


2.6.7-mm7


14:54:20.288655 < 172.16.12.1 > 172.16.12.128: icmp: echo request (frag 36620:0+)
14:54:20.288772 < 172.16.12.1 > 172.16.12.128: (frag 36620:1480+)
14:54:20.288856 < 172.16.12.1 > 172.16.12.128: (frag 36620:2960)

sergey_m

И в стеке они окажутся в обратном порядке.

sergey_m

У меня 2.4.20-28.7 Thu Dec 18 11:31:59 EST 2003 i686 unknown

sergey_m

Стало быть в конце 2.4.x исправили.

krishtaf

это почему ?
просвети темного

Marinavo_0507

пакеты в обратном порядке посылаются AFAIK во всех версиях
это сделано специально, под тем предлогом, что в этом случае
принимающая сторона после первого же куска будет знать полный размер пакета,
и сможет задействовать некоторые оптимизации (типа сразу выделить нужное количество памяти)

sergey_m

Интересная мысль. В какого рода структурах Linux хранит сетевые данные (очереди интерфейсов, буферы сокетов, очереди реассемблинга)? Я спрашиваю потому, что в BSD-derived стеках не стоит проблема выделения памяти под очередь реассемблинга.

Marinavo_0507

Есть более интересный прикол, недавно в рассылке упомянули.
При передаче по TCP, на каждый n-й сегмент ставится флаг PSH,
потому что какой-то супероптимизированный HTTP-клиент под винду (наверное, с IE как-то связяно)
не передаёт данные в юзер-спейс, пока не увидит этот флаг.
Если флаг не ставить периодически, от он будет пытаться весь файл копить в памяти ядра
Ещё более старый прикол: когда ядро отправляет TCP или UDP пакет с флагом DF,
(что бывает часто, так как в Линуксе PMTU-D реализовано и для TCP, и для UDP
то поле ID ставится в ноль (согласно букве RFC, непонятно, можно ли так делать,
но вроде бы можно, так как дефрагментировать такие пакеты не придётся).
Есть исключение - якобы против какого-то бага в виндовом PPP (не помню какой версии) - для connected-сокетов
ID ставится разный, но тупо - начиная с нуля, и дальше каждый раз ++ (внутри соединения
без этого типа этот виндовый PPP только половину пакетов принимал.
Это важная оптимизация, так как правильным образом вычислять ID дорого - нужно ведь,
чтобы врагу трудно было бы его предугадать.
Я наткнулся на это, когда реализовывал протокол WCCPv2 - долго думал, почему циска
не ест мои пакеты, хотя всё чётко по спецификации сделал.
Оказалось, там тоже ID проверяли зачем-то - только в WCCP, так как тот же SNMP нормально работает.

Marinavo_0507

В линуксе кажется нет такой оптимизации, но я этот код очень давно читал.
Тут похоже действительно, в новых версиях вроде бы порядок стал прямым.
Наверное, когда очередной раз этот вопрос возник, никто не смог привести
пример системы, для которой это актуально.
Структура skbuff довольно хитрая, я детали не знаю к сожалению, но гуру хвалятся,
что эффективнее, чем mbuf

sergey_m

При передаче по TCP, на каждый n-й сегмент ставится флаг PSH,
потому что какой-то супероптимизированный HTTP-клиент под винду (наверное, с IE как-то связяно)
не передаёт данные в юзер-спейс, пока не увидит этот флаг.
Если флаг не ставить периодически, от он будет пытаться весь файл копить в памяти ядра
AFAIK, без PSH стек может передавать данные в сокет, а с PSH должен.

Marinavo_0507

совершенно точно
когда http-сервер отдаёт большой файл, PSH ставить вообще говоря не зачем, кроме как в конце

sergey_m

> Структура skbuff довольно хитрая, я детали не знаю к сожалению, но гуру хвалятся, что эффективнее, чем mbuf
Ну в этом конечно никто не сомневается. Как и раньше не сомневались в том, что фрагменты в обратном порядке эффективнее.
Этих skbuff я так понимаю пул, и реассемблинг упорядочивает цепочку фрагментов вместе с вырванивнием, чтобы удалить пересечения. Тогда проблемы выделения памяти надумана. Или не так?

sergey_m

Я думаю в современных M$продуктах это уже не актуально.

Marinavo_0507

> Как и раньше не сомневались в том, что фрагменты в обратном порядке эффективнее.
Так не говорили, говорили, что пофиг на порядок, но в обратном порядке
кто-нибудь может захотеть применить вышеописанную оптимизацию.
> Тогда проблемы выделения памяти надумана.
Скорее всего да, к линуксу по крайней мере не относится.

Marinavo_0507

win98 - довольно современный продукт, по крайней мере пользователей огого

krishtaf

секонд эдишн
Оставить комментарий
Имя или ник:
Комментарий: