1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 /** \defgroup conmon Connection Latency information 26 * ## Connection Latency information 27 * 28 * When LWS_WITH_CONMON is enabled at build, collects detailed statistics 29 * about the client connection setup latency, available to the connection 30 * itself 31 */ 32 ///@{ 33 34 /* enough for 4191s, or just over an hour */ 35 typedef uint32_t lws_conmon_interval_us_t; 36 37 /* 38 * Connection latency information... note that not all wsi actually make 39 * connections, for example h2 streams after the initial one will have 0 40 * for everything except ciu_txn_resp. 41 * 42 * If represented in JSON, it should look like this 43 * 44 * { 45 * "peer": "46.105.127.147", 46 * "dns_us": 1234, 47 * "dns_disp": 1, 48 * "sockconn_us": 1234, 49 * "tls_us": 1234, 50 * "txn_resp_us": 1234, 51 * "dns":["46.105.127.147", "2001:41d0:2:ee93::1"], 52 * "prot_specific": { 53 * "protocol": "http", 54 * "resp": 200 55 * } 56 * } 57 * 58 * The indexes in "dns_disp" are declared in lws_conmon_dns_disposition_t 59 * below. 60 * 61 * "prot_specific" may not be present if the protocol doesn't have anything 62 * to report or is not supported. 63 */ 64 65 typedef enum lws_conmon_pcol { 66 LWSCONMON_PCOL_NONE, 67 LWSCONMON_PCOL_HTTP, /* .protocol_specific.http is valid */ 68 } lws_conmon_pcol_t; 69 70 typedef enum lws_conmon_dns_disposition { 71 LWSCONMON_DNS_NONE, 72 /**< did not attempt DNS */ 73 LWSCONMON_DNS_OK = 1, 74 /**< DNS lookup did give results */ 75 LWSCONMON_DNS_SERVER_UNREACHABLE = 2, 76 /**< DNS server was not reachable */ 77 LWSCONMON_DNS_NO_RESULT = 3 78 /**< DNS server replied but nothing usable */ 79 } lws_conmon_dns_disposition_t; 80 81 struct lws_conmon { 82 lws_sockaddr46 peer46; 83 /**< The peer we actually connected to, if any. .peer46.sa4.sa_family 84 * is either 0 if invalid, or the AF_ */ 85 86 union { 87 struct { 88 int response; 89 /**< h1 http response code */ 90 } http; 91 } protocol_specific; 92 /**< possibly-present protocol-specific additional information. This 93 * is only valid for the first transaction after connection and does 94 * not capture results for persistent or muxed connections like ws 95 * messages, mqtt messages, or h2 streams */ 96 97 struct addrinfo *dns_results_copy; 98 /**< NULL, or Allocated copy of dns results, owned by this object and 99 * freed when object destroyed. 100 * Only set if client flag LCCSCF_CONMON applied */ 101 102 lws_conmon_interval_us_t ciu_dns; 103 /**< 0, or if a socket connection, us taken to acquire this DNS response 104 * 105 */ 106 lws_conmon_interval_us_t ciu_sockconn; 107 /**< 0, or if connection-based, the us interval between the socket 108 * connect() attempt that succeeded, and the connection setup */ 109 lws_conmon_interval_us_t ciu_tls; 110 /**< 0 if no tls, or us taken to establish the tls tunnel */ 111 lws_conmon_interval_us_t ciu_txn_resp; 112 /**< 0, or if the protocol supports transactions, the interval between 113 * sending the initial transaction request and starting to receive the 114 * response */ 115 116 lws_conmon_pcol_t pcol; 117 /**< indicates which extra protocol_specific info member is valid, 118 * if any */ 119 120 lws_conmon_dns_disposition_t dns_disposition; 121 /**< indicates general disposition of DNS request */ 122 }; 123 124 /** 125 * lws_conmon_wsi_take() - create a connection latency object from client wsi 126 * 127 * \param context: lws wsi 128 * \param dest: conmon struct to fill 129 * 130 * Copies wsi conmon data into the caller's struct. Passes ownership of 131 * any allocations in the addrinfo list to the caller, lws will not delete that 132 * any more on wsi close after this call. The caller must call 133 * lws_conmon_release() on the struct to destroy any addrinfo in the struct 134 * that is prepared by this eventually but it can defer it as long as it wants. 135 * 136 * Other than the addrinfo list, the contents of the returned object are 137 * completely selfcontained and don't point outside of the object itself, ie, 138 * everything else in there remains in scope while the object itself does. 139 */ 140 LWS_VISIBLE LWS_EXTERN void 141 lws_conmon_wsi_take(struct lws *wsi, struct lws_conmon *dest); 142 143 /** 144 * lws_conmon_release() - free any allocations in the conmon struct 145 * 146 * \param conmon: pointer to conmon struct 147 * 148 * Destroys any allocations in the conmon struct so it can go out of scope. 149 * It doesn't free \p dest itself, it's designed to clean out a struct that 150 * is on the stack or embedded in another object. 151 */ 152 LWS_VISIBLE LWS_EXTERN void 153 lws_conmon_release(struct lws_conmon *conmon); 154 155 ///@} 156