2 test_optimal_pmtu.c -- Execution of specific meshlink black box test cases
3 Copyright (C) 2019 Guus Sliepen <guus@meshlink.io>
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.
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.
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.
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"
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);
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];
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;
60 struct sync_flag test_pmtu_nut_closed = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
61 static netns_state_t *test_pmtu_state;
63 static int setup_test(void **state) {
64 netns_create_topology(test_pmtu_state);
65 fprintf(stderr, "\nCreated topology\n");
67 test_pmtu_relay_running = true;
68 test_pmtu_peer_running = true;
69 test_pmtu_nut_running = true;
70 ping_channel_enable_07 = false;
71 memset(node_pmtu, 2, sizeof(node_pmtu[0]));
72 set_sync_flag(&test_pmtu_nut_closed, false);
73 meshlink_destroy("nut");
74 meshlink_destroy("peer");
75 meshlink_destroy("relay");
80 static int teardown_test(void **state) {
81 meshlink_destroy("nut");
82 meshlink_destroy("peer");
83 meshlink_destroy("relay");
84 netns_destroy_topology(test_pmtu_state);
89 static void execute_test(test_step_func_t step_func, void **state) {
91 fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m\n");
92 bool test_result = step_func();
99 static void *gen_inv(void *arg) {
100 mesh_invite_arg_t *mesh_invite_arg = (mesh_invite_arg_t *)arg;
101 meshlink_handle_t *mesh;
102 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);
105 char *invitation = meshlink_invite(mesh, NULL, mesh_invite_arg->invitee_name);
107 mesh_invite_arg->invite_str = invitation;
108 meshlink_close(mesh);
111 /* Test Steps for optimal PMTU discovery Test Case # 1 -
112 Validating NUT MTU parameters without blocking ICMP under designed
114 static void test_case_optimal_pmtu_01(void **state) {
115 execute_test(test_steps_optimal_pmtu_01, state);
119 /* Test Steps for optimal PMTU discovery Test Case # 1 - Success case
122 1. Create NAT setup and run each node instances in discrete namespace.
123 2. Open a channel from NUT to peer and hence triggering Peer to peer connection
124 3. Send the analyzed MTU parameters mesh event information to test driver
126 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
129 static bool test_steps_optimal_pmtu_01(void) {
130 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
131 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
132 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
135 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
136 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
137 run_node_in_namespace_thread(&netns_relay_nut_invite);
139 assert(relay_nut_invite_arg.invite_str);
140 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
142 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
143 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
144 run_node_in_namespace_thread(&netns_relay_peer_invite);
146 assert(relay_peer_invite_arg.invite_str);
147 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
149 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
150 run_node_in_namespace_thread(&netns_relay_handle);
152 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
153 run_node_in_namespace_thread(&netns_peer_handle);
155 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
156 run_node_in_namespace_thread(&netns_nut_handle);
158 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
159 test_pmtu_relay_running = false;
160 test_pmtu_peer_running = false;
163 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
164 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
165 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
166 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
171 /* Test Steps for optimal PMTU discovery Test Case # 2 -
172 Validating NUT MTU parameters blocking ICMP under designed
174 static void test_case_optimal_pmtu_02(void **state) {
175 execute_test(test_steps_optimal_pmtu_02, state);
179 /* Test Steps for optimal PMTU discovery Test Case # 2 -
181 1. Create NAT setup and run each node instances in discrete namespace,
182 2. Block ICMP protocol at NUT's NAT
183 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
184 4. Send the analyzed MTU parameters mesh event information to test driver
186 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
189 static bool test_steps_optimal_pmtu_02(void) {
190 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
191 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
192 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
194 assert(system("ip netns exec peer_nat iptables -A FORWARD -p icmp -j DROP") == 0);
195 assert(system("ip netns exec nut_nat iptables -A FORWARD -p icmp -j DROP") == 0);
197 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
198 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
199 run_node_in_namespace_thread(&netns_relay_nut_invite);
201 assert(relay_nut_invite_arg.invite_str);
202 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
204 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
205 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
206 run_node_in_namespace_thread(&netns_relay_peer_invite);
208 assert(relay_peer_invite_arg.invite_str);
209 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
211 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
212 run_node_in_namespace_thread(&netns_relay_handle);
214 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
215 run_node_in_namespace_thread(&netns_peer_handle);
217 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
218 run_node_in_namespace_thread(&netns_nut_handle);
220 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
221 test_pmtu_relay_running = false;
222 test_pmtu_peer_running = false;
225 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
226 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
227 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
228 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
233 /* Test Steps for optimal PMTU discovery Test Case # 3 -
234 Validating NUT MTU parameters with MTU size of NAT = 1250 under designed
236 static void test_case_optimal_pmtu_03(void **state) {
237 execute_test(test_steps_optimal_pmtu_03, state);
241 /* Test Steps for optimal PMTU discovery Test Case # 3 -
243 1. Create NAT setup and run each node instances in discrete namespace,
244 2. Change the MTU size of NUT's NAT to 1250
245 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
246 4. Send the analyzed MTU parameters mesh event information to test driver
248 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
251 static bool test_steps_optimal_pmtu_03(void) {
252 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
253 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
254 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
256 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1250") == 0);
258 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
259 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
260 run_node_in_namespace_thread(&netns_relay_nut_invite);
262 assert(relay_nut_invite_arg.invite_str);
263 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
265 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
266 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
267 run_node_in_namespace_thread(&netns_relay_peer_invite);
269 assert(relay_peer_invite_arg.invite_str);
270 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
272 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
273 run_node_in_namespace_thread(&netns_relay_handle);
275 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
276 run_node_in_namespace_thread(&netns_peer_handle);
278 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
279 run_node_in_namespace_thread(&netns_nut_handle);
281 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
282 test_pmtu_relay_running = false;
283 test_pmtu_peer_running = false;
286 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1200, 1250);
287 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1200, 1250);
292 /* Test Steps for optimal PMTU discovery Test Case # 4 -
293 Validating NUT MTU parameters with MTU size of NAT = 1000 under designed
295 static void test_case_optimal_pmtu_04(void **state) {
296 execute_test(test_steps_optimal_pmtu_04, state);
300 /* Test Steps for optimal PMTU discovery Test Case # 4 -
302 1. Create NAT setup and run each node instances in discrete namespace,
303 2. Change the MTU size of NUT's NAT to 1000
304 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
305 4. Send the analyzed MTU parameters mesh event information to test driver
307 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
310 static bool test_steps_optimal_pmtu_04(void) {
311 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
312 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
313 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
315 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1000") == 0);
317 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
318 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
319 run_node_in_namespace_thread(&netns_relay_nut_invite);
321 assert(relay_nut_invite_arg.invite_str);
322 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
324 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
325 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
326 run_node_in_namespace_thread(&netns_relay_peer_invite);
328 assert(relay_peer_invite_arg.invite_str);
329 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
331 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
332 run_node_in_namespace_thread(&netns_relay_handle);
334 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
335 run_node_in_namespace_thread(&netns_peer_handle);
337 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
338 run_node_in_namespace_thread(&netns_nut_handle);
340 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
341 test_pmtu_relay_running = false;
342 test_pmtu_peer_running = false;
345 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 925, 1000);
346 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 925, 1000);
351 /* Test Steps for optimal PMTU discovery Test Case # 5 -
352 Validating NUT MTU parameters with MTU size of NAT = 800 under designed
354 static void test_case_optimal_pmtu_05(void **state) {
355 execute_test(test_steps_optimal_pmtu_05, state);
359 /* Test Steps for optimal PMTU discovery Test Case # 5 -
361 1. Create NAT setup and run each node instances in discrete namespace,
362 2. Change the MTU size of NUT's NAT to 800
363 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
364 4. Send the analyzed MTU parameters mesh event information to test driver
366 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
369 static bool test_steps_optimal_pmtu_05(void) {
370 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
371 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
372 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
374 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 750") == 0);
376 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
377 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
378 run_node_in_namespace_thread(&netns_relay_nut_invite);
380 assert(relay_nut_invite_arg.invite_str);
381 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
383 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
384 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
385 run_node_in_namespace_thread(&netns_relay_peer_invite);
387 assert(relay_peer_invite_arg.invite_str);
388 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
390 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
391 run_node_in_namespace_thread(&netns_relay_handle);
393 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
394 run_node_in_namespace_thread(&netns_peer_handle);
396 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
397 run_node_in_namespace_thread(&netns_nut_handle);
399 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
400 test_pmtu_relay_running = false;
401 test_pmtu_peer_running = false;
404 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 700, 750);
405 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 700, 750);
410 /* Test Steps for optimal PMTU discovery Test Case # 6 -
411 Flushing the tracked connections via NUT NAT for every 60 seconds */
412 static void test_case_optimal_pmtu_06(void **state) {
413 execute_test(test_steps_optimal_pmtu_06, state);
417 static bool run_conntrack;
418 static pthread_t pmtu_test_case_conntrack_thread;
419 static void *conntrack_flush(void *arg) {
420 // flushes mappings for every 60 seconds
422 while(run_conntrack) {
424 assert(system("ip netns exec nut_nat conntrack -F") == 0);
425 assert(system("ip netns exec peer_nat conntrack -F") == 0);
431 /* Test Steps for optimal PMTU discovery Test Case # 6 -
433 1. Create NAT setup and Launch conntrack thread which flushes the tracked connections for every 90 seconds
434 2. Run each node instances in discrete namespace,
435 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
436 4. Send the analyzed MTU parameters mesh event information to test driver
438 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
441 static bool test_steps_optimal_pmtu_06(void) {
442 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
443 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
444 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
446 run_conntrack = true;
447 assert(!pthread_create(&pmtu_test_case_conntrack_thread, NULL, conntrack_flush, NULL));
449 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
450 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
451 run_node_in_namespace_thread(&netns_relay_nut_invite);
453 assert(relay_nut_invite_arg.invite_str);
454 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
456 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
457 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
458 run_node_in_namespace_thread(&netns_relay_peer_invite);
460 assert(relay_peer_invite_arg.invite_str);
461 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
463 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
464 run_node_in_namespace_thread(&netns_relay_handle);
466 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
467 run_node_in_namespace_thread(&netns_peer_handle);
469 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
470 run_node_in_namespace_thread(&netns_nut_handle);
472 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
473 test_pmtu_relay_running = false;
474 test_pmtu_peer_running = false;
475 run_conntrack = false;
476 pthread_join(pmtu_test_case_conntrack_thread, NULL);
480 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1440, 1500);
481 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1440, 1500);
482 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_ping.probes, 38, 42);
483 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_ping.probes, 38, 42);
488 /* Test Steps for optimal PMTU discovery Test Case # 7 -
489 NUT sending data to peer node via channel for every 30 seconds
491 static void test_case_optimal_pmtu_07(void **state) {
492 execute_test(test_steps_optimal_pmtu_07, state);
496 /* Test Steps for optimal PMTU discovery Test Case # 7 -
498 1. Create NAT setup and run each node instances in discrete namespace.
499 2. Open a channel from NUT to peer and hence triggering Peer to peer connection
500 3. Send data periodically via channel from NUT to peer node.
501 4. Send the analyzed MTU parameters mesh event information to test driver
503 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
506 static bool test_steps_optimal_pmtu_07(void) {
507 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
508 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
509 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
511 ping_channel_enable_07 = true;
513 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
514 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
515 run_node_in_namespace_thread(&netns_relay_nut_invite);
517 assert(relay_nut_invite_arg.invite_str);
518 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
520 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
521 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
522 run_node_in_namespace_thread(&netns_relay_peer_invite);
524 assert(relay_peer_invite_arg.invite_str);
525 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
527 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
528 run_node_in_namespace_thread(&netns_relay_handle);
530 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
531 run_node_in_namespace_thread(&netns_peer_handle);
533 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
534 run_node_in_namespace_thread(&netns_nut_handle);
536 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
537 test_pmtu_relay_running = false;
538 test_pmtu_peer_running = false;
541 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
542 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
543 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
544 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
549 // Optimal PMTU test case driver
551 int test_optimal_pmtu(void) {
552 interface_t nut_ifs[] = { { .if_peer = "nut_nat", .fetch_ip_netns_name = "nut_nat" } };
556 .interfaces = nut_ifs,
560 interface_t peer_ifs[] = { { .if_peer = "peer_nat", .fetch_ip_netns_name = "peer_nat" } };
564 .interfaces = peer_ifs,
568 interface_t relay_ifs[] = { { .if_peer = "wan_bridge" } };
569 namespace_t relay = {
572 .interfaces = relay_ifs,
576 netns_fullcone_handle_t nut_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "nut" };
577 netns_fullcone_handle_t *nut_nat_args[] = { &nut_nat_fullcone, NULL };
578 interface_t nut_nat_ifs[] = { { .if_peer = "nut", .fetch_ip_netns_name = "nut_nat" }, { .if_peer = "wan_bridge" } };
579 namespace_t nut_nat = {
582 .nat_arg = nut_nat_args,
583 .static_config_net_addr = "192.168.1.0/24",
584 .interfaces = nut_nat_ifs,
588 netns_fullcone_handle_t peer_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "peer" };
589 netns_fullcone_handle_t *peer_nat_args[] = { &peer_nat_fullcone, NULL };
590 interface_t peer_nat_ifs[] = { { .if_peer = "peer", .fetch_ip_netns_name = "peer_nat" }, { .if_peer = "wan_bridge" } };
591 namespace_t peer_nat = {
594 .nat_arg = peer_nat_args,
595 .static_config_net_addr = "192.168.1.0/24",
596 .interfaces = peer_nat_ifs,
600 interface_t wan_ifs[] = { { .if_peer = "peer_nat" }, { .if_peer = "nut_nat" }, { .if_peer = "relay" } };
601 namespace_t wan_bridge = {
602 .name = "wan_bridge",
604 .interfaces = wan_ifs,
608 namespace_t test_optimal_pmtu_1_nodes[] = { nut_nat, peer_nat, wan_bridge, nut, peer, relay };
610 netns_state_t test_pmtu_nodes = {
611 .test_case_name = "test_case_optimal_pmtu",
612 .namespaces = test_optimal_pmtu_1_nodes,
615 test_pmtu_state = &test_pmtu_nodes;
617 const struct CMUnitTest blackbox_group0_tests[] = {
618 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_01, setup_test, teardown_test,
619 (void *)&test_pmtu_state),
620 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_02, setup_test, teardown_test,
621 (void *)&test_pmtu_state),
622 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_03, setup_test, teardown_test,
623 (void *)&test_pmtu_state),
624 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_04, setup_test, teardown_test,
625 (void *)&test_pmtu_state),
626 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_05, setup_test, teardown_test,
627 (void *)&test_pmtu_state),
628 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_06, setup_test, teardown_test,
629 (void *)&test_pmtu_state),
630 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_07, setup_test, teardown_test,
631 (void *)&test_pmtu_state),
633 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
635 return cmocka_run_group_tests(blackbox_group0_tests, NULL, NULL);