Синтаксический анализ пакета для получения протоколов прикладного уровня, таких как http и tls, с использованием структуры пакетов dpdk без больших вычислительных затрат

У меня есть следующая функция проверки пакетов, которая анализирует протоколы транспортного уровня, такие как TCP и UDP. Мне нужно углубиться в пакет и получить протоколы прикладного уровня, такие как HTTP и TLS. Моя текущая теория состоит в том, чтобы реализовать функцию сопоставления с образцом для полезной нагрузки, но это было бы дорого с вычислительной точки зрения. Любые подсказки о том, как действовать?

void inspect_packet(struct rte_mbuf *pkt, unsigned port_id, int i)
{
    uint8_t *data = (uint8_t *)(pkt->buf_addr + pkt->data_off);
    unsigned int offset = 0;
    struct rte_ether_hdr *eth = (struct rte_ether_hdr *)data;
    offset += sizeof(struct rte_ether_hdr);

    a_counter[i].pkts_counter++;
    a_counter[i].bits_counter += pkt->pkt_len;

    if (eth->ether_type != htons(RTE_ETHER_TYPE_IPV4) && eth->ether_type != htons(RTE_ETHER_TYPE_IPV6) 
        && eth->ether_type != htons(RTE_ETHER_TYPE_ARP))
    {
        return;
    }

    if (eth->ether_type == RTE_ETHER_TYPE_ARP)
    {
        a_counter[i].arp_counter++;
        return;
    }

    struct rte_ipv4_hdr *iph = (struct rte_ipv4_hdr *)(data + offset);
    struct rte_ipv6_hdr *iph6 = (struct rte_ipv6_hdr *)(data + offset);

    struct rte_tcp_hdr *tcph = NULL;
    struct rte_udp_hdr *udph = NULL;

    if (eth->ether_type == htons(RTE_ETHER_TYPE_IPV4))
    {
        offset += 20; //header length
        switch (iph->next_proto_id)
        {
            case PROTOCOL_TCP:
                a_counter[i].tcp_counter++;
                tcph = (struct rte_tcp_hdr *)(data + offset);
                break;
            
            case PROTOCOL_UDP:
                a_counter[i].udp_counter++;
                udph = (struct rte_udp_hdr *)(data + offset);
                break;

            default:
                break;
        }
    }
    else if (eth->ether_type ==  htons(RTE_ETHER_TYPE_IPV6))
    {
        offset += 40; //header length
        switch (iph6->proto)
        {
            case PROTOCOL_TCP:
                tcph = (struct rte_tcp_hdr *)(data + offset);
                break;
            
            case PROTOCOL_UDP:
                udph = (struct rte_udp_hdr *)(data + offset);
                break;
        }
    }
    
    data = nullptr;
}

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

Jesper Juhl 13.10.2022 15:50

@JesperJuhl причина, по которой я выбрал dpdk, заключается в том, что я хочу провести анализ трафика на скоростях линии (до 10 Гбит/с), что невозможно с wirehark

Abhinav Gupta 13.10.2022 16:03

Это не значит, что вы не можете использовать его для вдохновения/идей.

Jesper Juhl 13.10.2022 17:07

@AbhinavGupta на основе объяснения вопроса My current theory is to implement a pattern matching function on the payload but that would be computationally expensive. Any leads on how to proceed?. Поэтому сначала, пожалуйста, обновите заголовок reflecting the intent. Что касается сопоставления с образцом, можно использовать regex как hyperscan library from intel. В 22.02 DPDK также есть регулярное выражение PMD.

Vipin Varghese 14.10.2022 04:54

@VipinVarghese эта теория больше похожа на «лучшее предположение о том, как действовать дальше». Я обновлю заголовок, если вы считаете, что сопоставление с образцом - лучший способ ответить на этот вопрос. Пожалуйста, подтвердите, если это так.

Abhinav Gupta 14.10.2022 12:13

@AbhinavGupta Я не следил за вашим последним комментарием, вы действительно хотите need help in sample reference code for using packet parsing using DPDK libraries. Если да, пожалуйста, обновите заголовок. Иначе я не уследил за вашим вопросом can you explain what is that you are looking for. Кстати, я уже использовал гиперскан для разбора и сравнения пакетов | полезной нагрузки при использовании DPDK. Таким образом, предыдущий комментарий не является best guess.

Vipin Varghese 14.10.2022 12:42

