net:channel_performance_measuring
Различия
Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
net:channel_performance_measuring [2022/02/28 18:19] – [Эксперимент №5 - делаем программу отправки трафика напрямую в сетевой интерфейс] san | net:channel_performance_measuring [2022/03/01 12:15] (текущий) – [Эксперимент №5 - делаем программу отправки трафика напрямую в сетевой интерфейс] san | ||
---|---|---|---|
Строка 1: | Строка 1: | ||
====== Измерение пропускной способности канала: | ====== Измерение пропускной способности канала: | ||
- | **Дано: | + | **Дано: |
**Требуется: | **Требуется: | ||
Строка 22: | Строка 22: | ||
<file bash> | <file bash> | ||
bmon -p eth1 -o curses: | bmon -p eth1 -o curses: | ||
+ | </ | ||
+ | |||
+ | <file console> | ||
+ | | ||
+ | Interfaces | ||
+ | > | ||
+ | ───────────────────────────────┴───────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | ||
+ | | ||
+ | 133.00 ..................|......................................... | ||
+ | 110.83 ..................|......................................... | ||
+ | 88.67 ..................|......................................... | ||
+ | 66.50 ..................|......................................... | ||
+ | 44.33 ..................|......................................... | ||
+ | 22.17 ..................|......................................... | ||
+ | | ||
+ | (RX Packets/ | ||
+ | 1.00 ..................|......................................... | ||
+ | 0.83 ..................|......................................... | ||
+ | 0.67 ..................|......................................... | ||
+ | 0.50 ..................|......................................... | ||
+ | 0.33 ..................|......................................... | ||
+ | 0.17 ..................|......................................... | ||
+ | | ||
</ | </ | ||
Строка 203: | Строка 226: | ||
Будем делать отправку данных не по ip, а генерировать ethernet-кадры и слать напрямую в сетевой интерфейс минуя обработку ip-пакетов системой. | Будем делать отправку данных не по ip, а генерировать ethernet-кадры и слать напрямую в сетевой интерфейс минуя обработку ip-пакетов системой. | ||
+ | В качестве документации берем статью [[https:// | ||
+ | Поскольку программа пихает пакеты в интерфейс не определяя MAC-адреса получателя, | ||
+ | |||
+ | < | ||
+ | <file C rawudpsender.c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #define MY_DEST_MAC0 0x00 | ||
+ | #define MY_DEST_MAC1 0x00 | ||
+ | #define MY_DEST_MAC2 0x00 | ||
+ | #define MY_DEST_MAC3 0x00 | ||
+ | #define MY_DEST_MAC4 0x00 | ||
+ | #define MY_DEST_MAC5 0x00 | ||
+ | |||
+ | char* server=(char*)" | ||
+ | unsigned port=8888; | ||
+ | size_t buflen=1500; | ||
+ | char ifName[IFNAMSIZ]=" | ||
+ | |||
+ | void die(const char *s) { perror(s); exit(1); } | ||
+ | |||
+ | char* FillBuf(char* buf, size_t s) | ||
+ | { | ||
+ | int i; | ||
+ | for (i = 0; i < s - 1; i++) | ||
+ | buf[i] = ' | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | void Usage() | ||
+ | { | ||
+ | | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | int ParceArgs(int argc, char *argv[]) | ||
+ | { | ||
+ | int opt; | ||
+ | | ||
+ | { | ||
+ | | ||
+ | { | ||
+ | case ' | ||
+ | strcpy(ifName, | ||
+ | break; | ||
+ | case ' | ||
+ | port = atoi(optarg); | ||
+ | break; | ||
+ | case ' | ||
+ | buflen = atoi(optarg); | ||
+ | break; | ||
+ | case ' | ||
+ | server = strdup(optarg); | ||
+ | break; | ||
+ | | ||
+ | Usage(); | ||
+ | exit(1); | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | |||
+ | | ||
+ | |||
+ | char* sendbuf = (char*) malloc(buflen); | ||
+ | if (!sendbuf) die(" | ||
+ | | ||
+ | |||
+ | int sockfd; | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | char* data = (char *) (sendbuf + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct udphdr)); | ||
+ | | ||
+ | | ||
+ | int ttl=250; | ||
+ | |||
+ | /* Open RAW socket to send on */ | ||
+ | if ((sockfd = socket(AF_PACKET, | ||
+ | |||
+ | | ||
+ | | ||
+ | if (ioctl(sockfd, | ||
+ | perror(" | ||
+ | |||
+ | /* Get the index of the interface to send on */ | ||
+ | | ||
+ | | ||
+ | if (ioctl(sockfd, | ||
+ | /* Get the MAC address of the interface to send on */ | ||
+ | | ||
+ | | ||
+ | if (ioctl(sockfd, | ||
+ | |||
+ | /* Construct the Ethernet header */ | ||
+ | /* Ethernet header */ | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | /* Ethertype field */ | ||
+ | | ||
+ | |||
+ | /* IP Header */ | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | /* Source IP address, can be spoofed */ | ||
+ | | ||
+ | /* Destination IP address */ | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | // udph-> | ||
+ | // udph-> | ||
+ | |||
+ | /* Packet data */ | ||
+ | | ||
+ | |||
+ | /* Index of the network device */ | ||
+ | | ||
+ | /* Address length*/ | ||
+ | | ||
+ | /* Destination MAC */ | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | while (1) | ||
+ | { | ||
+ | /* Send packet */ | ||
+ | if (sendto(sockfd, | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | Компилируем: | ||
+ | < | ||
+ | gcc -O3 -static rawudpsender.c -o rawudpsender | ||
+ | </ | ||
+ | Запускаем: | ||
+ | < | ||
+ | ./ | ||
+ | </ | ||
+ | В качестве параметров указываем ip-адрес и порт (это все как раньше). Указываем имя интерфейса в который будем отправлять пакеты. И что важно - размер пакета следует задать равным MTU для данного сетевого интерфейса (меньше будет непродуктивно, | ||
+ | |||
+ | Результаты: | ||
+ | |||
+ | Улучшим результат запустив флудилку в многопоточном режиме | ||
+ | |||
+ | <file bash netflood.sh> | ||
+ | #!/bin/bash | ||
+ | |||
+ | threads=32 # будем запускать в 32 потока | ||
+ | cmd=" | ||
+ | param=" | ||
+ | |||
+ | for i in $(seq 1 $threads) | ||
+ | do | ||
+ | " | ||
+ | | ||
+ | echo "Run thread $i - pid: ${pid[$i]}" | ||
+ | sleep 0.1 | ||
+ | done | ||
+ | |||
+ | read -p "Flood Started! Press enter to terminate flood" | ||
+ | |||
+ | for i in $(seq 1 $threads); do kill -9 ${pid[$i]}; done | ||
+ | </ | ||
+ | После запуска всех потоков флудилки скрипт ожидает нажатия Enter, после которого завершает запущенные потоки. Поэтому скрипт не рекомендуется прерывать по Ctrl+C, если так сделать, | ||
+ | Если скрипт был неправильно завершен, | ||
+ | |||
+ | Число потоков флудилки 32 было подобрано опытным путем. Начиная с 8 увеличивал, | ||
+ | |||
+ | Результаты: | ||
+ | О! 1, | ||
+ | |||
+ | Я пробовал запускать udpsender в много потоков. Результаты получались почти такие же как у отправлялки сырых пакетов, | ||
+ | |||
+ | ===== Послесловие ===== | ||
+ | |||
+ | При выполнении задачи описанной в статье важно озаботиться тюнингом сетевой карты. Как минимум увеличить размер очереди отправки: | ||
+ | <file bash> | ||
+ | ip link set dev eth1 txqueuelen 10000 | ||
+ | </ | ||
+ | Если на сетевой карте выставить MTU в 9000, то можно увеличить загрузку однопоточным зафлуживанием канала. В многопоточном варианте все-равно все упирается в потолок 1.08GiB/s, но зато можно снизить число запускаемых потоков для достижения этого " | ||
+ | |||
+ | Результатов превышающих абсолютно все описанные удалось добиться при использовании udpblast в многопоточном режиме **1.16GiB 150.92K** **1, | ||
+ | |||
+ | Вот скрипт многопоточного флуда с помощью tcpblast | ||
+ | <file bash netflood-max.sh> | ||
+ | #!/bin/bash | ||
+ | |||
+ | threads=32 | ||
+ | buflen=65535 | ||
+ | pkt=" | ||
+ | |||
+ | for i in $(seq 1 $threads) | ||
+ | do | ||
+ | (echo " | ||
+ | echo "Run thread $i" | ||
+ | sleep 0.1 | ||
+ | done | ||
+ | read -p "Flood Started! Press enter to terminate flood" | ||
+ | killall -9 udpblast | ||
+ | </ | ||
+ | |||
+ | |||
+ | {{tag> |
net/channel_performance_measuring.1646061586.txt.gz · Последнее изменение: 2022/02/28 18:19 — san