Как использовать интерфейс tun / tap для разделения пакетов, туннелирования и последующей повторной сборки. (аналогично MLPPP)

#python #networking #packet #tap

#python #сеть #пакет #коснитесь

Вопрос:

Я хочу создать клиент-серверное приложение, которое я мог бы использовать для разделения сетевых пакетов пополам, туннелирования каждой половины пакета по отдельному udp-соединению (поскольку каждое udp-соединение будет проходить по другому каналу Wi-Fi), а затем повторно собрать разделенные пакеты на другом конце. В дополнение к разделению пакетов, каждый полупакет также должен иметь идентификатор и порядковый номер, чтобы их можно было правильно повторно собрать.

В основном я пытаюсь сделать что-то похожее на MLPPP

Я собираюсь сделать это с помощью python и сетевого драйвера TUN / TAP. Я нашел следующие примеры кода на Python и модули, которые, на мой взгляд, могут быть полезны для этого проекта.

Python tun / tap

Обработка необработанных пакетов Python

Мой вопрос в том, можно ли выполнить необходимую модификацию пакета с помощью python и каков был бы возможный способ подойти к этому? Могу ли я использовать модули выше для этого или есть лучшее решение? Я ищу некоторые входные данные, которые направят меня в правильном направлении, поскольку я не опытный программист. Приветствуются любые примеры кода или дополнительные ссылки.

Комментарии:

1. У меня нет для вас ответа, но я скажу, что если вы меняете каждый пакет в пользовательском пространстве, я думаю, вы будете очень разочарованы производительностью. Как с точки зрения пропускной способности, так и с точки зрения задержки. Я сделал нечто подобное с scapy (аналогично обработке каждого пакета в пользовательской среде python), и производительность была просто ужасной. FWIW

2. Повлияет ли использование другого языка программирования на ситуацию или приемлемую производительность можно получить только с помощью чего-то вроде пользовательского модуля ядра?

3. Я недостаточно сделал, чтобы знать, но я читал некоторые другие исследования о стоимости переключения контекста из ядра в пользовательскую область, и я могу только представить, что если вам придется переключаться для каждого пакета, вы это почувствуете. Это не значит, что вы не можете сделать это достаточно быстро, чтобы удовлетворить ваши потребности, просто имейте реалистичные ожидания.

Ответ №1:

Мы делаем нечто подобное в производстве, и это работает довольно хорошо. Однако мы не разделяем отдельные пакеты. Мы устанавливаем дробные веса для каждого соединения (неограниченные) и отправляем пакеты. У нас есть некоторый код для работы с различными задержками в каждой строке. На другом конце мы буферизуем их и меняем порядок. Производительность довольно хорошая — у нас есть сайты с более чем 5 линиями ADSL и хорошей скоростью загрузки, более 40 Мбит / с.

Разделение пакетов (например, 1500/2 = 750) приведет к ненужным накладным расходам … держите ваши пакеты как можно большими.

Мы разработали наш собственный протокол (формат заголовка) для пакетов UDP. Мы провели циклическое тестирование на tun / tap со скоростью до 200 Мбит / с, так что, безусловно, взаимодействие ядра с пользовательским пространством работает хорошо. Ранее мы использовали NFQUEUE, но у него были проблемы с надежностью.

Все вышесказанное было написано на Python.

Комментарии:

1. Вы делали это также на Python?

2. Да, мы написали все на Python

3. Прошло больше года, а я все еще ничего с этим не сделал :-(. Я предполагаю, что, поскольку вы не выполняли разделение пакетов, размер MTU конечного связанного канала был ниже стандартного размера 1500. Было ли это проблемой для определенных приложений?

4. Извините за задержку с ответом… мы теряем около 24 байт, поэтому наш MTU немного меньше. Все приложения работают нормально, так как мы зажимаем TCP MSS. В Интернете распространены разные размеры MTU. Только подумайте, PPPoE часто равен 1492, и многие другие VPN-системы также имеют накладные расходы.

Ответ №2:

Для меня это выглядит вполне возможным.

Обнаруженные вами модули tun / tap выглядят так, как будто они справятся с этой задачей. Twisted обеспечит высокую производительность и минимизирует затраты на то, чтобы ломать голову над всем этим.

Что касается разделения пакетов, вам не нужно каким-либо образом интерпретировать данные, просто обработайте их как большой двоичный объект данных, разделите его на две части и добавьте заголовок — я бы не использовал для этого никаких сторонних модулей, просто обычную обработку строк python.

Или вы могли бы использовать netstrings, если вам нужен простой в использовании формат инкапсуляции пакетов.

Я не думаю, что это сработает как ракета, но я уверен, что вы многому научились бы, выполняя это!

Комментарии:

1. На самом деле я не хочу, чтобы это работало как ракета. Я думаю, мне следовало добавить свои требования к производительности к вопросу. В идеале я хотел бы, чтобы это приложение могло передавать данные со скоростью не менее 2 Мбит / с. Если это нереально с python или любой другой реализацией пользовательского пространства, то мне, вероятно, следует пойти другим путем.