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 | |