]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEV: udp: add support for random packet corruption
authorWilly Tarreau <w@1wt.eu>
Wed, 16 Mar 2022 14:07:51 +0000 (15:07 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Mar 2022 14:09:54 +0000 (15:09 +0100)
-c sets a corruption rate in % of the packets.
-o sets the start offset of the area to be corrupted.
-w sets the length of the area to be corrupted.

A single byte within that area will then be randomly XORed with a
random value.

dev/udp/udp-perturb.c

index 3df0f797f4bfc13caae350d23b5a59bf53371f8b..098e61c2c2b92b2443f9e2e90920625c6a54be31 100644 (file)
@@ -77,6 +77,9 @@ struct {
 } history[MAXREORDER];
 int history_idx = 0;
 unsigned int rand_rate = 0;
+unsigned int corr_rate = 0;
+unsigned int corr_span = 1;
+unsigned int corr_base = 0;
 
 struct conn conns[MAXCONN];        // sole connection for now
 int fd_frt;
@@ -319,6 +322,14 @@ int handle_frt(int fd, struct pollfd *pfd, struct conn *conns, int nbconn)
        if (ret < 0)
                return errno == EAGAIN ? 0 : -1;
 
+       if (corr_rate > 0 && prng(100) < corr_rate) {
+               unsigned int rnd = prng(corr_span * 256); // pos and value
+               unsigned int pos = corr_base + (rnd >> 8);
+
+               if (pos < ret)
+                       pktbuf[pos] ^= rnd;
+       }
+
        conn = NULL;
        for (i = 0; i < nbconn; i++) {
                if (addr.ss_family != conns[i].cli_addr.ss_family)
@@ -421,6 +432,9 @@ void usage(int status, const char *name)
            "  -h           display this help\n"
            "  -r rate      reorder/duplicate/lose around <rate>%% of packets\n"
            "  -s seed      force initial random seed (currently %#x)\n"
+           "  -c rate      corrupt around <rate>%% of packets\n"
+           "  -o ofs       start offset of corrupted area (def: 0)\n"
+           "  -w width     width of the corrupted area (def: 1)\n"
            "", name, prng_state);
 }
 
@@ -435,7 +449,7 @@ int main(int argc, char **argv)
        err.size = 100;
        err.msg = malloc(err.size);
 
-       while ((opt = getopt(argc, argv, "hr:s:")) != -1) {
+       while ((opt = getopt(argc, argv, "hr:s:c:o:w:")) != -1) {
                switch (opt) {
                case 'r': // rand_rate%
                        rand_rate = atoi(optarg);
@@ -443,6 +457,15 @@ int main(int argc, char **argv)
                case 's': // seed
                        prng_state = atol(optarg);
                        break;
+               case 'c': // corruption rate
+                       corr_rate = atol(optarg);
+                       break;
+               case 'o': // corruption offset
+                       corr_base = atol(optarg);
+                       break;
+               case 'w': // corruption width
+                       corr_span = atol(optarg);
+                       break;
                default: // help, anything else
                        usage(0, argv[0]);
                }