1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery *
4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*e7be843bSPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*e7be843bSPierre Pronchery * in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery */
9*e7be843bSPierre Pronchery
10*e7be843bSPierre Pronchery #include <openssl/bio.h>
11*e7be843bSPierre Pronchery #include "testutil.h"
12*e7be843bSPierre Pronchery
13*e7be843bSPierre Pronchery #ifndef OPENSSL_NO_DGRAM
test_dgram(void)14*e7be843bSPierre Pronchery static int test_dgram(void)
15*e7be843bSPierre Pronchery {
16*e7be843bSPierre Pronchery BIO *bio = BIO_new(BIO_s_dgram_mem()), *rbio = NULL;
17*e7be843bSPierre Pronchery int testresult = 0;
18*e7be843bSPierre Pronchery const char msg1[] = "12345656";
19*e7be843bSPierre Pronchery const char msg2[] = "abcdefghijklmno";
20*e7be843bSPierre Pronchery const char msg3[] = "ABCDEF";
21*e7be843bSPierre Pronchery const char msg4[] = "FEDCBA";
22*e7be843bSPierre Pronchery char buf[80];
23*e7be843bSPierre Pronchery
24*e7be843bSPierre Pronchery if (!TEST_ptr(bio))
25*e7be843bSPierre Pronchery goto err;
26*e7be843bSPierre Pronchery
27*e7be843bSPierre Pronchery rbio = BIO_new_mem_buf(msg1, sizeof(msg1));
28*e7be843bSPierre Pronchery if (!TEST_ptr(rbio))
29*e7be843bSPierre Pronchery goto err;
30*e7be843bSPierre Pronchery
31*e7be843bSPierre Pronchery /* Setting the EOF return value on a non datagram mem BIO should be fine */
32*e7be843bSPierre Pronchery if (!TEST_int_gt(BIO_set_mem_eof_return(rbio, 0), 0))
33*e7be843bSPierre Pronchery goto err;
34*e7be843bSPierre Pronchery
35*e7be843bSPierre Pronchery /* Setting the EOF return value on a datagram mem BIO should fail */
36*e7be843bSPierre Pronchery if (!TEST_int_le(BIO_set_mem_eof_return(bio, 0), 0))
37*e7be843bSPierre Pronchery goto err;
38*e7be843bSPierre Pronchery
39*e7be843bSPierre Pronchery /* Write 4 dgrams */
40*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg1, sizeof(msg1)), sizeof(msg1)))
41*e7be843bSPierre Pronchery goto err;
42*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg2, sizeof(msg2)), sizeof(msg2)))
43*e7be843bSPierre Pronchery goto err;
44*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg3, sizeof(msg3)), sizeof(msg3)))
45*e7be843bSPierre Pronchery goto err;
46*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg4, sizeof(msg4)), sizeof(msg4)))
47*e7be843bSPierre Pronchery goto err;
48*e7be843bSPierre Pronchery
49*e7be843bSPierre Pronchery /* Reading all 4 dgrams out again should all be the correct size */
50*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg1))
51*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg1), msg1, sizeof(msg1))
52*e7be843bSPierre Pronchery || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg2))
53*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg2), msg2, sizeof(msg2))
54*e7be843bSPierre Pronchery || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg3))
55*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg3), msg3, sizeof(msg3))
56*e7be843bSPierre Pronchery || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg4))
57*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg4), msg4, sizeof(msg4)))
58*e7be843bSPierre Pronchery goto err;
59*e7be843bSPierre Pronchery
60*e7be843bSPierre Pronchery /* Interleaving writes and reads should be fine */
61*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg1, sizeof(msg1)), sizeof(msg1)))
62*e7be843bSPierre Pronchery goto err;
63*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg2, sizeof(msg2)), sizeof(msg2)))
64*e7be843bSPierre Pronchery goto err;
65*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg1))
66*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg1), msg1, sizeof(msg1)))
67*e7be843bSPierre Pronchery goto err;
68*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg3, sizeof(msg3)), sizeof(msg3)))
69*e7be843bSPierre Pronchery goto err;
70*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg2))
71*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg2), msg2, sizeof(msg2))
72*e7be843bSPierre Pronchery || !TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg3))
73*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg3), msg3, sizeof(msg3)))
74*e7be843bSPierre Pronchery goto err;
75*e7be843bSPierre Pronchery
76*e7be843bSPierre Pronchery /*
77*e7be843bSPierre Pronchery * Requesting less than the available data in a dgram should not impact the
78*e7be843bSPierre Pronchery * next packet.
79*e7be843bSPierre Pronchery */
80*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg1, sizeof(msg1)), sizeof(msg1)))
81*e7be843bSPierre Pronchery goto err;
82*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, msg2, sizeof(msg2)), sizeof(msg2)))
83*e7be843bSPierre Pronchery goto err;
84*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_read(bio, buf, /* Short buffer */ 2), 2)
85*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, 2, msg1, 2))
86*e7be843bSPierre Pronchery goto err;
87*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(msg2))
88*e7be843bSPierre Pronchery || !TEST_mem_eq(buf, sizeof(msg2), msg2, sizeof(msg2)))
89*e7be843bSPierre Pronchery goto err;
90*e7be843bSPierre Pronchery
91*e7be843bSPierre Pronchery /*
92*e7be843bSPierre Pronchery * Writing a zero length datagram will return zero, but no datagrams will
93*e7be843bSPierre Pronchery * be written. Attempting to read when there are no datagrams to read should
94*e7be843bSPierre Pronchery * return a negative result, but not eof. Retry flags will be set.
95*e7be843bSPierre Pronchery */
96*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_write(bio, NULL, 0), 0)
97*e7be843bSPierre Pronchery || !TEST_int_lt(BIO_read(bio, buf, sizeof(buf)), 0)
98*e7be843bSPierre Pronchery || !TEST_false(BIO_eof(bio))
99*e7be843bSPierre Pronchery || !TEST_true(BIO_should_retry(bio)))
100*e7be843bSPierre Pronchery goto err;
101*e7be843bSPierre Pronchery
102*e7be843bSPierre Pronchery if (!TEST_int_eq(BIO_dgram_set_mtu(bio, 123456), 1)
103*e7be843bSPierre Pronchery || !TEST_int_eq(BIO_dgram_get_mtu(bio), 123456))
104*e7be843bSPierre Pronchery goto err;
105*e7be843bSPierre Pronchery
106*e7be843bSPierre Pronchery testresult = 1;
107*e7be843bSPierre Pronchery err:
108*e7be843bSPierre Pronchery BIO_free(rbio);
109*e7be843bSPierre Pronchery BIO_free(bio);
110*e7be843bSPierre Pronchery return testresult;
111*e7be843bSPierre Pronchery }
112*e7be843bSPierre Pronchery #endif
113*e7be843bSPierre Pronchery
setup_tests(void)114*e7be843bSPierre Pronchery int setup_tests(void)
115*e7be843bSPierre Pronchery {
116*e7be843bSPierre Pronchery if (!test_skip_common_options()) {
117*e7be843bSPierre Pronchery TEST_error("Error parsing test options\n");
118*e7be843bSPierre Pronchery return 0;
119*e7be843bSPierre Pronchery }
120*e7be843bSPierre Pronchery
121*e7be843bSPierre Pronchery #ifndef OPENSSL_NO_DGRAM
122*e7be843bSPierre Pronchery ADD_TEST(test_dgram);
123*e7be843bSPierre Pronchery #endif
124*e7be843bSPierre Pronchery
125*e7be843bSPierre Pronchery return 1;
126*e7be843bSPierre Pronchery }
127