From 9b2982510e5da8af2e44dc5ee26df14392b79c44 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 17 Aug 2021 21:48:11 +0900 Subject: [PATCH] nghttpx: Send stateless reset --- src/shrpx_quic_connection_handler.cc | 52 ++++++++++++++++++++++++++++ src/shrpx_quic_connection_handler.h | 3 ++ 2 files changed, 55 insertions(+) diff --git a/src/shrpx_quic_connection_handler.cc b/src/shrpx_quic_connection_handler.cc index 3d6d97ed..7fc1965a 100644 --- a/src/shrpx_quic_connection_handler.cc +++ b/src/shrpx_quic_connection_handler.cc @@ -92,6 +92,8 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr, remote_addr, local_addr); return 0; default: + // TODO Must be rate limited + send_stateless_reset(faddr, dcid, dcidlen, remote_addr, local_addr); return 0; } @@ -217,6 +219,56 @@ int QUICConnectionHandler::send_version_negotiation( 0); } +int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr, + const uint8_t *dcid, + size_t dcidlen, + const Address &remote_addr, + const Address &local_addr) { + int rv; + std::array token; + ngtcp2_cid cid; + + ngtcp2_cid_init(&cid, dcid, dcidlen); + + auto config = get_config(); + auto &quicconf = config->quic; + auto &stateless_resetconf = quicconf.stateless_reset; + + rv = generate_quic_stateless_reset_token(token.data(), &cid, + stateless_resetconf.secret.data(), + stateless_resetconf.secret.size()); + if (rv != 0) { + return -1; + } + + std::array rand_bytes; + + if (RAND_bytes(rand_bytes.data(), rand_bytes.size()) != 1) { + return -1; + } + + std::array buf; + + auto nwrite = + ngtcp2_pkt_write_stateless_reset(buf.data(), buf.size(), token.data(), + rand_bytes.data(), rand_bytes.size()); + if (nwrite < 0) { + LOG(ERROR) << "ngtcp2_pkt_write_stateless_reset: " + << ngtcp2_strerror(nwrite); + return -1; + } + + if (LOG_ENABLED(INFO)) { + LOG(INFO) << "Send stateless_reset to remote=" + << util::to_numeric_addr(&remote_addr) + << " dcid=" << util::format_hex(dcid, dcidlen); + } + + return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, + &local_addr.su.sa, local_addr.len, buf.data(), nwrite, + 0); +} + void QUICConnectionHandler::add_connection_id(const ngtcp2_cid *cid, ClientHandler *handler) { auto key = make_cid_key(cid); diff --git a/src/shrpx_quic_connection_handler.h b/src/shrpx_quic_connection_handler.h index 38b2f217..d4941ffe 100644 --- a/src/shrpx_quic_connection_handler.h +++ b/src/shrpx_quic_connection_handler.h @@ -55,6 +55,9 @@ public: const uint8_t *scid, size_t scidlen, const Address &remote_addr, const Address &local_addr); + int send_stateless_reset(const UpstreamAddr *faddr, const uint8_t *dcid, + size_t dcidlen, const Address &remote_addr, + const Address &local_addr); ClientHandler *handle_new_connection(const UpstreamAddr *faddr, const Address &remote_addr, const Address &local_addr,