]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_optimal_pmtu.c
Fix __warn_unused_result__, add more of it and fix the resulting warnings.
[meshlink] / test / blackbox / run_blackbox_tests / test_optimal_pmtu.c
1 /*
2     test_optimal_pmtu.c -- Execution of specific meshlink black box test cases
3     Copyright (C) 2019  Guus Sliepen <guus@meshlink.io>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifdef NDEBUG
21 #undef NDEBUG
22 #endif
23
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <setjmp.h>
27 #include <cmocka.h>
28 #include <assert.h>
29 #include <pthread.h>
30 #include "../common/containers.h"
31 #include "../common/test_step.h"
32 #include "../common/common_handlers.h"
33 #include "../common/network_namespace_framework.h"
34 #include "../../utils.h"
35 #include "../test_case_optimal_pmtu_01/test_case_optimal_pmtu.h"
36 #include "test_optimal_pmtu.h"
37
38 static void test_case_optimal_pmtu_01(void **state);
39 static bool test_steps_optimal_pmtu_01(void);
40 static void test_case_optimal_pmtu_02(void **state);
41 static bool test_steps_optimal_pmtu_02(void);
42 static void test_case_optimal_pmtu_03(void **state);
43 static bool test_steps_optimal_pmtu_03(void);
44 static void test_case_optimal_pmtu_04(void **state);
45 static bool test_steps_optimal_pmtu_04(void);
46 static void test_case_optimal_pmtu_05(void **state);
47 static bool test_steps_optimal_pmtu_05(void);
48 static void test_case_optimal_pmtu_06(void **state);
49 static bool test_steps_optimal_pmtu_06(void);
50 static void test_case_optimal_pmtu_07(void **state);
51 static bool test_steps_optimal_pmtu_07(void);
52
53 extern void *node_sim_relay_01(void *arg);
54 extern void *node_sim_peer_01(void *arg);
55 extern void *node_sim_nut_01(void *arg);
56 extern pmtu_attr_t node_pmtu[2];
57
58 typedef bool (*test_step_func_t)(void);
59 static int setup_test(void **state);
60 bool test_pmtu_relay_running = true;
61 bool test_pmtu_peer_running = true;
62 bool test_pmtu_nut_running = true;
63 bool ping_channel_enable_07 = false;
64
65 struct sync_flag test_pmtu_nut_closed = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
66 static netns_state_t *test_pmtu_state;
67
68 static int setup_test(void **state) {
69         (void)state;
70
71         netns_create_topology(test_pmtu_state);
72         fprintf(stderr, "\nCreated topology\n");
73
74         test_pmtu_relay_running = true;
75         test_pmtu_peer_running = true;
76         test_pmtu_nut_running = true;
77         ping_channel_enable_07 = false;
78         memset(node_pmtu, 0, sizeof(node_pmtu));
79         set_sync_flag(&test_pmtu_nut_closed, false);
80         assert(meshlink_destroy("nut"));
81         assert(meshlink_destroy("peer"));
82         assert(meshlink_destroy("relay"));
83
84         return EXIT_SUCCESS;
85 }
86
87 static int teardown_test(void **state) {
88         (void)state;
89
90         assert(meshlink_destroy("nut"));
91         assert(meshlink_destroy("peer"));
92         assert(meshlink_destroy("relay"));
93         netns_destroy_topology(test_pmtu_state);
94
95         return EXIT_SUCCESS;
96 }
97
98 static void execute_test(test_step_func_t step_func, void **state) {
99         (void)state;
100
101
102         fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m\n");
103         bool test_result = step_func();
104
105         if(!test_result) {
106                 fail();
107         }
108 }
109
110 static void *gen_inv(void *arg) {
111         mesh_invite_arg_t *mesh_invite_arg = (mesh_invite_arg_t *)arg;
112         meshlink_handle_t *mesh;
113         mesh = meshlink_open(mesh_invite_arg->mesh_arg->node_name, mesh_invite_arg->mesh_arg->confbase, mesh_invite_arg->mesh_arg->app_name, mesh_invite_arg->mesh_arg->dev_class);
114         assert(mesh);
115
116         char *invitation = meshlink_invite(mesh, NULL, mesh_invite_arg->invitee_name);
117         assert(invitation);
118         mesh_invite_arg->invite_str = invitation;
119         meshlink_close(mesh);
120
121         return NULL;
122 }
123
124 /* Test Steps for optimal PMTU discovery Test Case # 1 -
125     Validating NUT MTU parameters without blocking ICMP under designed
126     network topology */
127 static void test_case_optimal_pmtu_01(void **state) {
128         execute_test(test_steps_optimal_pmtu_01, state);
129         return;
130 }
131
132 /* Test Steps for optimal PMTU discovery Test Case # 1 - Success case
133
134     Test Steps:
135     1. Create NAT setup and run each node instances in discrete namespace.
136     2. Open a channel from NUT to peer and hence triggering Peer to peer connection
137     3. Send the analyzed MTU parameters mesh event information to test driver
138     Expected Result:
139       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
140       the expected range
141 */
142 static bool test_steps_optimal_pmtu_01(void) {
143         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
144         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
145         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
146
147
148         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
149         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
150         run_node_in_namespace_thread(&netns_relay_nut_invite);
151         sleep(1);
152         assert(relay_nut_invite_arg.invite_str);
153         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
154
155         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
156         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
157         run_node_in_namespace_thread(&netns_relay_peer_invite);
158         sleep(1);
159         assert(relay_peer_invite_arg.invite_str);
160         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
161
162         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
163         run_node_in_namespace_thread(&netns_relay_handle);
164
165         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
166         run_node_in_namespace_thread(&netns_peer_handle);
167
168         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
169         run_node_in_namespace_thread(&netns_nut_handle);
170
171         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
172         test_pmtu_relay_running = false;
173         test_pmtu_peer_running = false;
174
175         sleep(1);
176         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
177         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
178         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
179         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
180
181         return true;
182 }
183
184 /* Test Steps for optimal PMTU discovery Test Case # 2 -
185     Validating NUT MTU parameters blocking ICMP under designed
186     network topology */
187 static void test_case_optimal_pmtu_02(void **state) {
188         execute_test(test_steps_optimal_pmtu_02, state);
189         return;
190 }
191
192 /* Test Steps for optimal PMTU discovery Test Case # 2 -
193     Test Steps:
194     1. Create NAT setup and run each node instances in discrete namespace,
195     2. Block ICMP protocol at NUT's NAT
196     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
197     4. Send the analyzed MTU parameters mesh event information to test driver
198     Expected Result:
199       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
200       the expected range
201 */
202 static bool test_steps_optimal_pmtu_02(void) {
203         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
204         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
205         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
206
207         assert(system("ip netns exec peer_nat iptables -A FORWARD -p icmp -j DROP") == 0);
208         assert(system("ip netns exec nut_nat iptables -A FORWARD -p icmp -j DROP") == 0);
209
210         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
211         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
212         run_node_in_namespace_thread(&netns_relay_nut_invite);
213         sleep(1);
214         assert(relay_nut_invite_arg.invite_str);
215         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
216
217         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
218         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
219         run_node_in_namespace_thread(&netns_relay_peer_invite);
220         sleep(1);
221         assert(relay_peer_invite_arg.invite_str);
222         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
223
224         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
225         run_node_in_namespace_thread(&netns_relay_handle);
226
227         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
228         run_node_in_namespace_thread(&netns_peer_handle);
229
230         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
231         run_node_in_namespace_thread(&netns_nut_handle);
232
233         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
234         test_pmtu_relay_running = false;
235         test_pmtu_peer_running = false;
236
237         sleep(1);
238         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
239         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
240         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
241         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
242
243         return true;
244 }
245
246 /* Test Steps for optimal PMTU discovery Test Case # 3 -
247     Validating NUT MTU parameters with MTU size of NAT = 1250 under designed
248     network topology */
249 static void test_case_optimal_pmtu_03(void **state) {
250         execute_test(test_steps_optimal_pmtu_03, state);
251         return;
252 }
253
254 /* Test Steps for optimal PMTU discovery Test Case # 3 -
255     Test Steps:
256     1. Create NAT setup and run each node instances in discrete namespace,
257     2. Change the MTU size of NUT's NAT to 1250
258     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
259     4. Send the analyzed MTU parameters mesh event information to test driver
260     Expected Result:
261       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
262       the expected range
263 */
264 static bool test_steps_optimal_pmtu_03(void) {
265         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
266         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
267         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
268
269         assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1250") == 0);
270
271         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
272         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
273         run_node_in_namespace_thread(&netns_relay_nut_invite);
274         sleep(1);
275         assert(relay_nut_invite_arg.invite_str);
276         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
277
278         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
279         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
280         run_node_in_namespace_thread(&netns_relay_peer_invite);
281         sleep(1);
282         assert(relay_peer_invite_arg.invite_str);
283         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
284
285         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
286         run_node_in_namespace_thread(&netns_relay_handle);
287
288         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
289         run_node_in_namespace_thread(&netns_peer_handle);
290
291         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
292         run_node_in_namespace_thread(&netns_nut_handle);
293
294         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
295         test_pmtu_relay_running = false;
296         test_pmtu_peer_running = false;
297
298         sleep(1);
299         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1200, 1250);
300         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1200, 1250);
301
302         return true;
303 }
304
305 /* Test Steps for optimal PMTU discovery Test Case # 4 -
306     Validating NUT MTU parameters with MTU size of NAT = 1000 under designed
307     network topology */
308 static void test_case_optimal_pmtu_04(void **state) {
309         execute_test(test_steps_optimal_pmtu_04, state);
310         return;
311 }
312
313 /* Test Steps for optimal PMTU discovery Test Case # 4 -
314     Test Steps:
315     1. Create NAT setup and run each node instances in discrete namespace,
316     2. Change the MTU size of NUT's NAT to 1000
317     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
318     4. Send the analyzed MTU parameters mesh event information to test driver
319     Expected Result:
320       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
321       the expected range
322 */
323 static bool test_steps_optimal_pmtu_04(void) {
324         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
325         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
326         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
327
328         assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1000") == 0);
329
330         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
331         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
332         run_node_in_namespace_thread(&netns_relay_nut_invite);
333         sleep(1);
334         assert(relay_nut_invite_arg.invite_str);
335         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
336
337         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
338         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
339         run_node_in_namespace_thread(&netns_relay_peer_invite);
340         sleep(1);
341         assert(relay_peer_invite_arg.invite_str);
342         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
343
344         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
345         run_node_in_namespace_thread(&netns_relay_handle);
346
347         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
348         run_node_in_namespace_thread(&netns_peer_handle);
349
350         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
351         run_node_in_namespace_thread(&netns_nut_handle);
352
353         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
354         test_pmtu_relay_running = false;
355         test_pmtu_peer_running = false;
356
357         sleep(1);
358         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 925, 1000);
359         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 925, 1000);
360
361         return true;
362 }
363
364 /* Test Steps for optimal PMTU discovery Test Case # 5 -
365     Validating NUT MTU parameters with MTU size of NAT = 800 under designed
366     network topology */
367 static void test_case_optimal_pmtu_05(void **state) {
368         execute_test(test_steps_optimal_pmtu_05, state);
369         return;
370 }
371
372 /* Test Steps for optimal PMTU discovery Test Case # 5 -
373     Test Steps:
374     1. Create NAT setup and run each node instances in discrete namespace,
375     2. Change the MTU size of NUT's NAT to 800
376     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
377     4. Send the analyzed MTU parameters mesh event information to test driver
378     Expected Result:
379       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
380       the expected range
381 */
382 static bool test_steps_optimal_pmtu_05(void) {
383         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
384         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
385         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
386
387         assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 750") == 0);
388
389         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
390         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
391         run_node_in_namespace_thread(&netns_relay_nut_invite);
392         sleep(1);
393         assert(relay_nut_invite_arg.invite_str);
394         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
395
396         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
397         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
398         run_node_in_namespace_thread(&netns_relay_peer_invite);
399         sleep(1);
400         assert(relay_peer_invite_arg.invite_str);
401         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
402
403         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
404         run_node_in_namespace_thread(&netns_relay_handle);
405
406         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
407         run_node_in_namespace_thread(&netns_peer_handle);
408
409         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
410         run_node_in_namespace_thread(&netns_nut_handle);
411
412         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
413         test_pmtu_relay_running = false;
414         test_pmtu_peer_running = false;
415
416         sleep(1);
417         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 700, 750);
418         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 700, 750);
419
420         return true;
421 }
422
423 /* Test Steps for optimal PMTU discovery Test Case # 6 -
424     Flushing the tracked connections via NUT NAT for every 60 seconds */
425 static void test_case_optimal_pmtu_06(void **state) {
426         execute_test(test_steps_optimal_pmtu_06, state);
427         return;
428 }
429
430 static bool run_conntrack;
431 static pthread_t pmtu_test_case_conntrack_thread;
432 static void *conntrack_flush(void *arg) {
433         (void)arg;
434
435         // flushes mappings for every 60 seconds
436
437         while(run_conntrack) {
438                 sleep(100);
439                 assert(system("ip netns exec nut_nat conntrack -F") == 0);
440                 assert(system("ip netns exec peer_nat conntrack -F") == 0);
441         }
442
443         pthread_exit(NULL);
444 }
445
446 /* Test Steps for optimal PMTU discovery Test Case # 6 -
447     Test Steps:
448     1. Create NAT setup and Launch conntrack thread which flushes the tracked connections for every 90 seconds
449     2. Run each node instances in discrete namespace,
450     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
451     4. Send the analyzed MTU parameters mesh event information to test driver
452     Expected Result:
453       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
454       the expected range
455 */
456 static bool test_steps_optimal_pmtu_06(void) {
457         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
458         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
459         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
460
461         run_conntrack = true;
462         assert(!pthread_create(&pmtu_test_case_conntrack_thread, NULL, conntrack_flush, NULL));
463
464         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
465         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
466         run_node_in_namespace_thread(&netns_relay_nut_invite);
467         sleep(1);
468         assert(relay_nut_invite_arg.invite_str);
469         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
470
471         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
472         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
473         run_node_in_namespace_thread(&netns_relay_peer_invite);
474         sleep(1);
475         assert(relay_peer_invite_arg.invite_str);
476         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
477
478         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
479         run_node_in_namespace_thread(&netns_relay_handle);
480
481         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
482         run_node_in_namespace_thread(&netns_peer_handle);
483
484         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
485         run_node_in_namespace_thread(&netns_nut_handle);
486
487         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
488         test_pmtu_relay_running = false;
489         test_pmtu_peer_running = false;
490         run_conntrack = false;
491         pthread_join(pmtu_test_case_conntrack_thread, NULL);
492
493         sleep(1);
494
495         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1440, 1500);
496         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1440, 1500);
497         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_ping.probes, 38, 42);
498         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_ping.probes, 38, 42);
499
500         return true;
501 }
502
503 /* Test Steps for optimal PMTU discovery Test Case # 7 -
504     NUT sending data to peer node via channel for every 30 seconds
505     */
506 static void test_case_optimal_pmtu_07(void **state) {
507         execute_test(test_steps_optimal_pmtu_07, state);
508         return;
509 }
510
511 /* Test Steps for optimal PMTU discovery Test Case # 7 -
512     Test Steps:
513     1. Create NAT setup and run each node instances in discrete namespace.
514     2. Open a channel from NUT to peer and hence triggering Peer to peer connection
515     3. Send data periodically via channel from NUT to peer node.
516     4. Send the analyzed MTU parameters mesh event information to test driver
517     Expected Result:
518       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
519       the expected range
520 */
521 static bool test_steps_optimal_pmtu_07(void) {
522         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
523         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
524         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
525
526         ping_channel_enable_07 = true;
527
528         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
529         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
530         run_node_in_namespace_thread(&netns_relay_nut_invite);
531         sleep(1);
532         assert(relay_nut_invite_arg.invite_str);
533         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
534
535         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
536         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
537         run_node_in_namespace_thread(&netns_relay_peer_invite);
538         sleep(1);
539         assert(relay_peer_invite_arg.invite_str);
540         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
541
542         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
543         run_node_in_namespace_thread(&netns_relay_handle);
544
545         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
546         run_node_in_namespace_thread(&netns_peer_handle);
547
548         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
549         run_node_in_namespace_thread(&netns_nut_handle);
550
551         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
552         test_pmtu_relay_running = false;
553         test_pmtu_peer_running = false;
554
555         sleep(1);
556         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
557         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
558         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
559         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
560
561         return true;
562 }
563
564 // Optimal PMTU test case driver
565
566 int test_optimal_pmtu(void) {
567         interface_t nut_ifs[] = { { .if_peer = "nut_nat", .fetch_ip_netns_name = "nut_nat" } };
568         namespace_t nut = {
569                 .name = "nut",
570                 .type = HOST,
571                 .interfaces = nut_ifs,
572                 .interfaces_no = 1,
573         };
574
575         interface_t peer_ifs[] = { { .if_peer = "peer_nat", .fetch_ip_netns_name = "peer_nat" } };
576         namespace_t peer = {
577                 .name = "peer",
578                 .type = HOST,
579                 .interfaces = peer_ifs,
580                 .interfaces_no = 1,
581         };
582
583         interface_t relay_ifs[] = { { .if_peer = "wan_bridge" } };
584         namespace_t relay = {
585                 .name = "relay",
586                 .type = HOST,
587                 .interfaces = relay_ifs,
588                 .interfaces_no = 1,
589         };
590
591         netns_fullcone_handle_t nut_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "nut" };
592         netns_fullcone_handle_t *nut_nat_args[] = { &nut_nat_fullcone, NULL };
593         interface_t nut_nat_ifs[] = { { .if_peer = "nut", .fetch_ip_netns_name = "nut_nat" }, { .if_peer = "wan_bridge" } };
594         namespace_t nut_nat = {
595                 .name = "nut_nat",
596                 .type = FULL_CONE,
597                 .nat_arg = nut_nat_args,
598                 .static_config_net_addr = "192.168.1.0/24",
599                 .interfaces = nut_nat_ifs,
600                 .interfaces_no = 2,
601         };
602
603         netns_fullcone_handle_t peer_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "peer" };
604         netns_fullcone_handle_t *peer_nat_args[] = { &peer_nat_fullcone, NULL };
605         interface_t peer_nat_ifs[] = { { .if_peer = "peer", .fetch_ip_netns_name = "peer_nat" }, { .if_peer = "wan_bridge" } };
606         namespace_t peer_nat = {
607                 .name = "peer_nat",
608                 .type = FULL_CONE,
609                 .nat_arg = peer_nat_args,
610                 .static_config_net_addr = "192.168.1.0/24",
611                 .interfaces = peer_nat_ifs,
612                 .interfaces_no = 2,
613         };
614
615         interface_t wan_ifs[] = { { .if_peer = "peer_nat" }, { .if_peer = "nut_nat" }, { .if_peer = "relay" } };
616         namespace_t wan_bridge = {
617                 .name = "wan_bridge",
618                 .type = BRIDGE,
619                 .interfaces = wan_ifs,
620                 .interfaces_no = 3,
621         };
622
623         namespace_t test_optimal_pmtu_1_nodes[] = { nut_nat, peer_nat, wan_bridge, nut, peer, relay };
624
625         netns_state_t test_pmtu_nodes = {
626                 .test_case_name =  "test_case_optimal_pmtu",
627                 .namespaces =  test_optimal_pmtu_1_nodes,
628                 .num_namespaces = 6,
629         };
630         test_pmtu_state = &test_pmtu_nodes;
631
632         const struct CMUnitTest blackbox_group0_tests[] = {
633                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_01, setup_test, teardown_test,
634                                 (void *)&test_pmtu_state),
635                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_02, setup_test, teardown_test,
636                                 (void *)&test_pmtu_state),
637                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_03, setup_test, teardown_test,
638                                 (void *)&test_pmtu_state),
639                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_04, setup_test, teardown_test,
640                                 (void *)&test_pmtu_state),
641                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_05, setup_test, teardown_test,
642                                 (void *)&test_pmtu_state),
643                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_06, setup_test, teardown_test,
644                                 (void *)&test_pmtu_state),
645                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_07, setup_test, teardown_test,
646                                 (void *)&test_pmtu_state),
647         };
648         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
649
650         return cmocka_run_group_tests(blackbox_group0_tests, NULL, NULL);
651 }