nghttpx: Rate limit Stateless Reset transmission
This commit is contained in:
parent
67afbbbaa6
commit
85347e12de
|
@ -64,6 +64,7 @@ constexpr size_t SHRPX_QUIC_STATELESS_RESET_SECRETLEN = 32;
|
||||||
constexpr size_t SHRPX_QUIC_TOKEN_SECRETLEN = 32;
|
constexpr size_t SHRPX_QUIC_TOKEN_SECRETLEN = 32;
|
||||||
constexpr size_t SHRPX_QUIC_TOKEN_RAND_DATALEN = 16;
|
constexpr size_t SHRPX_QUIC_TOKEN_RAND_DATALEN = 16;
|
||||||
constexpr size_t SHRPX_QUIC_CONN_CLOSE_PKTLEN = 256;
|
constexpr size_t SHRPX_QUIC_CONN_CLOSE_PKTLEN = 256;
|
||||||
|
constexpr size_t SHRPX_QUIC_STATELESS_RESET_BURST = 100;
|
||||||
|
|
||||||
// SHRPX_QUIC_RETRY_TOKEN_MAGIC is the magic byte of Retry token.
|
// SHRPX_QUIC_RETRY_TOKEN_MAGIC is the magic byte of Retry token.
|
||||||
// Sent in plaintext.
|
// Sent in plaintext.
|
||||||
|
|
|
@ -37,10 +37,26 @@
|
||||||
|
|
||||||
namespace shrpx {
|
namespace shrpx {
|
||||||
|
|
||||||
QUICConnectionHandler::QUICConnectionHandler(Worker *worker)
|
namespace {
|
||||||
: worker_{worker} {}
|
void stateless_reset_bucket_regen_timercb(struct ev_loop *loop, ev_timer *w,
|
||||||
|
int revents) {
|
||||||
|
auto quic_conn_handler = static_cast<QUICConnectionHandler *>(w->data);
|
||||||
|
|
||||||
QUICConnectionHandler::~QUICConnectionHandler() {}
|
quic_conn_handler->on_stateless_reset_bucket_regen();
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
QUICConnectionHandler::QUICConnectionHandler(Worker *worker)
|
||||||
|
: worker_{worker},
|
||||||
|
stateless_reset_bucket_{SHRPX_QUIC_STATELESS_RESET_BURST} {
|
||||||
|
ev_timer_init(&stateless_reset_bucket_regen_timer_,
|
||||||
|
stateless_reset_bucket_regen_timercb, 0., 1.);
|
||||||
|
stateless_reset_bucket_regen_timer_.data = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUICConnectionHandler::~QUICConnectionHandler() {
|
||||||
|
ev_timer_stop(worker_->get_loop(), &stateless_reset_bucket_regen_timer_);
|
||||||
|
}
|
||||||
|
|
||||||
int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
|
int QUICConnectionHandler::handle_packet(const UpstreamAddr *faddr,
|
||||||
const Address &remote_addr,
|
const Address &remote_addr,
|
||||||
|
@ -378,6 +394,20 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr,
|
||||||
size_t dcidlen,
|
size_t dcidlen,
|
||||||
const Address &remote_addr,
|
const Address &remote_addr,
|
||||||
const Address &local_addr) {
|
const Address &local_addr) {
|
||||||
|
if (stateless_reset_bucket_ == 0) {
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
LOG(INFO) << "Stateless Reset bucket has been depleted";
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
--stateless_reset_bucket_;
|
||||||
|
|
||||||
|
if (!ev_is_active(&stateless_reset_bucket_regen_timer_)) {
|
||||||
|
ev_timer_again(worker_->get_loop(), &stateless_reset_bucket_regen_timer_);
|
||||||
|
}
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
std::array<uint8_t, NGTCP2_STATELESS_RESET_TOKENLEN> token;
|
std::array<uint8_t, NGTCP2_STATELESS_RESET_TOKENLEN> token;
|
||||||
ngtcp2_cid cid;
|
ngtcp2_cid cid;
|
||||||
|
@ -469,6 +499,14 @@ void QUICConnectionHandler::remove_close_wait(const CloseWait *cw) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QUICConnectionHandler::on_stateless_reset_bucket_regen() {
|
||||||
|
assert(stateless_reset_bucket_ < SHRPX_QUIC_STATELESS_RESET_BURST);
|
||||||
|
|
||||||
|
if (++stateless_reset_bucket_ == SHRPX_QUIC_STATELESS_RESET_BURST) {
|
||||||
|
ev_timer_stop(worker_->get_loop(), &stateless_reset_bucket_regen_timer_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void close_wait_timeoutcb(struct ev_loop *loop, ev_timer *w,
|
static void close_wait_timeoutcb(struct ev_loop *loop, ev_timer *w,
|
||||||
int revents) {
|
int revents) {
|
||||||
auto cw = static_cast<CloseWait *>(w->data);
|
auto cw = static_cast<CloseWait *>(w->data);
|
||||||
|
|
|
@ -126,10 +126,14 @@ public:
|
||||||
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);
|
||||||
|
|
||||||
|
void on_stateless_reset_bucket_regen();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Worker *worker_;
|
Worker *worker_;
|
||||||
std::unordered_map<ngtcp2_cid, ClientHandler *> connections_;
|
std::unordered_map<ngtcp2_cid, ClientHandler *> connections_;
|
||||||
std::unordered_map<ngtcp2_cid, CloseWait *> close_waits_;
|
std::unordered_map<ngtcp2_cid, CloseWait *> close_waits_;
|
||||||
|
ev_timer stateless_reset_bucket_regen_timer_;
|
||||||
|
size_t stateless_reset_bucket_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
Loading…
Reference in New Issue