]> git.meshlink.io Git - meshlink-tiny/commitdiff
Add a metering test. main
authorGuus Sliepen <guus@meshlink.io>
Sun, 26 Sep 2021 22:25:01 +0000 (00:25 +0200)
committerGuus Sliepen <guus@meshlink.io>
Sun, 26 Sep 2021 22:25:01 +0000 (00:25 +0200)
Currently it only measures traffic between tiny and full nodes during
the initial connection and while idle.

test/Makefile.am
test/metering.c [new file with mode: 0644]
test/netns_utils.c
test/netns_utils.h

index 3090ae9d2b315d38f7e8bd4f9ce6a1f556fc2420..06cb07cd0798c58f0a6e688be079a25d573d9fd6 100644 (file)
@@ -4,6 +4,7 @@ TESTS = \
        ephemeral \
        import-export \
        invite-join \
+       metering \
        sign-verify \
        storage-policy
 
@@ -18,6 +19,7 @@ check_PROGRAMS = \
        ephemeral \
        import-export \
        invite-join \
+       metering \
        sign-verify \
        storage-policy
 
@@ -37,5 +39,6 @@ ephemeral_SOURCES = ephemeral.c $(default_SOURCES)
 get_all_nodes_SOURCES = get-all-nodes.c $(default_SOURCES)
 import_export_SOURCES = import-export.c $(default_SOURCES)
 invite_join_SOURCES = invite-join.c $(default_SOURCES)
+metering_SOURCES = metering.c netns_utils.c $(default_SOURCES)
 sign_verify_SOURCES = sign-verify.c $(default_SOURCES)
 storage_policy_SOURCES = storage-policy.c $(default_SOURCES)
diff --git a/test/metering.c b/test/metering.c
new file mode 100644 (file)
index 0000000..fdccd5e
--- /dev/null
@@ -0,0 +1,80 @@
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "meshlink-tiny.h"
+#include "devtools.h"
+#include "netns_utils.h"
+#include "utils.h"
+
+#include "full.h"
+
+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");
+
+       assert(peers[0].full);
+
+       for(int i = 0; i < 3; i++) {
+               meshlink_node_t *node = full_meshlink_get_node(peers[0].mesh, peers[i].name);
+               assert(node);
+               struct devtool_node_status status;
+               full_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) {
+       init_full();
+
+       meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
+
+       // Set up relay, peer and NUT
+       peer_config_t *peers = setup_relay_peer_nut("metering");
+
+       // Ensure DEV_CLASS_STATIONARY uses a 5 minute ping time
+       for(int i = 0; i < 3; i++) {
+               peers[i].full
+               ? full_meshlink_set_dev_class_timeouts(peers[i].mesh, DEV_CLASS_STATIONARY, 300, 5)
+               : meshlink_set_dev_class_timeouts(peers[i].mesh, DEV_CLASS_BACKBONE, 300, 5);
+       }
+
+       for(int i = 0; i < 3; i++) {
+               assert(peers[i].full
+                      ? full_meshlink_start(peers[i].mesh)
+                      : 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)");
+       }
+
+       close_relay_peer_nut(peers);
+}
index 5e0ed2157f6ca50fd9ebe071f5381fab6d63c12b..476adbc9ebe1d3e54f1a689b5c04bb31f6148b2f 100644 (file)
@@ -1,6 +1,6 @@
 #define _GNU_SOURCE 1
 
-#ifndef NDEBUG
+#ifdef NDEBUG
 #undef NDEBUG
 #endif
 
 #include <sys/stat.h>
 #include <fcntl.h>
 
-#include "../src/meshlink-tiny.h"
+#include "meshlink-tiny.h"
 #include "netns_utils.h"
 #include "utils.h"
 
+#include "full.h"
+
 static int ip = 1;
 
 /// Create meshlink instances and network namespaces for a list of peers
