Coverage Report

Created: 2026-08-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/ssl/quic/qlog_event_helpers.c
Line
Count
Source
1
/*
2
 * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <stdio.h>
11
12
#include "internal/qlog_event_helpers.h"
13
#include "internal/common.h"
14
#include "internal/packet.h"
15
#include "internal/quic_channel.h"
16
#include "internal/quic_error.h"
17
18
void ossl_qlog_event_connectivity_connection_started(QLOG *qlog,
19
    const QUIC_CONN_ID *init_dcid)
20
0
{
21
0
#ifndef OPENSSL_NO_QLOG
22
0
    QLOG_EVENT_BEGIN(qlog, connectivity, connection_started)
23
0
    QLOG_STR("protocol", "quic");
24
0
    QLOG_CID("dst_cid", init_dcid);
25
0
    QLOG_EVENT_END()
26
0
#endif
27
0
}
28
29
#ifndef OPENSSL_NO_QLOG
30
static const char *map_state_to_qlog(uint32_t state,
31
    int handshake_complete,
32
    int handshake_confirmed)
33
0
{
34
0
    switch (state) {
35
0
    default:
36
0
    case QUIC_CHANNEL_STATE_IDLE:
37
0
        return NULL;
38
39
0
    case QUIC_CHANNEL_STATE_ACTIVE:
40
0
        if (handshake_confirmed)
41
0
            return "handshake_confirmed";
42
0
        else if (handshake_complete)
43
0
            return "handshake_complete";
44
0
        else
45
0
            return "attempted";
46
47
0
    case QUIC_CHANNEL_STATE_TERMINATING_CLOSING:
48
0
        return "closing";
49
50
0
    case QUIC_CHANNEL_STATE_TERMINATING_DRAINING:
51
0
        return "draining";
52
53
0
    case QUIC_CHANNEL_STATE_TERMINATED:
54
0
        return "closed";
55
0
    }
56
0
}
57
#endif
58
59
void ossl_qlog_event_connectivity_connection_state_updated(QLOG *qlog,
60
    uint32_t old_state,
61
    uint32_t new_state,
62
    int handshake_complete,
63
    int handshake_confirmed)
64
0
{
65
0
#ifndef OPENSSL_NO_QLOG
66
0
    const char *state_s;
67
68
0
    QLOG_EVENT_BEGIN(qlog, connectivity, connection_state_updated)
69
0
    state_s = map_state_to_qlog(new_state,
70
0
        handshake_complete,
71
0
        handshake_confirmed);
72
73
0
    if (state_s != NULL)
74
0
        QLOG_STR("state", state_s);
75
0
    QLOG_EVENT_END()
76
0
#endif
77
0
}
78
79
#ifndef OPENSSL_NO_QLOG
80
static const char *quic_err_to_qlog(uint64_t error_code)
81
0
{
82
0
    switch (error_code) {
83
0
    case OSSL_QUIC_ERR_INTERNAL_ERROR:
84
0
        return "internal_error";
85
0
    case OSSL_QUIC_ERR_CONNECTION_REFUSED:
86
0
        return "connection_refused";
87
0
    case OSSL_QUIC_ERR_FLOW_CONTROL_ERROR:
88
0
        return "flow_control_error";
89
0
    case OSSL_QUIC_ERR_STREAM_LIMIT_ERROR:
90
0
        return "stream_limit_error";
91
0
    case OSSL_QUIC_ERR_STREAM_STATE_ERROR:
92
0
        return "stream_state_error";
93
0
    case OSSL_QUIC_ERR_FINAL_SIZE_ERROR:
94
0
        return "final_size_error";
95
0
    case OSSL_QUIC_ERR_FRAME_ENCODING_ERROR:
96
0
        return "frame_encoding_error";
97
0
    case OSSL_QUIC_ERR_TRANSPORT_PARAMETER_ERROR:
98
0
        return "transport_parameter_error";
99
0
    case OSSL_QUIC_ERR_CONNECTION_ID_LIMIT_ERROR:
100
0
        return "connection_id_limit_error";
101
0
    case OSSL_QUIC_ERR_PROTOCOL_VIOLATION:
102
0
        return "protocol_violation";
103
0
    case OSSL_QUIC_ERR_INVALID_TOKEN:
104
0
        return "invalid_token";
105
0
    case OSSL_QUIC_ERR_APPLICATION_ERROR:
106
0
        return "application_error";
107
0
    case OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED:
108
0
        return "crypto_buffer_exceeded";
109
0
    case OSSL_QUIC_ERR_KEY_UPDATE_ERROR:
110
0
        return "key_update_error";
111
0
    case OSSL_QUIC_ERR_AEAD_LIMIT_REACHED:
112
0
        return "aead_limit_reached";
113
0
    case OSSL_QUIC_ERR_NO_VIABLE_PATH:
114
0
        return "no_viable_path";
115
0
    default:
116
0
        return NULL;
117
0
    }
118
0
}
119
#endif
120
121
void ossl_qlog_event_connectivity_connection_closed(QLOG *qlog,
122
    const QUIC_TERMINATE_CAUSE *tcause)
123
0
{
124
0
#ifndef OPENSSL_NO_QLOG
125
0
    QLOG_EVENT_BEGIN(qlog, connectivity, connection_closed)
126
0
    QLOG_STR("owner", tcause->remote ? "remote" : "local");
127
0
    if (tcause->app) {
128
0
        QLOG_U64("application_code", tcause->error_code);
129
0
    } else {
130
0
        const char *m = quic_err_to_qlog(tcause->error_code);
131
0
        char ce[32];
132
133
0
        if (tcause->error_code >= OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN
134
0
            && tcause->error_code <= OSSL_QUIC_ERR_CRYPTO_ERR_END) {
135
0
            snprintf(ce, sizeof(ce), "crypto_error_0x%03llx",
136
0
                (unsigned long long)tcause->error_code);
137
0
            m = ce;
138
0
        }
139
        /* TODO(QLOG FUTURE): Consider adding ERR information in the output. */
140
141
0
        if (m != NULL)
142
0
            QLOG_STR("connection_code", m);
143
0
        else
144
0
            QLOG_U64("connection_code", tcause->error_code);
145
0
    }
146
147
0
    QLOG_STR_LEN("reason", tcause->reason, tcause->reason_len);
148
0
    QLOG_EVENT_END()
149
0
#endif
150
0
}
151
152
#ifndef OPENSSL_NO_QLOG
153
static const char *quic_pkt_type_to_qlog(uint32_t pkt_type)
154
0
{
155
0
    switch (pkt_type) {
156
0
    case QUIC_PKT_TYPE_INITIAL:
157
0
        return "initial";
158
0
    case QUIC_PKT_TYPE_HANDSHAKE:
159
0
        return "handshake";
160
0
    case QUIC_PKT_TYPE_0RTT:
161
0
        return "0RTT";
162
0
    case QUIC_PKT_TYPE_1RTT:
163
0
        return "1RTT";
164
0
    case QUIC_PKT_TYPE_VERSION_NEG:
165
0
        return "version_negotiation";
166
0
    case QUIC_PKT_TYPE_RETRY:
167
0
        return "retry";
168
0
    default:
169
0
        return "unknown";
170
0
    }
171
0
}
172
#endif
173
174
void ossl_qlog_event_recovery_packet_lost(QLOG *qlog,
175
    const QUIC_TXPIM_PKT *tpkt)
176
0
{
177
0
#ifndef OPENSSL_NO_QLOG
178
0
    QLOG_EVENT_BEGIN(qlog, recovery, packet_lost)
179
0
    QLOG_BEGIN("header")
180
0
    QLOG_STR("packet_type", quic_pkt_type_to_qlog(tpkt->pkt_type));
181
0
    if (ossl_quic_pkt_type_has_pn(tpkt->pkt_type))
182
0
        QLOG_U64("packet_number", tpkt->ackm_pkt.pkt_num);
183
0
    QLOG_END()
184
0
    QLOG_EVENT_END()
185
0
#endif
186
0
}
187
188
#ifndef OPENSSL_NO_QLOG
189
#define MAX_ACK_RANGES 32
190
191
0
static void ignore_res(int x) { }
192
193
/*
194
 * For logging received packets, we need to parse all the frames in the packet
195
 * to log them. We should do this separately to the RXDP code because we want to
196
 * log the packet and its contents before we start to actually process it in
197
 * case it causes an error. We also in general don't want to do other
198
 * non-logging related work in the middle of an event logging transaction.
199
 * Reparsing packet data allows us to meet these needs while avoiding the need
200
 * to keep around bookkeeping data on what frames were in a packet, etc.
201
 *
202
 * For logging transmitted packets, we actually reuse the same code and reparse
203
 * the outgoing packet's payload. This again has the advantage that we only log
204
 * a packet when it is actually queued for transmission (and not if something
205
 * goes wrong before then) while avoiding the need to keep around bookkeeping
206
 * data on what frames it contained.
207
 */
