minimize elusive ARP lookup failure

This commit is contained in:
Sergio R. Caprile committed 2025-01-23 14:33:28 -03:00
1 parent 1a3588624d
commit 8d4a619a15
1 file changed
+44 -31
+44 -31
View File
@@ -5,7 +5,6 @@
#define FETCH_BUF_SIZE (16 * 1024)
#include <sys/socket.h>
#ifndef __OpenBSD__
#include <linux/if.h>
@@ -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