]> git.meshlink.io Git - meshlink/commitdiff
Add missing metering testcases.
authorGuus Sliepen <guus@meshlink.io>
Sun, 26 Sep 2021 22:19:38 +0000 (00:19 +0200)
committerGuus Sliepen <guus@meshlink.io>
Fri, 8 Oct 2021 18:52:03 +0000 (20:52 +0200)
test/Makefile.am
test/metering-relayed.c [new file with mode: 0644]
test/metering-slowping.c [new file with mode: 0644]
test/metering-tcponly.c [new file with mode: 0644]
test/netns_utils.c

index 94171596fb761c375017ef222ba90edb8f157f72..688d8b7d5861d29b4e53a6cb8d17206ad43f97ed 100644 (file)
@@ -22,6 +22,7 @@ TESTS = \
        invite-join \
        metering \
        metering-relayed \
+       metering-slowping \
        metering-tcponly \              
        meta-connections \
        sign-verify \
@@ -69,6 +70,7 @@ check_PROGRAMS = \
        invite-join \
        metering \
        metering-relayed \
+       metering-slowping \
        metering-tcponly \
        meta-connections \
        sign-verify \
@@ -156,6 +158,9 @@ metering_LDADD = $(top_builddir)/src/libmeshlink.la
 metering_relayed_SOURCES = metering-relayed.c netns_utils.c netns_utils.h utils.c utils.h
 metering_relayed_LDADD = $(top_builddir)/src/libmeshlink.la
 
+metering_slowping_SOURCES = metering-slowping.c netns_utils.c netns_utils.h utils.c utils.h
+metering_slowping_LDADD = $(top_builddir)/src/libmeshlink.la
+
 metering_tcponly_SOURCES = metering-tcponly.c netns_utils.c netns_utils.h utils.c utils.h
 metering_tcponly_LDADD = $(top_builddir)/src/libmeshlink.la
 
