nghttpx: Refactor quic

This commit is contained in:
Tatsuhiro Tsujikawa 2021-09-17 18:33:23 +09:00
parent 1320d7efab
commit fd107ab47c
5 changed files with 54 additions and 57 deletions

View File

@ -222,7 +222,7 @@ int get_new_connection_id(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token,
auto &quicconf = config->quic; auto &quicconf = config->quic;
if (generate_encrypted_quic_connection_id( 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) { quicconf.upstream.cid_encryption_key.data()) != 0) {
return NGTCP2_ERR_CALLBACK_FAILURE; 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 &quic_secret = worker->get_quic_secret();
auto &secret = quic_secret->stateless_reset_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) { secret.size()) != 0) {
return NGTCP2_ERR_CALLBACK_FAILURE; return NGTCP2_ERR_CALLBACK_FAILURE;
} }
auto quic_connection_handler = worker->get_quic_connection_handler(); 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; return 0;
} }
@ -251,7 +251,7 @@ int remove_connection_id(ngtcp2_conn *conn, const ngtcp2_cid *cid,
auto worker = handler->get_worker(); auto worker = handler->get_worker();
auto quic_conn_handler = worker->get_quic_connection_handler(); 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; return 0;
} }
@ -560,7 +560,7 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr,
ngtcp2_cid scid; ngtcp2_cid scid;
if (generate_encrypted_quic_connection_id( 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) { quicconf.upstream.cid_encryption_key.data()) != 0) {
return -1; return -1;
} }
@ -611,7 +611,7 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr,
auto &quic_secret = worker->get_quic_secret(); auto &quic_secret = worker->get_quic_secret();
auto &stateless_reset_secret = quic_secret->stateless_reset_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.data(),
stateless_reset_secret.size()); stateless_reset_secret.size());
if (rv != 0) { if (rv != 0) {
@ -643,8 +643,8 @@ int Http3Upstream::init(const UpstreamAddr *faddr, const Address &remote_addr,
return -1; return -1;
} }
quic_connection_handler->add_connection_id(&hashed_scid_, handler_); quic_connection_handler->add_connection_id(hashed_scid_, handler_);
quic_connection_handler->add_connection_id(&scid, handler_); quic_connection_handler->add_connection_id(scid, handler_);
return 0; return 0;
} }
@ -1336,7 +1336,7 @@ void Http3Upstream::on_handler_delete() {
scids.back() = hashed_scid_; scids.back() = hashed_scid_;
for (auto &cid : scids) { for (auto &cid : scids) {
quic_conn_handler->remove_connection_id(&cid); quic_conn_handler->remove_connection_id(cid);
} }
if (idle_close_ || retry_close_) { if (idle_close_ || retry_close_) {
@ -1632,7 +1632,7 @@ int Http3Upstream::on_read(const UpstreamAddr *faddr,
ngtcp2_cid_init(&ini_scid, scid, scidlen); ngtcp2_cid_init(&ini_scid, scid, scidlen);
quic_conn_handler->send_connection_close( 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); NGTCP2_CONNECTION_REFUSED);
return -1; return -1;

View File

@ -143,30 +143,30 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
return 0; return 0;
} }
int generate_quic_connection_id(ngtcp2_cid *cid, size_t cidlen) { int generate_quic_connection_id(ngtcp2_cid &cid, size_t cidlen) {
if (RAND_bytes(cid->data, cidlen) != 1) { if (RAND_bytes(cid.data, cidlen) != 1) {
return -1; return -1;
} }
cid->datalen = cidlen; cid.datalen = cidlen;
return 0; 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 *cid_prefix,
const uint8_t *key) { const uint8_t *key) {
assert(cidlen > SHRPX_QUIC_CID_PREFIXLEN); 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) { if (RAND_bytes(p, cidlen - SHRPX_QUIC_CID_PREFIXLEN) != 1) {
return -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, 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; 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, const uint8_t *secret,
size_t secretlen) { size_t secretlen) {
if (ngtcp2_crypto_generate_stateless_reset_token(token, secret, secretlen, if (ngtcp2_crypto_generate_stateless_reset_token(token, secret, secretlen,
cid) != 0) { &cid) != 0) {
return -1; 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, int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
socklen_t salen, const ngtcp2_cid *retry_scid, socklen_t salen, const ngtcp2_cid &retry_scid,
const ngtcp2_cid *odcid, const uint8_t *token_secret) { const ngtcp2_cid &odcid, const uint8_t *token_secret) {
auto t = std::chrono::duration_cast<std::chrono::nanoseconds>( auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::system_clock::now().time_since_epoch()) std::chrono::system_clock::now().time_since_epoch())
.count(); .count();
auto stokenlen = ngtcp2_crypto_generate_retry_token( auto stokenlen = ngtcp2_crypto_generate_retry_token(
token, token_secret, SHRPX_QUIC_TOKEN_SECRETLEN, sa, salen, retry_scid, token, token_secret, SHRPX_QUIC_TOKEN_SECRETLEN, sa, salen, &retry_scid,
odcid, t); &odcid, t);
if (stokenlen < 0) { if (stokenlen < 0) {
return -1; return -1;
} }
@ -283,17 +283,17 @@ int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
return 0; return 0;
} }
int verify_retry_token(ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen, int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen,
const ngtcp2_cid *dcid, const sockaddr *sa, const ngtcp2_cid &dcid, const sockaddr *sa,
socklen_t salen, const uint8_t *token_secret) { socklen_t salen, const uint8_t *token_secret) {
auto t = std::chrono::duration_cast<std::chrono::nanoseconds>( auto t = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::system_clock::now().time_since_epoch()) std::chrono::system_clock::now().time_since_epoch())
.count(); .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, SHRPX_QUIC_TOKEN_SECRETLEN, sa, salen,
dcid, 10 * NGTCP2_SECONDS, t) != 0) { &dcid, 10 * NGTCP2_SECONDS, t) != 0) {
return -1; return -1;
} }

