1 1.1 christos /* 2 1.1 christos * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #include <openssl/bio.h> 11 1.1 christos #include "quictestlib.h" 12 1.1 christos #include "../testutil.h" 13 1.1 christos 14 1.1.1.1.2.1 martin #define MSG_DATA_LEN_MAX 1472 15 1.1 christos #define SAMPLING_WINDOW_PERIOD 10 /* in milliseconds */ 16 1.1 christos #define MAX_PKTS_PER_WINDOW 1024 17 1.1 christos 18 1.1 christos struct pkt_info_st { 19 1.1 christos size_t size; 20 1.1 christos OSSL_TIME timestamp; 21 1.1 christos }; 22 1.1 christos 23 1.1 christos struct bw_limiter_st { 24 1.1 christos struct pkt_info_st pinfos[MAX_PKTS_PER_WINDOW]; /* ring buffer */ 25 1.1.1.1.2.1 martin size_t start, num; /* ring buffer start and number of items */ 26 1.1.1.1.2.1 martin size_t size_sum; /* sum of packet sizes in window */ 27 1.1.1.1.2.1 martin size_t bw; /* bandwidth in bytes/ms */ 28 1.1 christos }; 29 1.1 christos 30 1.1 christos struct noisy_dgram_st { 31 1.1 christos uint64_t this_dgram; 32 1.1 christos BIO_MSG msg; 33 1.1 christos uint64_t reinject_dgram; 34 1.1 christos int backoff; 35 1.1.1.1.2.1 martin int noise_rate; /* 1 in noise_rate packets will get noise */ 36 1.1 christos struct bw_limiter_st recv_limit, send_limit; 37 1.1 christos OSSL_TIME (*now_cb)(void *arg); 38 1.1 christos void *now_cb_arg; 39 1.1 christos }; 40 1.1 christos 41 1.1 christos static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr) 42 1.1 christos { 43 1.1 christos long ret; 44 1.1 christos BIO *next = BIO_next(bio); 45 1.1 christos 46 1.1 christos if (next == NULL) 47 1.1 christos return 0; 48 1.1 christos 49 1.1 christos switch (cmd) { 50 1.1 christos case BIO_CTRL_DUP: 51 1.1 christos ret = 0L; 52 1.1 christos break; 53 1.1 christos case BIO_CTRL_NOISE_BACK_OFF: { 54 1.1.1.1.2.1 martin struct noisy_dgram_st *data; 55 1.1 christos 56 1.1.1.1.2.1 martin data = BIO_get_data(bio); 57 1.1.1.1.2.1 martin if (!TEST_ptr(data)) 58 1.1.1.1.2.1 martin return 0; 59 1.1.1.1.2.1 martin data->backoff = (int)num; 60 1.1.1.1.2.1 martin ret = 1; 61 1.1.1.1.2.1 martin break; 62 1.1.1.1.2.1 martin } 63 1.1 christos case BIO_CTRL_NOISE_RATE: { 64 1.1.1.1.2.1 martin struct noisy_dgram_st *data; 65 1.1 christos 66 1.1.1.1.2.1 martin data = BIO_get_data(bio); 67 1.1.1.1.2.1 martin if (!TEST_ptr(data)) 68 1.1.1.1.2.1 martin return 0; 69 1.1.1.1.2.1 martin data->noise_rate = (int)num; 70 1.1.1.1.2.1 martin ret = 1; 71 1.1.1.1.2.1 martin break; 72 1.1.1.1.2.1 martin } 73 1.1 christos case BIO_CTRL_NOISE_RECV_BANDWIDTH: { 74 1.1.1.1.2.1 martin struct noisy_dgram_st *data; 75 1.1 christos 76 1.1.1.1.2.1 martin data = BIO_get_data(bio); 77 1.1.1.1.2.1 martin if (!TEST_ptr(data)) 78 1.1.1.1.2.1 martin return 0; 79 1.1.1.1.2.1 martin data->recv_limit.bw = (size_t)num; 80 1.1.1.1.2.1 martin ret = 1; 81 1.1.1.1.2.1 martin break; 82 1.1.1.1.2.1 martin } 83 1.1 christos case BIO_CTRL_NOISE_SEND_BANDWIDTH: { 84 1.1.1.1.2.1 martin struct noisy_dgram_st *data; 85 1.1 christos 86