Реализация переупорядочения пакетов TCP

#c #tcp-ip

#c #tcp

Вопрос:

Представьте файл PCAP file с только одним соединением между клиентом client и сервером server . Нет дублированных пакетов, нет потери пакетов, и пакеты правильно упорядочены.

Как я могу упорядочить пакеты программно, если пакеты file воспроизводятся в любом порядке без использования временных меток пакетов? (например, начиная с последнего пакета).

На данный момент у меня есть две очереди с пакетами: очередь передачи (пакеты, отправленные из client ) и очередь приема (пакеты, отправленные из server ). Я знаю, что не могу знать, кто это client , пока не найду пакет с флагом SYN и без флага ACK .

Для упорядочения пакетов в одной очереди:

  1. Большее SEQ число означает, что пакет прибыл позже (игнорируя перенос SEQ).
  2. Если два пакета имеют одинаковый 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-соединением, в котором пакеты расположены в любом порядке, и посмотреть, удастся ли мне упорядочить их так, чтобы они соответствовали исходному файлу (тому, в котором пакеты правильно упорядочены).