diff --git a/include/libwebsockets/lws-conmon.h b/include/libwebsockets/lws-conmon.h index 2e25f8c3d..12a0eec75 100644 --- a/include/libwebsockets/lws-conmon.h +++ b/include/libwebsockets/lws-conmon.h @@ -31,7 +31,7 @@ */ ///@{ -/* enough for 4191us, or just over an hour */ +/* enough for 4191s, or just over an hour */ typedef uint32_t lws_conmon_interval_us_t; /* @@ -44,18 +44,56 @@ typedef uint32_t lws_conmon_interval_us_t; * { * "peer": "46.105.127.147", * "dns_us": 1234, + * "dns_disp": 1, * "sockconn_us": 1234, * "tls_us": 1234, * "txn_resp_us": 1234, - * "dns":["46.105.127.147", "2001:41d0:2:ee93::1"] + * "dns":["46.105.127.147", "2001:41d0:2:ee93::1"], + * "prot_specific": { + * "protocol": "http", + * "resp": 200 + * } * } + * + * The indexes in "dns_disp" are declared in lws_conmon_dns_disposition_t + * below. + * + * "prot_specific" may not be present if the protocol doesn't have anything + * to report or is not supported. */ +typedef enum lws_conmon_pcol { + LWSCONMON_PCOL_NONE, + LWSCONMON_PCOL_HTTP, /* .protocol_specific.http is valid */ +} lws_conmon_pcol_t; + +typedef enum lws_conmon_dns_disposition { + LWSCONMON_DNS_NONE, + /**< did not attempt DNS */ + LWSCONMON_DNS_OK = 1, + /**< DNS lookup did give results */ + LWSCONMON_DNS_SERVER_UNREACHABLE = 2, + /**< DNS server was not reachable */ + LWSCONMON_DNS_NO_RESULT = 3 + /**< DNS server replied but nothing usable */ +} lws_conmon_dns_disposition_t; + struct lws_conmon { lws_sockaddr46 peer46; /**< The peer we actually connected to, if any. .peer46.sa4.sa_family * is either 0 if invalid, or the AF_ */ + union { + struct { + int response; + /**< h1 http response code */ + } http; + } protocol_specific; + /**< possibly-present protocol-specific additional information. This + * is only valid for the first transaction after connection and does + * not capture results for persistent or muxed connections like ws + * messages, mqtt messages, or h2 streams */ + struct addrinfo *dns_results_copy; /**< NULL, or Allocated copy of dns results, owned by this object and * freed when object destroyed. @@ -72,7 +110,15 @@ struct lws_conmon { /**< 0 if no tls, or us taken to establish the tls tunnel */ lws_conmon_interval_us_t ciu_txn_resp; /**< 0, or if the protocol supports transactions, the interval between - * sending the transaction request and starting to receive the resp */ + * sending the initial transaction request and starting to receive the + * response */ + + lws_conmon_pcol_t pcol; + /**< indicates which extra protocol_specific info member is valid, + * if any */ + + lws_conmon_dns_disposition_t dns_disposition; + /**< indicates general disposition of DNS request */ }; /** diff --git a/lib/core-net/client/connect2.c b/lib/core-net/client/connect2.c index 701fa11a7..2caf87bd9 100644 --- a/lib/core-net/client/connect2.c +++ b/lib/core-net/client/connect2.c @@ -93,9 +93,6 @@ lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result) || n == EAI_AGAIN #endif ) { -#if defined(LWS_WITH_SECURE_STREAMS) - -#endif wsi->dns_reachability = 1; lws_metrics_caliper_report(cal, METRES_NOGO); #if defined(LWS_WITH_SYS_METRICS) @@ -103,6 +100,10 @@ lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result) lws_metrics_hist_bump_priv_wsi(wsi, mth_conn_failures, buckname); #endif +#if defined(LWS_WITH_CONMON) + wsi->conmon.dns_disposition = LWSCONMON_DNS_SERVER_UNREACHABLE; +#endif + #if 0 lwsl_wsi_debug(wsi, "asking to recheck CPD in 1s"); lws_system_cpd_start_defer(wsi->a.context, LWS_US_PER_SEC); @@ -117,6 +118,10 @@ lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result) lws_metrics_hist_bump_priv_wsi(wsi, mth_conn_failures, buckname); } #endif +#if defined(LWS_WITH_CONMON) + wsi->conmon.dns_disposition = n < 0 ? LWSCONMON_DNS_NO_RESULT : + LWSCONMON_DNS_OK; +#endif lws_metrics_caliper_report(cal, n >= 0 ? METRES_GO : METRES_NOGO); diff --git a/lib/secure-streams/protocols/ss-h1.c b/lib/secure-streams/protocols/ss-h1.c index fa90fe1fe..9a73a6aa9 100644 --- a/lib/secure-streams/protocols/ss-h1.c +++ b/lib/secure-streams/protocols/ss-h1.c @@ -548,6 +548,12 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, lws_ss_assert_extant(wsi->a.context, wsi->tsi, h); #if defined(LWS_WITH_CONMON) + if (wsi->conmon.pcol == LWSCONMON_PCOL_NONE) { + wsi->conmon.pcol = LWSCONMON_PCOL_HTTP; + wsi->conmon.protocol_specific.http.response = + (int)lws_http_client_http_response(wsi); + } + lws_conmon_ss_json(h); #endif diff --git a/lib/secure-streams/secure-streams.c b/lib/secure-streams/secure-streams.c index 801edaa56..cfa355210 100644 --- a/lib/secure-streams/secure-streams.c +++ b/lib/secure-streams/secure-streams.c @@ -213,12 +213,14 @@ lws_conmon_ss_json(lws_ss_handle_t *h) buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "{\"peer\":\"%s\"," "\"dns_us\":%u," + "\"dns_disp\":%u," "\"sockconn_us\":%u," "\"tls_us\":%u," "\"txn_resp_us\":%u," "\"dns\":[", ads, (unsigned int)cm.ciu_dns, + (unsigned int)cm.dns_disposition, (unsigned int)cm.ciu_sockconn, (unsigned int)cm.ciu_tls, (unsigned int)cm.ciu_txn_resp); @@ -232,7 +234,19 @@ lws_conmon_ss_json(lws_ss_handle_t *h) ai = ai->ai_next; } - buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "]}"); + buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "]"); + + switch (cm.pcol) { + case LWSCONMON_PCOL_HTTP: + buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), + ",\"prot_specific\":{\"protocol\":\"http\",\"resp\":%u}", + (unsigned int)cm.protocol_specific.http.response); + break; + default: + break; + } + + buf += lws_snprintf(buf, lws_ptr_diff_size_t(end, buf), "}"); /* * This destroys the DNS list in the lws_conmon that we took