diff options
Diffstat (limited to '')
-rw-r--r-- | examples/debug.cc | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/examples/debug.cc b/examples/debug.cc new file mode 100644 index 0000000..98561fb --- /dev/null +++ b/examples/debug.cc @@ -0,0 +1,298 @@ +/* + * ngtcp2 + * + * Copyright (c) 2017 ngtcp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "debug.h" + +#include <cassert> +#include <random> +#include <iostream> + +#include "util.h" + +using namespace std::literals; + +namespace ngtcp2 { + +namespace debug { + +namespace { +auto randgen = util::make_mt19937(); +} // namespace + +namespace { +auto *outfile = stderr; +} // namespace + +int handshake_completed(ngtcp2_conn *conn, void *user_data) { + fprintf(outfile, "QUIC handshake has completed\n"); + return 0; +} + +int handshake_confirmed(ngtcp2_conn *conn, void *user_data) { + fprintf(outfile, "QUIC handshake has been confirmed\n"); + return 0; +} + +bool packet_lost(double prob) { + auto p = std::uniform_real_distribution<>(0, 1)(randgen); + return p < prob; +} + +void print_crypto_data(ngtcp2_crypto_level crypto_level, const uint8_t *data, + size_t datalen) { + const char *crypto_level_str; + switch (crypto_level) { + case NGTCP2_CRYPTO_LEVEL_INITIAL: + crypto_level_str = "Initial"; + break; + case NGTCP2_CRYPTO_LEVEL_HANDSHAKE: + crypto_level_str = "Handshake"; + break; + case NGTCP2_CRYPTO_LEVEL_APPLICATION: + crypto_level_str = "Application"; + break; + default: + assert(0); + abort(); + } + fprintf(outfile, "Ordered CRYPTO data in %s crypto level\n", + crypto_level_str); + util::hexdump(outfile, data, datalen); +} + +void print_stream_data(int64_t stream_id, const uint8_t *data, size_t datalen) { + fprintf(outfile, "Ordered STREAM data stream_id=0x%" PRIx64 "\n", stream_id); + util::hexdump(outfile, data, datalen); +} + +void print_initial_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "initial_secret=%s\n", util::format_hex(data, len).c_str()); +} + +void print_client_in_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "client_in_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_server_in_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "server_in_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_handshake_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "handshake_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_client_hs_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "client_hs_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_server_hs_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "server_hs_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_client_0rtt_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "client_0rtt_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_client_1rtt_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "client_1rtt_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_server_1rtt_secret(const uint8_t *data, size_t len) { + fprintf(outfile, "server_1rtt_secret=%s\n", + util::format_hex(data, len).c_str()); +} + +void print_client_pp_key(const uint8_t *data, size_t len) { + fprintf(outfile, "+ client_pp_key=%s\n", util::format_hex(data, len).c_str()); +} + +void print_server_pp_key(const uint8_t *data, size_t len) { + fprintf(outfile, "+ server_pp_key=%s\n", util::format_hex(data, len).c_str()); +} + +void print_client_pp_iv(const uint8_t *data, size_t len) { + fprintf(outfile, "+ client_pp_iv=%s\n", util::format_hex(data, len).c_str()); +} + +void print_server_pp_iv(const uint8_t *data, size_t len) { + fprintf(outfile, "+ server_pp_iv=%s\n", util::format_hex(data, len).c_str()); +} + +void print_client_pp_hp(const uint8_t *data, size_t len) { + fprintf(outfile, "+ client_pp_hp=%s\n", util::format_hex(data, len).c_str()); +} + +void print_server_pp_hp(const uint8_t *data, size_t len) { + fprintf(outfile, "+ server_pp_hp=%s\n", util::format_hex(data, len).c_str()); +} + +void print_secrets(const uint8_t *secret, size_t secretlen, const uint8_t *key, + size_t keylen, const uint8_t *iv, size_t ivlen, + const uint8_t *hp, size_t hplen) { + std::cerr << "+ secret=" << util::format_hex(secret, secretlen) << "\n" + << "+ key=" << util::format_hex(key, keylen) << "\n" + << "+ iv=" << util::format_hex(iv, ivlen) << "\n" + << "+ hp=" << util::format_hex(hp, hplen) << std::endl; +} + +void print_secrets(const uint8_t *secret, size_t secretlen, const uint8_t *key, + size_t keylen, const uint8_t *iv, size_t ivlen) { + std::cerr << "+ secret=" << util::format_hex(secret, secretlen) << "\n" + << "+ key=" << util::format_hex(key, keylen) << "\n" + << "+ iv=" << util::format_hex(iv, ivlen) << std::endl; +} + +void print_hp_mask(const uint8_t *mask, size_t masklen, const uint8_t *sample, + size_t samplelen) { + fprintf(outfile, "mask=%s sample=%s\n", + util::format_hex(mask, masklen).c_str(), + util::format_hex(sample, samplelen).c_str()); +} + +void log_printf(void *user_data, const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fprintf(stderr, "\n"); +} + +void path_validation(const ngtcp2_path *path, + ngtcp2_path_validation_result res) { + auto local_addr = util::straddr( + reinterpret_cast<sockaddr *>(path->local.addr), path->local.addrlen); + auto remote_addr = util::straddr( + reinterpret_cast<sockaddr *>(path->remote.addr), path->remote.addrlen); + + std::cerr << "Path validation against path {local:" << local_addr + << ", remote:" << remote_addr << "} " + << (res == NGTCP2_PATH_VALIDATION_RESULT_SUCCESS ? "succeeded" + : "failed") + << std::endl; +} + +void print_http_begin_request_headers(int64_t stream_id) { + fprintf(outfile, "http: stream 0x%" PRIx64 " request headers started\n", + stream_id); +} + +void print_http_begin_response_headers(int64_t stream_id) { + fprintf(outfile, "http: stream 0x%" PRIx64 " response headers started\n", + stream_id); +} + +namespace { +void print_header(const uint8_t *name, size_t namelen, const uint8_t *value, + size_t valuelen, uint8_t flags) { + fprintf(outfile, "[%.*s: %.*s]%s\n", static_cast<int>(namelen), name, + static_cast<int>(valuelen), value, + (flags & NGHTTP3_NV_FLAG_NEVER_INDEX) ? "(sensitive)" : ""); +} +} // namespace + +namespace { +void print_header(const nghttp3_rcbuf *name, const nghttp3_rcbuf *value, + uint8_t flags) { + auto namebuf = nghttp3_rcbuf_get_buf(name); + auto valuebuf = nghttp3_rcbuf_get_buf(value); + print_header(namebuf.base, namebuf.len, valuebuf.base, valuebuf.len, flags); +} +} // namespace + +namespace { +void print_header(const nghttp3_nv &nv) { + print_header(nv.name, nv.namelen, nv.value, nv.valuelen, nv.flags); +} +} // namespace + +void print_http_header(int64_t stream_id, const nghttp3_rcbuf *name, + const nghttp3_rcbuf *value, uint8_t flags) { + fprintf(outfile, "http: stream 0x%" PRIx64 " ", stream_id); + print_header(name, value, flags); +} + +void print_http_end_headers(int64_t stream_id) { + fprintf(outfile, "http: stream 0x%" PRIx64 " headers ended\n", stream_id); +} + +void print_http_data(int64_t stream_id, const uint8_t *data, size_t datalen) { + fprintf(outfile, "http: stream 0x%" PRIx64 " body %zu bytes\n", stream_id, + datalen); + util::hexdump(outfile, data, datalen); +} + +void print_http_begin_trailers(int64_t stream_id) { + fprintf(outfile, "http: stream 0x%" PRIx64 " trailers started\n", stream_id); +} + +void print_http_end_trailers(int64_t stream_id) { + fprintf(outfile, "http: stream 0x%" PRIx64 " trailers ended\n", stream_id); +} + +void print_http_request_headers(int64_t stream_id, const nghttp3_nv *nva, + size_t nvlen) { + fprintf(outfile, "http: stream 0x%" PRIx64 " submit request headers\n", + stream_id); + for (size_t i = 0; i < nvlen; ++i) { + auto &nv = nva[i]; + print_header(nv); + } +} + +void print_http_response_headers(int64_t stream_id, const nghttp3_nv *nva, + size_t nvlen) { + fprintf(outfile, "http: stream 0x%" PRIx64 " submit response headers\n", + stream_id); + for (size_t i = 0; i < nvlen; ++i) { + auto &nv = nva[i]; + print_header(nv); + } +} + +std::string_view secret_title(ngtcp2_crypto_level level) { + switch (level) { + case NGTCP2_CRYPTO_LEVEL_EARLY: + return "early_traffic"sv; + case NGTCP2_CRYPTO_LEVEL_HANDSHAKE: + return "handshake_traffic"sv; + case NGTCP2_CRYPTO_LEVEL_APPLICATION: + return "application_traffic"sv; + default: + assert(0); + abort(); + } +} + +} // namespace debug + +} // namespace ngtcp2 |