From e998d125abc5cc2134bced24a509c095081e4a4d Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 31 Aug 2021 13:23:52 +0900 Subject: [PATCH] nghttpx: Send CONNECTION_CLOSE if Retry token validation failed --- src/shrpx_quic_connection_handler.cc | 33 ++++++++++++++++++++++++++-- src/shrpx_quic_connection_handler.h | 9 ++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/shrpx_quic_connection_handler.cc b/src/shrpx_quic_connection_handler.cc index 5f7bdfcd..0f62e7d5 100644 --- a/src/shrpx_quic_connection_handler.cc +++ b/src/shrpx_quic_connection_handler.cc @@ -127,8 +127,10 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr, if (verify_retry_token(&odcid, hd.token.base, hd.token.len, &hd.dcid, &remote_addr.su.sa, remote_addr.len, secret.data()) != 0) { - // 2nd Retry packet is not allowed, so just drop it or send - // CONNECTIONC_CLOE with INVALID_TOKEN. + // 2nd Retry packet is not allowed, so send CONNECTIONC_CLOE + // with INVALID_TOKEN. + send_connection_close(faddr, version, &hd.dcid, &hd.scid, remote_addr, + local_addr, NGTCP2_INVALID_TOKEN); return 0; } @@ -406,6 +408,33 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr, 0); } +int QUICConnectionHandler::send_connection_close( + const UpstreamAddr *faddr, uint32_t version, const ngtcp2_cid *ini_dcid, + const ngtcp2_cid *ini_scid, const Address &remote_addr, + const Address &local_addr, uint64_t error_code) { + std::array buf; + + auto nwrite = ngtcp2_crypto_write_connection_close( + buf.data(), buf.size(), version, ini_scid, ini_dcid, error_code); + if (nwrite < 0) { + LOG(ERROR) << "ngtcp2_crypto_write_connection_close failed"; + return -1; + } + + if (LOG_ENABLED(INFO)) { + LOG(INFO) << "Send Initial CONNECTION_CLOSE with error_code=" << log::hex + << error_code << log::dec + << " to remote=" << util::to_numeric_addr(&remote_addr) + << " dcid=" << util::format_hex(ini_scid->data, ini_scid->datalen) + << " scid=" + << util::format_hex(ini_dcid->data, ini_dcid->datalen); + } + + 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 a536c170..f045a839 100644 --- a/src/shrpx_quic_connection_handler.h +++ b/src/shrpx_quic_connection_handler.h @@ -71,6 +71,15 @@ public: int send_stateless_reset(const UpstreamAddr *faddr, const uint8_t *dcid, size_t dcidlen, const Address &remote_addr, const Address &local_addr); + // Send Initial CONNECTION_CLOSE. |ini_dcid| is the destination + // Connection ID which appeared in Client Initial packet. + // |ini_scid| is the source Connection ID which appeared in Client + // Initial packet. + int send_connection_close(const UpstreamAddr *faddr, uint32_t version, + const ngtcp2_cid *ini_dcid, + const ngtcp2_cid *ini_scid, + const Address &remote_addr, + const Address &local_addr, uint64_t error_code); ClientHandler *handle_new_connection(const UpstreamAddr *faddr, const Address &remote_addr, const Address &local_addr,