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 · Последнее изменение: — san
