From fd107ab47cdf456c9c662f39062c3b3bc53d71c4 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 17 Sep 2021 18:33:23 +0900 Subject: [PATCH] nghttpx: Refactor quic --- src/shrpx_http3_upstream.cc | 20 ++++++++-------- src/shrpx_quic.cc | 34 +++++++++++++-------------- src/shrpx_quic.h | 14 +++++------ src/shrpx_quic_connection_handler.cc | 35 +++++++++++++--------------- src/shrpx_quic_connection_handler.h | 8 +++---- 5 files changed, 54 insertions(+), 57 deletions(-) diff --git a/src/shrpx_http3_upstream.cc b/src/shrpx_http3_upstream.cc index b3c509f5..68775eb2 100644 --- a/src/shrpx_http3_upstream.cc +++ b/src/shrpx_http3_upstream.cc @@ -222,7 +222,7 @@ int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token, auto &quicconf = config->quic; if (generate_encrypted_quic_connection_id( - cid, cidlen, worker->get_cid_prefix(), + *cid, cidlen, worker->get_cid_prefix(), quicconf.upstream.cid_encryption_key.data()) != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -230,14 +230,14 @@ int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token, auto &quic_secret = worker->get_quic_secret(); auto &secret = quic_secret->stateless_reset_secret; - if (generate_quic_stateless_reset_token(token, cid, secret.data(), + if (generate_quic_stateless_reset_token(token, *cid, secret.data(), secret.size()) != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } auto quic_connection_handler = worker->get_quic_connection_handler(); - quic_connection_handler->add_connection_id(cid, handler); + quic_connection_handler->add_connection_id(*cid, handler); return 0; } @@ -251,7 +251,7 @@ int remove_connection_id(ngtcp2_conn *conn, const ngtcp2_cid *cid, auto worker = handler->get_worker(); auto quic_conn_handler = worker->get_quic_connection_handler(); - quic_conn_handler->remove_connection_id(cid); + quic_conn_handler->remove_connection_id(*cid); return 0; } @@ -560,7 +560,7 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr, ngtcp2_cid scid; if (generate_encrypted_quic_connection_id( - &scid, SHRPX_QUIC_SCIDLEN, worker->get_cid_prefix(), + scid, SHRPX_QUIC_SCIDLEN, worker->get_cid_prefix(), quicconf.upstream.cid_encryption_key.data()) != 0) { return -1; } @@ -611,7 +611,7 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr, auto &quic_secret = worker->get_quic_secret(); auto &stateless_reset_secret = quic_secret->stateless_reset_secret; - rv = generate_quic_stateless_reset_token(params.stateless_reset_token, &scid, + rv = generate_quic_stateless_reset_token(params.stateless_reset_token, scid, stateless_reset_secret.data(), stateless_reset_secret.size()); if (rv != 0) { @@ -643,8 +643,8 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr, return -1; } - quic_connection_handler->add_connection_id(&hashed_scid_, handler_); - quic_connection_handler->add_connection_id(&scid, handler_); + quic_connection_handler->add_connection_id(hashed_scid_, handler_); + quic_connection_handler->add_connection_id(scid, handler_); return 0; } @@ -1336,7 +1336,7 @@ void Http3Upstream::on_handler_delete() { scids.back() = hashed_scid_; for (auto &cid : scids) { - quic_conn_handler->remove_connection_id(&cid); + quic_conn_handler->remove_connection_id(cid); } if (idle_close_ || retry_close_) { @@ -1632,7 +1632,7 @@ int Http3Upstream::on_read(const UpstreamAddr *faddr, ngtcp2_cid_init(&ini_scid, scid, scidlen); quic_conn_handler->send_connection_close( - faddr, version, &ini_dcid, &ini_scid, remote_addr, local_addr, + faddr, version, ini_dcid, ini_scid, remote_addr, local_addr, NGTCP2_CONNECTION_REFUSED); return -1; diff --git a/src/shrpx_quic.cc b/src/shrpx_quic.cc index fc710b48..aa38617a 100644 --- a/src/shrpx_quic.cc +++ b/src/shrpx_quic.cc @@ -143,30 +143,30 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, return 0; } -int generate_quic_connection_id(ngtcp2_cid *cid, size_t cidlen) { - if (RAND_bytes(cid->data, cidlen) != 1) { +int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen) { + if (RAND_bytes(cid.data, cidlen) != 1) { return -1; } - cid->datalen = cidlen; + cid.datalen = cidlen; return 0; } -int generate_encrypted_quic_connection_id(ngtcp2_cid *cid, size_t cidlen, +int generate_encrypted_quic_connection_id(ngtcp2_cid &cid, size_t cidlen, const uint8_t *cid_prefix, const uint8_t *key) { assert(cidlen > SHRPX_QUIC_CID_PREFIXLEN); - auto p = std::copy_n(cid_prefix, SHRPX_QUIC_CID_PREFIXLEN, cid->data); + auto p = std::copy_n(cid_prefix, SHRPX_QUIC_CID_PREFIXLEN, cid.data); if (RAND_bytes(p, cidlen - SHRPX_QUIC_CID_PREFIXLEN) != 1) { return -1; } - cid->datalen = cidlen; + cid.datalen = cidlen; - return encrypt_quic_connection_id(cid->data, cid->data, key); + return encrypt_quic_connection_id(cid.data, cid.data, key); } int encrypt_quic_connection_id(uint8_t *dest, const uint8_t *src, @@ -237,11 +237,11 @@ int generate_quic_hashed_connection_id(ngtcp2_cid &dest, return 0; } -int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid *cid, +int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid &cid, const uint8_t *secret, size_t secretlen) { if (ngtcp2_crypto_generate_stateless_reset_token(token, secret, secretlen, - cid) != 0) { + &cid) != 0) { return -1; } @@ -265,15 +265,15 @@ int generate_quic_token_secret(uint8_t *secret) { } int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, - socklen_t salen, const ngtcp2_cid *retry_scid, - const ngtcp2_cid *odcid, const uint8_t *token_secret) { + socklen_t salen, const ngtcp2_cid &retry_scid, + const ngtcp2_cid &odcid, const uint8_t *token_secret) { auto t = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count(); auto stokenlen = ngtcp2_crypto_generate_retry_token( - token, token_secret, SHRPX_QUIC_TOKEN_SECRETLEN, sa, salen, retry_scid, - odcid, t); + token, token_secret, SHRPX_QUIC_TOKEN_SECRETLEN, sa, salen, &retry_scid, + &odcid, t); if (stokenlen < 0) { return -1; } @@ -283,17 +283,17 @@ int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, return 0; } -int verify_retry_token(ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen, - const ngtcp2_cid *dcid, const sockaddr *sa, +int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen, + const ngtcp2_cid &dcid, const sockaddr *sa, socklen_t salen, const uint8_t *token_secret) { auto t = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count(); - if (ngtcp2_crypto_verify_retry_token(odcid, token, tokenlen, token_secret, + if (ngtcp2_crypto_verify_retry_token(&odcid, token, tokenlen, token_secret, SHRPX_QUIC_TOKEN_SECRETLEN, sa, salen, - dcid, 10 * NGTCP2_SECONDS, t) != 0) { + &dcid, 10 * NGTCP2_SECONDS, t) != 0) { return -1; } diff --git a/src/shrpx_quic.h b/src/shrpx_quic.h index 8bf6e4ab..96a109fc 100644 --- a/src/shrpx_quic.h +++ b/src/shrpx_quic.h @@ -78,9 +78,9 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, size_t local_salen, const uint8_t *data, size_t datalen, size_t gso_size); -int generate_quic_connection_id(ngtcp2_cid *cid, size_t cidlen); +int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen); -int generate_encrypted_quic_connection_id(ngtcp2_cid *cid, size_t cidlen, +int generate_encrypted_quic_connection_id(ngtcp2_cid &cid, size_t cidlen, const uint8_t *cid_prefix, const uint8_t *key); @@ -95,7 +95,7 @@ int generate_quic_hashed_connection_id(ngtcp2_cid &dest, const Address &local_addr, const ngtcp2_cid &cid); -int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid *cid, +int generate_quic_stateless_reset_token(uint8_t *token, const ngtcp2_cid &cid, const uint8_t *secret, size_t secretlen); @@ -104,11 +104,11 @@ int generate_quic_stateless_reset_secret(uint8_t *secret); int generate_quic_token_secret(uint8_t *secret); int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, - socklen_t salen, const ngtcp2_cid *retry_scid, - const ngtcp2_cid *odcid, const uint8_t *token_secret); + socklen_t salen, const ngtcp2_cid &retry_scid, + const ngtcp2_cid &odcid, const uint8_t *token_secret); -int verify_retry_token(ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen, - const ngtcp2_cid *dcid, const sockaddr *sa, +int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen, + const ngtcp2_cid &dcid, const sockaddr *sa, socklen_t salen, const uint8_t *token_secret); int generate_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, diff --git a/src/shrpx_quic_connection_handler.cc b/src/shrpx_quic_connection_handler.cc index 28b6c17c..41b8b9e4 100644 --- a/src/shrpx_quic_connection_handler.cc +++ b/src/shrpx_quic_connection_handler.cc @@ -181,7 +181,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr, } if (worker_->get_graceful_shutdown()) { - send_connection_close(faddr, version, &hd.dcid, &hd.scid, remote_addr, + send_connection_close(faddr, version, hd.dcid, hd.scid, remote_addr, local_addr, NGTCP2_CONNECTION_REFUSED); return 0; } @@ -202,7 +202,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr, switch (hd.token.base[0]) { case NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY: - if (verify_retry_token(&odcid, hd.token.base, hd.token.len, &hd.dcid, + if (verify_retry_token(odcid, hd.token.base, hd.token.len, hd.dcid, &remote_addr.su.sa, remote_addr.len, secret.data()) != 0) { if (LOG_ENABLED(INFO)) { @@ -212,7 +212,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr, // 2nd Retry packet is not allowed, so send CONNECTION_CLOSE // with INVALID_TOKEN. - send_connection_close(faddr, version, &hd.dcid, &hd.scid, remote_addr, + send_connection_close(faddr, version, hd.dcid, hd.scid, remote_addr, local_addr, NGTCP2_INVALID_TOKEN); return 0; } @@ -269,7 +269,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr, } case NGTCP2_ERR_RETRY: if (worker_->get_graceful_shutdown()) { - send_connection_close(faddr, version, &hd.dcid, &hd.scid, remote_addr, + send_connection_close(faddr, version, hd.dcid, hd.scid, remote_addr, local_addr, NGTCP2_CONNECTION_REFUSED); return 0; } @@ -421,9 +421,7 @@ int QUICConnectionHandler::send_retry( ngtcp2_cid retry_scid; - retry_scid.datalen = SHRPX_QUIC_SCIDLEN; - // We do not steer packet based on Retry CID. - if (RAND_bytes(retry_scid.data, retry_scid.datalen) != 1) { + if (generate_quic_connection_id(retry_scid, SHRPX_QUIC_SCIDLEN) != 0) { return -1; } @@ -438,7 +436,7 @@ int QUICConnectionHandler::send_retry( auto &secret = quic_secret->token_secret; if (generate_retry_token(token.data(), tokenlen, &remote_addr.su.sa, - remote_addr.len, &retry_scid, &idcid, + remote_addr.len, retry_scid, idcid, secret.data()) != 0) { return -1; } @@ -539,7 +537,7 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr, auto &quic_secret = worker_->get_quic_secret(); auto &secret = quic_secret->stateless_reset_secret; - rv = generate_quic_stateless_reset_token(token.data(), &cid, secret.data(), + rv = generate_quic_stateless_reset_token(token.data(), cid, secret.data(), secret.size()); if (rv != 0) { return -1; @@ -574,13 +572,13 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr, } 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 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); + buf.data(), buf.size(), version, &ini_scid, &ini_dcid, error_code); if (nwrite < 0) { LOG(ERROR) << "ngtcp2_crypto_write_connection_close failed"; return -1; @@ -590,9 +588,8 @@ int QUICConnectionHandler::send_connection_close( 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); + << " 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, @@ -600,13 +597,13 @@ int QUICConnectionHandler::send_connection_close( 0); } -void QUICConnectionHandler::add_connection_id(const ngtcp2_cid *cid, +void QUICConnectionHandler::add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler) { - connections_.emplace(*cid, handler); + connections_.emplace(cid, handler); } -void QUICConnectionHandler::remove_connection_id(const ngtcp2_cid *cid) { - connections_.erase(*cid); +void QUICConnectionHandler::remove_connection_id(const ngtcp2_cid &cid) { + connections_.erase(cid); } void QUICConnectionHandler::add_close_wait(CloseWait *cw) { diff --git a/src/shrpx_quic_connection_handler.h b/src/shrpx_quic_connection_handler.h index 95e598f5..39c1b7d2 100644 --- a/src/shrpx_quic_connection_handler.h +++ b/src/shrpx_quic_connection_handler.h @@ -110,8 +110,8 @@ public: // |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 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, @@ -120,8 +120,8 @@ public: const ngtcp2_pkt_hd &hd, const ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen); - void add_connection_id(const ngtcp2_cid *cid, ClientHandler *handler); - void remove_connection_id(const ngtcp2_cid *cid); + void add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler); + void remove_connection_id(const ngtcp2_cid &cid); void add_close_wait(CloseWait *cw); void remove_close_wait(const CloseWait *cw);