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