quic_trace.c 18 KB

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