View File

@ -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 local_salen, const uint8_t *data, size_t datalen,
size_t gso_size); 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 *cid_prefix,
const uint8_t *key); const uint8_t *key);
@ -95,7 +95,7 @@ int generate_quic_hashed_connection_id(ngtcp2_cid &dest,
const Address &local_addr, const Address &local_addr,
const ngtcp2_cid &cid); 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, const uint8_t *secret,
size_t secretlen); 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_quic_token_secret(uint8_t *secret);
int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, int generate_retry_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,
socklen_t salen, const ngtcp2_cid *retry_scid, socklen_t salen, const ngtcp2_cid &retry_scid,
const ngtcp2_cid *odcid, const uint8_t *token_secret); const ngtcp2_cid &odcid, const uint8_t *token_secret);
int verify_retry_token(ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen, int verify_retry_token(ngtcp2_cid &odcid, const uint8_t *token, size_t tokenlen,
const ngtcp2_cid *dcid, const sockaddr *sa, const ngtcp2_cid &dcid, const sockaddr *sa,
socklen_t salen, const uint8_t *token_secret); socklen_t salen, const uint8_t *token_secret);
int generate_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa, int generate_token(uint8_t *token, size_t &tokenlen, const sockaddr *sa,

View File

@ -181,7 +181,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
} }
if (worker_->get_graceful_shutdown()) { 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); local_addr, NGTCP2_CONNECTION_REFUSED);
return 0; return 0;
} }
@ -202,7 +202,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
switch (hd.token.base[0]) { switch (hd.token.base[0]) {
case NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY: 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, &remote_addr.su.sa, remote_addr.len,
secret.data()) != 0) { secret.data()) != 0) {
if (LOG_ENABLED(INFO)) { 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 // 2nd Retry packet is not allowed, so send CONNECTION_CLOSE
// with INVALID_TOKEN. // 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); local_addr, NGTCP2_INVALID_TOKEN);
return 0; return 0;
} }
@ -269,7 +269,7 @@ int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
} }
case NGTCP2_ERR_RETRY: case NGTCP2_ERR_RETRY:
if (worker_->get_graceful_shutdown()) { 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); local_addr, NGTCP2_CONNECTION_REFUSED);
return 0; return 0;
} }
@ -421,9 +421,7 @@ int QUICConnectionHandler::send_retry(
ngtcp2_cid retry_scid; ngtcp2_cid retry_scid;
retry_scid.datalen = SHRPX_QUIC_SCIDLEN; if (generate_quic_connection_id(retry_scid, SHRPX_QUIC_SCIDLEN) != 0) {
// We do not steer packet based on Retry CID.
if (RAND_bytes(retry_scid.data, retry_scid.datalen) != 1) {
return -1; return -1;
} }
@ -438,7 +436,7 @@ int QUICConnectionHandler::send_retry(
auto &secret = quic_secret->token_secret; auto &secret = quic_secret->token_secret;
if (generate_retry_token(token.data(), tokenlen, &remote_addr.su.sa, 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) { secret.data()) != 0) {
return -1; return -1;
} }
@ -539,7 +537,7 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr,
auto &quic_secret = worker_->get_quic_secret(); auto &quic_secret = worker_->get_quic_secret();
auto &secret = quic_secret->stateless_reset_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()); secret.size());
if (rv != 0) { if (rv != 0) {
return -1; return -1;
@ -574,13 +572,13 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr,
} }
int QUICConnectionHandler::send_connection_close( int QUICConnectionHandler::send_connection_close(
const UpstreamAddr *faddr, uint32_t version, const ngtcp2_cid *ini_dcid, const UpstreamAddr *faddr, uint32_t version, const ngtcp2_cid &ini_dcid,
const ngtcp2_cid *ini_scid, const Address &remote_addr, const ngtcp2_cid &ini_scid, const Address &remote_addr,
const Address &local_addr, uint64_t error_code) { const Address &local_addr, uint64_t error_code) {
std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf; std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf;
auto nwrite = ngtcp2_crypto_write_connection_close( 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) { if (nwrite < 0) {
LOG(ERROR) << "ngtcp2_crypto_write_connection_close failed"; LOG(ERROR) << "ngtcp2_crypto_write_connection_close failed";
return -1; return -1;
@ -590,9 +588,8 @@ int QUICConnectionHandler::send_connection_close(
LOG(INFO) << "Send Initial CONNECTION_CLOSE with error_code=" << log::hex LOG(INFO) << "Send Initial CONNECTION_CLOSE with error_code=" << log::hex
<< error_code << log::dec << error_code << log::dec
<< " to remote=" << util::to_numeric_addr(&remote_addr) << " to remote=" << util::to_numeric_addr(&remote_addr)
<< " dcid=" << util::format_hex(ini_scid->data, ini_scid->datalen) << " dcid=" << util::format_hex(ini_scid.data, ini_scid.datalen)
<< " scid=" << " scid=" << util::format_hex(ini_dcid.data, ini_dcid.datalen);
<< util::format_hex(ini_dcid->data, ini_dcid->datalen);
} }
return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
@ -600,13 +597,13 @@ int QUICConnectionHandler::send_connection_close(
0); 0);
} }
void QUICConnectionHandler::add_connection_id(const ngtcp2_cid *cid, void QUICConnectionHandler::add_connection_id(const ngtcp2_cid &cid,
ClientHandler *handler) { ClientHandler *handler) {
connections_.emplace(*cid, handler); connections_.emplace(cid, handler);
} }
void QUICConnectionHandler::remove_connection_id(const ngtcp2_cid *cid) { void QUICConnectionHandler::remove_connection_id(const ngtcp2_cid &cid) {
connections_.erase(*cid); connections_.erase(cid);
} }
void QUICConnectionHandler::add_close_wait(CloseWait *cw) { void QUICConnectionHandler::add_close_wait(CloseWait *cw) {

View File

@ -110,8 +110,8 @@ public:
// |ini_scid| is the source Connection ID which appeared in Client // |ini_scid| is the source Connection ID which appeared in Client
// Initial packet. // Initial packet.
int send_connection_close(const UpstreamAddr *faddr, uint32_t version, int send_connection_close(const UpstreamAddr *faddr, uint32_t version,
const ngtcp2_cid *ini_dcid, const ngtcp2_cid &ini_dcid,
const ngtcp2_cid *ini_scid, const ngtcp2_cid &ini_scid,
const Address &remote_addr, const Address &remote_addr,
const Address &local_addr, uint64_t error_code); const Address &local_addr, uint64_t error_code);
ClientHandler *handle_new_connection(const UpstreamAddr *faddr, ClientHandler *handle_new_connection(const UpstreamAddr *faddr,
@ -120,8 +120,8 @@ public:
const ngtcp2_pkt_hd &hd, const ngtcp2_pkt_hd &hd,
const ngtcp2_cid *odcid, const ngtcp2_cid *odcid,
const uint8_t *token, size_t tokenlen); const uint8_t *token, size_t tokenlen);
void add_connection_id(const ngtcp2_cid *cid, ClientHandler *handler); void add_connection_id(const ngtcp2_cid &cid, ClientHandler *handler);
void remove_connection_id(const ngtcp2_cid *cid); void remove_connection_id(const ngtcp2_cid &cid);
void add_close_wait(CloseWait *cw); void add_close_wait(CloseWait *cw);
void remove_close_wait(const CloseWait *cw); void remove_close_wait(const CloseWait *cw);