From: Guus Sliepen Date: Fri, 28 Aug 2020 21:04:52 +0000 (+0200) Subject: Add test for detecting failing UDP communication. X-Git-Url: https://git.meshlink.io/?a=commitdiff_plain;h=02c21bf1a7bcdb22ae2b1dc189791b3678b71aab;p=meshlink Add test for detecting failing UDP communication. Add a test that, starting with a working UDP connection between two peers, blocks UDP packets, and then checks if this is detected by MeshLink. Also avoid parsing log messages to detect MTU changes, use devtools for this. --- diff --git a/test/pmtu.c b/test/pmtu.c index cb39d4bc..7a179007 100644 --- a/test/pmtu.c +++ b/test/pmtu.c @@ -13,6 +13,7 @@ #include #include "meshlink.h" +#include "devtools.h" #include "utils.h" #define nnodes 3 @@ -61,50 +62,56 @@ static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint return true; } -static void parse_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) { - if(level >= MESHLINK_INFO) { - log_cb(mesh, level, text); - } - - struct state *state = mesh->priv; +static void wait_for_pmtu(void) { + // Set up a channel from peer to nut + meshlink_set_channel_accept_cb(states[2].mesh, accept_cb); + meshlink_handle_t *mesh = states[1].mesh; + meshlink_node_t *peer = meshlink_get_node(mesh, nodes[2].name); + meshlink_channel_t *channel = meshlink_channel_open(mesh, peer, 1, NULL, NULL, 0); + assert(channel); - if(state->pmtu != 0) { - return; - } + // While sending regular data, wait for PMTU discovery to finish + for(int i = 0; i < 30; i++) { + sleep(1); - int len; - char name[10] = ""; + devtool_node_status_t status; + devtool_get_node_status(mesh, peer, &status); + states[1].pmtu = status.minmtu; - if(sscanf(text, "Sending UDP probe length %d to %9s", &len, name) == 2 || sscanf(text, "Got PMTU probe length %d from %s", &len, name) == 2) { - if(!strcmp(name, "nut")) { - state->probe_count++; - state->probe_bytes += len; - } - } else if(sscanf(text, "Fixing PMTU of %9s to %d", name, &len) == 2) { - if(!strcmp(name, "nut")) { - state->pmtu = len; + if(status.minmtu == status.maxmtu) { + break; } + + assert(meshlink_channel_send(mesh, channel, "ping", 4) == 4); } + + meshlink_channel_close(mesh, channel); } -static void wait_for_pmtu(void) { +static void wait_for_udp_timeout(void) { // Set up a channel from peer to nut meshlink_set_channel_accept_cb(states[2].mesh, accept_cb); - meshlink_channel_t *channel = meshlink_channel_open(states[1].mesh, meshlink_get_node(states[1].mesh, nodes[2].name), 1, NULL, NULL, 0); + meshlink_handle_t *mesh = states[1].mesh; + meshlink_node_t *peer = meshlink_get_node(mesh, nodes[2].name); + meshlink_channel_t *channel = meshlink_channel_open(mesh, peer, 1, NULL, NULL, 0); assert(channel); - // While sending regular data, wait for PMTU discovery to finish - for(int i = 0; i < 30; i++) { + // While sending regular data, wait for UDP to time out + for(int i = 0; i < 20; i++) { sleep(1); - if(states[1].pmtu) { + devtool_node_status_t status; + devtool_get_node_status(mesh, peer, &status); + states[1].pmtu = status.minmtu; + + if(!status.minmtu) { break; } - assert(meshlink_channel_send(states[1].mesh, channel, "ping", 4) == 4); + assert(meshlink_channel_send(mesh, channel, "ping", 4) == 4); } - meshlink_channel_close(states[1].mesh, channel); + meshlink_channel_close(mesh, channel); } static void start_peer_nut(void) { @@ -159,7 +166,7 @@ int main(void) { meshlink_enable_discovery(states[i].mesh, false); init_sync_flag(&states[i].up_flag); - meshlink_set_log_cb(states[i].mesh, MESHLINK_DEBUG, parse_log_cb); + meshlink_set_log_cb(states[i].mesh, MESHLINK_INFO, log_cb); // Link the relay node to the other nodes if(i > 0) { @@ -196,6 +203,16 @@ int main(void) { assert(states[1].probe_count <= 20); assert(states[1].probe_bytes <= 800 * 20); + // Block UDP + + assert(system("ip netns exec pmtu_p iptables -A INPUT -p udp -j DROP") == 0); + assert(system("ip netns exec pmtu_n iptables -A INPUT -p udp -j DROP") == 0); + + // Wait + + wait_for_udp_timeout(); + assert(states[1].pmtu == 0); + // Cleanup for(int i = 0; i < nnodes; i++) { meshlink_close(states[i].mesh);