#c #tcp-ip
#c #tcp
Вопрос:
Представьте файл PCAP file
с только одним соединением между клиентом client
и сервером server
. Нет дублированных пакетов, нет потери пакетов, и пакеты правильно упорядочены.
Как я могу упорядочить пакеты программно, если пакеты file
воспроизводятся в любом порядке без использования временных меток пакетов? (например, начиная с последнего пакета).
На данный момент у меня есть две очереди с пакетами: очередь передачи (пакеты, отправленные из client
) и очередь приема (пакеты, отправленные из server
). Я знаю, что не могу знать, кто это client
, пока не найду пакет с флагом SYN
и без флага ACK
.
Для упорядочения пакетов в одной очереди:
- Большее
SEQ
число означает, что пакет прибыл позже (игнорируя перенос SEQ). - Если два пакета имеют одинаковый
SEQ
номер, я сравниваюACK
числа.- Большее
ACK
число означает, что пакет прибыл позже. - Если пакеты имеют одинаковый
ACK
номер, который я делаю (и я не знаю, правильно ли это):- Если у одного пакета есть
FIN
флаг, он прибыл позже. - Если у одного пакета есть
PSH
флаг, он прибыл позже.
- Если у одного пакета есть
- Большее
Как только пакеты (надеюсь) правильно упорядочены в соответствующих очередях, я начинаю перебирать обе очереди ( q1
и q2
):
/* If q1 and q2 are not empty... */
if SEQ number in the queue q1 < ACK number in the queue q2
take packet p in q1
else if SEQ number in the queue q1 == ACK number in the queue q2
if ACK number in the queue q1 < SEQ number in the queue q2
take packet p in q1
else if ACK number in the queue q1 == SEQ number in the queue q2
/* I have implemented this based on what I have seen in file. */
if FIN bit in the queue q1 amp;amp; FIN bit in the queue q2
/* Compare previous SEQ numbers in both queues, is this correct? */
if the SEQ number of the current packet in q1 is the same as the SEQ number of the previous packet in q1
take packet p in q1
else
take packet p in q2
endif
else if FIN bit in the queue q1
take packet p in q2
else if FIN bit in the queue q1
take packet p in queue q1
else
/* What to do? Is this combination possible? */
endif
else
take packet p in q2
endif
else
take packet p in q2
endif
show packet p
Сравнение SEQ
номера в одной очереди с ACK
номером в другой очереди и наоборот — это основная вещь.
Чего я не знаю, так это что делать, когда (SEQ in q1 == ACK in q2) and (ACK in q1 == SEQ in q2)
. То, что я реализовал, основано на наблюдении за двумя файлами PCAP.
Каков был бы правильный способ сделать это (если это возможно)?
Комментарии:
1. Этого не может произойти. После того, как вы вычтете начальные порядковые номера, для каждой стороны SEQ — это количество отправленных байтов, а ACK — количество байтов, полученных на данный момент. Вы можете получить N байтов только после того, как другая сторона отправит N байтов. Итак, в вашем сценарии каждый из двух пакетов следует за другим.
2. Я знаю, что это не должно происходить в реальности. Я хочу прочитать файл PCAP только с одним TCP-соединением, в котором пакеты расположены в любом порядке, и посмотреть, удастся ли мне упорядочить их так, чтобы они соответствовали исходному файлу (тому, в котором пакеты правильно упорядочены).