annotate src/http/v3/ngx_http_v3.c @ 9189:fcec773dd249

QUIC: avoid partial expansion of PATH_CHALLENGE/PATH_RESPONSE. By default packets with these frames are expanded to 1200 bytes. Previously, if anti-amplification limit did not allow this expansion, it was limited to whatever size was allowed. However RFC 9000 clearly states no partial expansion should happen in both cases. Section 8.2.1. Initiating Path Validation: An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame to at least the smallest allowed maximum datagram size of 1200 bytes, unless the anti-amplification limit for the path does not permit sending a datagram of this size. Section 8.2.2. Path Validation Responses: An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame to at least the smallest allowed maximum datagram size of 1200 bytes. ... However, an endpoint MUST NOT expand the datagram containing the PATH_RESPONSE if the resulting data exceeds the anti-amplification limit.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 29 Nov 2023 18:13:25 +0400
parents 4939fd04737f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
1
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
2 /*
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
3 * Copyright (C) Roman Arutyunyan
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
5 */
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
6
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
7
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
10 #include <ngx_http.h>
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
11
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
12
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
13 static void ngx_http_v3_keepalive_handler(ngx_event_t *ev);
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
14 static void ngx_http_v3_cleanup_session(void *data);
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
15
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
16
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
17 ngx_int_t
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
18 ngx_http_v3_init_session(ngx_connection_t *c)
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
19 {
9081
c851a2ed5ce8 HTTP/3: "quic" parameter of "listen" directive.
Roman Arutyunyan <arut@nginx.com>
parents: 9058
diff changeset
20 ngx_pool_cleanup_t *cln;
c851a2ed5ce8 HTTP/3: "quic" parameter of "listen" directive.
Roman Arutyunyan <arut@nginx.com>
parents: 9058
diff changeset
21 ngx_http_connection_t *hc;
c851a2ed5ce8 HTTP/3: "quic" parameter of "listen" directive.
Roman Arutyunyan <arut@nginx.com>
parents: 9058
diff changeset
22 ngx_http_v3_session_t *h3c;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
23
9058
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
24 hc = c->data;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
25
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
26 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init session");
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
27
9058
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
28 h3c = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_session_t));
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
29 if (h3c == NULL) {
8902
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
30 goto failed;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
31 }
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
32
9161
4939fd04737f HTTP/3: postponed session creation to init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9108
diff changeset
33 h3c->http_connection = hc;
4939fd04737f HTTP/3: postponed session creation to init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9108
diff changeset
34
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
35 ngx_queue_init(&h3c->blocked);
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
36
9058
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
37 h3c->keepalive.log = c->log;
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
38 h3c->keepalive.data = c;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
39 h3c->keepalive.handler = ngx_http_v3_keepalive_handler;
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
40
9058
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
41 h3c->table.send_insert_count.log = c->log;
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
42 h3c->table.send_insert_count.data = c;
8989
81a3429db8b0 HTTP/3: delayed Insert Count Increment instruction.
Roman Arutyunyan <arut@nginx.com>
parents: 8988
diff changeset
43 h3c->table.send_insert_count.handler = ngx_http_v3_inc_insert_count_handler;
81a3429db8b0 HTTP/3: delayed Insert Count Increment instruction.
Roman Arutyunyan <arut@nginx.com>
parents: 8988
diff changeset
44
9058
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
45 cln = ngx_pool_cleanup_add(c->pool, 0);
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
46 if (cln == NULL) {
8902
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
47 goto failed;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
48 }
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
49
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
50 cln->handler = ngx_http_v3_cleanup_session;
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
51 cln->data = h3c;
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
52
9161
4939fd04737f HTTP/3: postponed session creation to init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9108
diff changeset
53 c->data = h3c;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
54
9058
b0c2234aaa9f QUIC: application init() callback.
Roman Arutyunyan <arut@nginx.com>
parents: 9056
diff changeset
55 return NGX_OK;
8902
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
56
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
57 failed:
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
58
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
59 ngx_log_error(NGX_LOG_ERR, c->log, 0, "failed to create http3 session");
925572184d4a HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents: 8881
diff changeset
60 return NGX_ERROR;
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
61 }
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
62
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
63
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
64 static void
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
65 ngx_http_v3_keepalive_handler(ngx_event_t *ev)
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
66 {
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
67 ngx_connection_t *c;
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
68
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
69 c = ev->data;
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
70
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
71 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 keepalive handler");
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
72
8988
6434160b4b78 QUIC: allowed main QUIC connection for some operations.
Roman Arutyunyan <arut@nginx.com>
parents: 8902
diff changeset
73 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_NO_ERROR,
6434160b4b78 QUIC: allowed main QUIC connection for some operations.
Roman Arutyunyan <arut@nginx.com>
parents: 8902
diff changeset
74 "keepalive timeout");
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
75 }
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
76
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
77
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
78 static void
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
79 ngx_http_v3_cleanup_session(void *data)
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
80 {
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
81 ngx_http_v3_session_t *h3c = data;
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
82
8775
6e2c23481abb HTTP/3: clean up table from session cleanup handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8774
diff changeset
83 ngx_http_v3_cleanup_table(h3c);
6e2c23481abb HTTP/3: clean up table from session cleanup handler.
Roman Arutyunyan <arut@nginx.com>
parents: 8774
diff changeset
84
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
85 if (h3c->keepalive.timer_set) {
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
86 ngx_del_timer(&h3c->keepalive);
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
87 }
8989
81a3429db8b0 HTTP/3: delayed Insert Count Increment instruction.
Roman Arutyunyan <arut@nginx.com>
parents: 8988
diff changeset
88
81a3429db8b0 HTTP/3: delayed Insert Count Increment instruction.
Roman Arutyunyan <arut@nginx.com>
parents: 8988
diff changeset
89 if (h3c->table.send_insert_count.posted) {
81a3429db8b0 HTTP/3: delayed Insert Count Increment instruction.
Roman Arutyunyan <arut@nginx.com>
parents: 8988
diff changeset
90 ngx_delete_posted_event(&h3c->table.send_insert_count);
81a3429db8b0 HTTP/3: delayed Insert Count Increment instruction.
Roman Arutyunyan <arut@nginx.com>
parents: 8988
diff changeset
91 }
8774
f4d3f5d93a82 HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
92 }
8881
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
93
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
94
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
95 ngx_int_t
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
96 ngx_http_v3_check_flood(ngx_connection_t *c)
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
97 {
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
98 ngx_http_v3_session_t *h3c;
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
99
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
100 h3c = ngx_http_v3_get_session(c);
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
101
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
102 if (h3c->total_bytes / 8 > h3c->payload_bytes + 1048576) {
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
103 ngx_log_error(NGX_LOG_INFO, c->log, 0, "http3 flood detected");
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
104
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
105 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_NO_ERROR,
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
106 "HTTP/3 flood detected");
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
107 return NGX_ERROR;
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
108 }
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
109
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
110 return NGX_OK;
72b304f6207c HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents: 8796
diff changeset
111 }