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