@VipinVarghese я ищу способ получить данные прикладного уровня (независимо от того, принадлежит ли пакет HTTP, HTTPS, QUIC и т. д.). Получить данные транспортного уровня легко через заголовки (rte_tcp_hdr и rte_udp_hdr). Но мне нужно получить доступ к полезной нагрузке, чтобы получить данные прикладного уровня. Мы можем подробно обсудить это по почте, если это сработает для вас. Я могу поделиться своим текущим рабочим кодом для лучшего понимания моей проблемы. Я опубликую свой вывод здесь, как только найду решение.

Abhinav Gupta 14.10.2022 13:37

@VipinVarghese, можете ли вы поделиться примером кода, как реализовать гиперсканирование?

Abhinav Gupta 14.10.2022 13:40

@AbhinavGupta Теперь я могу быть доступен, Google Meet, Skype Zoom работает для меня.

Vipin Varghese 14.10.2022 14:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
9
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

[на основе живого обсуждения]

Вопрос: Моя текущая теория состоит в том, чтобы реализовать функцию сопоставления с образцом для полезной нагрузки, но это было бы дорого с точки зрения вычислений. Любые подсказки о том, как действовать?

Ответ: Логика приложения для идентификации протоколов и приложения будет иметь фиксированную стоимость. Таким образом, первая цель состоит в том, чтобы этапы предварительной и последующей обработки приводили к минимальным потерям. Они также варьируются от физического сетевого адаптера до виртуального сетевого адаптера.

Итак, позвольте мне объяснить несколько советов, которым я следую для достижения наилучшего результата.

  1. В виртуальном сетевом адаптере я использую memif или vhost для лучшей производительности.
  2. если я знаю конкретный IP, VLAN, MPLS, VXLAN, которые фильтруются, я предпочитаю использовать AF_XDP PMD на виртуальном сетевом адаптере, который разделяет трафик.
  3. В случае физической сетевой карты используйте сетевую карту, которая поддерживает перенаправление PTYPES, RSS, QUEUE.

(Физическая разгрузка сетевой карты)

  1. Используя RSS, можно запрограммировать RSS для распределения трафика по всем очередям.
  2. Комбинируя перенаправление очереди с RSS, можно специально отправлять желаемый трафик, такой как IPv4, IPv6, VxLAN, GRE, Geneve, GTPu, в RSS по выборочным очередям. Это позволяет всем пакетам ARP, ND, lldp и другим попадать в очередь по умолчанию.
  3. Использование DPDK APi rte_eth_dev_set_ptypes позволяет rte_mbuf передавать информацию о ptype из дескриптора.
  4. обязательно используйте векторный режим (AVX2 и/или AV512) с меньшим размером дескриптора, если это возможно для определенной сетевой карты.

Таким образом, хорошо настроенные (BIOS и командная строка ядра) ядра теперь смогут получать RX-пакеты DMA с достаточным количеством метаданных. Это позволит уменьшить дополнительные накладные расходы на анализ каждого пакета, поскольку выбранный трафик отправляется в определенную очередь, а PTYPE в очереди RSS помогает выполнять предварительную фильтрацию.

Затем разделите разработку на несколько этапов

  • этап-1: пакеты rx и счетчики протокола увеличиваются, затем используется rte_mbuf_free без отбрасывания
  • этап-2: увеличить ref_cnt для интересующего пакета и выполнить tx_burst. затем выполните этап-2
  • этап-3: запустить один экземпляр оптимизированного парсера приложения и узнать, сколько циклов накладных расходов и есть ли отбрасывание пакетов

если присутствуют потери пакетов, это означает, что трафик одной очереди необходимо либо распределить по нескольким очередям (больше очередей RX) в случае модели выполнения до завершения. В противном случае изучите возможность использования eventdev or flow distributor с несколькими потоками lcore в качестве парсеров приложений.

Примечание:

  • как уже отмечалось, можно использовать HW FPGA lookaside или регулярное выражение SW (гиперсканирование) для оптимизации синтаксического анализа приложений.
  • это будет работать с открытым текстом, в случае TLS, для соединения, у которого нет ключей, которые нужно завершить, можно обойти с помощью using rte_flow to carry 32bit marker.

Приведенная выше логика верна для режима IDS. В случае режима IPS иногда могут возникать требования для обеспечения порядка пакетов. Так что используйте atomic eventdev для всех трех этапов.

Другие вопросы по теме