208
static int log_frame_actual(QLOG *qlog_instance, PACKET *pkt,
209
    size_t *need_skip)
210
0
{
211
0
    uint64_t frame_type;
212
0
    OSSL_QUIC_FRAME_ACK ack;
213
0
    OSSL_QUIC_ACK_RANGE ack_ranges[MAX_ACK_RANGES];
214
0
    uint64_t num_ranges, total_ranges;
215
0
    size_t i;
216
0
    PACKET orig_pkt = *pkt;
217
218
0
    if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, NULL)) {
219
0
        *need_skip = SIZE_MAX;
220
0
        return 0;
221
0
    }
222
223
    /*
224
     * If something goes wrong decoding a frame we cannot log it as that frame
225
     * as we need to know how to decode it in order to be able to do so, but in
226
     * that case we log it as an unknown frame to assist with diagnosis.
227
     */
228
0
    switch (frame_type) {
229
0
    case OSSL_QUIC_FRAME_TYPE_PADDING:
230
0
        QLOG_STR("frame_type", "padding");
231
0
        QLOG_U64("payload_length",
232
0
            ossl_quic_wire_decode_padding(pkt));
233
0
        break;
234
0
    case OSSL_QUIC_FRAME_TYPE_PING:
235
0
        if (!ossl_quic_wire_decode_frame_ping(pkt))
236
0
            goto unknown;
237
238
0
        QLOG_STR("frame_type", "ping");
239
0
        break;
240
0
    case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN:
241
0
    case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN:
242
0
        if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &num_ranges))
243
0
            goto unknown;
244
245
0
        ack.ack_ranges = ack_ranges;
246
0
        ack.num_ack_ranges = OSSL_NELEM(ack_ranges);
247
0
        if (!ossl_quic_wire_decode_frame_ack(pkt, 3, &ack, &total_ranges))
248
0
            goto unknown;
249
250
0
        QLOG_STR("frame_type", "ack");
251
0
        QLOG_U64("ack_delay", ossl_time2ms(ack.delay_time));
252
0
        if (ack.ecn_present) {
253
0
            QLOG_U64("ect1", ack.ect0);
254
0
            QLOG_U64("ect0", ack.ect1);
255
0
            QLOG_U64("ce", ack.ecnce);
256
0
        }
257
0
        QLOG_BEGIN_ARRAY("acked_ranges");
258
0
        for (i = 0; i < ack.num_ack_ranges; ++i) {
259
0
            QLOG_BEGIN_ARRAY(NULL)
260
0
            QLOG_U64(NULL, ack.ack_ranges[i].start);
261
0
            if (ack.ack_ranges[i].end != ack.ack_ranges[i].start)
262
0
                QLOG_U64(NULL, ack.ack_ranges[i].end);
263
0
            QLOG_END_ARRAY()
264
0
        }
265
0
        QLOG_END_ARRAY()
266
0
        break;
267
0
    case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: {
268
0
        OSSL_QUIC_FRAME_RESET_STREAM f;
269
270
0
        if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &f))
271
0
            goto unknown;
272
273
0
        QLOG_STR("frame_type", "reset_stream");
274
0
        QLOG_U64("stream_id", f.stream_id);
275
0
        QLOG_U64("error_code", f.app_error_code);
276
0
        QLOG_U64("final_size", f.final_size);
277
0
    } break;
278
0
    case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: {
279
0
        OSSL_QUIC_FRAME_STOP_SENDING f;
280
281
0
        if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &f))
282
0
            goto unknown;
283
284
0
        QLOG_STR("frame_type", "stop_sending");
