Mercurial > hg > nginx
annotate src/http/v3/ngx_http_v3.c @ 8906:41caf5410110 quic
QUIC: reject streams which we could not create.
The reasons why a stream may not be created by server currently include hitting
worker_connections limit and memory allocation error. Previously in these
cases the entire QUIC connection was closed and all its streams were shut down.
Now the new stream is rejected and existing streams continue working.
To reject an HTTP/3 request stream, RESET_STREAM and STOP_SENDING with
H3_REQUEST_REJECTED error code are sent to client. HTTP/3 uni streams and
Stream streams are not rejected.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 11 Nov 2021 19:07:00 +0300 |
parents | 925572184d4a |
children | 6434160b4b78 |
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 { |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
20 ngx_connection_t *pc; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
21 ngx_pool_cleanup_t *cln; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
22 ngx_http_connection_t *hc; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
23 ngx_http_v3_session_t *h3c; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
24 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
25 pc = c->quic->parent; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
26 hc = pc->data; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
27 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
28 if (hc->v3_session) { |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
29 return NGX_OK; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
30 } |
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 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
|
33 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
34 h3c = ngx_pcalloc(pc->pool, sizeof(ngx_http_v3_session_t)); |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
35 if (h3c == NULL) { |
8902
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
36 goto failed; |
8774
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
37 } |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
38 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
39 h3c->max_push_id = (uint64_t) -1; |
8796
1fec68e322d0
HTTP/3: client GOAWAY support.
Roman Arutyunyan <arut@nginx.com>
parents:
8775
diff
changeset
|
40 h3c->goaway_push_id = (uint64_t) -1; |
8774
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
41 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
42 ngx_queue_init(&h3c->blocked); |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
43 ngx_queue_init(&h3c->pushing); |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
44 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
45 h3c->keepalive.log = pc->log; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
46 h3c->keepalive.data = pc; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
47 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
|
48 h3c->keepalive.cancelable = 1; |
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 = ngx_pool_cleanup_add(pc->pool, 0); |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
51 if (cln == NULL) { |
8902
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
52 goto failed; |
8774
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
53 } |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
54 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
55 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
|
56 cln->data = h3c; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
57 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
58 hc->v3_session = h3c; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
59 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
60 return ngx_http_v3_send_settings(c); |
8902
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
61 |
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
62 failed: |
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
63 |
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
64 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
|
65 |
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
66 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, |
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
67 "failed to create http3 session"); |
925572184d4a
HTTP/3: adjusted QUIC connection finalization.
Roman Arutyunyan <arut@nginx.com>
parents:
8881
diff
changeset
|
68 return NGX_ERROR; |
8774
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
69 } |
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 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
72 static void |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
73 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
|
74 { |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
75 ngx_connection_t *c; |
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 c = ev->data; |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
78 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
79 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
|
80 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
81 ngx_quic_finalize_connection(c, NGX_HTTP_V3_ERR_NO_ERROR, |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
82 "keepalive timeout"); |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
83 } |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
84 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
85 |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
86 static void |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
87 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
|
88 { |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
89 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
|
90 |
8775
6e2c23481abb
HTTP/3: clean up table from session cleanup handler.
Roman Arutyunyan <arut@nginx.com>
parents:
8774
diff
changeset
|
91 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
|
92 |
8774
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
93 if (h3c->keepalive.timer_set) { |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
94 ngx_del_timer(&h3c->keepalive); |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
95 } |
f4d3f5d93a82
HTTP/3: moved session initialization to a separate file.
Roman Arutyunyan <arut@nginx.com>
parents:
diff
changeset
|
96 } |
8881
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 |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
99 ngx_int_t |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
100 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
|
101 { |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
102 ngx_http_v3_session_t *h3c; |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
103 |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
104 h3c = ngx_http_v3_get_session(c); |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
105 |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
106 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
|
107 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
|
108 |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
109 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
|
110 "HTTP/3 flood detected"); |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
111 return NGX_ERROR; |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
112 } |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
113 |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
114 return NGX_OK; |
72b304f6207c
HTTP/3: traffic-based flood detection.
Roman Arutyunyan <arut@nginx.com>
parents:
8796
diff
changeset
|
115 } |