Устройство Socat Tun очень низкая пропускная способность
Я возился с socat и пытался использовать socat для создания устройства TUN для туннелирования между двумя стретч-серверами Debian. Однако пропускная способность выглядела очень низкой, и по сравнению с iperf по сравнению с TCP/TCP-Listen на локальном хосте TUN имеет пропускную способность примерно на 5 порядков меньше.
Вот "минимальный рабочий пример", чтобы показать, как влияет скорость.
Сокат с устройством TUN
Сторона сервера:
# socat
socat TUN:10.10.0.2/16,iff-up TCP4-LISTEN:54321,bind=192.168.1.2,fork
# iperf service
iperf -s -p 15001 -B 10.10.0.2
Сторона клиента:
# socat
socat TUN:10.10.0.1/16,iff-up TCP4:192.168.1.2:54321
# iperf
iperf -c 10.10.0.2 -p 15001 -t 30
Сокат с TCP/TCP-LISTEN
Сторона сервера:
# socat
socat TCP4-LISTEN:12345,bind=192.168.1.2,fork TCP4:127.0.0.1:15001
# iperf service
iperf -s -p 15001 -B 127.0.0.1
Сторона клиента:
# socat
socat TCP4-LISTEN:54321,bind=127.0.0.1,fork TCP4:192.168.1.2:12345
# iperf
iperf -c 127.0.0.1 -p 54321 -t 30
Результаты
Устройство TUN:
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-39.7 sec 640 KBytes 132 Kbits/sec
TCP / TCP-СЛУШАТЬ:
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-30.0 sec 3.30 GBytes 944 Mbits/sec
Если вы хотите воспроизвести результаты, используя строки выше, вам нужно каким-то образом запустить строки socat и сервер iperf в фоновом режиме или демонизировать, я просто использовал сеансы экрана.
Поэтому, хотя я и предполагал, что пропускная способность в некоторой степени пострадает, мне кажется странным, что он снизится с предполагаемого гигабитного (оба сервера на одном коммутаторе) до простого 100 Кбит. Быстрый взгляд на atop
не показывает никаких существенных узких мест, так что это не просто загрузка процессора или потребление оперативной памяти.
Почему пропускная способность такая низкая? Какая-то логическая ошибка, которую я сделал? Или проблема в ядре, плохая реализация в socat или неправильное использование iperf?
Есть ли какие-либо параметры или настройки (ядро, socat, что-нибудь), чтобы улучшить это? Что-нибудь, что я мог проверить? И, самое главное, есть ли способ использовать устройство TUN, которое дает мне полезную пропускную способность?
1 ответ
У меня возникла аналогичная проблема при использованииsocat
для создания IP-соединения между двумя компьютерами с помощью последовательного соединения Bluetooth (черезrfcomm
). Необработанное последовательное соединение было довольно быстрым (около 15 КиБ/с), но при подключении к веб-серверу через устройство TUN, созданное socat, скорость была очень низкой, и браузер в конце концов просто сдался после загрузки на некоторое время.
На странице руководства socat говорится следующее.
Note that streaming eg. via TCP or SSL does not guarantee to retain packet boundaries and may thus cause packet loss.
Это заставило меня задуматься, отбрасываются ли пакеты или обрезаются ли они. Конечно же,tcpdump -i tun0
показало множество пакетов, в которых отсутствовали байты (в некоторых отсутствовало более 140 байт). Посмотрев на MTU (максимальную единицу передачи — размер пакета) я обнаружил, что оно равно 1500 (). Однако MTU Bluetooth составлял 1021 (?) байт согласноhciconfig --all
(если я правильно читаю его вывод).
Таким образом, для тестирования я уменьшил MTU на (по обе стороны туннеля - на обоих компьютерах) до 100 байт. Это сработало… ну, это все еще было не супер быстро, но я был подключен через Bluetooth, и это было намного быстрее, чем раньше. По крайней мере, у меня больше не было проблем с подключением. Обратите внимание, что это значение, вероятно, можно установить намного больше, но я просто проверял, решит ли это проблему.
Ниже приведена команда обновления MTU на устройстве, созданном socat (после вызова socat), до 100 байт. Это необходимо запустить в обеих системах (и, вероятно, должно совпадать).
ip link set mtu 100 tun0
Таким образом, вы выполните следующее.
Серверная часть:
# socat
socat TUN:10.10.0.2/16,iff-up TCP4-LISTEN:54321,bind=192.168.1.2,fork
# set MTU to 100
ip link set mtu 100 tun0
# iperf service
iperf -s -p 15001 -B 10.10.0.2
Сторона клиента:
# socat
socat TUN:10.10.0.1/16,iff-up TCP4:192.168.1.2:54321
# Set MTU to 100
ip link set mtu 100 tun0
# iperf
iperf -c 10.10.0.2 -p 15001 -t 30
Примечание: вы можете использовать
ip link
чтобы показать все ссылки - ищите
tun
чтобы найти нужное устройство, если
tun0
не работает.