Это старая версия документа!
Содержание
Измерение пропускной способности канала: флудим по полной
Дано: есть арендованный оптический канал со скоростью 2 гигабита по договору. С одной стороны этот канал можно воткнуть в сервер, другая сторона находится далеко и разместить там измерительное оборудование не представляется возможным. С удаленной стороны канал подключен к коммутатору с которого можно снять значения приходящего из канала трафика.
Требуется: проверить что обещанные 2 гигабита предоставляются арендованным каналом.
Решение:
Если бы можно было разместить с удаленной стороны второй сервер, то можно было бы воспользоваться программами iperf3, netperf и другими подобными. И задача была бы решена. Поскольку такое невозможно по условию задачи (указанные программы требуют обязательной ответной части, которую разместить негде), то будем как-то изголяться.
Можно загрузить канал по максимуму с ближней стороны исходящим трафиком с сервера и замерять приходящий трафик на коммутаторе.
Загрузить канал можно например UDP-трафиком. Тоесть нужно найти решение предоставляющее возможность нафлудить в канал по максимуму. Данная методика не является идеальной, поскольку мы сможем загрузить канал только в одном направлении. Однако за неимением лучшего и принимая во внимание, что ассиметричный шейпинг тестируемого канала маловероятен будем довольствоваться тем что можем сделать.
Итак, начинаем изыскания:
Предварительная подготовка
Настроем тестируемую сеть. На интерфейсе eth1, который подключен к тестируемому каналу выставим какой-нибудь ip-адрес. Будем использовать 192.168.10.1/24. Отправлять пакеты будем на адрес 192.168.10.25
С противоположной стороны будут сниматься показания со счетчиков порта на коммутаторе и никакой настройки не требуется.
Для того, чтоб удостовериться в достаточной загрузке канала со стороны сервера, будем смотреть загрузку интерфейса eth1. Для этого вполне подойдет прогамма bmon, которую будем запускать следующим образом
bmon -p eth1 -o curses:ngraph=2,curses:details,curses:info
Кроме всего прочего надо иметь в виду, что ip-трафик не пойдет в интерфейс, если операционная система не будет знать, что с другой стороны канала есть устройство, способное принимать данные. Будут отправляться arp-запросы, на которые некому отвечать и больше никакого трафика. Чтобы эту проблему решить "отравим" arp-кэш - подставим в него липовые данные (любой мак-адрес для ip-адреса 192.168.10.25)
arp -s 192.168.10.25 78:e3:b5:f5:7a:DD
После окончания экспериментов следует удалить из арп-кэша фиктивное значение.
arp -d 192.168.10.25
Эксперимент №1 - пользуемся средствами bash
- netflood1.sh
#!/bin/bash # Будем делать отправку большими блоками данных по 64КБ buflen=65535 # Формируем блок данных, заполняя его случайными цифробуквенными данными pkt="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $buflen| head -n 1)" # отправляем в бесконечном цикле UDP-трафик на ip 192.168.10.25 и # порт 5555 (можно выбрать любой - не принципиально) while true; do echo "$pkt"; done >/dev/udp/192.168.10.25/5555
Смотрим в bmon и видим такие результаты 29.41MiB/сек 20.69K пакетов в секунду.
Ну даже в мегабиты переводить не имеет смысла - такой загрузки недостаточно для тестирования.
Эксперимент №2 - пользуемся программой netcat
В скрипте меняем только последнюю строку с циклом
- netflood2.sh
#!/bin/sh while true; do echo "$pkt"; done |nc -4u 192.168.10.25 5555
Результаты ну совсем мало отличаются от предыдущих: 29.93MiB 22.41K…
Тоже слабовато для тестирования.
Эксперимент №3 - пользуемся программой udpblast
Сначала укажем программе самой генерировать передаваемый трафик (ключ -a)
- netflood3.sh
#!/bin/sh buflen=65535 pkt="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $buflen| head -n 1)" udpblast -4qa -s 32kb -c1m 10.48.1.25:5555
Результаты: 61.66MiB 44.31K
А теперь будем отправлять заранее подготовленные пакеты
- netflood3-1.sh
#!/bin/sh buflen=65535 pkt="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $buflen| head -n 1)" echo "$pkt" |udpblast -4q -s 32kb -c1m 10.48.1.25:5555
Результаты: 550.48MiB 395.61K … хм-м-м-м… а вот это уже что-то. 550*8/1024=4,296875 гигабита/сек.
Можно запустить команду генерирующую трафик в несколько потоков и еще улучшить результат.
В принципе поставленная задача решена (нам надо проверить полосу в 2 гигабита), но настоящие джедаи никогда не остановятся на достигнутом, если можно улучшить результат.
Эксперимент №4 - делаем собственную программу генерации UDP-трафика
Настоящий джедай сам изготавливает себе световой меч. Ну и мы не будем отступать от светлого пути. Наскоро накидаем программку, отправляющие UDP-пакеты.
Компилируем исходный код
gcc -O3 -static udpsender.c -o udpsender
Запускаем тестирование (шлем пакеты на 192.168.10.25 на порт 5555 размер пакетов максимальный - 65508):
./udpsender -d 192.168.10.25 -p 5555 -s 65508
Результаты: 485.53MiB 341.71K - немного ниже чем у udpblast.
Эксперимент №5 - делаем программу отправки трафика напрямую в сетевой интерфейс
Будем делать отправку данных не по ip, а генерировать ethernet-кадры и слать напрямую в сетевой интерфейс минуя обработку ip-пакетов системой.