diff --git a/src/event/quic/ngx_event_quic_output.c b/src/event/quic/ngx_event_quic_output.c index 72119a8ea..f98c834a1 100644 --- a/src/event/quic/ngx_event_quic_output.c +++ b/src/event/quic/ngx_event_quic_output.c @@ -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) {