diff --git a/test/metering-relayed.c b/test/metering-relayed.c
new file mode 100644 (file)
index 0000000..18a421b
--- /dev/null
@@ -0,0 +1,141 @@
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "meshlink.h"
+#include "devtools.h"
+#include "netns_utils.h"
+#include "utils.h"
+
+static struct sync_flag peer_reachable;
+static struct sync_flag aio_done;
+static const size_t size = 10000000;
+static char *buffer;
+
+static void nut_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
+       (void)mesh;
+
+       if(reachable && !strcmp(node->name, "peer")) {
+               set_sync_flag(&peer_reachable, true);
+       }
+}
+
+static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
+       (void)mesh;
+       (void)channel;
+       (void)data;
+       (void)len;
+       (void)priv;
+
+       set_sync_flag(&aio_done, true);
+}
+
+static void peer_aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
+       (void)mesh;
+       (void)channel;
+       (void)data;
+       (void)len;
+       (void)priv;
+
+       meshlink_channel_close(mesh, channel);
+}
+
+static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+       (void)port;
+       (void)data;
+       (void)len;
+
+       assert(buffer);
+       assert(meshlink_channel_aio_receive(mesh, channel, buffer, size, peer_aio_cb, NULL));
+       return true;
+}
+
+static void print_counters(peer_config_t *peers, const char *description) {
+       printf("%s:\n", description);
+       printf("        %9s %9s %9s %9s %9s %9s\n",
+              "in data",
+              "forward",
+              "meta",
+              "out data",
+              "forward",
+              "meta");
+
+       for(int i = 0; i < 3; i++) {
+               meshlink_node_t *node = meshlink_get_node(peers[0].mesh, peers[i].name);
+               assert(node);
+               struct devtool_node_status status;
+               devtool_reset_node_counters(peers[0].mesh, node, &status);
+               printf(" %5s: %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 "\n",
+                      node->name,
+                      status.in_data,
+                      status.in_forward,
+                      status.in_meta,
+                      status.out_data,
+                      status.out_forward,
+                      status.out_meta);
+       }
+}
+
+
+int main(void) {
+       meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
+
+       init_sync_flag(&peer_reachable);
+       init_sync_flag(&aio_done);
+
+       // Set up relay, peer and NUT
+       peer_config_t *peers = setup_relay_peer_nut_indirect("metering-relayed");
+
+       meshlink_set_node_status_cb(peers[2].mesh, nut_status_cb);
+
+       for(int i = 0; i < 3; i++) {
+               assert(meshlink_start(peers[i].mesh));
+       }
+
+       // Measure traffic after 1 minute of PMTU probing
+       sleep(60);
+       print_counters(peers, "PMTU probing (1 min)");
+
+       // Measure traffic after 1 minute of idle
+       for(int i = 0; i < 10; i++) {
+               sleep(60);
+               print_counters(peers, "Idle (1 min)");
+       }
+
+       // Measure channel traffic between relay and peer
+       buffer = calloc(1, size);
+       assert(buffer);
+       meshlink_node_t *peer = meshlink_get_node(peers[0].mesh, peers[1].name);
+       assert(peer);
+       meshlink_set_channel_accept_cb(peers[1].mesh, accept_cb);
+       meshlink_channel_t *channel = meshlink_channel_open(peers[0].mesh, peer, 1, NULL, NULL, 0);
+       assert(channel);
+       assert(meshlink_channel_aio_send(peers[0].mesh, channel, buffer, size, aio_cb, NULL));
+       assert(wait_sync_flag(&aio_done, 15));
+       meshlink_channel_close(peers[0].mesh, channel);
+       sleep(1);
+       print_counters(peers, "relay->peer channel traffic");
+
+       // Measure channel traffic between NUT and peer
+       assert(wait_sync_flag(&peer_reachable, 5));
+       meshlink_node_t *nut = meshlink_get_node(peers[0].mesh, peers[2].name);
+       assert(nut);
+       peer = meshlink_get_node(peers[2].mesh, peers[1].name);
+       assert(peer);
+       channel = meshlink_channel_open(peers[2].mesh, peer, 1, NULL, NULL, 0);
+       assert(channel);
+       init_sync_flag(&aio_done);
+       assert(meshlink_channel_aio_send(peers[2].mesh, channel, buffer, size, aio_cb, NULL));
+       assert(wait_sync_flag(&aio_done, 15));
+       meshlink_channel_close(peers[2].mesh, channel);
+       sleep(1);
+       print_counters(peers, "NUT->peer channel traffic");
+
+       close_relay_peer_nut(peers);
+}
diff --git a/test/metering-slowping.c b/test/metering-slowping.c
new file mode 100644 (file)
index 0000000..e421d6d
--- /dev/null
@@ -0,0 +1,147 @@
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "meshlink.h"
+#include "devtools.h"
+#include "netns_utils.h"
+#include "utils.h"
+
+static struct sync_flag peer_reachable;
+static struct sync_flag aio_done;
+static const size_t size = 10000000;
+static char *buffer;
+
+static void nut_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
+       (void)mesh;
+
+       if(reachable && !strcmp(node->name, "peer")) {
+               set_sync_flag(&peer_reachable, true);
+       }
+}
+
+static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
+       (void)mesh;
+       (void)channel;
+       (void)data;
+       (void)len;
+       (void)priv;
+
+       set_sync_flag(&aio_done, true);
+}
+
+static void peer_aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
+       (void)mesh;
+       (void)channel;
+       (void)data;
+       (void)len;
+       (void)priv;
+
+       meshlink_channel_close(mesh, channel);
+}
+
+static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+       (void)port;
+       (void)data;
+       (void)len;
+
+       assert(buffer);
+       assert(meshlink_channel_aio_receive(mesh, channel, buffer, size, peer_aio_cb, NULL));
+       return true;
+}
+
+static void print_counters(peer_config_t *peers, const char *description) {
+       printf("%s:\n", description);
+       printf("        %9s %9s %9s %9s %9s %9s\n",
+              "in data",
+              "forward",
+              "meta",
+              "out data",
+              "forward",
+              "meta");
+
+       for(int i = 0; i < 3; i++) {
+               meshlink_node_t *node = meshlink_get_node(peers[0].mesh, peers[i].name);
+               assert(node);
+               struct devtool_node_status status;
+               devtool_reset_node_counters(peers[0].mesh, node, &status);
+               printf(" %5s: %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 "\n",
+                      node->name,
+                      status.in_data,
+                      status.in_forward,
+                      status.in_meta,
+                      status.out_data,
+                      status.out_forward,
+                      status.out_meta);
+       }
+}
+
+
+int main(void) {
+       meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
+
+       init_sync_flag(&peer_reachable);
+       init_sync_flag(&aio_done);
+
+       // Set up relay, peer and NUT
+       peer_config_t *peers = setup_relay_peer_nut("metering-slowping");
+       set_peers_tcponly(peers, 3);
+
+       // Ensure DEV_CLASS_STATIONARY uses a 5 minute ping time
+       for(int i = 0; i < 3; i++) {
+               meshlink_set_dev_class_timeouts(peers[i].mesh, i ? DEV_CLASS_BACKBONE : DEV_CLASS_STATIONARY, 300, 5);
+       }
+
+       meshlink_set_node_status_cb(peers[2].mesh, nut_status_cb);
+
+       for(int i = 0; i < 3; i++) {
+               assert(meshlink_start(peers[i].mesh));
+       }
+
+       // Measure traffic after 1 minute of PMTU probing
+       sleep(60);
+       print_counters(peers, "PMTU probing (1 min)");
+
+       // Measure traffic after 1 minute of idle
+       for(int i = 0; i < 10; i++) {
+               sleep(60);
+               print_counters(peers, "Idle (1 min)");
+       }
+
+       // Measure channel traffic between relay and peer
+       buffer = calloc(1, size);
+       assert(buffer);
+       meshlink_node_t *peer = meshlink_get_node(peers[0].mesh, peers[1].name);
+       assert(peer);
+       meshlink_set_channel_accept_cb(peers[1].mesh, accept_cb);
+       meshlink_channel_t *channel = meshlink_channel_open(peers[0].mesh, peer, 1, NULL, NULL, 0);
+       assert(channel);
+       assert(meshlink_channel_aio_send(peers[0].mesh, channel, buffer, size, aio_cb, NULL));
+       assert(wait_sync_flag(&aio_done, 15));
+       meshlink_channel_close(peers[0].mesh, channel);
+       sleep(1);
+       print_counters(peers, "relay->peer channel traffic");
+
+       // Measure channel traffic between NUT and peer
+       assert(wait_sync_flag(&peer_reachable, 5));
+       meshlink_node_t *nut = meshlink_get_node(peers[0].mesh, peers[2].name);
+       assert(nut);
+       peer = meshlink_get_node(peers[2].mesh, peers[1].name);
+       assert(peer);
+       channel = meshlink_channel_open(peers[2].mesh, peer, 1, NULL, NULL, 0);
+       assert(channel);
+       init_sync_flag(&aio_done);
+       assert(meshlink_channel_aio_send(peers[2].mesh, channel, buffer, size, aio_cb, NULL));
+       assert(wait_sync_flag(&aio_done, 15));
+       meshlink_channel_close(peers[2].mesh, channel);
+       sleep(1);
+       print_counters(peers, "NUT->peer channel traffic");
+
+       close_relay_peer_nut(peers);
+}
diff --git a/test/metering-tcponly.c b/test/metering-tcponly.c
new file mode 100644 (file)
index 0000000..ba0b13f
--- /dev/null
@@ -0,0 +1,142 @@
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "meshlink.h"
+#include "devtools.h"
+#include "netns_utils.h"
+#include "utils.h"
+
+static struct sync_flag peer_reachable;
+static struct sync_flag aio_done;
+static const size_t size = 10000000;
+static char *buffer;
+
+static void nut_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
+       (void)mesh;
+
+       if(reachable && !strcmp(node->name, "peer")) {
+               set_sync_flag(&peer_reachable, true);
+       }
+}
+
+static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
+       (void)mesh;
+       (void)channel;
+       (void)data;
+       (void)len;
+       (void)priv;
+
+       set_sync_flag(&aio_done, true);
+}
+
+static void peer_aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
+       (void)mesh;
+       (void)channel;
+       (void)data;
+       (void)len;
+       (void)priv;
+
+       meshlink_channel_close(mesh, channel);
+}
+
+static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
+       (void)port;
+       (void)data;
+       (void)len;
+
+       assert(buffer);
+       assert(meshlink_channel_aio_receive(mesh, channel, buffer, size, peer_aio_cb, NULL));
+       return true;
+}
+
+static void print_counters(peer_config_t *peers, const char *description) {
+       printf("%s:\n", description);
+       printf("        %9s %9s %9s %9s %9s %9s\n",
+              "in data",
+              "forward",
+              "meta",
+              "out data",
+              "forward",
+              "meta");
+
+       for(int i = 0; i < 3; i++) {
+               meshlink_node_t *node = meshlink_get_node(peers[0].mesh, peers[i].name);
+               assert(node);
+               struct devtool_node_status status;
+               devtool_reset_node_counters(peers[0].mesh, node, &status);
+               printf(" %5s: %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 "\n",
+                      node->name,
+                      status.in_data,
+                      status.in_forward,
+                      status.in_meta,
+                      status.out_data,
+                      status.out_forward,
+                      status.out_meta);
+       }
+}
+
+
+int main(void) {
+       meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
+
+       init_sync_flag(&peer_reachable);
+       init_sync_flag(&aio_done);
+
+       // Set up relay, peer and NUT
+       peer_config_t *peers = setup_relay_peer_nut("metering-tcponly");
+       set_peers_tcponly(peers, 3);
+
+       meshlink_set_node_status_cb(peers[2].mesh, nut_status_cb);
+
+       for(int i = 0; i < 3; i++) {
+               assert(meshlink_start(peers[i].mesh));
+       }
+
+       // Measure traffic after 1 minute of PMTU probing
+       sleep(60);
+       print_counters(peers, "PMTU probing (1 min)");
+
+       // Measure traffic after 1 minute of idle
+       for(int i = 0; i < 10; i++) {
+               sleep(60);
+               print_counters(peers, "Idle (1 min)");
+       }
+
+       // Measure channel traffic between relay and peer
+       buffer = calloc(1, size);
+       assert(buffer);
+       meshlink_node_t *peer = meshlink_get_node(peers[0].mesh, peers[1].name);
+       assert(peer);
+       meshlink_set_channel_accept_cb(peers[1].mesh, accept_cb);
+       meshlink_channel_t *channel = meshlink_channel_open(peers[0].mesh, peer, 1, NULL, NULL, 0);
+       assert(channel);
+       assert(meshlink_channel_aio_send(peers[0].mesh, channel, buffer, size, aio_cb, NULL));
+       assert(wait_sync_flag(&aio_done, 15));
+       meshlink_channel_close(peers[0].mesh, channel);
+       sleep(1);
+       print_counters(peers, "relay->peer channel traffic");
+
+       // Measure channel traffic between NUT and peer
+       assert(wait_sync_flag(&peer_reachable, 5));
+       meshlink_node_t *nut = meshlink_get_node(peers[0].mesh, peers[2].name);
+       assert(nut);
+       peer = meshlink_get_node(peers[2].mesh, peers[1].name);
+       assert(peer);
+       channel = meshlink_channel_open(peers[2].mesh, peer, 1, NULL, NULL, 0);
+       assert(channel);
+       init_sync_flag(&aio_done);
+       assert(meshlink_channel_aio_send(peers[2].mesh, channel, buffer, size, aio_cb, NULL));
+       assert(wait_sync_flag(&aio_done, 15));
+       meshlink_channel_close(peers[2].mesh, channel);
+       sleep(1);
+       print_counters(peers, "NUT->peer channel traffic");
+
+       close_relay_peer_nut(peers);
+}
index 58c01ff5f60d9d24d1fd5aa8fb143c3f530fe914..ec7aee4a8e65bda041788cd890bfd8e3e3d7f18f 100644 (file)
@@ -183,12 +183,12 @@ peer_config_t *setup_relay_peer_nut_indirect(const char *prefix) {
 
 /// Make all nodes only be able to communicate via TCP
 void set_peers_tcponly(peer_config_t *peers, int npeers) {
-       for (int i = 0; i < npeers; i++) {
+       for(int i = 0; i < npeers; i++) {
                char *command = NULL;
                assert(asprintf(&command,
-                                               "/bin/ip netns exec %1$s iptables -A INPUT -p udp -j DROP;"
-                                               "/bin/ip netns exec %1$s iptables -A OUTPUT -p udp -j DROP;",
-                                               peers[i].netns_name));
+                               "/bin/ip netns exec %1$s iptables -A INPUT -p udp -j DROP;"
+                               "/bin/ip netns exec %1$s iptables -A OUTPUT -p udp -j DROP;",
+                               peers[i].netns_name));
                assert(command);
                assert(system(command) == 0);
                free(command);