OpenVPN
test_packet_id.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2016-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program (see the file COPYING included with this
21  * distribution); if not, write to the Free Software Foundation, Inc.,
22  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include "syshead.h"
30 
31 #include <stdarg.h>
32 #include <stddef.h>
33 #include <setjmp.h>
34 #include <cmocka.h>
35 
36 #include "packet_id.h"
37 #include "reliable.h"
38 #include "test_common.h"
39 
41  struct {
42  uint32_t buf_id;
43  uint32_t buf_time;
44  } test_buf_data;
45  struct buffer test_buf;
47 };
48 
49 static int
51 {
52  struct test_packet_id_write_data *data =
53  calloc(1, sizeof(struct test_packet_id_write_data));
54 
55  if (!data)
56  {
57  return -1;
58  }
59 
60  data->test_buf.data = (void *) &data->test_buf_data;
61  data->test_buf.capacity = sizeof(data->test_buf_data);
62 
63  *state = data;
64  return 0;
65 }
66 
67 static int
69 {
70  free(*state);
71  return 0;
72 }
73 
74 static void
76 {
77  struct test_packet_id_write_data *data = *state;
78 
79  now = 5010;
80  assert_true(packet_id_write(&data->pis, &data->test_buf, false, false));
81  assert_true(data->pis.id == 1);
82  assert_true(data->test_buf_data.buf_id == htonl(1));
83  assert_true(data->test_buf_data.buf_time == 0);
84 }
85 
86 static void
88 {
89  struct test_packet_id_write_data *data = *state;
90 
91  now = 5010;
92  assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
93  assert(data->pis.id == 1);
94  assert(data->pis.time == now);
95  assert_true(data->test_buf_data.buf_id == htonl(1));
96  assert_true(data->test_buf_data.buf_time == htonl(now));
97 }
98 
99 static void
101 {
102  struct test_packet_id_write_data *data = *state;
103 
104  data->test_buf.offset = sizeof(packet_id_type);
105  now = 5010;
106  assert_true(packet_id_write(&data->pis, &data->test_buf, false, true));
107  assert_true(data->pis.id == 1);
108  assert_true(data->test_buf_data.buf_id == htonl(1));
109  assert_true(data->test_buf_data.buf_time == 0);
110 }
111 
112 static void
114 {
115  struct test_packet_id_write_data *data = *state;
116 
117  data->test_buf.offset = sizeof(data->test_buf_data);
118  now = 5010;
119  assert_true(packet_id_write(&data->pis, &data->test_buf, true, true));
120  assert(data->pis.id == 1);
121  assert(data->pis.time == now);
122  assert_true(data->test_buf_data.buf_id == htonl(1));
123  assert_true(data->test_buf_data.buf_time == htonl(now));
124 }
125 
126 static void
128 {
129  struct test_packet_id_write_data *data = *state;
130 
131  data->pis.id = ~0;
132  assert_false(packet_id_write(&data->pis, &data->test_buf, false, false));
133 }
134 
135 static void
137 {
138  struct test_packet_id_write_data *data = *state;
139 
140  data->pis.id = ~0;
141  data->pis.time = 5006;
142 
143  /* Write fails if time did not change */
144  now = 5006;
145  assert_false(packet_id_write(&data->pis, &data->test_buf, true, false));
146 
147  /* Write succeeds if time moved forward */
148  now = 5010;
149  assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
150 
151  assert(data->pis.id == 1);
152  assert(data->pis.time == now);
153  assert_true(data->test_buf_data.buf_id == htonl(1));
154  assert_true(data->test_buf_data.buf_time == htonl(now));
155 }
156 
157 static void
159 {
160 
161  struct reliable *rel = malloc(sizeof(struct reliable));
162  reliable_init(rel, 100, 50, 8, false);
163 
164  rel->array[5].active = true;
165  rel->array[5].packet_id = 100;
166 
167  rel->packet_id = 103;
168 
169  assert_int_equal(5, reliable_get_num_output_sequenced_available(rel));
170 
171  rel->array[6].active = true;
172  rel->array[6].packet_id = 97;
173  assert_int_equal(2, reliable_get_num_output_sequenced_available(rel));
174 
175  /* test ids close to int/unsigned int barrier */
176 
177  rel->array[5].active = true;
178  rel->array[5].packet_id = (0x80000000u -3);
179  rel->array[6].active = false;
180  rel->packet_id = (0x80000000u -1);
181 
182  assert_int_equal(6, reliable_get_num_output_sequenced_available(rel));
183 
184  rel->array[5].active = true;
185  rel->array[5].packet_id = (0x80000000u -3);
186  rel->packet_id = 0x80000001u;
187 
188  assert_int_equal(4, reliable_get_num_output_sequenced_available(rel));
189 
190 
191  /* test wrapping */
192  rel->array[5].active = true;
193  rel->array[5].packet_id = (0xffffffffu -3);
194  rel->array[6].active = false;
195  rel->packet_id = (0xffffffffu - 1);
196 
197  assert_int_equal(6, reliable_get_num_output_sequenced_available(rel));
198 
199  rel->array[2].packet_id = 0;
200  rel->array[2].active = true;
201 
202  assert_int_equal(6, reliable_get_num_output_sequenced_available(rel));
203 
204  rel->packet_id = 3;
205  assert_int_equal(1, reliable_get_num_output_sequenced_available(rel));
206 
207  reliable_free(rel);
208 }
209 
210 
211 static void
213 {
214  struct reliable_ack ack = { .len = 4, .packet_id = {2, 1, 3, 2} };
215 
216  struct reliable_ack mru_ack = {0 };
217 
218  /* Test copying to empty ack structure */
219  copy_acks_to_mru(&ack, &mru_ack, 4);
220  assert_int_equal(mru_ack.len, 3);
221  assert_int_equal(mru_ack.packet_id[0], 2);
222  assert_int_equal(mru_ack.packet_id[1], 1);
223  assert_int_equal(mru_ack.packet_id[2], 3);
224 
225  /* Copying again should not change the result */
226  copy_acks_to_mru(&ack, &mru_ack, 4);
227  assert_int_equal(mru_ack.len, 3);
228  assert_int_equal(mru_ack.packet_id[0], 2);
229  assert_int_equal(mru_ack.packet_id[1], 1);
230  assert_int_equal(mru_ack.packet_id[2], 3);
231 
232  /* Copying just the first two element should not change the order
233  * as they are still the most recent*/
234  struct reliable_ack mru_ack2 = mru_ack;
235  copy_acks_to_mru(&ack, &mru_ack2, 2);
236  assert_int_equal(mru_ack2.packet_id[0], 2);
237  assert_int_equal(mru_ack2.packet_id[1], 1);
238  assert_int_equal(mru_ack2.packet_id[2], 3);
239 
240  /* Adding just two packets shoudl ignore the 42 in array and
241  * reorder the order in the MRU */
242  struct reliable_ack ack2 = { .len = 3, .packet_id = {3, 2, 42} };
243  copy_acks_to_mru(&ack2, &mru_ack2, 2);
244  assert_int_equal(mru_ack2.packet_id[0], 3);
245  assert_int_equal(mru_ack2.packet_id[1], 2);
246  assert_int_equal(mru_ack2.packet_id[2], 1);
247 
248  /* Copying a zero array into it should also change nothing */
249  struct reliable_ack empty_ack = { .len = 0 };
250  copy_acks_to_mru(&empty_ack, &mru_ack, 0);
251  assert_int_equal(mru_ack.len, 3);
252  assert_int_equal(mru_ack.packet_id[0], 2);
253  assert_int_equal(mru_ack.packet_id[1], 1);
254  assert_int_equal(mru_ack.packet_id[2], 3);
255 
256  /* Or should just 0 elements of the ack */
257  copy_acks_to_mru(&ack, &mru_ack, 0);
258  assert_int_equal(mru_ack.len, 3);
259  assert_int_equal(mru_ack.packet_id[0], 2);
260  assert_int_equal(mru_ack.packet_id[1], 1);
261  assert_int_equal(mru_ack.packet_id[2], 3);
262 
263  struct reliable_ack ack3 = { .len = 7, .packet_id = {5, 6, 7, 8, 9, 10, 11}};
264 
265  /* Adding multiple acks tests if the a full array is handled correctly */
266  copy_acks_to_mru(&ack3, &mru_ack, 7);
267 
268  struct reliable_ack expected_ack = { .len = 8, .packet_id = {5, 6, 7, 8, 9, 10, 11, 2}};
269  assert_int_equal(mru_ack.len, expected_ack.len);
270 
271  assert_memory_equal(mru_ack.packet_id, expected_ack.packet_id, sizeof(expected_ack.packet_id));
272 }
273 
274 int
275 main(void)
276 {
278  const struct CMUnitTest tests[] = {
279  cmocka_unit_test_setup_teardown(test_packet_id_write_short,
282  cmocka_unit_test_setup_teardown(test_packet_id_write_long,
285  cmocka_unit_test_setup_teardown(test_packet_id_write_short_prepend,
288  cmocka_unit_test_setup_teardown(test_packet_id_write_long_prepend,
291  cmocka_unit_test_setup_teardown(test_packet_id_write_short_wrap,
294  cmocka_unit_test_setup_teardown(test_packet_id_write_long_wrap,
297  cmocka_unit_test(test_get_num_output_sequenced_available),
298  cmocka_unit_test(test_copy_acks_to_lru)
299 
300  };
301 
302  return cmocka_run_group_tests_name("packet_id tests", tests, NULL, NULL);
303 }
packet_id_send::id
packet_id_type id
Definition: packet_id.h:167
test_packet_id_write_short_prepend
static void test_packet_id_write_short_prepend(void **state)
Definition: test_packet_id.c:100
test_copy_acks_to_lru
static void test_copy_acks_to_lru(void **state)
Definition: test_packet_id.c:212
packet_id_send::time
time_t time
Definition: packet_id.h:168
test_packet_id_write_short
static void test_packet_id_write_short(void **state)
Definition: test_packet_id.c:75
openvpn_unit_test_setup
static void openvpn_unit_test_setup()
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
Definition: test_common.h:36
test_packet_id_write_data::buf_id
uint32_t buf_id
Definition: test_packet_id.c:42
test_common.h
buffer::capacity
int capacity
Size in bytes of memory allocated by malloc().
Definition: buffer.h:62
reliable::array
struct reliable_entry array[RELIABLE_CAPACITY]
Definition: reliable.h:98
test_packet_id_write_long
static void test_packet_id_write_long(void **state)
Definition: test_packet_id.c:87
reliable_ack::len
int len
Definition: reliable.h:63
reliable.h
reliable_get_num_output_sequenced_available
int reliable_get_num_output_sequenced_available(struct reliable *rel)
Counts the number of free buffers in output that can be potentially used for sending.
Definition: reliable.c:552
test_packet_id_write_teardown
static int test_packet_id_write_teardown(void **state)
Definition: test_packet_id.c:68
packet_id.h
test_packet_id_write_long_wrap
static void test_packet_id_write_long_wrap(void **state)
Definition: test_packet_id.c:136
test_packet_id_write_data::buf_time
uint32_t buf_time
Definition: test_packet_id.c:43
test_packet_id_write_data::test_buf
struct buffer test_buf
Definition: test_packet_id.c:45
test_packet_id_write_long_prepend
static void test_packet_id_write_long_prepend(void **state)
Definition: test_packet_id.c:113
reliable_ack::packet_id
packet_id_type packet_id[RELIABLE_ACK_SIZE]
Definition: reliable.h:64
packet_id_type
uint32_t packet_id_type
Definition: packet_id.h:44
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
packet_id_send
Definition: packet_id.h:165
reliable::packet_id
packet_id_type packet_id
Definition: reliable.h:95
syshead.h
main
int main(void)
Definition: test_packet_id.c:275
buffer::offset
int offset
Offset in bytes of the actual content within the allocated memory.
Definition: buffer.h:64
packet_id_write
bool packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, bool prepend)
Write a packet ID to buf, and update the packet ID state.
Definition: packet_id.c:347
reliable
The reliability layer storage structure for one VPN tunnel's control channel in one direction.
Definition: reliable.h:91
test_packet_id_write_data::test_buf_data
struct test_packet_id_write_data::@20 test_buf_data
reliable_entry::packet_id
packet_id_type packet_id
Definition: reliable.h:79
reliable_entry::active
bool active
Definition: reliable.h:76
test_packet_id_write_short_wrap
static void test_packet_id_write_short_wrap(void **state)
Definition: test_packet_id.c:127
test_get_num_output_sequenced_available
static void test_get_num_output_sequenced_available(void **state)
Definition: test_packet_id.c:158
test_packet_id_write_setup
static int test_packet_id_write_setup(void **state)
Definition: test_packet_id.c:50
test_packet_id_write_data
Definition: test_packet_id.c:40
now
time_t now
Definition: otime.c:34
test_packet_id_write_data::pis
struct packet_id_send pis
Definition: test_packet_id.c:46
config.h
reliable_init
void reliable_init(struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
Initialize a reliable structure.
Definition: reliable.c:358
copy_acks_to_mru
void copy_acks_to_mru(struct reliable_ack *ack, struct reliable_ack *ack_mru, int n)
Copies the first n acks from ack to ack_mru.
Definition: reliable.c:211
reliable_ack
The acknowledgment structure in which packet IDs are stored for later acknowledgment.
Definition: reliable.h:61
reliable_free
void reliable_free(struct reliable *rel)
Free allocated memory associated with a reliable structure and the pointer itself.
Definition: reliable.c:376
buffer::data
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68