nghttpx: Store Retry in CloseWait to rate limit its transmission
This commit is contained in:
parent
095ee9683d
commit
7cdc6cfa6d
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue