nghttpx: Store Retry in CloseWait to rate limit its transmission

This commit is contained in:
Tatsuhiro Tsujikawa 2021-09-17 17:52:05 +09:00
parent 095ee9683d
commit 7cdc6cfa6d
2 changed files with 35 additions and 15 deletions

View File

@ -431,7 +431,8 @@ int QUICConnectionHandler::send_retry(
return -1; return -1;
} }
std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf; std::vector<uint8_t> buf;
buf.resize(256);
auto nwrite = auto nwrite =
ngtcp2_crypto_write_retry(buf.data(), buf.size(), version, &iscid, ngtcp2_crypto_write_retry(buf.data(), buf.size(), version, &iscid,
@ -441,9 +442,28 @@ int QUICConnectionHandler::send_retry(
return -1; return -1;
} }
return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, buf.resize(nwrite);
&local_addr.su.sa, local_addr.len, buf.data(), nwrite,
quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, buf.data(), buf.size(),
0); 0);
if (generate_quic_hashed_connection_id(idcid, remote_addr, local_addr,
idcid) != 0) {
return -1;
}
auto d =
static_cast<ev_tstamp>(NGTCP2_DEFAULT_INITIAL_RTT * 3) / NGTCP2_SECONDS;
auto cw = std::make_unique<CloseWait>(worker_, std::vector<ngtcp2_cid>{idcid},
std::move(buf), d);
add_close_wait(cw.get());
cw.release();
return 0;
} }
int QUICConnectionHandler::send_version_negotiation( int QUICConnectionHandler::send_version_negotiation(
@ -607,10 +627,10 @@ static void close_wait_timeoutcb(struct ev_loop *loop, ev_timer *w,
} }
CloseWait::CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids, CloseWait::CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids,
std::vector<uint8_t> conn_close, ev_tstamp period) std::vector<uint8_t> pkt, ev_tstamp period)
: worker{worker}, : worker{worker},
scids{std::move(scids)}, scids{std::move(scids)},
conn_close{std::move(conn_close)}, pkt{std::move(pkt)},
bytes_recv{0}, bytes_recv{0},
bytes_sent{0}, bytes_sent{0},
num_pkts_recv{0}, num_pkts_recv{0},
@ -641,26 +661,26 @@ int CloseWait::handle_packet(const UpstreamAddr *faddr,
const Address &remote_addr, const Address &remote_addr,
const Address &local_addr, const uint8_t *data, const Address &local_addr, const uint8_t *data,
size_t datalen) { size_t datalen) {
if (conn_close.empty()) { if (pkt.empty()) {
return 0; return 0;
} }
++num_pkts_recv; ++num_pkts_recv;
bytes_recv += datalen; bytes_recv += datalen;
if (bytes_sent + conn_close.size() > 3 * bytes_recv || if (bytes_sent + pkt.size() > 3 * bytes_recv ||
next_pkts_recv > num_pkts_recv) { next_pkts_recv > num_pkts_recv) {
return 0; return 0;
} }
if (quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, if (quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, conn_close.data(), &local_addr.su.sa, local_addr.len, pkt.data(),
conn_close.size(), 0) != 0) { pkt.size(), 0) != 0) {
return -1; return -1;
} }
next_pkts_recv *= 2; next_pkts_recv *= 2;
bytes_sent += conn_close.size(); bytes_sent += pkt.size();
return 0; return 0;
} }

View File

@ -51,7 +51,7 @@ class Worker;
// closing period). // closing period).
struct CloseWait { struct CloseWait {
CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids, CloseWait(Worker *worker, std::vector<ngtcp2_cid> scids,
std::vector<uint8_t> conn_close, ev_tstamp period); std::vector<uint8_t> pkt, ev_tstamp period);
~CloseWait(); ~CloseWait();
int handle_packet(const UpstreamAddr *faddr, const Address &remote_addr, int handle_packet(const UpstreamAddr *faddr, const Address &remote_addr,
@ -61,9 +61,9 @@ struct CloseWait {
Worker *worker; Worker *worker;
// Source Connection IDs of the connection. // Source Connection IDs of the connection.
std::vector<ngtcp2_cid> scids; std::vector<ngtcp2_cid> scids;
// QUIC packet containing CONNECTION_CLOSE. It is empty when a // QUIC packet which is sent in response to the incoming packet. It
// connection entered in draining state. // might be empty.
std::vector<uint8_t> conn_close; std::vector<uint8_t> pkt;
// Close-wait (draining or closing period) timer. // Close-wait (draining or closing period) timer.
ev_timer timer; ev_timer timer;
// The number of bytes received during close-wait period. // The number of bytes received during close-wait period.