summaryrefslogtreecommitdiffstats
path: root/test/helpers
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2023-09-21 11:25:00 +0200
committerMatt Caswell <matt@openssl.org>2023-09-22 14:56:43 +0200
commit523c5a06c590b7f2950043a6b8308c3f3e49cb51 (patch)
tree3a274dc0eaa8f53bd436a4d0df7e8c63f6897938 /test/helpers
parentEnsure we free all the BIOs in a chain for QUIC like we do in TLS (diff)
downloadopenssl-523c5a06c590b7f2950043a6b8308c3f3e49cb51.tar.xz
openssl-523c5a06c590b7f2950043a6b8308c3f3e49cb51.zip
Clarify the terminology in the noisy dgram BIO
The previous terminology was quite confusing. We try to use drop, duplicate and delay more consistently and introduce the "reinject" terminology as a mechanism for implementing duplicates and delays. Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/22157)
Diffstat (limited to 'test/helpers')
-rw-r--r--test/helpers/noisydgrambio.c107
1 files changed, 71 insertions, 36 deletions
diff --git a/test/helpers/noisydgrambio.c b/test/helpers/noisydgrambio.c
index c93b6961ec..8b68726dd2 100644
--- a/test/helpers/noisydgrambio.c
+++ b/test/helpers/noisydgrambio.c
@@ -16,7 +16,7 @@
struct noisy_dgram_st {
uint64_t this_dgram;
BIO_MSG msg;
- uint64_t delayed_dgram;
+ uint64_t reinject_dgram;
};
static long noisy_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
@@ -54,31 +54,66 @@ static int noisy_dgram_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride,
return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed);
}
-static void get_noise(uint64_t *delay, int *should_drop)
+/* 1 in NOISE_RATE datagrams will be noisy. With a value of 5 that is 20% */
+#define NOISE_RATE 5
+
+/*
+ * We have 3 different types of noise: drop, duplicate and delay
+ * Each of these have equal probability.
+ */
+#define NOISE_TYPE_DROP 0
+#define NOISE_TYPE_DUPLICATE 1
+#define NOISE_TYPE_DELAY 2
+#define NUM_NOISE_TYPES 3
+
+/*
+ * When a duplicate occurs we reinject the new datagram after up to
+ * MAX_DGRAM_REINJECT datagrams have been sent. A reinject of 1 means that the
+ * duplicate follows immediately after the original datagram. A reinject of 4
+ * means that original datagram plus 3 other datagrams are sent before the
+ * reinjected datagram is inserted.
+ * This also controls when a delay (not a duplicate) occurs. In that case
+ * we add 1 to the number because there is no point in skipping the current
+ * datagram only to immediately reinject it in the next datagram.
+ */
+#define MAX_DGRAM_REINJECT 4
+
+static void get_noise(uint64_t *reinject, int *should_drop)
{
uint32_t type;
- /* 20% of all datagrams should be noisy */
- if (test_random() % 5 != 0) {
- *delay = 0;
+ if (test_random() % NOISE_RATE != 0) {
+ *reinject = 0;
*should_drop = 0;
return;
}
- type = test_random() % 3;
+ type = test_random() % NUM_NOISE_TYPES;
- /* Of noisy datagrams, 33% drop only, 33% delay only, 33% drop and delay */
-
- *should_drop = (type == 0 || type == 1);
+ /*
+ * Of noisy datagrams, 33% drop, 33% duplicate, 33% delay
+ * A duplicated datagram keeps the current datagram and reinjects a new
+ * identical one after up to MAX_DGRAM_DELAY datagrams have been sent.
+ * A delayed datagram is implemented as both a reinject and a drop, i.e. an
+ * identical datagram is reinjected after the given number of datagrams have
+ * been sent and the current datagram is dropped.
+ */
+ *should_drop = (type == NOISE_TYPE_DROP || type == NOISE_TYPE_DELAY);
- /* Where a delay occurs we delay by 1 - 4 datagrams */
- *delay = (type == 0) ? 0 : (uint64_t)((test_random() % 4) + 1);
+ /*
+ * Where a duplicate occurs we reinject the copy of the datagram up to
+ * MAX_DGRAM_DELAY datagrams later
+ */
+ *reinject = (type == NOISE_TYPE_DROP)
+ ? 0
+ : (uint64_t)((test_random() % MAX_DGRAM_REINJECT) + 1);
/*
- * No point in delaying by 1 datagram if we are also dropping, so we delay
- * by an extra datagram in that case
+ * No point in reinjecting after 1 datagram if the current datagram is also
+ * dropped (i.e. this is a delay not a duplicate), so we reinject after an
+ * extra datagram in that case
*/
- *delay += (uint64_t)(*should_drop);
+ *reinject += (uint64_t)(*should_drop);
}
static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride,
@@ -133,14 +168,14 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride,
for (i = 0, thismsg = msg;
i < msg_cnt;
i++, thismsg++, data->this_dgram++) {
- uint64_t delay;
+ uint64_t reinject;
int should_drop;
- /* If we have a delayed message ready insert it now */
- if (data->delayed_dgram > 0
- && data->delayed_dgram == data->this_dgram) {
+ /* If we have a message to reinject then insert it now */
+ if (data->reinject_dgram > 0
+ && data->reinject_dgram == data->this_dgram) {
if (msg_cnt < num_msg) {
- /* Make space for the inserted message */
+ /* Make space for the injected message */
for (j = msg_cnt; j > i; j--) {
if (!bio_msg_copy(&msg[j], &msg[j - 1]))
return 0;
@@ -148,38 +183,38 @@ static int noisy_dgram_recvmmsg(BIO *bio, BIO_MSG *msg, size_t stride,
if (!bio_msg_copy(thismsg, &data->msg))
return 0;
msg_cnt++;
- data->delayed_dgram = 0;
+ data->reinject_dgram = 0;
#ifdef OSSL_NOISY_DGRAM_DEBUG
- printf("**Inserting a delayed datagram\n");
+ printf("**Injecting a datagram\n");
BIO_dump_fp(stdout, thismsg->data, thismsg->data_len);
printf("\n");
#endif
continue;
- } /* else we have no space for the insertion, so just drop it */
- data->delayed_dgram = 0;
+ } /* else we have no space for the injection, so just drop it */
+ data->reinject_dgram = 0;
}
- get_noise(&delay, &should_drop);
+ get_noise(&reinject, &should_drop);
- /* We ignore delay if a message is already delayed */
- if (delay > 0 && data->delayed_dgram == 0) {
+ /*
+ * We ignore reinjection if a message is already waiting to be
+ * reinjected
+ */
+ if (reinject > 0 && data->reinject_dgram == 0) {
/*
- * Note that a message may be delayed *and* dropped, or delayed
- * and *not* dropped.
- * Delayed and dropped means the message will not be sent now and
- * will only be sent after the delay.
- * Delayed and not dropped means the message will be sent now and
- * a duplicate will also be sent after the delay.
+ * Both duplicated and delayed datagrams get reintroduced after the
+ * delay period. Datagrams that are delayed only (not duplicated)
+ * will also have the current copy of the datagram dropped (i.e
+ * should_drop below will be true).
*/
-
if (!bio_msg_copy(&data->msg, thismsg))
return 0;
- data->delayed_dgram = data->this_dgram + delay;
+ data->reinject_dgram = data->this_dgram + reinject;
#ifdef OSSL_NOISY_DGRAM_DEBUG
- printf("**Delaying a datagram for %u messages%s\n",
- (unsigned int)delay, should_drop ? "" : "(duplicating)");
+ printf("**Scheduling a reinject after %u messages%s\n",
+ (unsigned int)reinject, should_drop ? "" : "(duplicating)");
BIO_dump_fp(stdout, thismsg->data, thismsg->data_len);
printf("\n");
#endif