summaryrefslogtreecommitdiffhomepage
path: root/src/event
diff options
context:
space:
mode:
Diffstat (limited to 'src/event')
-rw-r--r--src/event/quic/ngx_event_quic_output.c65
1 files changed, 61 insertions, 4 deletions
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)
{