Как построить сообщение из сегментов TCP - PullRequest
1 голос
/ 22 октября 2010

работая в C #, я использую SharpPCap для получения сегментов из трассировки winpcap.

Мне нужно перестроить все сообщения, отправленные и полученные в этой трассировке.

В моей ситуации IP клиента и сервера никогда не будут одинаковыми. Порт клиента не обязательно меняется.

Протокол, используемый сообщением, может быть HTTP или что-то нестандартное, чего я не знаю.

Вот как я сейчас это делаю:

            if (ipPacket.Protocol == IPProtocolType.TCP)
            {
                TcpPacket tcpPacket = (TcpPacket)ipPacket.PayloadPacket;

                Packet dataPacket = tcpPacket;
                while (dataPacket.PayloadPacket != null)
                    dataPacket = dataPacket.PayloadPacket;

                if (dataPacket.PayloadData.Length > 0)
                {
                    if (m_MessageContainer.IsEmpty()
                        || ((m_MessageContainer.Last().SourceIp.ToString() != ipPacket.SourceAddress.ToString())
                             && tcpPacket.Psh))
                    {
                        m_MessageContainer.Add(BuildMessage(ipPacket, tcpPacket));                      
                    }
                    m_MessageContainer.Last().AddData(dataPacket.PayloadData);
                }
            }

Проблема с моим решением заключается в том, что клиент отправляет два запроса подряд. Я просто объединяю два сообщения в одно. Если я изменю

if (m_MessageContainer.IsEmpty()
  || ((m_MessageContainer.Last().SourceIp.ToString() != ipPacket.SourceAddress.ToString())
       && tcpPacket.Psh))
 {
     m_MessageContainer.Add(BuildMessage(ipPacket, tcpPacket));                      
 }

по

if (m_MessageContainer.IsEmpty()
  || tcpPacket.Psh)
 {
     m_MessageContainer.Add(BuildMessage(ipPacket, tcpPacket));                      
 }

тогда возникает проблема, когда сообщение разбивается между несколькими сегментами tcp, и флаг psh устанавливается как минимум на два из этих сегментов tcp.

Мне нужен способ правильного объединения сегментов для перестройки исходных сообщений. Я не могу полагаться на протокол, используемый через TCP.

Спасибо!

Редактировать: В wireshark, когда вы следуете по tcp-потоку, он не обязательно знает протокол по tcp, но способен отображать каждый запрос и ответ разными цветами. Как это может сделать это? Я ищу ту же функциональность, потому что в моей ситуации никогда не будет второго запроса до получения ответа в потоке. Спасибо

1 Ответ

0 голосов
/ 22 октября 2010

Невозможно узнать, просто наблюдая за потоком в сети, как исходный код приложения записал в сокет.Вы говорите об использовании подсказок, которые могут появляться при определенных обстоятельствах, но вы не можете полагаться на них (как вы обнаружили).

write(sock, "GET / HTTP/1.0\r\n\r\n", len);

write(sock, "GET / HTTP/1.0\r\n", len);
write(sock, "\r\n", 2);

write(sock, "GET / HTTP/1.0\r\n", len);
sleep(1);
write(sock, "\r\n", 2);

Все три из этих примеров являются законными способами написания HTTP-запроса.,Все три могут выглядеть одинаково на проводе.Конечно, последний имеет большой шанс отличиться, даже если это означает одно и то же (представьте, что сон не явный, но, возможно, вызван чтением файлов cookie с диска).Даже в этом случае последний может быть свернут в одну передачу, если конкретный сокет TCP удерживается повторными попытками в момент, когда происходят две записи.Второй пример может отображаться как один или два пакета только на основе другой загрузки интерфейса (или параметров сокетов, таких как CORK).

...