LINUX.ORG.RU

имплементировать реодеринг пакетов на C (offline, то есть из pcap-ов)

 , , ,


0

2

Есть код обрабатывающий кучу pcap-файлов c TCP/IP трафиком, извлекает из них пакеты, создает flow-таблицу и распределяет пакеты соответственно в нужные flows, в виде списка пакетов.

Так как пакеты могут прибывать неупорядоченными (out-of-order), мне нужно их разложить по порядку. Хочу использовать для этого поле SEQ(sequence number, 32-бита) в TCP заголовке, я уже читаю это поле из пакетов также как и подсчитываю ожидаемый sequnce number в следующем пакете:

pkt->seq + TCP_segment_size

1) Не уверен, что использовать только SEQ для моих целей это правильно, ведь sequence может переполняться, что будет в этом случае?

2) Можно тупо отсортировать список с пакетами (который я формирую, когда бегаю по pcap-ам) по sequence номерам — но это будет медленно.

Как обычно имплементируют реодеринг пакетов? Что посоветуете? Спасибо.

★★

когда он переполнится, он обнулится и будет дальше увеличиваться.

единого алгоритма нет. пакеты могут теряться, перепосылаться, при этом разные системы имеют разные алгоритмы действий при перепосылке - перетирание всей последовательности, только конкретных пакетов и т.д. всё это обзывается TCP congestion control и на эту тему есть много разных алгоритмов.

что касается «реордеринга» - тебе проще сделать связные списки, если оверхед позволяет. но если ты хочешь эмулировать действия конкретной системы, то надо вникать в детали конкретной реализации этих алгоритмов. бывают моменты, когда, например, маздай и Linux дадут разные итоговые данные при одинаковом наборе пакетов (если там были перепосылки).

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Ответ на: комментарий от Iron_Bug

Спасибо за дельный ответ!

когда он переполнится, он обнулится и будет дальше увеличиваться.

Но ведь возможна ситуация, что для данного потока (flow), будут пакеты с одинаковыми sequence номерами? (Какой-нить долгоиграющий поток) Что делать в такой ситуации?

что касается «реордеринга» - тебе проще сделать связные списки, если оверхед позволяет.

Ну я так пока и мыслю – в структуре, содержающей поток (flow), завести список reordered_list куда класть пакеты в правильном порядке.

Я смотрел разные имплементации, например tcpflow (https://github.com/simsong/tcpflow.git), позволяет «склеивать» порезанные tcp-сегменты в один, честно говоря пока не разобрался – не только смотрят на seq, но и на ack значения.

PS. Эмулировать ОС не требуется.

cruz7 ★★
() автор топика

Можно использовать время кэпчеринга. Фактически у тебя кольцевой буфер в ядре из которого происходит чтение новых пакетов и дополнительная сортировка тут не нужна, если у тебя нет fanout’а. out-of-order запланированное поведение.

Про переплонение ты знаешь сколько в какую сторону отправлялось данных, соотвественно знаешь в какой момент переполнится seq.

xpahos ★★★★★
()
Ответ на: комментарий от cruz7

вот как раз congestion algorithms и решает подобные вопросы. если у тебя данные уже приняты, то они уходят в апстрим, ты их не накапливаешь бесконечно. ну и представь себе, какой должен быть поток, чтобы быть настолько длинным, чтобы там стали повторяться по кругу одни и те же номера. там скорее таймаут произойдёт и начнётся новая сессия.

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

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 3)
Ответ на: комментарий от Iron_Bug

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

Согласен. По хорошему конечно нужно все это поддерживать при анализе pcap-ов: что делать с дубликатами, ретрансмитами, проверять чексуммы и т.д.

По этой причине «в лоб» сортировать по SEQ и брать это в качестве цепочки reordered пакетов не получится.

cruz7 ★★
() автор топика
Последнее исправление: cruz7 (всего исправлений: 1)
Ответ на: комментарий от cruz7

Родился вот такой псевдокод:

for flow in flows:
   # берем самый первый пакет flow
   # по идее это должен быть SYN с initial sequence number
   nextseq = pkt->nextseq
   for pkt in flow:
      # цикл для всех остальных пакетов цепочки
      if pkt->seq != nextseq:
         # тут могут быть варианты: либо зановой посланный пакет
         # либо пакет из будущего, т.е. есть между этими
         # сегментами есть потерянный сегмент
         # все это надо как-то обработать ....

      nextseq = pkt->seq
      ...

Как-то так...

cruz7 ★★
() автор топика
Последнее исправление: cruz7 (всего исправлений: 1)

1) Не уверен, что использовать только SEQ для моих целей это правильно, ведь sequence может переполняться, что будет в этом случае?

Roll-over counter (ROC) можно использовать помимо SEQ, как в SRTP

https://tools.ietf.org/html/rfc3711#section-3.3.1

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.