mirror of
https://github.com/nginx/nginx.git
synced 2026-07-16 12:23:00 -04:00
QUIC: Stateless Reset rate limiting.
Some checks are pending
buildbot / buildbot (push) Waiting to run
Some checks are pending
buildbot / buildbot (push) Waiting to run
It uses a bloom filter to limit sending Stateless Reset packets no more than once per second in average for the given address. This allows to address resource asymmetry from precomputed packets, as well as to limit potential Stateless Reset exchange.
This commit is contained in:
parent
2f039e6f72
commit
e6ffe8384e
1 changed files with 61 additions and 4 deletions
|
|
@ -64,6 +64,7 @@ static ssize_t ngx_quic_send(ngx_connection_t *c, u_char *buf, size_t len,
|
|||
struct sockaddr *sockaddr, socklen_t socklen);
|
||||
static void ngx_quic_set_packet_number(ngx_quic_header_t *pkt,
|
||||
ngx_quic_send_ctx_t *ctx);
|
||||
static ngx_int_t ngx_quic_stateless_reset_filter(ngx_connection_t *c);
|
||||
|
||||
|
||||
ngx_int_t
|
||||
|
|
@ -823,10 +824,11 @@ ngx_int_t
|
|||
ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
||||
ngx_quic_header_t *pkt)
|
||||
{
|
||||
u_char *token;
|
||||
size_t len, max;
|
||||
uint16_t rndbytes;
|
||||
u_char buf[NGX_QUIC_MAX_SR_PACKET];
|
||||
u_char *token;
|
||||
size_t len, max;
|
||||
uint16_t rndbytes;
|
||||
ngx_int_t rc;
|
||||
u_char buf[NGX_QUIC_MAX_SR_PACKET];
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic handle stateless reset output");
|
||||
|
|
@ -835,6 +837,11 @@ ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
|||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
rc = ngx_quic_stateless_reset_filter(c);
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (pkt->len <= NGX_QUIC_MIN_SR_PACKET) {
|
||||
len = pkt->len - 1;
|
||||
|
||||
|
|
@ -870,6 +877,56 @@ ngx_quic_send_stateless_reset(ngx_connection_t *c, ngx_quic_conf_t *conf,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_stateless_reset_filter(ngx_connection_t *c)
|
||||
{
|
||||
time_t now;
|
||||
u_char salt;
|
||||
ngx_uint_t i, n, m, hit;
|
||||
u_char hash[20];
|
||||
|
||||
static time_t t;
|
||||
static u_char rndbyte;
|
||||
static uint8_t bitmap[65536];
|
||||
|
||||
now = ngx_time();
|
||||
|
||||
if (t != now) {
|
||||
t = now;
|
||||
|
||||
if (RAND_bytes(&rndbyte, 1) != 1) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(bitmap, sizeof(bitmap));
|
||||
}
|
||||
|
||||
hit = 0;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
salt = rndbyte + i;
|
||||
|
||||
ngx_quic_address_hash(c->sockaddr, c->socklen, 0, &salt, 1, hash);
|
||||
|
||||
n = hash[0] | hash[1] << 8;
|
||||
m = 1 << hash[2] % 8;
|
||||
|
||||
if (!(bitmap[n] & m)) {
|
||||
bitmap[n] |= m;
|
||||
|
||||
} else {
|
||||
hit++;
|
||||
}
|
||||
}
|
||||
|
||||
if (hit == 3) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_quic_send_cc(ngx_connection_t *c)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue