lsquic_ev_log.c revision 2a5cd80e
1/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc.  See LICENSE. */
2#ifndef WIN32
3#include <arpa/inet.h>
4#else
5#include <vc_compat.h>
6#endif
7#include <errno.h>
8#include <inttypes.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/queue.h>
12
13#include "lsquic.h"
14#include "lsquic_types.h"
15#include "lsquic_int_types.h"
16#include "lsquic_packet_common.h"
17#include "lsquic_packet_in.h"
18#include "lsquic_packet_out.h"
19#include "lsquic_parse.h"
20#include "lsquic_frame_common.h"
21#include "lsquic_frame_reader.h"
22#include "lsquic_ev_log.h"
23
24#define LSQUIC_LOGGER_MODULE LSQLM_EVENT
25#include "lsquic_logger.h"
26
27
28/*  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  */
29/*  ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  */
30/* Messages that do not include connection ID go above this point */
31
32#define LSQUIC_LOG_CONN_ID cid
33#define LCID(...) LSQ_LOG2(LSQ_LOG_DEBUG, __VA_ARGS__)   /* LCID: log with CID */
34
35/* Messages that are to include connection ID go below this point */
36/*  ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||  */
37/*  VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV  */
38
39void
40lsquic_ev_log_packet_in (lsquic_cid_t cid, const lsquic_packet_in_t *packet_in)
41{
42    LCID("packet in: %"PRIu64, packet_in->pi_packno);
43}
44
45
46void
47lsquic_ev_log_ack_frame_in (lsquic_cid_t cid, const struct ack_info *acki)
48{
49    size_t sz;
50    char *buf;
51
52    if ((buf = acki2str(acki, &sz)))
53    {
54        LCID("ACK frame in: %.*s", (int) sz, buf);
55        free(buf);
56    }
57}
58
59
60void
61lsquic_ev_log_stream_frame_in (lsquic_cid_t cid,
62                                        const struct stream_frame *frame)
63{
64    LCID("STREAM frame in: stream %u; offset %"PRIu64"; size %"PRIu16
65        "; fin: %d", frame->stream_id, frame->data_frame.df_offset,
66        frame->data_frame.df_size, (int) frame->data_frame.df_fin);
67}
68
69
70void
71lsquic_ev_log_stop_waiting_frame_in (lsquic_cid_t cid, lsquic_packno_t least)
72{
73    LCID("STOP_WAITING frame in: least unacked packno %"PRIu64, least);
74}
75
76
77void
78lsquic_ev_log_window_update_frame_in (lsquic_cid_t cid, uint32_t stream_id,
79                                                            uint64_t offset)
80{
81    LCID("WINDOW_UPDATE frame in: stream %"PRIu32"; offset %"PRIu64,
82        stream_id, offset);
83}
84
85
86void
87lsquic_ev_log_blocked_frame_in (lsquic_cid_t cid, uint32_t stream_id)
88{
89    LCID("BLOCKED frame in: stream %"PRIu32, stream_id);
90}
91
92
93void
94lsquic_ev_log_connection_close_frame_in (lsquic_cid_t cid,
95                    uint32_t error_code, int reason_len, const char *reason)
96{
97    LCID("CONNECTION_CLOSE frame in: error code %"PRIu32", reason: %.*s",
98        error_code, reason_len, reason);
99}
100
101
102void
103lsquic_ev_log_goaway_frame_in (lsquic_cid_t cid, uint32_t error_code,
104                    uint32_t stream_id, int reason_len, const char *reason)
105{
106    LCID("GOAWAY frame in: error code %"PRIu32", stream %"PRIu32
107        ", reason: %.*s", error_code, stream_id, reason_len, reason);
108}
109
110
111void
112lsquic_ev_log_rst_stream_frame_in (lsquic_cid_t cid, uint32_t stream_id,
113                                        uint64_t offset, uint32_t error_code)
114{
115    LCID("RST_FRAME frame in: error code %"PRIu32", stream %"PRIu32
116        ", offset: %"PRIu64, error_code, stream_id, offset);
117}
118
119
120void
121lsquic_ev_log_padding_frame_in (lsquic_cid_t cid, size_t len)
122{
123    LCID("PADDING frame in of %zd bytes", len);
124}
125
126
127void
128lsquic_ev_log_ping_frame_in (lsquic_cid_t cid)
129{
130    LCID("PING frame in");
131}
132
133
134void
135lsquic_ev_log_packet_created (lsquic_cid_t cid,
136                                const struct lsquic_packet_out *packet_out)
137{
138    LCID("created packet %"PRIu64"; flags: version=%d, nonce=%d, conn_id=%d",
139        packet_out->po_packno,
140        !!(packet_out->po_flags & PO_VERSION),
141        !!(packet_out->po_flags & PO_NONCE),
142        !!(packet_out->po_flags & PO_CONN_ID));
143}
144
145
146void
147lsquic_ev_log_packet_sent (lsquic_cid_t cid,
148                                const struct lsquic_packet_out *packet_out)
149{
150    char frames[lsquic_frame_types_str_sz];
151    if (lsquic_packet_out_verneg(packet_out))
152        LCID("sent version negotiation packet, size %hu",
153                                                    packet_out->po_data_sz);
154    else if (lsquic_packet_out_pubres(packet_out))
155        LCID("sent public reset packet, size %hu", packet_out->po_data_sz);
156    else
157        LCID("sent packet %"PRIu64", size %hu, frame types: %s",
158            packet_out->po_packno, packet_out->po_enc_data_sz,
159                /* Frame types is a list of different frames types contained
160                 * in the packet, no more.  Count and order of frames is not
161                 * printed.
162                 */
163                lsquic_frame_types_to_str(frames, sizeof(frames),
164                                                packet_out->po_frame_types));
165}
166
167
168void
169lsquic_ev_log_packet_not_sent (lsquic_cid_t cid,
170                                const struct lsquic_packet_out *packet_out)
171{
172    char frames[lsquic_frame_types_str_sz];
173    LCID("unsent packet %"PRIu64", size %hu, frame types: %s",
174        packet_out->po_packno, packet_out->po_enc_data_sz,
175            /* Frame types is a list of different frames types contained in
176             * the packet, no more.  Count and order of frames is not printed.
177             */
178            lsquic_frame_types_to_str(frames, sizeof(frames),
179                                                packet_out->po_frame_types));
180}
181
182
183void
184lsquic_ev_log_http_headers_in (lsquic_cid_t cid, int is_server,
185                                        const struct uncompressed_headers *uh)
186{
187    const char *cr, *p;
188
189    if (uh->uh_flags & UH_PP)
190        LCID("read push promise; stream %"PRIu32", promised stream %"PRIu32,
191            uh->uh_stream_id, uh->uh_oth_stream_id);
192    else
193        LCID("read %s headers; stream: %"PRIu32", depends on stream: %"PRIu32
194            ", weight: %hu, exclusive: %d, fin: %d",
195            is_server ? "request" : "response",
196            uh->uh_stream_id, uh->uh_oth_stream_id, uh->uh_weight,
197            (int) uh->uh_exclusive, !!(uh->uh_flags & UH_FIN));
198
199    for (p = uh->uh_headers; p < uh->uh_headers + uh->uh_size; p = cr + 2)
200    {
201        cr = strchr(p, '\r');
202        if (cr && cr > p)
203            LCID("  %.*s", (int) (cr - p), p);
204        else
205            break;
206    }
207}
208
209
210void
211lsquic_ev_log_action_stream_frame (lsquic_cid_t cid,
212    const struct parse_funcs *pf, const unsigned char *buf, size_t bufsz,
213    const char *what)
214{
215    struct stream_frame frame;
216    int len;
217
218    len = pf->pf_parse_stream_frame(buf, bufsz, &frame);
219    if (len > 0)
220        LCID("%s STREAM frame: stream %"PRIu32", offset: %"PRIu64
221            ", size: %"PRIu16", fin: %d", what, frame.stream_id,
222            frame.data_frame.df_offset, frame.data_frame.df_size,
223            frame.data_frame.df_fin);
224    else
225        LSQ_LOG2(LSQ_LOG_WARN, "cannot parse STREAM frame");
226}
227
228
229void
230lsquic_ev_log_generated_ack_frame (lsquic_cid_t cid, const struct parse_funcs *pf,
231                                   const unsigned char *ack_buf, size_t ack_buf_sz)
232{
233    struct ack_info acki;
234    size_t sz;
235    char *buf;
236    int len;
237
238    len = pf->pf_parse_ack_frame(ack_buf, ack_buf_sz, &acki);
239    if (len < 0)
240    {
241        LSQ_LOG2(LSQ_LOG_WARN, "cannot parse ACK frame");
242        return;
243    }
244
245    if ((buf = acki2str(&acki, &sz)))
246    {
247        LCID("generated ACK frame: %.*s", (int) sz, buf);
248        free(buf);
249    }
250}
251
252
253void
254lsquic_ev_log_generated_stop_waiting_frame (lsquic_cid_t cid,
255                                            lsquic_packno_t lunack)
256{
257    LCID("generated STOP_WAITING frame; least unacked: %"PRIu64, lunack);
258}
259
260
261void
262lsquic_ev_log_generated_http_headers (lsquic_cid_t cid, uint32_t stream_id,
263                    int is_server, const struct http_prio_frame *prio_frame,
264                    const struct lsquic_http_headers *headers)
265{
266    uint32_t dep_stream_id;
267    int exclusive, i;
268    unsigned short weight;
269
270    if (is_server)
271        LCID("generated HTTP response HEADERS for stream %"PRIu32, stream_id);
272    else
273    {
274        memcpy(&dep_stream_id, prio_frame->hpf_stream_id, 4);
275        dep_stream_id = htonl(dep_stream_id);
276        exclusive = dep_stream_id >> 31;
277        dep_stream_id &= ~(1 << 31);
278        weight = prio_frame->hpf_weight + 1;
279        LCID("generated HTTP request HEADERS for stream %"PRIu32
280            ", dep stream: %"PRIu32", weight: %hu, exclusive: %d", stream_id,
281            dep_stream_id, weight, exclusive);
282    }
283
284    for (i = 0; i < headers->count; ++i)
285        LCID("  %.*s: %.*s",
286            (int)    headers->headers[i].name.iov_len,
287            (char *) headers->headers[i].name.iov_base,
288            (int)    headers->headers[i].value.iov_len,
289            (char *) headers->headers[i].value.iov_base);
290}
291
292
293void
294lsquic_ev_log_generated_http_push_promise (lsquic_cid_t cid,
295                            uint32_t stream_id, uint32_t promised_stream_id,
296                            const struct lsquic_http_headers *headers,
297                            const struct lsquic_http_headers *extra_headers)
298{
299    int i;
300
301    LCID("generated HTTP PUSH_PROMISE for stream %"PRIu32"; promised stream %"
302        PRIu32, stream_id, promised_stream_id);
303
304    for (i = 0; i < headers->count; ++i)
305        LCID("  %.*s: %.*s",
306            (int)    headers->headers[i].name.iov_len,
307            (char *) headers->headers[i].name.iov_base,
308            (int)    headers->headers[i].value.iov_len,
309            (char *) headers->headers[i].value.iov_base);
310
311    if (extra_headers)
312        for (i = 0; i < extra_headers->count; ++i)
313            LCID("  %.*s: %.*s",
314                (int)    extra_headers->headers[i].name.iov_len,
315                (char *) extra_headers->headers[i].name.iov_base,
316                (int)    extra_headers->headers[i].value.iov_len,
317                (char *) extra_headers->headers[i].value.iov_base);
318}
319
320
321