]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_optimal_pmtu.c
Add test cases for the PMTU discovery mechanism.
[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 "execute_tests.h"
25 #include "test_cases.h"
26 #include "pthread.h"
27 #include "../common/containers.h"
28 #include "../common/test_step.h"
29 #include "../common/common_handlers.h"
30 #include "../common/mesh_event_handler.h"
31 #include "test_optimal_pmtu.h"
32
33 #define RELAY_ID "0"
34 #define PEER_ID  "1"
35 #define NUT_ID   "2"
36 #define PEER_NAT "peer_nat"
37 #define NUT_NAT "nut_nat"
38
39 #pragma pack(1)
40
41 static void test_case_optimal_pmtu_01(void **state);
42 static bool test_steps_optimal_pmtu_01(void);
43 static void test_case_optimal_pmtu_02(void **state);
44 static bool test_steps_optimal_pmtu_02(void);
45 static void test_case_optimal_pmtu_03(void **state);
46 static bool test_steps_optimal_pmtu_03(void);
47 static void test_case_optimal_pmtu_04(void **state);
48 static bool test_steps_optimal_pmtu_04(void);
49 static void test_case_optimal_pmtu_05(void **state);
50 static bool test_steps_optimal_pmtu_05(void);
51 static void test_case_optimal_pmtu_06(void **state);
52 static bool test_steps_optimal_pmtu_06(void);
53 static void test_case_optimal_pmtu_07(void **state);
54 static bool test_steps_optimal_pmtu_07(void);
55 static void tcpdump_in_container(const char *cmd, const char *container_name);
56
57 static char *test_optimal_pmtu_1_nodes[] = { "relay", "peer", "nut" };
58 static black_box_state_t test_pmtu_state_01 = {
59         .test_case_name =  "test_case_optimal_pmtu_01",
60         .node_names =  test_optimal_pmtu_1_nodes,
61         .num_nodes =  3,
62 };
63
64 static black_box_state_t test_pmtu_state_02 = {
65         .test_case_name =  "test_case_optimal_pmtu_02",
66         .node_names =  test_optimal_pmtu_1_nodes,
67         .num_nodes =  3,
68 };
69
70 static black_box_state_t test_pmtu_state_03 = {
71         .test_case_name =  "test_case_optimal_pmtu_03",
72         .node_names =  test_optimal_pmtu_1_nodes,
73         .num_nodes =  3,
74 };
75
76 static black_box_state_t test_pmtu_state_04 = {
77         .test_case_name =  "test_case_optimal_pmtu_04",
78         .node_names =  test_optimal_pmtu_1_nodes,
79         .num_nodes =  3,
80 };
81
82 static black_box_state_t test_pmtu_state_05 = {
83         .test_case_name =  "test_case_optimal_pmtu_05",
84         .node_names =  test_optimal_pmtu_1_nodes,
85         .num_nodes =  3,
86 };
87
88 static black_box_state_t test_pmtu_state_06 = {
89         .test_case_name =  "test_case_optimal_pmtu_06",
90         .node_names =  test_optimal_pmtu_1_nodes,
91         .num_nodes =  3,
92 };
93
94 static black_box_state_t test_pmtu_state_07 = {
95         .test_case_name =  "test_case_optimal_pmtu_07",
96         .node_names =  test_optimal_pmtu_1_nodes,
97         .num_nodes =  3,
98 };
99
100 static pmtu_attr_t node_pmtu_peer;
101 static pmtu_attr_t node_pmtu_relay;
102 static char *import = NULL;
103
104
105 static void tcpdump_in_container(const char *cmd, const char *container_name) {
106         execute_in_container(cmd, container_name, true);
107 }
108
109 static int setup_pmtu_test_case(void **state) {
110         char *ret_str;
111         char container_name[200];
112
113         PRINT_TEST_CASE_MSG("\n\n======================================================================\n\n\n");
114
115         fprintf(stderr, "Setting up Containers\n");
116         state_ptr = (black_box_state_t *)(*state);
117
118         // Setup containers for test cases
119         setup_containers(state);
120
121         // Switch bridges of test containers from lxcbr0 to it's respective NAT bridges
122         assert(snprintf(container_name, sizeof(container_name), "%s_%s", state_ptr->test_case_name, "nut") >= 0);
123         container_switch_bridge(container_name, lxc_path, lxc_bridge, "nut_nat_bridge");
124         assert(snprintf(container_name, sizeof(container_name), "%s_%s", state_ptr->test_case_name, "peer") >= 0);
125         container_switch_bridge(container_name, lxc_path, lxc_bridge, "peer_nat_bridge");
126
127         // Flush iptable filter rules if there are any
128         flush_nat_rules(NUT_NAT, "-t filter");
129         flush_nat_rules(PEER_NAT, "-t filter");
130
131         // Reset the MTU size of NAT's public interface to 1500 bytes
132         assert(change_container_mtu(NUT_NAT, PUB_INTERFACE, 1500) == NULL);
133         assert(change_container_mtu(PEER_NAT, PUB_INTERFACE, 1500) == NULL);
134
135         // Flush all the pushed data in the meshlink event handler receive queue
136         mesh_events_flush();
137
138         return EXIT_SUCCESS;
139 }
140
141 static int teardown_pmtu_test_case(void **state) {
142
143         // Reset the MTU size of NAT's public interface to 1500 bytes
144         change_container_mtu(NUT_NAT, PUB_INTERFACE, 1500);
145         change_container_mtu(PEER_NAT, PUB_INTERFACE, 1500);
146
147         // Flush iptable filter rules if there are any
148         flush_nat_rules(NUT_NAT, "-t filter");
149         flush_nat_rules(PEER_NAT, "-t filter");
150
151         black_box_state_t *test_state = (black_box_state_t *)(*state);
152         int i;
153
154         // Send SIG_TERM to all the running nodes
155         for(i = 0; i < test_state->num_nodes; i++) {
156                 /* Shut down node */
157                 node_step_in_container(test_state->node_names[i], "SIGTERM");
158         }
159
160         return teardown_test(state);
161 }
162
163 // Print the calculated values of MTU parameters obtained from the node
164 static void print_mtu_calc(pmtu_attr_t node_pmtu) {
165         fprintf(stderr, "MTU size : %d\n", node_pmtu.mtu_size);
166         fprintf(stderr, "Probes took for calculating PMTU discovery : %d\n", node_pmtu.mtu_discovery.probes);
167         fprintf(stderr, "Probes total length took for calculating PMTU discovery : %d\n", node_pmtu.mtu_discovery.probes_total_len);
168         fprintf(stderr, "Time took for calculating PMTU discovery : %lu\n", node_pmtu.mtu_discovery.time);
169         fprintf(stderr, "Total MTU ping probes : %d\n", node_pmtu.mtu_ping.probes);
170         fprintf(stderr, "Total MTU ping probes length : %d\n", node_pmtu.mtu_ping.probes_total_len);
171         float avg = 0;
172
173         if(node_pmtu.mtu_ping.probes) {
174                 avg = (float)node_pmtu.mtu_ping.time / (float)node_pmtu.mtu_ping.probes;
175         }
176
177         fprintf(stderr, "Average MTU ping probes ping time : %f\n", avg);
178         fprintf(stderr, "Total probes received %d\n", node_pmtu.mtu_recv_probes.probes);
179         fprintf(stderr, "Total probes sent %d\n", node_pmtu.mtu_sent_probes.probes);
180 }
181
182 static int black_box_pmtu_group_setup(void **state) {
183         const char *nodes[] = { "relay", "peer", "nut" };
184         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
185
186         /*
187                                 ------------
188             ____________________|  lxcbr0  |_____________________
189            |eth0                ------------                    |eth0
190          -------------               |                  --------------
191         // NUT NAT  //               |                 //  Peer NAT //
192          ------------           -------------           --------------
193                |eth1            |           |                   |eth1
194                |                |   relay   |                   |
195         -------------------     |           |        --------------------
196         |  nut_nat_bridge |     -------------        |  peer_nat_bridge |
197         -------------------                          --------------------
198                |                                                |
199         ---------------                                ------------------
200         |             |                                |                |
201         |     NUT     |                                |      peer      |
202         |             |                                |                |
203         ---------------                                ------------------
204         */
205
206         PRINT_TEST_CASE_MSG("Creating Containers\n");
207
208         // Create Node-Under-Test(NUT) and Peer node's containers
209
210         destroy_containers();
211         create_containers(nodes, num_nodes);
212
213         // Create NAT containers for NUT and peer nodes
214
215         nat_create(NUT_NAT, lxc_path, FULLCONE_NAT);
216         nat_create(PEER_NAT, lxc_path, FULLCONE_NAT);
217
218         tcpdump_in_container("tcpdump udp -i any > tcpdump.log", NUT_NAT);
219
220         /*char cmd[200];
221         assert(snprintf(cmd, sizeof(cmd),
222                         "%s/" LXC_UTIL_REL_PATH "/log_drops.sh %s",
223                         meshlink_root_path, NUT_NAT) >= 0);
224         assert(system(cmd) == 0);*/
225
226         // Switch the Node-under-test node and peer node containers to the respective bridge
227         // i.e making the node to sit behind the NAT's private network interface
228
229         container_switch_bridge("run_nut", lxc_path, lxc_bridge, "nut_nat_bridge");
230         container_switch_bridge("run_peer", lxc_path, lxc_bridge, "peer_nat_bridge");
231
232         // Open mesh event handling UDP socket
233         import = mesh_event_sock_create(eth_if_name);
234         assert(import);
235
236         return 0;
237 }
238
239 static int black_box_pmtu_group_teardown(void **state) {
240         PRINT_TEST_CASE_MSG("Destroying Containers\n");
241         destroy_containers();
242         nat_destroy(NUT_NAT);
243         nat_destroy(PEER_NAT);
244
245         mesh_event_destroy();
246
247         return 0;
248 }
249
250 static bool mtu_calc_peer = false;
251 static bool mtu_calc_relay = false;
252
253 // Common event handler callback for all the test cases
254 static bool event_mtu_handle_cb(mesh_event_payload_t payload) {
255         char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
256         fprintf(stderr, " %s : ", event_node_name[payload.client_id]);
257         char *name;
258         uint32_t payload_length = payload.payload_length;
259         uint32_t node_pmtu_calc_size = sizeof(pmtu_attr_t);
260
261         switch(payload.mesh_event) {
262         case META_CONN_CLOSED   :
263                 name = (char *)payload.payload;
264                 fprintf(stderr, "NUT closed connection with %s\n", name);
265                 break;
266
267         case META_CONN_SUCCESSFUL   :
268                 name = (char *)payload.payload;
269                 fprintf(stderr, "NUT made connection with %s\n", name);
270                 break;
271
272         case NODE_JOINED  :
273                 name = (char *)payload.payload;
274                 fprintf(stderr, "Node %s joined with NUT\n", name);
275                 break;
276
277         case NODE_LEFT  :
278                 name = (char *)payload.payload;
279                 fprintf(stderr, "Node %s the left mesh\n", name);
280                 break;
281
282         case ERR_NETWORK            :
283                 name = (char *)payload.payload;
284                 fprintf(stderr, "NUT closed channel with %s\n", name);
285                 break;
286
287         case NODE_STARTED           :
288                 fprintf(stderr, "%s node started\n", event_node_name[payload.client_id]);
289                 break;
290
291         case CHANNEL_OPENED         :
292                 fprintf(stderr, "Channel opened\n");
293                 break;
294
295         case OPTIMAL_PMTU_PEER      :
296                 assert(payload.payload);
297                 fprintf(stderr, "Obtained peer MTU values from NUT\n");
298                 memcpy(&node_pmtu_peer, payload.payload, payload_length);
299                 fprintf(stderr, "NUT and peer PMTU handling in 120 seconds with ICMP unblocked\n");
300                 print_mtu_calc(node_pmtu_peer);
301                 mtu_calc_peer = true;
302
303                 if(mtu_calc_peer && mtu_calc_relay) {
304                         return true;
305                 }
306
307                 break;
308
309         case OPTIMAL_PMTU_RELAY      :
310                 assert(payload.payload);
311                 //assert(payload_length != node_pmtu_calc_size);
312                 fprintf(stderr, "Obtained relay MTU values from NUT\n");
313                 memcpy(&node_pmtu_relay, payload.payload, payload_length);
314                 fprintf(stderr, "NUT and peer PMTU handling in 120 seconds with ICMP unblocked\n");
315                 print_mtu_calc(node_pmtu_relay);
316                 mtu_calc_relay = true;
317
318                 if(mtu_calc_peer && mtu_calc_relay) {
319                         return true;
320                 }
321
322                 break;
323
324         default :
325                 fprintf(stderr, "UNDEFINED EVENT RECEIVED (%d)\n", payload.mesh_event);
326         }
327
328         return false;
329 }
330
331 /* Test Steps for optimal PMTU discovery Test Case # 1 -
332     Validating NUT MTU parameters without blocking ICMP under designed
333     network topology */
334 static void test_case_optimal_pmtu_01(void **state) {
335         execute_test(test_steps_optimal_pmtu_01, state);
336 }
337
338 /* Test Steps for optimal PMTU discovery Test Case # 1 - Success case
339
340     Test Steps:
341     1. Create NAT setup and run each node instances in discrete containers.
342     2. Open a channel from NUT to peer and hence triggering Peer to peer connection
343     3. Send the analyzed MTU parameters mesh event information to test driver
344     Expected Result:
345       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
346       the expected range
347 */
348 static bool test_steps_optimal_pmtu_01(void) {
349         char *invite_peer, *invite_nut;
350
351         mtu_calc_peer = false;
352         mtu_calc_relay = false;
353         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
354         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
355
356         // Invite peer and nut nodes by relay node
357         invite_peer = invite_in_container("relay", "peer");
358         assert(invite_peer);
359         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
360         assert(invite_nut);
361
362         // Launch NUT, relay and peer nodes in discrete containers
363         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
364         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
365         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
366
367         // Wait for test case events
368         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
369         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
370
371         // Verify the obtained values
372         assert_in_range(node_pmtu_peer.mtu_size, 1450, 1501);
373         assert_in_range(node_pmtu_peer.mtu_discovery.probes, 38, 42);
374         assert_in_range(node_pmtu_relay.mtu_size, 1450, 1501);
375         assert_in_range(node_pmtu_relay.mtu_discovery.probes, 38, 42);
376
377         return true;
378 }
379
380 /* Test Steps for optimal PMTU discovery Test Case # 2 -
381     Validating NUT MTU parameters blocking ICMP under designed
382     network topology */
383 static void test_case_optimal_pmtu_02(void **state) {
384         execute_test(test_steps_optimal_pmtu_02, state);
385 }
386
387 /* Test Steps for optimal PMTU discovery Test Case # 2 -
388
389     Test Steps:
390     1. Create NAT setup and run each node instances in discrete containers,
391     2. Block ICMP protocol at NUT's NAT
392     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
393     4. Send the analyzed MTU parameters mesh event information to test driver
394     Expected Result:
395       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
396       the expected range
397 */
398 static bool test_steps_optimal_pmtu_02(void) {
399         char *invite_peer, *invite_nut;
400
401         mtu_calc_peer = false;
402         mtu_calc_relay = false;
403         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
404         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
405
406         block_icmp(NUT_NAT);
407
408         invite_peer = invite_in_container("relay", "peer");
409         assert(invite_peer);
410         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
411         assert(invite_nut);
412         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
413         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
414         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
415
416         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
417         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
418
419         assert_in_range(node_pmtu_peer.mtu_size, 1450, 1501);
420         assert_in_range(node_pmtu_peer.mtu_discovery.probes, 38, 42);
421         assert_in_range(node_pmtu_relay.mtu_size, 1450, 1501);
422         assert_in_range(node_pmtu_relay.mtu_discovery.probes, 38, 42);
423         return true;
424 }
425
426 /* Test Steps for optimal PMTU discovery Test Case # 3 -
427     Validating NUT MTU parameters with MTU size of NAT = 1250 under designed
428     network topology */
429 static void test_case_optimal_pmtu_03(void **state) {
430         execute_test(test_steps_optimal_pmtu_03, state);
431 }
432
433 /* Test Steps for optimal PMTU discovery Test Case # 3 -
434
435     Test Steps:
436     1. Create NAT setup and run each node instances in discrete containers,
437     2. Change the MTU size of NUT's NAT to 1250
438     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
439     4. Send the analyzed MTU parameters mesh event information to test driver
440     Expected Result:
441       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
442       the expected range
443 */
444 static bool test_steps_optimal_pmtu_03(void) {
445         char *invite_peer, *invite_nut;
446
447         mtu_calc_peer = false;
448         mtu_calc_relay = false;
449         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
450         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
451
452         change_container_mtu(NUT_NAT, "eth0", 1250);
453
454         invite_peer = invite_in_container("relay", "peer");
455         assert(invite_peer);
456         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
457         assert(invite_nut);
458         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
459         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
460         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
461
462         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
463         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
464
465         assert_in_range(node_pmtu_relay.mtu_size, 1200, 1250);
466         assert_in_range(node_pmtu_peer.mtu_size, 1200, 1250);
467         assert_in_range(node_pmtu_peer.mtu_discovery.probes, 38, 42);
468         assert_in_range(node_pmtu_relay.mtu_size, 1450, 1501);
469         assert_in_range(node_pmtu_relay.mtu_discovery.probes, 38, 42);
470         return true;
471 }
472 /* Test Steps for optimal PMTU discovery Test Case # 4 -
473     Validating NUT MTU parameters with MTU size of NAT = 1000 under designed
474     network topology */
475 static void test_case_optimal_pmtu_04(void **state) {
476         execute_test(test_steps_optimal_pmtu_04, state);
477 }
478
479 /* Test Steps for optimal PMTU discovery Test Case # 4 -
480
481     Test Steps:
482     1. Create NAT setup and run each node instances in discrete containers,
483     2. Change the MTU size of NUT's NAT to 1000
484     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
485     4. Send the analyzed MTU parameters mesh event information to test driver
486     Expected Result:
487       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
488       the expected range
489 */
490 static bool test_steps_optimal_pmtu_04(void) {
491         char *invite_peer, *invite_nut;
492
493         mtu_calc_peer = false;
494         mtu_calc_relay = false;
495         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
496         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
497
498         change_container_mtu(NUT_NAT, "eth0", 1000);
499
500         invite_peer = invite_in_container("relay", "peer");
501         assert(invite_peer);
502         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
503         assert(invite_nut);
504         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
505         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
506         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
507
508         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
509         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
510
511         assert_in_range(node_pmtu_relay.mtu_size, 925, 1000);
512         assert_in_range(node_pmtu_peer.mtu_size, 925, 1000);
513         assert_in_range(node_pmtu_peer.mtu_discovery.probes, 38, 42);
514         assert_in_range(node_pmtu_relay.mtu_size, 1450, 1501);
515         assert_in_range(node_pmtu_relay.mtu_discovery.probes, 38, 42);
516         return true;
517 }
518 /* Test Steps for optimal PMTU discovery Test Case # 5 -
519     Validating NUT MTU parameters with MTU size of NAT = 800 under designed
520     network topology */
521 static void test_case_optimal_pmtu_05(void **state) {
522         execute_test(test_steps_optimal_pmtu_05, state);
523 }
524
525 /* Test Steps for optimal PMTU discovery Test Case # 5 -
526
527     Test Steps:
528     1. Create NAT setup and run each node instances in discrete containers,
529     2. Change the MTU size of NUT's NAT to 800
530     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
531     4. Send the analyzed MTU parameters mesh event information to test driver
532     Expected Result:
533       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
534       the expected range
535 */
536 static bool test_steps_optimal_pmtu_05(void) {
537         char *invite_peer, *invite_nut;
538
539         mtu_calc_peer = false;
540         mtu_calc_relay = false;
541         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
542         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
543
544         change_container_mtu(NUT_NAT, "eth0", 800);
545
546         invite_peer = invite_in_container("relay", "peer");
547         assert(invite_peer);
548         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
549         assert(invite_nut);
550         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
551         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
552         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
553
554         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
555         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
556
557         assert_in_range(node_pmtu_relay.mtu_size, 750, 800);
558         assert_in_range(node_pmtu_peer.mtu_size, 750, 800);
559         //assert_in_range(node_pmtu_peer.mtu_discovery.probes, 38, 42);
560         //assert_in_range(node_pmtu_relay.mtu_size, 1450, 1501);
561         //assert_in_range(node_pmtu_relay.mtu_discovery.probes, 38, 42);
562         return true;
563 }
564
565 /* Test Steps for optimal PMTU discovery Test Case # 6 -
566     Flushing the tracked connections via NUT NAT for every 60 seconds */
567 static void test_case_optimal_pmtu_06(void **state) {
568         execute_test(test_steps_optimal_pmtu_06, state);
569 }
570
571 static pthread_t pmtu_test_case_conntrack_thread;
572 static void *conntrcak_flush(void *timeout) {
573         int thread_timeout = *((int *)timeout);
574         time_t thread_end_time = time(NULL) + thread_timeout;
575
576         while(thread_end_time > time(NULL)) {
577                 sleep(90);
578                 flush_conntrack(NUT_NAT);
579                 flush_conntrack(PEER_NAT);
580         }
581
582 }
583
584 static int teardown_conntrack_test_case(void **state) {
585
586         // Close the conntrack thread
587         pthread_cancel(pmtu_test_case_conntrack_thread);
588         // Close all the test cases
589         return teardown_pmtu_test_case(state);
590 }
591
592 /* Test Steps for optimal PMTU discovery Test Case # 6 -
593
594     Test Steps:
595     1. Create NAT setup and Launch conntrack thread which flushes the tracked connections for every 90 seconds
596     2. Run each node instances in discrete containers,
597     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
598     4. Send the analyzed MTU parameters mesh event information to test driver
599     Expected Result:
600       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
601       the expected range
602 */
603 static bool test_steps_optimal_pmtu_06(void) {
604         char *invite_peer, *invite_nut;
605         float ping_avg;
606
607         mtu_calc_peer = false;
608         mtu_calc_relay = false;
609         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
610         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
611
612         int thread_timeout = PING_TRACK_TIMEOUT + 30;
613         assert(!pthread_create(&pmtu_test_case_conntrack_thread, NULL, conntrcak_flush, &thread_timeout));
614         invite_peer = invite_in_container("relay", "peer");
615         assert(invite_peer);
616         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
617         assert(invite_nut);
618         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
619         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
620         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
621
622         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
623         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
624
625         assert_in_range(node_pmtu_relay.mtu_size, 1440, 1500);
626         assert_in_range(node_pmtu_peer.mtu_size, 1440, 1500);
627         assert_in_range(node_pmtu_peer.mtu_ping.probes, 38, 42);
628         assert_in_range(node_pmtu_relay.mtu_ping.probes, 38, 42);
629
630         ping_avg = 0;
631
632         if(node_pmtu_peer.mtu_ping.probes) {
633                 ping_avg = ping_avg = node_pmtu_peer.mtu_ping.time / node_pmtu_peer.mtu_ping.probes;
634         }
635
636         assert_in_range(ping_avg, 15.0, 20.0);
637
638         ping_avg = 0;
639
640         if(node_pmtu_relay.mtu_ping.probes) {
641                 ping_avg = ping_avg = node_pmtu_relay.mtu_ping.time / node_pmtu_relay.mtu_ping.probes;
642         }
643
644         assert_in_range(ping_avg, 15.0, 20.0);
645         return true;
646 }
647
648 /* Test Steps for optimal PMTU discovery Test Case # 7 -
649     NUT sending data to peer node via channel for every 30 seconds
650     */
651 static void test_case_optimal_pmtu_07(void **state) {
652         execute_test(test_steps_optimal_pmtu_07, state);
653 }
654
655 /* Test Steps for optimal PMTU discovery Test Case # 7 -
656
657     Test Steps:
658     1. Create NAT setup and run each node instances in discrete containers.
659     2. Open a channel from NUT to peer and hence triggering Peer to peer connection
660     3. Send data periodically via channel from NUT to peer node.
661     4. Send the analyzed MTU parameters mesh event information to test driver
662     Expected Result:
663       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
664       the expected range
665 */
666 static bool test_steps_optimal_pmtu_07(void) {
667         char *invite_peer, *invite_nut;
668
669         mtu_calc_peer = false;
670         mtu_calc_relay = false;
671         memset(&node_pmtu_peer, 0, sizeof(node_pmtu_peer));
672         memset(&node_pmtu_relay, 0, sizeof(node_pmtu_relay));
673         invite_peer = invite_in_container("relay", "peer");
674         assert(invite_peer);
675         invite_nut = invite_in_container("relay", NUT_NODE_NAME);
676         assert(invite_nut);
677         node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
678         node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
679         node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
680
681         bool ret = wait_for_event(event_mtu_handle_cb, PING_TRACK_TIMEOUT + 100);
682         assert_int_equal(ret && mtu_calc_peer && mtu_calc_relay, true);
683
684         assert_in_range(node_pmtu_peer.mtu_size, 1450, 1501);
685         assert_in_range(node_pmtu_peer.mtu_discovery.probes, 38, 42);
686         assert_in_range(node_pmtu_relay.mtu_size, 1450, 1501);
687         assert_in_range(node_pmtu_relay.mtu_discovery.probes, 38, 42);
688
689         return true;
690 }
691
692 // Optimal PMTU test case driver
693 int test_optimal_pmtu(void) {
694         const struct CMUnitTest blackbox_group0_tests[] = {
695                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_01, setup_pmtu_test_case, teardown_pmtu_test_case,
696                                 (void *)&test_pmtu_state_01),
697                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_02, setup_pmtu_test_case, teardown_pmtu_test_case,
698                                 (void *)&test_pmtu_state_02),
699                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_03, setup_pmtu_test_case, teardown_pmtu_test_case,
700                                 (void *)&test_pmtu_state_03),
701                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_04, setup_pmtu_test_case, teardown_pmtu_test_case,
702                                 (void *)&test_pmtu_state_04),
703                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_05, setup_pmtu_test_case, teardown_pmtu_test_case,
704                                 (void *)&test_pmtu_state_05),
705                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_06, setup_pmtu_test_case, teardown_pmtu_test_case,
706                                 (void *)&test_pmtu_state_06),
707                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_07, setup_pmtu_test_case, teardown_pmtu_test_case,
708                                 (void *)&test_pmtu_state_07),
709         };
710         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
711
712         return cmocka_run_group_tests(blackbox_group0_tests, black_box_pmtu_group_setup, NULL);
713 }