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 
39 #include "mock_msg.h"
40 
42  struct {
43  uint32_t buf_id;
44  uint32_t buf_time;
45  } test_buf_data;
46  struct buffer test_buf;
48 };
49 
50 static int
52 {
53  struct test_packet_id_write_data *data =
54  calloc(1, sizeof(struct test_packet_id_write_data));
55 
56  if (!data)
57  {
58  return -1;
59  }
60 
61  data->test_buf.data = (void *) &data->test_buf_data;
62  data->test_buf.capacity = sizeof(data->test_buf_data);
63 
64  *state = data;
65  return 0;
66 }
67 
68 static int
70 {
71  free(*state);
72  return 0;
73 }
74 
75 static void
77 {
78  struct test_packet_id_write_data *data = *state;
79 
80  now = 5010;
81  assert_true(packet_id_write(&data->pis, &data->test_buf, false, false));
82  assert_true(data->pis.id == 1);
83  assert_true(data->test_buf_data.buf_id == htonl(1));
84  assert_true(data->test_buf_data.buf_time == 0);
85 }
86 
87 static void
89 {
90  struct test_packet_id_write_data *data = *state;
91 
92  now = 5010;
93  assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
94  assert(data->pis.id == 1);
95  assert(data->pis.time == now);
96  assert_true(data->test_buf_data.buf_id == htonl(1));
97  assert_true(data->test_buf_data.buf_time == htonl(now));
98 }
99 
100 static void
102 {
103  struct test_packet_id_write_data *data = *state;
104 
105  data->test_buf.offset = sizeof(packet_id_type);
106  now = 5010;
107  assert_true(packet_id_write(&data->pis, &data->test_buf, false, true));
108  assert_true(data->pis.id == 1);
109  assert_true(data->test_buf_data.buf_id == htonl(1));
110  assert_true(data->test_buf_data.buf_time == 0);
111 }
112 
113 static void
115 {
116  struct test_packet_id_write_data *data = *state;
117 
118  data->test_buf.offset = sizeof(data->test_buf_data);
119  now = 5010;
120  assert_true(packet_id_write(&data->pis, &data->test_buf, true, true));
121  assert(data->pis.id == 1);
122  assert(data->pis.time == now);
123  assert_true(data->test_buf_data.buf_id == htonl(1));
124  assert_true(data->test_buf_data.buf_time == htonl(now));
125 }
126 
127 static void
129 {
130  struct test_packet_id_write_data *data = *state;
131 
132  data->pis.id = ~0;
133  assert_false(packet_id_write(&data->pis, &data->test_buf, false, false));
134 }
135 
136 static void
138 {
139  struct test_packet_id_write_data *data = *state;
140 
141  data->pis.id = ~0;
142  data->pis.time = 5006;
143 
144  /* Write fails if time did not change */
145  now = 5006;
146  assert_false(packet_id_write(&data->pis, &data->test_buf, true, false));
147 
148  /* Write succeeds if time moved forward */
149  now = 5010;
150  assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
151 
152  assert(data->pis.id == 1);
153  assert(data->pis.time == now);
154  assert_true(data->test_buf_data.buf_id == htonl(1));
155  assert_true(data->test_buf_data.buf_time == htonl(now));
156 }
157 
158 static void
160 {
161 
162  struct reliable *rel = malloc(sizeof(struct reliable));
163  reliable_init(rel, 100, 50, 8, false);
164 
165  rel->array[5].active = true;
166  rel->array[5].packet_id = 100;
167 
168  rel->packet_id = 103;
169 
170  assert_int_equal(5, reliable_get_num_output_sequenced_available(rel));
171 
172  rel->array[6].active = true;
173  rel->array[6].packet_id = 97;
174  assert_int_equal(2, reliable_get_num_output_sequenced_available(rel));
175 
176  /* test ids close to int/unsigned int barrier */
177 
178  rel->array[5].active = true;
179  rel->array[5].packet_id = (0x80000000u -3);
180  rel->array[6].active = false;
181  rel->packet_id = (0x80000000u -1);
182 
183  assert_int_equal(6, reliable_get_num_output_sequenced_available(rel));
184 
185  rel->array[5].active = true;
186  rel->array[5].packet_id = (0x80000000u -3);
187  rel->packet_id = 0x80000001u;
188 
189  assert_int_equal(4, reliable_get_num_output_sequenced_available(rel));
190 
191 
192  /* test wrapping */
193  rel->array[5].active = true;
194  rel->array[5].packet_id = (0xffffffffu -3);
195  rel->array[6].active = false;
196  rel->packet_id = (0xffffffffu - 1);
197 
198  assert_int_equal(6, reliable_get_num_output_sequenced_available(rel));
199 
200  rel->array[2].packet_id = 0;
201  rel->array[2].active = true;
202 
203  assert_int_equal(6, reliable_get_num_output_sequenced_available(rel));
204 
205  rel->packet_id = 3;
206  assert_int_equal(1, reliable_get_num_output_sequenced_available(rel));
207 
208  reliable_free(rel);
209 }
210 
211 
212 static void
214 {
215  struct reliable_ack ack = { .len = 4, .packet_id = {2, 1, 3, 2} };
216 
217  struct reliable_ack mru_ack = {0 };
218 
219  /* Test copying to empty ack structure */
220  copy_acks_to_mru(&ack, &mru_ack, 4);
221  assert_int_equal(mru_ack.len, 3);
222  assert_int_equal(mru_ack.packet_id[0], 2);
223  assert_int_equal(mru_ack.packet_id[1], 1);
224  assert_int_equal(mru_ack.packet_id[2], 3);
225 
226  /* Copying again should not change the result */
227  copy_acks_to_mru(&ack, &mru_ack, 4);
228  assert_int_equal(mru_ack.len, 3);
229  assert_int_equal(mru_ack.packet_id[0], 2);
230  assert_int_equal(mru_ack.packet_id[1], 1);
231  assert_int_equal(mru_ack.packet_id[2], 3);
232 
233  /* Copying just the first two element should not change the order
234  * as they are still the most recent*/
235  struct reliable_ack mru_ack2 = mru_ack;
236  copy_acks_to_mru(&ack, &mru_ack2, 2);
237  assert_int_equal(mru_ack2.packet_id[0], 2);
238  assert_int_equal(mru_ack2.packet_id[1], 1);
239  assert_int_equal(mru_ack2.packet_id[2], 3);
240 
241  /* Adding just two packets shoudl ignore the 42 in array and
242  * reorder the order in the MRU */
243  struct reliable_ack ack2 = { .len = 3, .packet_id = {3, 2, 42} };
244  copy_acks_to_mru(&ack2, &mru_ack2, 2);
245  assert_int_equal(mru_ack2.packet_id[0], 3);
246  assert_int_equal(mru_ack2.packet_id[1], 2);
247  assert_int_equal(mru_ack2.packet_id[2], 1);
248 
249  /* Copying a zero array into it should also change nothing */
250  struct reliable_ack empty_ack = { .len = 0 };
251  copy_acks_to_mru(&empty_ack, &mru_ack, 0);
252  assert_int_equal(mru_ack.len, 3);
253  assert_int_equal(mru_ack.packet_id[0], 2);
254  assert_int_equal(mru_ack.packet_id[1], 1);
255  assert_int_equal(mru_ack.packet_id[2], 3);
256 
257  /* Or should just 0 elements of the ack */
258  copy_acks_to_mru(&ack, &mru_ack, 0);
259  assert_int_equal(mru_ack.len, 3);
260  assert_int_equal(mru_ack.packet_id[0], 2);
261  assert_int_equal(mru_ack.packet_id[1], 1);
262  assert_int_equal(mru_ack.packet_id[2], 3);
263 
264  struct reliable_ack ack3 = { .len = 7, .packet_id = {5, 6, 7, 8, 9, 10, 11}};
265 
266  /* Adding multiple acks tests if the a full array is handled correctly */
267  copy_acks_to_mru(&ack3, &mru_ack, 7);
268 
269  struct reliable_ack expected_ack = { .len = 8, .packet_id = {5, 6, 7, 8, 9, 10, 11, 2}};
270  assert_int_equal(mru_ack.len, expected_ack.len);
271 
272  assert_memory_equal(mru_ack.packet_id, expected_ack.packet_id, sizeof(expected_ack.packet_id));
273 }
274 
275 int
276 main(void)
277 {
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:101
test_copy_acks_to_lru
static void test_copy_acks_to_lru(void **state)
Definition: test_packet_id.c:213
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:76
test_packet_id_write_data::buf_id
uint32_t buf_id
Definition: test_packet_id.c:43
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:88
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:69
packet_id.h
test_packet_id_write_long_wrap
static void test_packet_id_write_long_wrap(void **state)
Definition: test_packet_id.c:137
test_packet_id_write_data::buf_time
uint32_t buf_time
Definition: test_packet_id.c:44
test_packet_id_write_data::test_buf
struct buffer test_buf
Definition: test_packet_id.c:46
test_packet_id_write_long_prepend
static void test_packet_id_write_long_prepend(void **state)
Definition: test_packet_id.c:114
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
mock_msg.h
syshead.h
main
int main(void)
Definition: test_packet_id.c:276
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:128
test_get_num_output_sequenced_available
static void test_get_num_output_sequenced_available(void **state)
Definition: test_packet_id.c:159
test_packet_id_write_setup
static int test_packet_id_write_setup(void **state)
Definition: test_packet_id.c:51
test_packet_id_write_data
Definition: test_packet_id.c:41
now
time_t now
Definition: otime.c:34
test_packet_id_write_data::pis
struct packet_id_send pis
Definition: test_packet_id.c:47
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