285
0
        QLOG_U64("stream_id", f.stream_id);
286
0
        QLOG_U64("error_code", f.app_error_code);
287
0
    } break;
288
0
    case OSSL_QUIC_FRAME_TYPE_CRYPTO: {
289
0
        OSSL_QUIC_FRAME_CRYPTO f;
290
291
0
        if (!ossl_quic_wire_decode_frame_crypto(pkt, 1, &f))
292
0
            goto unknown;
293
294
0
        QLOG_STR("frame_type", "crypto");
295
0
        QLOG_U64("offset", f.offset);
296
0
        QLOG_U64("payload_length", f.len);
297
0
        *need_skip += (size_t)f.len;
298
0
    } break;
299
0
    case OSSL_QUIC_FRAME_TYPE_STREAM:
300
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_FIN:
301
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_LEN:
302
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN:
303
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_OFF:
304
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN:
305
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN:
306
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: {
307
0
        OSSL_QUIC_FRAME_STREAM f;
308
309
0
        if (!ossl_quic_wire_decode_frame_stream(pkt, 1, &f))
310
0
            goto unknown;
311
312
0
        QLOG_STR("frame_type", "stream");
313
0
        QLOG_U64("stream_id", f.stream_id);
314
0
        QLOG_U64("offset", f.offset);
315
0
        QLOG_U64("payload_length", f.len);
316
0
        QLOG_BOOL("explicit_length", f.has_explicit_len);
317
0
        if (f.is_fin)
318
0
            QLOG_BOOL("fin", 1);
319
0
        *need_skip = f.has_explicit_len
320
0
            ? *need_skip + (size_t)f.len
321
0
            : SIZE_MAX;
322
0
    } break;
323
0
    case OSSL_QUIC_FRAME_TYPE_MAX_DATA: {
324
0
        uint64_t x;
325
326
0
        if (!ossl_quic_wire_decode_frame_max_data(pkt, &x))
327
0
            goto unknown;
328
329
0
        QLOG_STR("frame_type", "max_data");
330
0
        QLOG_U64("maximum", x);
331
0
    } break;
332
0
    case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI:
333
0
    case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: {
334
0
        uint64_t x;
335
336
0
        if (!ossl_quic_wire_decode_frame_max_streams(pkt, &x))
337
0
            goto unknown;
338
339
0
        QLOG_STR("frame_type", "max_streams");
340
0
        QLOG_STR("stream_type",
341
0
            frame_type == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI
342
0
                ? "bidirectional"
343
0
                : "unidirectional");
344
0
        QLOG_U64("maximum", x);
345
0
    } break;
346
0
    case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: {
347
0
        uint64_t stream_id, max_data;
348
349
0
        if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id,
350
0
                &max_data))
351
0
            goto unknown;
352
353
0
        QLOG_STR("frame_type", "max_stream_data");
354
0
        QLOG_U64("stream_id", stream_id);
355
0
        QLOG_U64("maximum", max_data);
356
0
    } break;
357
0
    case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE: {
358
0
        uint64_t challenge;
359
360
0
        if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &challenge))
361
0
            goto unknown;
362
363
0
        QLOG_STR("frame_type", "path_challenge");
364
0
    } break;
365
0
    case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: {
366
0
        uint64_t challenge;
367
368
0
        if (!ossl_quic_wire_decode_frame_path_response(pkt, &challenge))
369
0
            goto unknown;
370
371
0
        QLOG_STR("frame_type", "path_response");
372
0
    } break;
373
0
    case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP:
374
0
    case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: {
375
0
        OSSL_QUIC_FRAME_CONN_CLOSE f;
376
377
0
        if (!ossl_quic_wire_decode_frame_conn_close(pkt, &f))
378
0
            goto unknown;
379
380
0
        QLOG_STR("frame_type", "connection_close");
381
0
        QLOG_STR("error_space", f.is_app ? "application" : "transport");
382
0
        QLOG_U64("error_code_value", f.error_code);
383
0
        if (f.is_app)
384
0
            QLOG_U64("error_code", f.error_code);
385
0
        if (!f.is_app && f.frame_type != 0)
386
0
            QLOG_U64("trigger_frame_type", f.frame_type);
387
0
        QLOG_STR_LEN("reason", f.reason, f.reason_len);
388
0
    } break;
