]> git.meshlink.io Git - meshlink/blob - test/metering-slowping.c
Add missing metering testcases.
[meshlink] / test / metering-slowping.c
1 #ifdef NDEBUG
2 #undef NDEBUG
3 #endif
4
5 #include <assert.h>
6 #include <inttypes.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "meshlink.h"
12 #include "devtools.h"
13 #include "netns_utils.h"
14 #include "utils.h"
15
16 static struct sync_flag peer_reachable;
17 static struct sync_flag aio_done;
18 static const size_t size = 10000000;
19 static char *buffer;
20
21 static void nut_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
22         (void)mesh;
23
24         if(reachable && !strcmp(node->name, "peer")) {
25                 set_sync_flag(&peer_reachable, true);
26         }
27 }
28
29 static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
30         (void)mesh;
31         (void)channel;
32         (void)data;
33         (void)len;
34         (void)priv;
35
36         set_sync_flag(&aio_done, true);
37 }
38
39 static void peer_aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
40         (void)mesh;
41         (void)channel;
42         (void)data;
43         (void)len;
44         (void)priv;
45
46         meshlink_channel_close(mesh, channel);
47 }
48
49 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
50         (void)port;
51         (void)data;
52         (void)len;
53
54         assert(buffer);
55         assert(meshlink_channel_aio_receive(mesh, channel, buffer, size, peer_aio_cb, NULL));
56         return true;
57 }
58
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",
62                "in data",
63                "forward",
64                "meta",
65                "out data",
66                "forward",
67                "meta");
68
69         for(int i = 0; i < 3; i++) {
70                 meshlink_node_t *node = meshlink_get_node(peers[0].mesh, peers[i].name);
71                 assert(node);
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",
75                        node->name,
76                        status.in_data,
77                        status.in_forward,
78                        status.in_meta,
79                        status.out_data,
80                        status.out_forward,
81                        status.out_meta);
82         }
83 }
84
85
86 int main(void) {
87         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
88
89         init_sync_flag(&peer_reachable);
90         init_sync_flag(&aio_done);
91
92         // Set up relay, peer and NUT
93         peer_config_t *peers = setup_relay_peer_nut("metering-slowping");
94         set_peers_tcponly(peers, 3);
95
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);
99         }
100
101         meshlink_set_node_status_cb(peers[2].mesh, nut_status_cb);
102
103         for(int i = 0; i < 3; i++) {
104                 assert(meshlink_start(peers[i].mesh));
105         }
106
107         // Measure traffic after 1 minute of PMTU probing
108         sleep(60);
109         print_counters(peers, "PMTU probing (1 min)");
110
111         // Measure traffic after 1 minute of idle
112         for(int i = 0; i < 10; i++) {
113                 sleep(60);
114                 print_counters(peers, "Idle (1 min)");
115         }
116
117         // Measure channel traffic between relay and peer
118         buffer = calloc(1, size);
119         assert(buffer);
120         meshlink_node_t *peer = meshlink_get_node(peers[0].mesh, peers[1].name);
121         assert(peer);
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);
124         assert(channel);
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);
128         sleep(1);
129         print_counters(peers, "relay->peer channel traffic");
130
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);
134         assert(nut);
135         peer = meshlink_get_node(peers[2].mesh, peers[1].name);
136         assert(peer);
137         channel = meshlink_channel_open(peers[2].mesh, peer, 1, NULL, NULL, 0);
138         assert(channel);
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);
143         sleep(1);
144         print_counters(peers, "NUT->peer channel traffic");
145
146         close_relay_peer_nut(peers);
147 }