1 1.1 christos /* 2 1.1 christos * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #include <openssl/bio.h> 11 1.1 christos #include "../ssl_local.h" 12 1.1 christos #include "internal/quic_trace.h" 13 1.1 christos #include "internal/quic_ssl.h" 14 1.1 christos #include "internal/quic_channel.h" 15 1.1 christos #include "internal/quic_wire_pkt.h" 16 1.1 christos #include "internal/quic_wire.h" 17 1.1 christos #include "internal/ssl_unwrap.h" 18 1.1 christos 19 1.1 christos static const char *packet_type(int type) 20 1.1 christos { 21 1.1 christos switch (type) { 22 1.1 christos case QUIC_PKT_TYPE_INITIAL: 23 1.1 christos return "Initial"; 24 1.1 christos 25 1.1 christos case QUIC_PKT_TYPE_0RTT: 26 1.1 christos return "0RTT"; 27 1.1 christos 28 1.1 christos case QUIC_PKT_TYPE_HANDSHAKE: 29 1.1 christos return "Handshake"; 30 1.1 christos 31 1.1 christos case QUIC_PKT_TYPE_RETRY: 32 1.1 christos return "Retry"; 33 1.1 christos 34 1.1 christos case QUIC_PKT_TYPE_1RTT: 35 1.1 christos return "1RTT"; 36 1.1 christos 37 1.1 christos case QUIC_PKT_TYPE_VERSION_NEG: 38 1.1 christos return "VersionNeg"; 39 1.1 christos 40 1.1 christos default: 41 1.1 christos return "Unknown"; 42 1.1 christos } 43 1.1 christos } 44 1.1 christos 45 1.1 christos /* Print a non-NUL terminated string to BIO */ 46 1.1 christos static void put_str(BIO *bio, char *str, size_t slen) 47 1.1 christos { 48 1.1 christos size_t i; 49 1.1 christos 50 1.1 christos for (i = 0; i < slen; i++) 51 1.1 christos BIO_printf(bio, "%c", str[i]); 52 1.1 christos } 53 1.1 christos 54 1.1 christos static void put_data(BIO *bio, const uint8_t *data, size_t datalen) 55 1.1 christos { 56 1.1 christos size_t i; 57 1.1 christos 58 1.1 christos for (i = 0; i < datalen; i++) 59 1.1 christos BIO_printf(bio, "%02x", data[i]); 60 1.1 christos } 61 1.1 christos 62 1.1 christos static void put_conn_id(BIO *bio, QUIC_CONN_ID *id) 63 1.1 christos { 64 1.1 christos if (id->id_len == 0) { 65 1.1 christos BIO_puts(bio, "<zero length id>"); 66 1.1 christos return; 67 1.1 christos } 68 1.1 christos 69 1.1 christos BIO_puts(bio, "0x"); 70 1.1 christos put_data(bio, id->id, id->id_len); 71 1.1 christos } 72 1.1 christos 73 1.1 christos static void put_token(BIO *bio, const uint8_t *token, size_t token_len) 74 1.1 christos { 75 1.1 christos if (token_len == 0) 76 1.1 christos BIO_puts(bio, "<zero length token>"); 77 1.1 christos else 78 1.1 christos put_data(bio, token, token_len); 79 1.1 christos } 80 1.1 christos 81 1.1 christos static int frame_ack(BIO *bio, PACKET *pkt) 82 1.1 christos { 83 1.1 christos OSSL_QUIC_FRAME_ACK ack; 84 1.1 christos OSSL_QUIC_ACK_RANGE *ack_ranges = NULL; 85 1.1 christos uint64_t total_ranges = 0; 86 1.1 christos uint64_t i; 87 1.1 christos int ret = 0; 88 1.1 christos 89 1.1 christos if (!ossl_quic_wire_peek_frame_ack_num_ranges(pkt, &total_ranges) 90 1.1 christos /* In case sizeof(uint64_t) > sizeof(size_t) */ 91 1.1 christos || total_ranges > SIZE_MAX / sizeof(ack_ranges[0]) 92 1.1 christos || (ack_ranges = OPENSSL_zalloc(sizeof(ack_ranges[0]) 93 1.1.1.2 christos * (size_t)total_ranges)) 94 1.1.1.2 christos == NULL) 95 1.1 christos return ret; 96 1.1 christos 97 1.1 christos ack.ack_ranges = ack_ranges; 98 1.1 christos ack.num_ack_ranges = (size_t)total_ranges; 99 1.1 christos 100 1.1 christos /* Ack delay exponent is 0, so we can get the raw delay time below */ 101 1.1 christos if (!ossl_quic_wire_decode_frame_ack(pkt, 0, &ack, NULL)) 102 1.1 christos goto end; 103 1.1 christos 104 1.1 christos BIO_printf(bio, " Largest acked: %llu\n", 105 1.1.1.2 christos (unsigned long long)ack.ack_ranges[0].end); 106 1.1 christos BIO_printf(bio, " Ack delay (raw) %llu\n", 107 1.1.1.2 christos (unsigned long long)ossl_time2ticks(ack.delay_time)); 108 1.1 christos BIO_printf(bio, " Ack range count: %llu\n", 109 1.1.1.2 christos (unsigned long long)total_ranges - 1); 110 1.1 christos BIO_printf(bio, " First ack range: %llu\n", 111 1.1.1.2 christos (unsigned long long)(ack.ack_ranges[0].end 112 1.1.1.2 christos - ack.ack_ranges[0].start)); 113 1.1 christos for (i = 1; i < total_ranges; i++) { 114 1.1 christos BIO_printf(bio, " Gap: %llu\n", 115 1.1.1.2 christos (unsigned long long)(ack.ack_ranges[i - 1].start 116 1.1.1.2 christos - ack.ack_ranges[i].end - 2)); 117 1.1 christos BIO_printf(bio, " Ack range len: %llu\n", 118 1.1.1.2 christos (unsigned long long)(ack.ack_ranges[i].end 119 1.1.1.2 christos - ack.ack_ranges[i].start)); 120 1.1 christos } 121 1.1 christos 122 1.1 christos ret = 1; 123 1.1 christos end: 124 1.1 christos OPENSSL_free(ack_ranges); 125 1.1 christos return ret; 126 1.1 christos } 127 1.1 christos 128 1.1 christos static int frame_reset_stream(BIO *bio, PACKET *pkt) 129 1.1 christos { 130 1.1 christos OSSL_QUIC_FRAME_RESET_STREAM frame_data; 131 1.1 christos 132 1.1 christos if (!ossl_quic_wire_decode_frame_reset_stream(pkt, &frame_data)) 133 1.1 christos return 0; 134 1.1 christos 135 1.1 christos BIO_printf(bio, " Stream id: %llu\n", 136 1.1.1.2 christos (unsigned long long)frame_data.stream_id); 137 1.1 christos BIO_printf(bio, " App Protocol Error Code: %llu\n", 138 1.1.1.2 christos (unsigned long long)frame_data.app_error_code); 139 1.1 christos BIO_printf(bio, " Final size: %llu\n", 140 1.1.1.2 christos (unsigned long long)frame_data.final_size); 141 1.1 christos 142 1.1 christos return 1; 143 1.1 christos } 144 1.1 christos 145 1.1 christos static int frame_stop_sending(BIO *bio, PACKET *pkt) 146 1.1 christos { 147 1.1 christos OSSL_QUIC_FRAME_STOP_SENDING frame_data; 148 1.1 christos 149 1.1 christos if (!ossl_quic_wire_decode_frame_stop_sending(pkt, &frame_data)) 150 1.1 christos return 0; 151 1.1 christos 152 1.1 christos BIO_printf(bio, " Stream id: %llu\n", 153 1.1.1.2 christos (unsigned long long)frame_data.stream_id); 154 1.1 christos BIO_printf(bio, " App Protocol Error Code: %llu\n", 155 1.1.1.2 christos (unsigned long long)frame_data.app_error_code); 156 1.1 christos 157 1.1 christos return 1; 158 1.1 christos } 159 1.1 christos 160 1.1 christos static int frame_crypto(BIO *bio, PACKET *pkt) 161 1.1 christos { 162 1.1 christos OSSL_QUIC_FRAME_CRYPTO frame_data; 163 1.1 christos 164 1.1 christos if (!ossl_quic_wire_decode_frame_crypto(pkt, 1, &frame_data)) 165 1.1 christos return 0; 166 1.1 christos 167 1.1 christos BIO_printf(bio, " Offset: %llu\n", (unsigned long long)frame_data.offset); 168 1.1 christos BIO_printf(bio, " Len: %llu\n", (unsigned long long)frame_data.len); 169 1.1 christos 170 1.1 christos return 1; 171 1.1 christos } 172 1.1 christos 173 1.1 christos static int frame_new_token(BIO *bio, PACKET *pkt) 174 1.1 christos { 175 1.1 christos const uint8_t *token; 176 1.1 christos size_t token_len; 177 1.1 christos 178 1.1 christos if (!ossl_quic_wire_decode_frame_new_token(pkt, &token, &token_len)) 179 1.1 christos return 0; 180 1.1 christos 181 1.1 christos BIO_puts(bio, " Token: "); 182 1.1 christos put_token(bio, token, token_len); 183 1.1 christos BIO_puts(bio, "\n"); 184 1.1 christos 185 1.1 christos return 1; 186 1.1 christos } 187 1.1 christos 188 1.1 christos static int frame_stream(BIO *bio, PACKET *pkt, uint64_t frame_type) 189 1.1 christos { 190 1.1 christos 191 1.1 christos OSSL_QUIC_FRAME_STREAM frame_data; 192 1.1 christos 193 1.1 christos BIO_puts(bio, "Stream"); 194 1.1.1.2 christos switch (frame_type) { 195 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM: 196 1.1 christos BIO_puts(bio, "\n"); 197 1.1 christos break; 198 1.1 christos 199 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_FIN: 200 1.1 christos BIO_puts(bio, " (Fin)\n"); 201 1.1 christos break; 202 1.1 christos 203 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_LEN: 204 1.1 christos BIO_puts(bio, " (Len)\n"); 205 1.1 christos break; 206 1.1 christos 207 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN: 208 1.1 christos BIO_puts(bio, " (Len, Fin)\n"); 209 1.1 christos break; 210 1.1 christos 211 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF: 212 1.1 christos BIO_puts(bio, " (Off)\n"); 213 1.1 christos break; 214 1.1 christos 215 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN: 216 1.1 christos BIO_puts(bio, " (Off, Fin)\n"); 217 1.1 christos break; 218 1.1 christos 219 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN: 220 1.1 christos BIO_puts(bio, " (Off, Len)\n"); 221 1.1 christos break; 222 1.1 christos 223 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: 224 1.1 christos BIO_puts(bio, " (Off, Len, Fin)\n"); 225 1.1 christos break; 226 1.1 christos 227 1.1 christos default: 228 1.1 christos return 0; 229 1.1 christos } 230 1.1 christos 231 1.1 christos if (!ossl_quic_wire_decode_frame_stream(pkt, 1, &frame_data)) 232 1.1 christos return 0; 233 1.1 christos 234 1.1 christos BIO_printf(bio, " Stream id: %llu\n", 235 1.1.1.2 christos (unsigned long long)frame_data.stream_id); 236 1.1 christos BIO_printf(bio, " Offset: %llu\n", 237 1.1.1.2 christos (unsigned long long)frame_data.offset); 238 1.1 christos /* 239 1.1 christos * It would be nice to find a way of passing the implicit length through 240 1.1 christos * to the msg_callback. But this is not currently possible. 241 1.1 christos */ 242 1.1 christos if (frame_data.has_explicit_len) 243 1.1 christos BIO_printf(bio, " Len: %llu\n", (unsigned long long)frame_data.len); 244 1.1 christos else 245 1.1 christos BIO_puts(bio, " Len: <implicit length>\n"); 246 1.1 christos 247 1.1 christos return 1; 248 1.1 christos } 249 1.1 christos 250 1.1 christos static int frame_max_data(BIO *bio, PACKET *pkt) 251 1.1 christos { 252 1.1 christos uint64_t max_data = 0; 253 1.1 christos 254 1.1 christos if (!ossl_quic_wire_decode_frame_max_data(pkt, &max_data)) 255 1.1 christos return 0; 256 1.1 christos 257 1.1 christos BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); 258 1.1 christos 259 1.1 christos return 1; 260 1.1 christos } 261 1.1 christos 262 1.1 christos static int frame_max_stream_data(BIO *bio, PACKET *pkt) 263 1.1 christos { 264 1.1 christos uint64_t stream_id = 0; 265 1.1 christos uint64_t max_stream_data = 0; 266 1.1 christos 267 1.1 christos if (!ossl_quic_wire_decode_frame_max_stream_data(pkt, &stream_id, 268 1.1.1.2 christos &max_stream_data)) 269 1.1 christos return 0; 270 1.1 christos 271 1.1 christos BIO_printf(bio, " Max Stream Data: %llu\n", 272 1.1.1.2 christos (unsigned long long)max_stream_data); 273 1.1 christos 274 1.1 christos return 1; 275 1.1 christos } 276 1.1 christos 277 1.1 christos static int frame_max_streams(BIO *bio, PACKET *pkt) 278 1.1 christos { 279 1.1 christos uint64_t max_streams = 0; 280 1.1 christos 281 1.1 christos if (!ossl_quic_wire_decode_frame_max_streams(pkt, &max_streams)) 282 1.1 christos return 0; 283 1.1 christos 284 1.1 christos BIO_printf(bio, " Max Streams: %llu\n", (unsigned long long)max_streams); 285 1.1 christos 286 1.1 christos return 1; 287 1.1 christos } 288 1.1 christos 289 1.1 christos static int frame_data_blocked(BIO *bio, PACKET *pkt) 290 1.1 christos { 291 1.1 christos uint64_t max_data = 0; 292 1.1 christos 293 1.1 christos if (!ossl_quic_wire_decode_frame_data_blocked(pkt, &max_data)) 294 1.1 christos return 0; 295 1.1 christos 296 1.1 christos BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); 297 1.1 christos 298 1.1 christos return 1; 299 1.1 christos } 300 1.1 christos 301 1.1 christos static int frame_stream_data_blocked(BIO *bio, PACKET *pkt) 302 1.1 christos { 303 1.1 christos uint64_t stream_id = 0; 304 1.1 christos uint64_t max_data = 0; 305 1.1 christos 306 1.1 christos if (!ossl_quic_wire_decode_frame_stream_data_blocked(pkt, &stream_id, 307 1.1.1.2 christos &max_data)) 308 1.1 christos return 0; 309 1.1 christos 310 1.1 christos BIO_printf(bio, " Stream id: %llu\n", (unsigned long long)stream_id); 311 1.1 christos BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); 312 1.1 christos 313 1.1 christos return 1; 314 1.1 christos } 315 1.1 christos 316 1.1 christos static int frame_streams_blocked(BIO *bio, PACKET *pkt) 317 1.1 christos { 318 1.1 christos uint64_t max_data = 0; 319 1.1 christos 320 1.1 christos if (!ossl_quic_wire_decode_frame_streams_blocked(pkt, &max_data)) 321 1.1 christos return 0; 322 1.1 christos 323 1.1 christos BIO_printf(bio, " Max Data: %llu\n", (unsigned long long)max_data); 324 1.1 christos 325 1.1 christos return 1; 326 1.1 christos } 327 1.1 christos 328 1.1 christos static int frame_new_conn_id(BIO *bio, PACKET *pkt) 329 1.1 christos { 330 1.1 christos OSSL_QUIC_FRAME_NEW_CONN_ID frame_data; 331 1.1 christos 332 1.1 christos if (!ossl_quic_wire_decode_frame_new_conn_id(pkt, &frame_data)) 333 1.1 christos return 0; 334 1.1 christos 335 1.1 christos BIO_printf(bio, " Sequence Number: %llu\n", 336 1.1.1.2 christos (unsigned long long)frame_data.seq_num); 337 1.1 christos BIO_printf(bio, " Retire prior to: %llu\n", 338 1.1.1.2 christos (unsigned long long)frame_data.retire_prior_to); 339 1.1 christos BIO_puts(bio, " Connection id: "); 340 1.1 christos put_conn_id(bio, &frame_data.conn_id); 341 1.1 christos BIO_puts(bio, "\n Stateless Reset Token: "); 342 1.1 christos put_data(bio, frame_data.stateless_reset.token, 343 1.1.1.2 christos sizeof(frame_data.stateless_reset.token)); 344 1.1 christos BIO_puts(bio, "\n"); 345 1.1 christos 346 1.1 christos return 1; 347 1.1 christos } 348 1.1 christos 349 1.1 christos static int frame_retire_conn_id(BIO *bio, PACKET *pkt) 350 1.1 christos { 351 1.1 christos uint64_t seq_num; 352 1.1 christos 353 1.1 christos if (!ossl_quic_wire_decode_frame_retire_conn_id(pkt, &seq_num)) 354 1.1 christos return 0; 355 1.1 christos 356 1.1 christos BIO_printf(bio, " Sequence Number: %llu\n", (unsigned long long)seq_num); 357 1.1 christos 358 1.1 christos return 1; 359 1.1 christos } 360 1.1 christos 361 1.1 christos static int frame_path_challenge(BIO *bio, PACKET *pkt) 362 1.1 christos { 363 1.1 christos uint64_t data = 0; 364 1.1 christos 365 1.1 christos if (!ossl_quic_wire_decode_frame_path_challenge(pkt, &data)) 366 1.1 christos return 0; 367 1.1 christos 368 1.1 christos BIO_printf(bio, " Data: %016llx\n", (unsigned long long)data); 369 1.1 christos 370 1.1 christos return 1; 371 1.1 christos } 372 1.1 christos 373 1.1 christos static int frame_path_response(BIO *bio, PACKET *pkt) 374 1.1 christos { 375 1.1 christos uint64_t data = 0; 376 1.1 christos 377 1.1 christos if (!ossl_quic_wire_decode_frame_path_response(pkt, &data)) 378 1.1 christos return 0; 379 1.1 christos 380 1.1 christos BIO_printf(bio, " Data: %016llx\n", (unsigned long long)data); 381 1.1 christos 382 1.1 christos return 1; 383 1.1 christos } 384 1.1 christos 385 1.1 christos static int frame_conn_closed(BIO *bio, PACKET *pkt) 386 1.1 christos { 387 1.1 christos OSSL_QUIC_FRAME_CONN_CLOSE frame_data; 388 1.1 christos 389 1.1 christos if (!ossl_quic_wire_decode_frame_conn_close(pkt, &frame_data)) 390 1.1 christos return 0; 391 1.1 christos 392 1.1 christos BIO_printf(bio, " Error Code: %llu\n", 393 1.1.1.2 christos (unsigned long long)frame_data.error_code); 394 1.1 christos BIO_puts(bio, " Reason: "); 395 1.1 christos put_str(bio, frame_data.reason, frame_data.reason_len); 396 1.1 christos BIO_puts(bio, "\n"); 397 1.1 christos 398 1.1 christos return 1; 399 1.1 christos } 400 1.1 christos 401 1.1 christos static int trace_frame_data(BIO *bio, PACKET *pkt) 402 1.1 christos { 403 1.1 christos uint64_t frame_type; 404 1.1 christos 405 1.1 christos if (!ossl_quic_wire_peek_frame_header(pkt, &frame_type, NULL)) 406 1.1 christos return 0; 407 1.1 christos 408 1.1 christos switch (frame_type) { 409 1.1 christos case OSSL_QUIC_FRAME_TYPE_PING: 410 1.1 christos BIO_puts(bio, "Ping\n"); 411 1.1 christos if (!ossl_quic_wire_decode_frame_ping(pkt)) 412 1.1 christos return 0; 413 1.1 christos break; 414 1.1 christos 415 1.1 christos case OSSL_QUIC_FRAME_TYPE_PADDING: 416 1.1 christos BIO_puts(bio, "Padding\n"); 417 1.1 christos ossl_quic_wire_decode_padding(pkt); 418 1.1 christos break; 419 1.1 christos 420 1.1 christos case OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN: 421 1.1 christos case OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN: 422 1.1 christos BIO_puts(bio, "Ack "); 423 1.1 christos if (frame_type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) 424 1.1 christos BIO_puts(bio, " (with ECN)\n"); 425 1.1 christos else 426 1.1 christos BIO_puts(bio, " (without ECN)\n"); 427 1.1 christos if (!frame_ack(bio, pkt)) 428 1.1 christos return 0; 429 1.1 christos break; 430 1.1 christos 431 1.1 christos case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: 432 1.1 christos BIO_puts(bio, "Reset stream\n"); 433 1.1 christos if (!frame_reset_stream(bio, pkt)) 434 1.1 christos return 0; 435 1.1 christos break; 436 1.1 christos 437 1.1 christos case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: 438 1.1 christos BIO_puts(bio, "Stop sending\n"); 439 1.1 christos if (!frame_stop_sending(bio, pkt)) 440 1.1 christos return 0; 441 1.1 christos break; 442 1.1 christos 443 1.1 christos case OSSL_QUIC_FRAME_TYPE_CRYPTO: 444 1.1 christos BIO_puts(bio, "Crypto\n"); 445 1.1 christos if (!frame_crypto(bio, pkt)) 446 1.1 christos return 0; 447 1.1 christos break; 448 1.1 christos 449 1.1 christos case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: 450 1.1 christos BIO_puts(bio, "New token\n"); 451 1.1 christos if (!frame_new_token(bio, pkt)) 452 1.1 christos return 0; 453 1.1 christos break; 454 1.1 christos 455 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM: 456 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_FIN: 457 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_LEN: 458 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_LEN_FIN: 459 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF: 460 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_FIN: 461 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN: 462 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN_FIN: 463 1.1 christos /* frame_stream() prints the frame type string */ 464 1.1 christos if (!frame_stream(bio, pkt, frame_type)) 465 1.1 christos return 0; 466 1.1 christos break; 467 1.1 christos 468 1.1 christos case OSSL_QUIC_FRAME_TYPE_MAX_DATA: 469 1.1 christos BIO_puts(bio, "Max data\n"); 470 1.1 christos if (!frame_max_data(bio, pkt)) 471 1.1 christos return 0; 472 1.1 christos break; 473 1.1 christos 474 1.1 christos case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: 475 1.1 christos BIO_puts(bio, "Max stream data\n"); 476 1.1 christos if (!frame_max_stream_data(bio, pkt)) 477 1.1 christos return 0; 478 1.1 christos break; 479 1.1 christos 480 1.1 christos case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: 481 1.1 christos case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: 482 1.1 christos BIO_puts(bio, "Max streams "); 483 1.1 christos if (frame_type == OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI) 484 1.1 christos BIO_puts(bio, " (Bidi)\n"); 485 1.1 christos else 486 1.1 christos BIO_puts(bio, " (Uni)\n"); 487 1.1 christos if (!frame_max_streams(bio, pkt)) 488 1.1 christos return 0; 489 1.1 christos break; 490 1.1 christos 491 1.1 christos case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED: 492 1.1 christos BIO_puts(bio, "Data blocked\n"); 493 1.1 christos if (!frame_data_blocked(bio, pkt)) 494 1.1 christos return 0; 495 1.1 christos break; 496 1.1 christos 497 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED: 498 1.1 christos BIO_puts(bio, "Stream data blocked\n"); 499 1.1 christos if (!frame_stream_data_blocked(bio, pkt)) 500 1.1 christos return 0; 501 1.1 christos break; 502 1.1 christos 503 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI: 504 1.1 christos case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI: 505 1.1 christos BIO_puts(bio, "Streams blocked"); 506 1.1 christos if (frame_type == OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI) 507 1.1 christos BIO_puts(bio, " (Bidi)\n"); 508 1.1 christos else 509 1.1 christos BIO_puts(bio, " (Uni)\n"); 510 1.1 christos if (!frame_streams_blocked(bio, pkt)) 511 1.1 christos return 0; 512 1.1 christos break; 513 1.1 christos 514 1.1 christos case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: 515 1.1 christos BIO_puts(bio, "New conn id\n"); 516 1.1 christos if (!frame_new_conn_id(bio, pkt)) 517 1.1 christos return 0; 518 1.1 christos break; 519 1.1 christos 520 1.1 christos case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: 521 1.1 christos BIO_puts(bio, "Retire conn id\n"); 522 1.1 christos if (!frame_retire_conn_id(bio, pkt)) 523 1.1 christos return 0; 524 1.1 christos break; 525 1.1 christos 526 1.1 christos case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE: 527 1.1 christos BIO_puts(bio, "Path challenge\n"); 528 1.1 christos if (!frame_path_challenge(bio, pkt)) 529 1.1 christos return 0; 530 1.1 christos break; 531 1.1 christos 532 1.1 christos case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: 533 1.1 christos BIO_puts(bio, "Path response\n"); 534 1.1 christos if (!frame_path_response(bio, pkt)) 535 1.1 christos return 0; 536 1.1 christos break; 537 1.1 christos 538 1.1 christos case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: 539 1.1 christos case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_TRANSPORT: 540 1.1 christos BIO_puts(bio, "Connection close"); 541 1.1 christos if (frame_type == OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP) 542 1.1 christos BIO_puts(bio, " (app)\n"); 543 1.1 christos else 544 1.1 christos BIO_puts(bio, " (transport)\n"); 545 1.1 christos if (!frame_conn_closed(bio, pkt)) 546 1.1 christos return 0; 547 1.1 christos break; 548 1.1 christos 549 1.1 christos case OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE: 550 1.1 christos BIO_puts(bio, "Handshake done\n"); 551 1.1 christos if (!ossl_quic_wire_decode_frame_handshake_done(pkt)) 552 1.1 christos return 0; 553 1.1 christos break; 554 1.1 christos 555 1.1 christos default: 556 1.1 christos return 0; 557 1.1 christos } 558 1.1 christos 559 1.1 christos if (PACKET_remaining(pkt) != 0) 560 1.1 christos BIO_puts(bio, " <unexpected trailing frame data skipped>\n"); 561 1.1 christos 562 1.1 christos return 1; 563 1.1 christos } 564 1.1 christos 565 1.1 christos int ossl_quic_trace(int write_p, int version, int content_type, 566 1.1.1.2 christos const void *buf, size_t msglen, SSL *ssl, void *arg) 567 1.1 christos { 568 1.1 christos BIO *bio = arg; 569 1.1 christos PACKET pkt; 570 1.1 christos size_t id_len = 0; 571 1.1 christos QUIC_CHANNEL *ch; 572 1.1 christos 573 1.1 christos switch (content_type) { 574 1.1 christos case SSL3_RT_QUIC_DATAGRAM: 575 1.1 christos BIO_puts(bio, write_p ? "Sent" : "Received"); 576 1.1 christos /* 577 1.1 christos * Unfortunately there is no way of receiving auxiliary information 578 1.1 christos * about the datagram through the msg_callback API such as the peer 579 1.1 christos * address 580 1.1 christos */ 581 1.1 christos BIO_printf(bio, " Datagram\n Length: %zu\n", msglen); 582 1.1 christos break; 583 1.1 christos 584 1.1.1.2 christos case SSL3_RT_QUIC_PACKET: { 585 1.1.1.2 christos QUIC_PKT_HDR hdr; 586 1.1.1.2 christos size_t i; 587 1.1.1.2 christos 588 1.1.1.2 christos if (!PACKET_buf_init(&pkt, buf, msglen)) 589 1.1.1.2 christos return 0; 590 1.1.1.2 christos /* Decode the packet header */ 591 1.1.1.2 christos ch = ossl_quic_conn_get_channel(ssl); 592 1.1.1.2 christos id_len = ossl_quic_channel_get_short_header_conn_id_len(ch); 593 1.1.1.2 christos if (ossl_quic_wire_decode_pkt_hdr(&pkt, id_len, 0, 1, &hdr, NULL, 594 1.1.1.2 christos NULL) 595 1.1.1.2 christos != 1) 596 1.1.1.2 christos return 0; 597 1.1.1.2 christos 598 1.1.1.2 christos BIO_puts(bio, write_p ? "Sent" : "Received"); 599 1.1.1.2 christos BIO_puts(bio, " Packet\n"); 600 1.1.1.2 christos BIO_printf(bio, " Packet Type: %s\n", packet_type(hdr.type)); 601 1.1.1.2 christos if (hdr.type != QUIC_PKT_TYPE_1RTT) 602 1.1.1.2 christos BIO_printf(bio, " Version: 0x%08lx\n", 603 1.1.1.2 christos (unsigned long)hdr.version); 604 1.1.1.2 christos BIO_puts(bio, " Destination Conn Id: "); 605 1.1.1.2 christos put_conn_id(bio, &hdr.dst_conn_id); 606 1.1.1.2 christos BIO_puts(bio, "\n"); 607 1.1.1.2 christos if (hdr.type != QUIC_PKT_TYPE_1RTT) { 608 1.1.1.2 christos BIO_puts(bio, " Source Conn Id: "); 609 1.1.1.2 christos put_conn_id(bio, &hdr.src_conn_id); 610 1.1.1.2 christos BIO_puts(bio, "\n"); 611 1.1.1.2 christos } 612 1.1.1.2 christos BIO_printf(bio, " Payload length: %zu\n", hdr.len); 613 1.1.1.2 christos if (hdr.type == QUIC_PKT_TYPE_INITIAL) { 614 1.1.1.2 christos BIO_puts(bio, " Token: "); 615 1.1.1.2 christos put_token(bio, hdr.token, hdr.token_len); 616 1.1.1.2 christos BIO_puts(bio, "\n"); 617 1.1.1.2 christos } 618 1.1.1.2 christos if (hdr.type != QUIC_PKT_TYPE_VERSION_NEG 619 1.1.1.2 christos && hdr.type != QUIC_PKT_TYPE_RETRY) { 620 1.1.1.2 christos BIO_puts(bio, " Packet Number: 0x"); 621 1.1.1.2 christos /* Will always be at least 1 byte */ 622 1.1.1.2 christos for (i = 0; i < hdr.pn_len; i++) 623 1.1.1.2 christos BIO_printf(bio, "%02x", hdr.pn[i]); 624 1.1 christos BIO_puts(bio, "\n"); 625 1.1 christos } 626 1.1.1.2 christos break; 627 1.1.1.2 christos } 628 1.1 christos 629 1.1 christos case SSL3_RT_QUIC_FRAME_PADDING: 630 1.1 christos case SSL3_RT_QUIC_FRAME_FULL: 631 1.1.1.2 christos case SSL3_RT_QUIC_FRAME_HEADER: { 632 1.1.1.2 christos BIO_puts(bio, write_p ? "Sent" : "Received"); 633 1.1.1.2 christos BIO_puts(bio, " Frame: "); 634 1.1.1.2 christos 635 1.1.1.2 christos if (!PACKET_buf_init(&pkt, buf, msglen)) 636 1.1.1.2 christos return 0; 637 1.1.1.2 christos if (!trace_frame_data(bio, &pkt)) { 638 1.1.1.2 christos BIO_puts(bio, " <error processing frame data>\n"); 639 1.1.1.2 christos return 0; 640 1.1 christos } 641 1.1.1.2 christos } break; 642 1.1 christos 643 1.1 christos default: 644 1.1 christos /* Unrecognised content_type. We defer to SSL_trace */ 645 1.1 christos return 0; 646 1.1 christos } 647 1.1 christos 648 1.1 christos return 1; 649 1.1 christos } 650