• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 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  * included from libwebsockets.h
25  */
26 
27 enum {
28 
29 	/* types of latency, all nonblocking except name resolution */
30 
31 	LDLT_READ,	/* time taken to read LAT_DUR_PROXY_RX_TO_CLIENT_WRITE */
32 	LDLT_WRITE,
33 	LDLT_NAME_RESOLUTION, /* BLOCKING: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
34 	LDLT_CONNECTION, /* conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
35 	LDLT_TLS_NEG_CLIENT, /* tls conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
36 	LDLT_TLS_NEG_SERVER, /* tls conn duration: LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE */
37 
38 	LDLT_USER,
39 
40 	/* interval / duration elements in latencies array */
41 
42 	LAT_DUR_PROXY_CLIENT_REQ_TO_WRITE				= 0,
43 		/* us the client spent waiting to write to proxy */
44 	LAT_DUR_PROXY_CLIENT_WRITE_TO_PROXY_RX,
45 		/* us the packet took to be received by proxy */
46 	LAT_DUR_PROXY_PROXY_REQ_TO_WRITE,
47 		/* us the proxy has to wait before it could write */
48 	LAT_DUR_PROXY_RX_TO_ONWARD_TX,
49 		/* us the proxy spent waiting to write to destination, or
50 		 * if nonproxied, then time between write request and write */
51 
52 	LAT_DUR_USERCB, /* us duration of user callback */
53 
54 	LAT_DUR_STEPS /* last */
55 };
56 
57 typedef struct lws_detlat {
58 	lws_usec_t		earliest_write_req;
59 	lws_usec_t		earliest_write_req_pre_write;
60 		/**< use this for interval comparison */
61 	const char		*aux; /* name for name resolution timing */
62 	int			type;
63 	uint32_t		latencies[LAT_DUR_STEPS];
64 	size_t			req_size;
65 	size_t			acc_size;
66 } lws_detlat_t;
67 
68 typedef int (*det_lat_buf_cb_t)(struct lws_context *context,
69 				const lws_detlat_t *d);
70 
71 /**
72  * lws_det_lat_cb() - inject your own latency records
73  *
74  * \param context: the lws_context
75  * \param d: the lws_detlat_t you have prepared
76  *
77  * For proxying or similar cases where latency information is available from
78  * user code rather than lws itself, you can generate your own latency callback
79  * events with your own lws_detlat_t.
80  */
81 
82 LWS_VISIBLE LWS_EXTERN int
83 lws_det_lat_cb(struct lws_context *context, lws_detlat_t *d);
84 
85 /*
86  * detailed_latency_plot_cb() - canned save to file in plottable format cb
87  *
88  * \p context: the lws_context
89  * \p d: the detailed latency event information
90  *
91  * This canned callback makes it easy to export the detailed latency information
92  * to a file.  Just set the context creation members like this
93  *
94  * #if defined(LWS_WITH_DETAILED_LATENCY)
95  *	info.detailed_latency_cb = lws_det_lat_plot_cb;
96  *	info.detailed_latency_filepath = "/tmp/lws-latency-results";
97  * #endif
98  *
99  * and you will get a file containing information like this
100  *
101  * 718823864615 N 10589 0 0 10589 0 0 0
102  * 718823880837 C 16173 0 0 16173 0 0 0
103  * 718823913063 T 32212 0 0 32212 0 0 0
104  * 718823931835 r 0 0 0 0 232 30 256
105  * 718823948757 r 0 0 0 0 40 30 256
106  * 718823948799 r 0 0 0 0 83 30 256
107  * 718823965602 r 0 0 0 0 27 30 256
108  * 718823965617 r 0 0 0 0 43 30 256
109  * 718823965998 r 0 0 0 0 12 28 256
110  * 718823983887 r 0 0 0 0 74 3 4096
111  * 718823986411 w 16 87 7 110 9 80 80
112  * 718824006358 w 8 68 6 82 6 80 80
113  *
114  * which is easy to grep and pass to gnuplot.
115  *
116  * The columns are
117  *
118  *  - unix time in us
119  *  - N = Name resolution, C = TCP Connection, T = TLS negotiation server,
120  *    t = TLS negotiation client, r = Read, w = Write
121  *  - us duration, for w time client spent waiting to write
122  *  - us duration, for w time data spent in transit to proxy
123  *  - us duration, for w time proxy waited to send data
124  *  - as a convenience, sum of last 3 columns above
125  *  - us duration, time spent in callback
126  *  - last 2 are actual / requested size in bytes
127  */
128 LWS_VISIBLE LWS_EXTERN int
129 lws_det_lat_plot_cb(struct lws_context *context, const lws_detlat_t *d);
130 
131 /**
132  * lws_det_lat_active() - indicates if latencies are being measured
133  *
134  * \context: lws_context
135  *
136  * Returns 0 if latency measurement has not been set up (the callback is NULL).
137  * Otherwise returns 1
138  */
139 LWS_VISIBLE LWS_EXTERN int
140 lws_det_lat_active(struct lws_context *context);
141