From 8d4a619a15a77708ed0210f0cce6382692a28926 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Thu, 23 Jan 2025 14:33:28 -0300 Subject: [PATCH] minimize elusive ARP lookup failure --- test/mip_tap_test.c | 75 ++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/test/mip_tap_test.c b/test/mip_tap_test.c index e1a060d6..a12b6d1e 100644 --- a/test/mip_tap_test.c +++ b/test/mip_tap_test.c @@ -5,7 +5,6 @@ #define FETCH_BUF_SIZE (16 * 1024) - #include #ifndef __OpenBSD__ #include @@ -21,10 +20,9 @@ #include "driver_mock.c" - -#define MQTT_URL "mqtt://broker.hivemq.com:1883" // MQTT broker URL +#define MQTT_URL "mqtt://broker.hivemq.com:1883" // MQTT broker URL #if MG_TLS == MG_TLS_BUILTIN -#define MQTTS_URL "mqtts://mongoose.ws:8883" // HiveMQ does not do TLS1.3 +#define MQTTS_URL "mqtts://mongoose.ws:8883" // HiveMQ does not do TLS1.3 #define MQTTS_CA mg_str(s_ca_cert) static const char *s_ca_cert = "-----BEGIN CERTIFICATE-----\n" @@ -59,18 +57,17 @@ static const char *s_ca_cert = "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n" "-----END CERTIFICATE-----\n"; #elif MG_TLS -#define MQTTS_URL "mqtts://broker.hivemq.com:8883" // MQTT broker URL +#define MQTTS_URL "mqtts://broker.hivemq.com:8883" // MQTT broker URL #define MQTTS_CA mg_unpacked("/data/ca.pem") #endif - static char *host_ip; static int s_num_tests = 0; -#define ABORT() \ - usleep(500000); /* 500 ms, GH print reason */ \ - abort(); +#define ABORT() \ + usleep(500000); /* 500 ms, GH print reason */ \ + abort(); #define ASSERT(expr) \ do { \ @@ -96,7 +93,6 @@ static int cmpbody(const char *buf, const char *str) { return mg_strcmp(hm.body, s); } - // MIP TUNTAP driver static size_t tap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) { ssize_t received = read(*(int *) ifp->driver_data, buf, len); @@ -118,14 +114,14 @@ static bool tap_up(struct mg_tcpip_if *ifp) { return ifp->driver_data ? true : false; } - static void eh1(struct mg_connection *c, int ev, void *ev_data) { struct mg_tls_opts *topts = (struct mg_tls_opts *) c->fn_data; if (ev == MG_EV_ACCEPT && topts != NULL) mg_tls_init(c, topts); if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; - MG_DEBUG(("[%.*s %.*s] message len %d", (int) hm->method.len, hm->method.buf, - (int) hm->uri.len, hm->uri.buf, (int) hm->message.len)); + MG_DEBUG(("[%.*s %.*s] message len %d", (int) hm->method.len, + hm->method.buf, (int) hm->uri.len, hm->uri.buf, + (int) hm->message.len)); if (mg_match(hm->uri, mg_str("/foo/*"), NULL)) { mg_http_reply(c, 200, "", "uri: %.*s", hm->uri.len - 5, hm->uri.buf + 5); } else if (mg_match(hm->uri, mg_str("/ws"), NULL)) { @@ -171,11 +167,13 @@ static void fcb(struct mg_connection *c, int ev, void *ev_data) { } } else if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; - snprintf(fd->buf, FETCH_BUF_SIZE, "%.*s", (int) hm->message.len, hm->message.buf); + snprintf(fd->buf, FETCH_BUF_SIZE, "%.*s", (int) hm->message.len, + hm->message.buf); fd->code = atoi(hm->uri.buf); fd->closed = 1; c->is_closing = 1; - MG_DEBUG(("CODE: %d, MSG: %.*s", fd->code, (int) hm->message.len, hm->message.buf)); + MG_DEBUG(("CODE: %d, MSG: %.*s", fd->code, (int) hm->message.len, + hm->message.buf)); (void) c; } else if (ev == MG_EV_CLOSE) { MG_DEBUG(("CLOSE")); @@ -192,6 +190,8 @@ static int fetch(struct mg_mgr *mgr, char *buf, const char *url, int i; struct mg_connection *c = NULL; va_list ap; + mg_mgr_poll(mgr, 0); // update ifp->now to avoid ARP lookup using an old + // timestamp (from an ancient call in other test) c = mg_http_connect(mgr, url, fcb, &fd); ASSERT(c != NULL); va_start(ap, fmt); @@ -200,7 +200,10 @@ static int fetch(struct mg_mgr *mgr, char *buf, const char *url, buf[0] = '\0'; for (i = 0; i < 500 && buf[0] == '\0' && !fd.closed; i++) { mg_mgr_poll(mgr, 0); - usleep(10000); // 10 ms. Slow down poll loop to ensure packet transit + usleep(5000); // 5 ms. Slow down poll loop to ensure packet transit, but + // allow enough loops to get the ARP response, otherwise, + // given enough traffic, the timer expires before we get a + // chance to see the response } if (!fd.closed) c->is_closing = 1; mg_mgr_poll(mgr, 0); @@ -213,16 +216,20 @@ static void test_http_client(struct mg_mgr *mgr) { const bool ipv6 = 0; #if MG_TLS if (ipv6) { - rc = fetch(mgr, buf, "https://ipv6.google.com", "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n"); + rc = fetch(mgr, buf, "https://ipv6.google.com", + "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n"); } else { - rc = fetch(mgr, buf, "https://cesanta.com", "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n"); + rc = fetch(mgr, buf, "https://cesanta.com", + "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n"); } ASSERT(rc == 200); // OK #else if (ipv6) { - rc = fetch(mgr, buf, "http://ipv6.google.com", "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n"); + rc = fetch(mgr, buf, "http://ipv6.google.com", + "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n"); } else { - rc = fetch(mgr, buf, "http://cesanta.com", "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n"); + rc = fetch(mgr, buf, "http://cesanta.com", + "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n"); } ASSERT(rc == 301); // OK: Permanently moved (HTTP->HTTPS redirect) @@ -257,8 +264,10 @@ static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data) { mg_mqtt_pub(c, &pub_opts); } else if (ev == MG_EV_MQTT_MSG) { struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data; - MG_DEBUG(("TOPIC: %.*s, MSG: %.*s", (int) mm->topic.len, mm->topic.buf, (int) mm->data.len, mm->data.buf)); - ASSERT(mm->topic.len == strlen(s_topic) && strcmp(mm->topic.buf, s_topic) == 0); + MG_DEBUG(("TOPIC: %.*s, MSG: %.*s", (int) mm->topic.len, mm->topic.buf, + (int) mm->data.len, mm->data.buf)); + ASSERT(mm->topic.len == strlen(s_topic) && + strcmp(mm->topic.buf, s_topic) == 0); ASSERT(mm->data.len == 2 && strcmp(mm->data.buf, "hi") == 0); mg_mqtt_disconnect(c, NULL); *(bool *) c->fn_data = true; @@ -311,15 +320,18 @@ static void test_http_server(struct mg_mgr *mgr) { opts.cert = mg_unpacked("/certs/server.crt"); opts.key = mg_unpacked("/certs/server.key"); c = mg_http_listen(mgr, "https://0.0.0.0:12347", eh1, &opts); - cmd = mg_mprintf("./mip_curl.sh --insecure https://%M:12347", mg_print_ip4, &mgr->ifp->ip); + cmd = mg_mprintf("./mip_curl.sh --insecure https://%M:12347", mg_print_ip4, + &mgr->ifp->ip); #else c = mg_http_listen(mgr, "http://0.0.0.0:12347", eh1, NULL); - cmd = mg_mprintf("./mip_curl.sh http://%M:12347", mg_print_ip4, &mgr->ifp->ip); + cmd = + mg_mprintf("./mip_curl.sh http://%M:12347", mg_print_ip4, &mgr->ifp->ip); #endif ASSERT(c != NULL); - pthread_create(&thread_id, NULL, poll_thread, mgr); // simpler this way, no concurrency anyway + pthread_create(&thread_id, NULL, poll_thread, + mgr); // simpler this way, no concurrency anyway MG_DEBUG(("CURL")); - ASSERT(system(cmd) == 0); // wait for curl + ASSERT(system(cmd) == 0); // wait for curl MG_DEBUG(("MONGOOSE")); pthread_join(thread_id, NULL); // wait for Mongoose MG_DEBUG(("DONE")); @@ -329,20 +341,21 @@ static void test_http_server(struct mg_mgr *mgr) { static void test_tls(struct mg_mgr *mgr) { #if MG_TLS char *url; - char buf[FETCH_BUF_SIZE]; // make sure it can hold Makefile + char buf[FETCH_BUF_SIZE]; // make sure it can hold Makefile struct mg_str data = mg_unpacked("/Makefile"); - if (host_ip == NULL) { + if (host_ip == NULL) { MG_INFO(("No HOST_IP provided, skipping tests")); return; } MG_DEBUG(("HOST_IP: %s", host_ip)); - // - POST a large file, make sure we drain TLS buffers and read all: done at server test, using curl as POSTing client + // - POST a large file, make sure we drain TLS buffers and read all: done at + // server test, using curl as POSTing client // - Fire patched server, test multiple TLS records per TCP segment handling - url = mg_mprintf("https://%s:8443", host_ip); // for historic reasons + url = mg_mprintf("https://%s:8443", host_ip); // for historic reasons ASSERT(system("tls_multirec/server -d tls_multirec &") == 0); sleep(1); ASSERT(fetch(mgr, buf, url, "GET /thefile HTTP/1.0\n\n") == 200); - ASSERT(cmpbody(buf, data.buf) == 0); // "thefile" links to Makefile + ASSERT(cmpbody(buf, data.buf) == 0); // "thefile" links to Makefile system("killall tls_multirec/server"); free(url); #else