389
0
    case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: {
390
0
        if (!ossl_quic_wire_decode_frame_handshake_done(pkt))
391
0
            goto unknown;
392
393
0
        QLOG_STR("frame_type", "handshake_done");
394
0
    } break;
395
0
    case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: {
396
0
        OSSL_QUIC_FRAME_NEW_CONN_ID f;
397
398
0
        if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &f))
399
0
            goto unknown;
400
401
0
        QLOG_STR("frame_type", "new_connection_id");
402
0
        QLOG_U64("sequence_number", f.seq_num);
403
0
        QLOG_U64("retire_prior_to", f.retire_prior_to);
404
0
        QLOG_CID("connection_id", &f.conn_id);
405
0
        QLOG_BIN("stateless_reset_token",
406
0
            f.stateless_reset.token,
407
0
            sizeof(f.stateless_reset.token));
408
0
    } break;
409
0
    case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: {
410
0
        uint64_t seq_num;
411
412
0
        if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num))
413
0
            goto unknown;
414
415
0
        QLOG_STR("frame_type", "retire_connection_id");
416
0
        QLOG_U64("sequence_number", seq_num);
417
0
    } break;
418
0
    case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED: {
419
0
        uint64_t x;
420
421
0
        if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &x))
422
0
            goto unknown;
423
424
0
        QLOG_STR("frame_type", "data_blocked");
425
0
        QLOG_U64("limit", x);
426
0
    } break;
427
0
    case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED: {
428
0
        uint64_t stream_id, x;
429
430
0
        if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt,
431
0
                &stream_id,
432
0
                &x))
433
0
            goto unknown;
434
435
0
        QLOG_STR("frame_type", "stream_data_blocked");
436
0
        QLOG_U64("stream_id", stream_id);
437
0
        QLOG_U64("limit", x);
438
0
    } break;
439
0
    case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI:
440
0
    case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI: {
441
0
        uint64_t x;
442
443
0
        if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &x))
444
0
            goto unknown;
445
446
0
        QLOG_STR("frame_type", "streams_blocked");
447
0
        QLOG_STR("stream_type",
448
0
            frame_type == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI
449
0
                ? "bidirectional"
450
0
                : "unidirectional");
451
0
        QLOG_U64("limit", x);
452
0
    } break;
453
0
    case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: {
454
0
        const unsigned char *token;
455
0
        size_t token_len;
456
457
0
        if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len))
458
0
            goto unknown;
459
460
0
        QLOG_STR("frame_type", "new_token");
461
0
        QLOG_BEGIN("token");
462
0
        QLOG_BEGIN("raw");
463
0
        QLOG_BIN("data", token, token_len);
464
0
        QLOG_END();
465
0
        QLOG_END();
466
0
    } break;
467
0
    default:
468
0
    unknown:
469
0
        QLOG_STR("frame_type", "unknown");
470
0
        QLOG_U64("frame_type_value", frame_type);
471
472
        /*
473
         * Can't continue scanning for frames in this case as the frame length
474
         * is unknown. We log the entire body of the rest of the packet payload
475
         * as the raw data of the frame.
476
         */
477
0
        QLOG_BEGIN("raw");
478
0
        QLOG_BIN("data", PACKET_data(&orig_pkt),
479
0
            PACKET_remaining(&orig_pkt));
480
0
        QLOG_END();
481
0
        ignore_res(PACKET_forward(pkt, PACKET_remaining(pkt)));
482
0
        break;
483
0
    }
484
485
0
    return 1;
486
0
}
487
488
static void log_frame(QLOG *qlog_instance, PACKET *pkt,
489
    size_t *need_skip)
490
0
{
491
0
    size_t rem_before, rem_after;
492
493
0
    rem_before = PACKET_remaining(pkt);
494
495
0
    if (!log_frame_actual(qlog_instance, pkt, need_skip))
496
0
        return;
497
498
0
    rem_after = PACKET_remaining(pkt);
499
0
    QLOG_U64("length", rem_before - rem_after);
500
0
}
501
502
static int log_frames(QLOG *qlog_instance,
503
    const OSSL_QTX_IOVEC *iovec,
504
    size_t num_iovec)
