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 */
35typedef 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
65typedef enum lws_conmon_pcol {
66 LWSCONMON_PCOL_NONE,
67 LWSCONMON_PCOL_HTTP, /* .protocol_specific.http is valid */
68} lws_conmon_pcol_t;
69
70typedef 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
81struct 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 */
140LWS_VISIBLE LWS_EXTERN void
141lws_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 */
152LWS_VISIBLE LWS_EXTERN void
153lws_conmon_release(struct lws_conmon *conmon);
154
155///@}
156