13 #include "netns_utils.h"
16 static struct sync_flag peer_reachable;
17 static struct sync_flag aio_done;
18 static const size_t size = 10000000;
21 static void nut_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
24 if(reachable && !strcmp(node->name, "peer")) {
25 set_sync_flag(&peer_reachable, true);
29 static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
36 set_sync_flag(&aio_done, true);
39 static void peer_aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
46 meshlink_channel_close(mesh, channel);
49 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
55 assert(meshlink_channel_aio_receive(mesh, channel, buffer, size, peer_aio_cb, NULL));
59 static void print_counters(peer_config_t *peers, const char *description) {
60 printf("%s:\n", description);
61 printf(" %9s %9s %9s %9s %9s %9s\n",
69 for(int i = 0; i < 3; i++) {
70 meshlink_node_t *node = meshlink_get_node(peers[0].mesh, peers[i].name);
72 struct devtool_node_status status;
73 devtool_reset_node_counters(peers[0].mesh, node, &status);
74 printf(" %5s: %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 "\n",
87 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
89 init_sync_flag(&peer_reachable);
90 init_sync_flag(&aio_done);
92 // Set up relay, peer and NUT
93 peer_config_t *peers = setup_relay_peer_nut("metering-slowping");
94 set_peers_tcponly(peers, 3);
96 // Ensure DEV_CLASS_STATIONARY uses a 5 minute ping time
97 for(int i = 0; i < 3; i++) {
98 meshlink_set_dev_class_timeouts(peers[i].mesh, i ? DEV_CLASS_BACKBONE : DEV_CLASS_STATIONARY, 300, 5);
101 meshlink_set_node_status_cb(peers[2].mesh, nut_status_cb);
103 for(int i = 0; i < 3; i++) {
104 assert(meshlink_start(peers[i].mesh));
107 // Measure traffic after 1 minute of PMTU probing
109 print_counters(peers, "PMTU probing (1 min)");
111 // Measure traffic after 1 minute of idle
112 for(int i = 0; i < 10; i++) {
114 print_counters(peers, "Idle (1 min)");
117 // Measure channel traffic between relay and peer
118 buffer = calloc(1, size);
120 meshlink_node_t *peer = meshlink_get_node(peers[0].mesh, peers[1].name);
122 meshlink_set_channel_accept_cb(peers[1].mesh, accept_cb);
123 meshlink_channel_t *channel = meshlink_channel_open(peers[0].mesh, peer, 1, NULL, NULL, 0);
125 assert(meshlink_channel_aio_send(peers[0].mesh, channel, buffer, size, aio_cb, NULL));
126 assert(wait_sync_flag(&aio_done, 15));
127 meshlink_channel_close(peers[0].mesh, channel);
129 print_counters(peers, "relay->peer channel traffic");
131 // Measure channel traffic between NUT and peer
132 assert(wait_sync_flag(&peer_reachable, 5));
133 meshlink_node_t *nut = meshlink_get_node(peers[0].mesh, peers[2].name);
135 peer = meshlink_get_node(peers[2].mesh, peers[1].name);
137 channel = meshlink_channel_open(peers[2].mesh, peer, 1, NULL, NULL, 0);
139 init_sync_flag(&aio_done);
140 assert(meshlink_channel_aio_send(peers[2].mesh, channel, buffer, size, aio_cb, NULL));
141 assert(wait_sync_flag(&aio_done, 15));
142 meshlink_channel_close(peers[2].mesh, channel);
144 print_counters(peers, "NUT->peer channel traffic");
146 close_relay_peer_nut(peers);