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;
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;

View File

@ -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::nanoseconds>(
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::nanoseconds>(
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;
}

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 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,

View File

@ -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<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> 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) {

View File

@ -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);