@@ -24,6 +26,8 @@ static void create_peers(peer_config_t *peers, int npeers, const char *prefix) {
        }
 
        for(int i = 0; i < npeers; i++) {
+               bool full = peers[i].full;
+
                assert(asprintf(&peers[i].netns_name, "%s%d", prefix, i) > 0);
                char *command = NULL;
                assert(asprintf(&command,
@@ -45,16 +49,25 @@ static void create_peers(peer_config_t *peers, int npeers, const char *prefix) {
                char *conf_path = NULL;
                assert(asprintf(&conf_path, "%s_conf.%d", prefix, i + 1) > 0);
                assert(conf_path);
-               assert(meshlink_destroy(conf_path));
+               assert(full ? full_meshlink_destroy(conf_path) : meshlink_destroy(conf_path));
 
-               meshlink_open_params_t *params = meshlink_open_params_init(conf_path, peers[i].name, prefix, peers[i].devclass);
+               meshlink_open_params_t *params = full
+                                                ? full_meshlink_open_params_init(conf_path, peers[i].name, prefix, peers[i].devclass)
+                                                : meshlink_open_params_init(conf_path, peers[i].name, prefix, peers[i].devclass);
                assert(params);
-               assert(meshlink_open_params_set_netns(params, peers[i].netns));
+               assert(full
+                      ? full_meshlink_open_params_set_netns(params, peers[i].netns)
+                      : meshlink_open_params_set_netns(params, peers[i].netns)
+                     );
 
-               peers[i].mesh = meshlink_open_ex(params);
+               peers[i].mesh = full ? full_meshlink_open_ex(params) : meshlink_open_ex(params);
                assert(peers[i].mesh);
                free(params);
                free(conf_path);
+
+               if(full) {
+                       full_meshlink_enable_discovery(peers[i].mesh, false);
+               }
        }
 }
 
@@ -90,6 +103,26 @@ static void setup_lan_topology(peer_config_t *peers, int npeers) {
        }
 }
 
+/// Set up an indirect topology where all peers can only access the relay
+static void setup_indirect_topology(peer_config_t *peers, int npeers) {
+       // Add an interface to each peer that is connected to the relay
+       for(int i = 1; i < npeers; i++) {
+               char *command = NULL;
+               assert(asprintf(&command,
+                               "/bin/ip netns exec %1$s /bin/ip link add eth0 type veth peer eth%3$d netns %2$s;"
+                               "/bin/ip netns exec %1$s ip addr flush dev eth0;"
+                               "/bin/ip netns exec %1$s ip addr add 192.168.%3$d.2/24 dev eth0;"
+                               "/bin/ip netns exec %1$s /bin/ip link set dev eth0 up;"
+                               "/bin/ip netns exec %2$s ip addr flush dev eth%3$d;"
+                               "/bin/ip netns exec %2$s ip addr add 192.168.%3$d.1/24 dev eth%3$d;"
+                               "/bin/ip netns exec %2$s /bin/ip link set dev eth%3$d up;",
+                               peers[i].netns_name, peers[0].netns_name, i));
+               assert(command);
+               assert(system(command) == 0);
+               free(command);
+       }
+}
+
 /// Give a peer a unique IP address
 void change_peer_ip(peer_config_t *peer) {
        char *command = NULL;
@@ -104,23 +137,25 @@ void change_peer_ip(peer_config_t *peer) {
 }
 
 /// Let the first peer in a list invite all the subsequent peers
-static void link_peers(peer_config_t *peers, int npeers) {
+static void invite_peers(peer_config_t *peers, int npeers) {
+       assert(peers[0].full);
+       assert(full_meshlink_start(peers[0].mesh));
+
        for(int i = 1; i < npeers; i++) {
-               char *export_relay = meshlink_export(peers[0].mesh);
-               char *export_peer = meshlink_export(peers[i].mesh);
-               assert(export_relay);
-               assert(export_peer);
-               assert(meshlink_import(peers[0].mesh, export_peer));
-               assert(meshlink_import(peers[i].mesh, export_relay));
-               free(export_relay);
-               free(export_peer);
+               char *invitation = full_meshlink_invite_ex(peers[0].mesh, NULL, peers[i].name, MESHLINK_INVITE_LOCAL | MESHLINK_INVITE_NUMERIC);
+               assert(invitation);
+               printf("%s\n", invitation);
+               assert(peers[i].full ? full_meshlink_join(peers[i].mesh, invitation) : meshlink_join(peers[i].mesh, invitation));
+               free(invitation);
        }
+
+       full_meshlink_stop(peers[0].mesh);
 }
 
 /// Close meshlink instances and clean up
 static void close_peers(peer_config_t *peers, int npeers) {
        for(int i = 0; i < npeers; i++) {
-               meshlink_close(peers[i].mesh);
+               peers[i].full ? full_meshlink_close(peers[i].mesh) : meshlink_close(peers[i].mesh);
                close(peers[i].netns);
                free(peers[i].netns_name);
        }
@@ -129,18 +164,49 @@ static void close_peers(peer_config_t *peers, int npeers) {
 /// Set up relay, peer and NUT that are directly connected
 peer_config_t *setup_relay_peer_nut(const char *prefix) {
        static peer_config_t peers[] = {
-               {"relay", DEV_CLASS_BACKBONE},
-               {"peer", DEV_CLASS_STATIONARY},
-               {"nut", DEV_CLASS_STATIONARY},
+               {"relay", DEV_CLASS_BACKBONE, NULL, 0, true, NULL},
+               {"peer", DEV_CLASS_STATIONARY, NULL, 0, false, NULL},
+               {"nut", DEV_CLASS_STATIONARY, NULL, 0, false, NULL},
        };
 
        create_peers(peers, 3, prefix);
        setup_lan_topology(peers, 3);
-       link_peers(peers, 3);
+       invite_peers(peers, 3);
+
+       return peers;
+}
+
+/// Set up relay, peer and NUT that are directly connected
+peer_config_t *setup_relay_peer_nut_indirect(const char *prefix) {
+       static peer_config_t peers[] = {
+               {"relay", DEV_CLASS_BACKBONE, NULL, 0, true, NULL},
+               {"peer", DEV_CLASS_STATIONARY, NULL, 0, false, NULL},
+               {"nut", DEV_CLASS_STATIONARY, NULL, 0, false, NULL},
+       };
+
+       create_peers(peers, 3, prefix);
+       setup_indirect_topology(peers, 3);
+       assert(full_meshlink_add_invitation_address(peers[0].mesh, "192.168.1.1", NULL));
+       assert(full_meshlink_add_invitation_address(peers[0].mesh, "192.168.2.1", NULL));
+       invite_peers(peers, 3);
 
        return peers;
 }
 
+/// 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++) {
+               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));
+               assert(command);
+               assert(system(command) == 0);
+               free(command);
+       }
+}
+
 void close_relay_peer_nut(peer_config_t *peers) {
        close_peers(peers, 3);
 }
index 7bbe51a279540146f44b1f4027d138e1245aa259..80a5e6735c4d84253451c36b138d7be02a34f4b2 100644 (file)
@@ -7,11 +7,14 @@ typedef struct peer_config {
 
        char *netns_name;
        int netns;
+       bool full;
        meshlink_handle_t *mesh;
 } peer_config_t;
 
 extern void change_peer_ip(peer_config_t *peer);
 extern peer_config_t *setup_relay_peer_nut(const char *prefix);
+extern peer_config_t *setup_relay_peer_nut_indirect(const char *prefix);
+extern void set_peers_tcponly(peer_config_t *peers, int npeers);
 extern void close_relay_peer_nut(peer_config_t *peers);
 
 #endif