505
0
{
506
0
    size_t i;
507
0
    PACKET pkt;
508
0
    size_t need_skip = 0;
509
510
0
    for (i = 0; i < num_iovec; ++i) {
511
0
        if (!PACKET_buf_init(&pkt, iovec[i].buf, iovec[i].buf_len))
512
0
            return 0;
513
514
0
        while (PACKET_remaining(&pkt) > 0) {
515
0
            if (need_skip > 0) {
516
0
                size_t adv = need_skip;
517
518
0
                if (adv > PACKET_remaining(&pkt))
519
0
                    adv = PACKET_remaining(&pkt);
520
521
0
                if (!PACKET_forward(&pkt, adv))
522
0
                    return 0;
523
524
0
                need_skip -= adv;
525
0
                continue;
526
0
            }
527
528
0
            QLOG_BEGIN(NULL)
529
0
            {
530
0
                log_frame(qlog_instance, &pkt, &need_skip);
531
0
            }
532
0
            QLOG_END()
533
0
        }
534
0
    }
535
536
0
    return 1;
537
0
}
538
539
static void log_packet(QLOG *qlog_instance,
540
    const QUIC_PKT_HDR *hdr,
541
    QUIC_PN pn,
542
    const OSSL_QTX_IOVEC *iovec,
543
    size_t num_iovec,
544
    uint64_t datagram_id)
545
0
{
546
0
    const char *type_s;
547
548
0
    QLOG_BEGIN("header")
549
0
    type_s = quic_pkt_type_to_qlog(hdr->type);
550
0
    if (type_s == NULL)
551
0
        type_s = "unknown";
552
553
0
    QLOG_STR("packet_type", type_s);
554
0
    if (ossl_quic_pkt_type_has_pn(hdr->type))
555
0
        QLOG_U64("packet_number", pn);
556
557
0
    QLOG_CID("dcid", &hdr->dst_conn_id);
558
0
    if (ossl_quic_pkt_type_has_scid(hdr->type))
559
0
        QLOG_CID("scid", &hdr->src_conn_id);
560
561
0
    if (hdr->token_len > 0) {
562
0
        QLOG_BEGIN("token")
563
0
        QLOG_BEGIN("raw")
564
0
        QLOG_BIN("data", hdr->token, hdr->token_len);
565
0
        QLOG_END()
566
0
        QLOG_END()
567
0
    }
568
    /* TODO(QLOG FUTURE): flags, length */
569
0
    QLOG_END()
570
0
    QLOG_U64("datagram_id", datagram_id);
571
572
0
    if (ossl_quic_pkt_type_is_encrypted(hdr->type)) {
573
0
        QLOG_BEGIN_ARRAY("frames")
574
0
        log_frames(qlog_instance, iovec, num_iovec);
575
0
        QLOG_END_ARRAY()
576
0
    }
577
0
}
578
579
#endif
580
581
void ossl_qlog_event_transport_packet_sent(QLOG *qlog,
582
    const QUIC_PKT_HDR *hdr,
583
    QUIC_PN pn,
584
    const OSSL_QTX_IOVEC *iovec,
585
    size_t num_iovec,
586
    uint64_t datagram_id)
587
0
{
588
0
#ifndef OPENSSL_NO_QLOG
589
0
    QLOG_EVENT_BEGIN(qlog, transport, packet_sent)
590
0
    log_packet(qlog, hdr, pn, iovec, num_iovec, datagram_id);
591
0
    QLOG_EVENT_END()
592
0
#endif
593
0
}
594
595
void ossl_qlog_event_transport_packet_received(QLOG *qlog,
596
    const QUIC_PKT_HDR *hdr,
597
    QUIC_PN pn,
598
    const OSSL_QTX_IOVEC *iovec,
599
    size_t num_iovec,
600
    uint64_t datagram_id)
601
0
{
602
0
#ifndef OPENSSL_NO_QLOG
603
0
    QLOG_EVENT_BEGIN(qlog, transport, packet_received)
604
0
    log_packet(qlog, hdr, pn, iovec, num_iovec, datagram_id);
605
0
    QLOG_EVENT_END()
606
0
#endif
607
0
}