Path: blob/main/tests/sys/netinet/libalias/perf.c
102423 views
/*1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright 2021 Lutz Donnerhacke4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above12* copyright notice, this list of conditions and the following13* disclaimer in the documentation and/or other materials provided14* with the distribution.15* 3. Neither the name of the copyright holder nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND20* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,21* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF22* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS24* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,25* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED26* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,27* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON28* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR29* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF30* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31* SUCH DAMAGE.32*/33#include <stdio.h>34#include <stdlib.h>35#include <strings.h>36#include <sys/time.h>37#include "util.h"38#include <alias.h>3940static void usage(void) __dead2;4142#define timevalcmp(tv, uv, cmp) \43(((tv).tv_sec == (uv).tv_sec) \44? ((tv).tv_usec cmp (uv).tv_usec) \45: ((tv).tv_sec cmp (uv).tv_sec))4647#define timevaldiff(n, o) (float) \48(((n).tv_sec - (o).tv_sec)*1000000l + \49((n).tv_usec - (o).tv_usec))5051#define check_timeout() do { \52if (check_timeout_cnt++ > 1000) { \53check_timeout_cnt = 0; \54gettimeofday(&now, NULL); \55if (timevalcmp(now, timeout, >=)) \56goto out; \57} } while(0)5859static void60usage(void) {61printf("Usage: perf [max_seconds [batch_size [random_size [attack_size [redir_size]]]]]\n");62exit(1);63}6465int main(int argc, char ** argv)66{67struct libalias *la;68struct timeval timeout, now, start;69struct ip *p;70struct udphdr *u;71struct {72struct in_addr src, dst;73uint16_t sport, dport, aport;74} *batch;75struct {76unsigned long ok, fail;77} nat, usenat, unnat, random, attack;78int i, round, check_timeout_cnt = 0;79int max_seconds = 90, batch_size = 2000,80random_size = 1000, attack_size = 1000,81redir_size = 2000;8283if (argc >= 2) {84char * end;8586max_seconds = strtol(argv[1], &end, 10);87if (max_seconds < 2 || end[0] != '\0')88usage();89}90if (argc > 2 && (batch_size = atoi(argv[2])) < 0) usage();91if (argc > 3 && (random_size = atoi(argv[3])) < 0) usage();92if (argc > 4 && (attack_size = atoi(argv[4])) < 0) usage();93if (argc > 5 && (redir_size = atoi(argv[5])) < 0) usage();9495printf("Running perfomance test with parameters:\n");96printf(" Maximum Runtime (max_seconds) = %d\n", max_seconds);97printf(" Amount of valid connections (batch_size) = %d\n", batch_size);98printf(" Amount of random, incoming packets (batch_size) = %d\n", random_size);99printf(" Repeat count of a random, incoming packet (attack_size) = %d\n", attack_size);100printf(" Amount of open port forwardings (redir_size) = %d\n", redir_size);101printf("\n");102103if (NULL == (la = LibAliasInit(NULL))) {104perror("LibAliasInit");105return -1;106}107108bzero(&nat, sizeof(nat));109bzero(&usenat, sizeof(usenat));110bzero(&unnat, sizeof(unnat));111bzero(&random, sizeof(random));112bzero(&attack, sizeof(attack));113114LibAliasSetAddress(la, masq);115LibAliasSetMode(la, PKT_ALIAS_SAME_PORTS | PKT_ALIAS_DENY_INCOMING, ~0);116117prv1.s_addr &= htonl(0xffff0000);118ext.s_addr &= htonl(0xffff0000);119120for (i = 0; i < redir_size; i++) {121int aport = htons(rand_range(1000, 2000));122int sport = htons(rand_range(1000, 2000));123124prv2.s_addr &= htonl(0xffff0000);125prv2.s_addr |= rand_range(0, 0xffff);126LibAliasRedirectPort(la, prv2, sport, ANY_ADDR, 0, masq, aport, IPPROTO_UDP);127}128129p = ip_packet(0, 64);130u = set_udp(p, 0, 0);131132if (NULL == (batch = calloc(batch_size, sizeof(*batch)))) {133perror("calloc(batch)");134return -1;135}136137gettimeofday(&timeout, NULL);138timeout.tv_sec += max_seconds;139140printf("RND SECOND newNAT RANDOM ATTACK useNAT\n");141for (round = 0; ; round++) {142int res, cnt;143144printf("%3d ", round+1);145146gettimeofday(&start, NULL);147printf("%6.1f ", max_seconds - timevaldiff(timeout, start)/1000000.0f);148for (cnt = i = 0; i < batch_size; i++, cnt++) {149batch[i].src.s_addr = prv1.s_addr | htonl(rand_range(0, 0xffff));150batch[i].dst.s_addr = ext.s_addr | htonl(rand_range(0, 0xffff));151batch[i].sport = rand_range(1000, 60000);152batch[i].dport = rand_range(1000, 60000);153154p->ip_src = batch[i].src;155p->ip_dst = batch[i].dst;156u = set_udp(p, batch[i].sport, batch[i].dport);157158res = LibAliasOut(la, p, 64);159batch[i].aport = htons(u->uh_sport);160161if (res == PKT_ALIAS_OK &&162u->uh_dport == htons(batch[i].dport) &&163addr_eq(p->ip_dst, batch[i].dst) &&164addr_eq(p->ip_src, masq))165nat.ok++;166else167nat.fail++;168169check_timeout();170}171gettimeofday(&now, NULL);172if (cnt > 0)173printf("%6.2f ", timevaldiff(now, start) / cnt);174else175printf("------ ");176177start = now;178for (cnt = i = 0; i < random_size; i++, cnt++) {179p->ip_src.s_addr = ext.s_addr & htonl(0xfff00000);180p->ip_src.s_addr |= htonl(rand_range(0, 0xffff));181p->ip_dst = masq;182u = set_udp(p, rand_range(1, 0xffff), rand_range(1, 0xffff));183184res = LibAliasIn(la, p, 64);185186if (res == PKT_ALIAS_OK)187random.ok++;188else189random.fail++;190191check_timeout();192}193gettimeofday(&now, NULL);194if (cnt > 0)195printf("%6.2f ", timevaldiff(now, start) / cnt);196else197printf("------ ");198199start = now;200p->ip_src.s_addr = ext.s_addr & htonl(0xfff00000);201p->ip_src.s_addr |= htonl(rand_range(0, 0xffff));202p->ip_dst = masq;203u = set_udp(p, rand_range(1, 0xffff), rand_range(1, 0xffff));204for (cnt = i = 0; i < attack_size; i++, cnt++) {205res = LibAliasIn(la, p, 64);206207if (res == PKT_ALIAS_OK)208attack.ok++;209else210attack.fail++;211212check_timeout();213}214gettimeofday(&now, NULL);215if (cnt > 0)216printf("%6.2f ", timevaldiff(now, start) / cnt);217else218printf("------ ");219220qsort(batch, batch_size, sizeof(*batch), randcmp);221222gettimeofday(&start, NULL);223for (cnt = i = 0; i < batch_size; i++) {224int j;225226/* random communication length */227for(j = rand_range(1, 150); j-- > 0; cnt++) {228int k;229230/* a random flow out of rolling window */231k = rand_range(i, i + 25);232if (k >= batch_size)233k = i;234235/* 10% outgoing, 90% incoming */236if (rand_range(0, 100) > 10) {237p->ip_src = batch[k].dst;238p->ip_dst = masq;239u = set_udp(p, batch[k].dport, batch[k].aport);240241res = LibAliasIn(la, p, 64);242if (res == PKT_ALIAS_OK &&243u->uh_sport == htons(batch[k].dport) &&244u->uh_dport == htons(batch[k].sport) &&245addr_eq(p->ip_dst, batch[k].src) &&246addr_eq(p->ip_src, batch[k].dst))247unnat.ok++;248else249unnat.fail++;250} else {251p->ip_src = batch[k].src;252p->ip_dst = batch[k].dst;253u = set_udp(p, batch[k].sport, batch[k].dport);254255res = LibAliasOut(la, p, 64);256if (res == PKT_ALIAS_OK &&257u->uh_sport == htons(batch[k].aport) &&258u->uh_dport == htons(batch[k].dport) &&259addr_eq(p->ip_dst, batch[k].dst) &&260addr_eq(p->ip_src, masq))261usenat.ok++;262else263usenat.fail++;264}265check_timeout();266}267}268gettimeofday(&now, NULL);269if (cnt > 0)270printf("%6.2f ", timevaldiff(now, start) / cnt);271else272printf("------ ");273274printf("\n");275}276out:277printf("\n\n");278free(batch);279free(p);280281printf("Results\n");282printf(" Rounds : %9u\n", round);283printf("newNAT ok : %9lu\n", nat.ok);284printf("newNAT fail: %9lu\n", nat.fail);285printf("useNAT ok : %9lu (out)\n", usenat.ok);286printf("useNAT fail: %9lu (out)\n", usenat.fail);287printf("useNAT ok : %9lu (in)\n", unnat.ok);288printf("useNAT fail: %9lu (in)\n", unnat.fail);289printf("RANDOM ok : %9lu\n", random.ok);290printf("RANDOM fail: %9lu\n", random.fail);291printf("ATTACK ok : %9lu\n", attack.ok);292printf("ATTACK fail: %9lu\n", attack.fail);293printf(" ---------\n");294printf(" Total: %9lu\n",295nat.ok + nat.fail +296unnat.ok + unnat.fail +297usenat.ok + usenat.fail +298random.ok + random.fail +299attack.ok + attack.fail);300301gettimeofday(&start, NULL);302printf("\n Cleanup : ");303LibAliasUninit(la);304gettimeofday(&now, NULL);305printf("%.2fs\n", timevaldiff(now, start)/1000000l);306return (0);307}308309310