55
66#define FETCH_BUF_SIZE (16 * 1024)
77
8-
98#include <sys/socket.h>
109#ifndef __OpenBSD__
1110#include <linux/if.h>
2120
2221#include "driver_mock.c"
2322
24-
25- #define MQTT_URL "mqtt://broker.hivemq.com:1883" // MQTT broker URL
23+ #define MQTT_URL "mqtt://broker.hivemq.com:1883" // MQTT broker URL
2624#if MG_TLS == MG_TLS_BUILTIN
27- #define MQTTS_URL "mqtts://mongoose.ws:8883" // HiveMQ does not do TLS1.3
25+ #define MQTTS_URL "mqtts://mongoose.ws:8883" // HiveMQ does not do TLS1.3
2826#define MQTTS_CA mg_str(s_ca_cert)
2927static const char * s_ca_cert =
3028 "-----BEGIN CERTIFICATE-----\n"
@@ -59,18 +57,17 @@ static const char *s_ca_cert =
5957 "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n"
6058 "-----END CERTIFICATE-----\n" ;
6159#elif MG_TLS
62- #define MQTTS_URL "mqtts://broker.hivemq.com:8883" // MQTT broker URL
60+ #define MQTTS_URL "mqtts://broker.hivemq.com:8883" // MQTT broker URL
6361#define MQTTS_CA mg_unpacked("/data/ca.pem")
6462#endif
6563
66-
6764static char * host_ip ;
6865
6966static int s_num_tests = 0 ;
7067
71- #define ABORT () \
72- usleep(500000); /* 500 ms, GH print reason */ \
73- abort ();
68+ #define ABORT () \
69+ usleep(500000); /* 500 ms, GH print reason */ \
70+ abort ();
7471
7572#define ASSERT (expr ) \
7673 do { \
@@ -96,7 +93,6 @@ static int cmpbody(const char *buf, const char *str) {
9693 return mg_strcmp (hm .body , s );
9794}
9895
99-
10096// MIP TUNTAP driver
10197static size_t tap_rx (void * buf , size_t len , struct mg_tcpip_if * ifp ) {
10298 ssize_t received = read (* (int * ) ifp -> driver_data , buf , len );
@@ -118,14 +114,14 @@ static bool tap_up(struct mg_tcpip_if *ifp) {
118114 return ifp -> driver_data ? true : false;
119115}
120116
121-
122117static void eh1 (struct mg_connection * c , int ev , void * ev_data ) {
123118 struct mg_tls_opts * topts = (struct mg_tls_opts * ) c -> fn_data ;
124119 if (ev == MG_EV_ACCEPT && topts != NULL ) mg_tls_init (c , topts );
125120 if (ev == MG_EV_HTTP_MSG ) {
126121 struct mg_http_message * hm = (struct mg_http_message * ) ev_data ;
127- MG_DEBUG (("[%.*s %.*s] message len %d" , (int ) hm -> method .len , hm -> method .buf ,
128- (int ) hm -> uri .len , hm -> uri .buf , (int ) hm -> message .len ));
122+ MG_DEBUG (("[%.*s %.*s] message len %d" , (int ) hm -> method .len ,
123+ hm -> method .buf , (int ) hm -> uri .len , hm -> uri .buf ,
124+ (int ) hm -> message .len ));
129125 if (mg_match (hm -> uri , mg_str ("/foo/*" ), NULL )) {
130126 mg_http_reply (c , 200 , "" , "uri: %.*s" , hm -> uri .len - 5 , hm -> uri .buf + 5 );
131127 } 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) {
171167 }
172168 } else if (ev == MG_EV_HTTP_MSG ) {
173169 struct mg_http_message * hm = (struct mg_http_message * ) ev_data ;
174- snprintf (fd -> buf , FETCH_BUF_SIZE , "%.*s" , (int ) hm -> message .len , hm -> message .buf );
170+ snprintf (fd -> buf , FETCH_BUF_SIZE , "%.*s" , (int ) hm -> message .len ,
171+ hm -> message .buf );
175172 fd -> code = atoi (hm -> uri .buf );
176173 fd -> closed = 1 ;
177174 c -> is_closing = 1 ;
178- MG_DEBUG (("CODE: %d, MSG: %.*s" , fd -> code , (int ) hm -> message .len , hm -> message .buf ));
175+ MG_DEBUG (("CODE: %d, MSG: %.*s" , fd -> code , (int ) hm -> message .len ,
176+ hm -> message .buf ));
179177 (void ) c ;
180178 } else if (ev == MG_EV_CLOSE ) {
181179 MG_DEBUG (("CLOSE" ));
@@ -192,6 +190,8 @@ static int fetch(struct mg_mgr *mgr, char *buf, const char *url,
192190 int i ;
193191 struct mg_connection * c = NULL ;
194192 va_list ap ;
193+ mg_mgr_poll (mgr , 0 ); // update ifp->now to avoid ARP lookup using an old
194+ // timestamp (from an ancient call in other test)
195195 c = mg_http_connect (mgr , url , fcb , & fd );
196196 ASSERT (c != NULL );
197197 va_start (ap , fmt );
@@ -200,7 +200,10 @@ static int fetch(struct mg_mgr *mgr, char *buf, const char *url,
200200 buf [0 ] = '\0' ;
201201 for (i = 0 ; i < 500 && buf [0 ] == '\0' && !fd .closed ; i ++ ) {
202202 mg_mgr_poll (mgr , 0 );
203- usleep (10000 ); // 10 ms. Slow down poll loop to ensure packet transit
203+ usleep (5000 ); // 5 ms. Slow down poll loop to ensure packet transit, but
204+ // allow enough loops to get the ARP response, otherwise,
205+ // given enough traffic, the timer expires before we get a
206+ // chance to see the response
204207 }
205208 if (!fd .closed ) c -> is_closing = 1 ;
206209 mg_mgr_poll (mgr , 0 );
@@ -213,16 +216,20 @@ static void test_http_client(struct mg_mgr *mgr) {
213216 const bool ipv6 = 0 ;
214217#if MG_TLS
215218 if (ipv6 ) {
216- rc = fetch (mgr , buf , "https://ipv6.google.com" , "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n" );
219+ rc = fetch (mgr , buf , "https://ipv6.google.com" ,
220+ "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n" );
217221 } else {
218- rc = fetch (mgr , buf , "https://cesanta.com" , "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n" );
222+ rc = fetch (mgr , buf , "https://cesanta.com" ,
223+ "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n" );
219224 }
220225 ASSERT (rc == 200 ); // OK
221226#else
222227 if (ipv6 ) {
223- rc = fetch (mgr , buf , "http://ipv6.google.com" , "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n" );
228+ rc = fetch (mgr , buf , "http://ipv6.google.com" ,
229+ "GET / HTTP/1.0\r\nHost: ipv6.google.com\r\n\r\n" );
224230 } else {
225- rc = fetch (mgr , buf , "http://cesanta.com" , "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n" );
231+ rc = fetch (mgr , buf , "http://cesanta.com" ,
232+ "GET /robots.txt HTTP/1.0\r\nHost: cesanta.com\r\n\r\n" );
226233 }
227234 ASSERT (rc == 301 ); // OK: Permanently moved (HTTP->HTTPS redirect)
228235
@@ -257,8 +264,10 @@ static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data) {
257264 mg_mqtt_pub (c , & pub_opts );
258265 } else if (ev == MG_EV_MQTT_MSG ) {
259266 struct mg_mqtt_message * mm = (struct mg_mqtt_message * ) ev_data ;
260- MG_DEBUG (("TOPIC: %.*s, MSG: %.*s" , (int ) mm -> topic .len , mm -> topic .buf , (int ) mm -> data .len , mm -> data .buf ));
261- ASSERT (mm -> topic .len == strlen (s_topic ) && strcmp (mm -> topic .buf , s_topic ) == 0 );
267+ MG_DEBUG (("TOPIC: %.*s, MSG: %.*s" , (int ) mm -> topic .len , mm -> topic .buf ,
268+ (int ) mm -> data .len , mm -> data .buf ));
269+ ASSERT (mm -> topic .len == strlen (s_topic ) &&
270+ strcmp (mm -> topic .buf , s_topic ) == 0 );
262271 ASSERT (mm -> data .len == 2 && strcmp (mm -> data .buf , "hi" ) == 0 );
263272 mg_mqtt_disconnect (c , NULL );
264273 * (bool * ) c -> fn_data = true;
@@ -311,15 +320,18 @@ static void test_http_server(struct mg_mgr *mgr) {
311320 opts .cert = mg_unpacked ("/certs/server.crt" );
312321 opts .key = mg_unpacked ("/certs/server.key" );
313322 c = mg_http_listen (mgr , "https://0.0.0.0:12347" , eh1 , & opts );
314- cmd = mg_mprintf ("./mip_curl.sh --insecure https://%M:12347" , mg_print_ip4 , & mgr -> ifp -> ip );
323+ cmd = mg_mprintf ("./mip_curl.sh --insecure https://%M:12347" , mg_print_ip4 ,
324+ & mgr -> ifp -> ip );
315325#else
316326 c = mg_http_listen (mgr , "http://0.0.0.0:12347" , eh1 , NULL );
317- cmd = mg_mprintf ("./mip_curl.sh http://%M:12347" , mg_print_ip4 , & mgr -> ifp -> ip );
327+ cmd =
328+ mg_mprintf ("./mip_curl.sh http://%M:12347" , mg_print_ip4 , & mgr -> ifp -> ip );
318329#endif
319330 ASSERT (c != NULL );
320- pthread_create (& thread_id , NULL , poll_thread , mgr ); // simpler this way, no concurrency anyway
331+ pthread_create (& thread_id , NULL , poll_thread ,
332+ mgr ); // simpler this way, no concurrency anyway
321333 MG_DEBUG (("CURL" ));
322- ASSERT (system (cmd ) == 0 ); // wait for curl
334+ ASSERT (system (cmd ) == 0 ); // wait for curl
323335 MG_DEBUG (("MONGOOSE" ));
324336 pthread_join (thread_id , NULL ); // wait for Mongoose
325337 MG_DEBUG (("DONE" ));
@@ -329,20 +341,21 @@ static void test_http_server(struct mg_mgr *mgr) {
329341static void test_tls (struct mg_mgr * mgr ) {
330342#if MG_TLS
331343 char * url ;
332- char buf [FETCH_BUF_SIZE ]; // make sure it can hold Makefile
344+ char buf [FETCH_BUF_SIZE ]; // make sure it can hold Makefile
333345 struct mg_str data = mg_unpacked ("/Makefile" );
334- if (host_ip == NULL ) {
346+ if (host_ip == NULL ) {
335347 MG_INFO (("No HOST_IP provided, skipping tests" ));
336348 return ;
337349 }
338350 MG_DEBUG (("HOST_IP: %s" , host_ip ));
339- // - POST a large file, make sure we drain TLS buffers and read all: done at server test, using curl as POSTing client
351+ // - POST a large file, make sure we drain TLS buffers and read all: done at
352+ // server test, using curl as POSTing client
340353 // - Fire patched server, test multiple TLS records per TCP segment handling
341- url = mg_mprintf ("https://%s:8443" , host_ip ); // for historic reasons
354+ url = mg_mprintf ("https://%s:8443" , host_ip ); // for historic reasons
342355 ASSERT (system ("tls_multirec/server -d tls_multirec &" ) == 0 );
343356 sleep (1 );
344357 ASSERT (fetch (mgr , buf , url , "GET /thefile HTTP/1.0\n\n" ) == 200 );
345- ASSERT (cmpbody (buf , data .buf ) == 0 ); // "thefile" links to Makefile
358+ ASSERT (cmpbody (buf , data .buf ) == 0 ); // "thefile" links to Makefile
346359 system ("killall tls_multirec/server" );
347360 free (url );
348361#else
0 commit comments