Mercurial > hg > nginx
comparison src/http/v3/ngx_http_v3_streams.c @ 8460:72f9ff4e0a88 quic
HTTP/3: close QUIC connection with HTTP/QPACK errors when needed.
Previously errors led only to closing streams.
To simplify closing QUIC connection from a QUIC stream context, new macro
ngx_http_v3_finalize_connection() is introduced. It calls
ngx_quic_finalize_connection() for the parent connection.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 02 Jul 2020 16:47:51 +0300 |
parents | c9538aef3211 |
children | 0d2b2664b41c |
comparison
equal
deleted
inserted
replaced
8459:1ed698947172 | 8460:72f9ff4e0a88 |
---|---|
37 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 37 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
38 "http3 new uni stream id:0x%uxL", c->qs->id); | 38 "http3 new uni stream id:0x%uxL", c->qs->id); |
39 | 39 |
40 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t)); | 40 us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t)); |
41 if (us == NULL) { | 41 if (us == NULL) { |
42 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, | |
43 NULL); | |
42 ngx_http_v3_close_uni_stream(c); | 44 ngx_http_v3_close_uni_stream(c); |
43 return; | 45 return; |
44 } | 46 } |
45 | 47 |
46 us->index = -1; | 48 us->index = -1; |
83 static void | 85 static void |
84 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) | 86 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev) |
85 { | 87 { |
86 u_char ch; | 88 u_char ch; |
87 ssize_t n; | 89 ssize_t n; |
88 ngx_int_t index; | 90 ngx_int_t index, rc; |
89 ngx_connection_t *c; | 91 ngx_connection_t *c; |
90 ngx_http_v3_connection_t *h3c; | 92 ngx_http_v3_connection_t *h3c; |
91 ngx_http_v3_uni_stream_t *us; | 93 ngx_http_v3_uni_stream_t *us; |
92 | 94 |
93 c = rev->data; | 95 c = rev->data; |
98 | 100 |
99 while (rev->ready) { | 101 while (rev->ready) { |
100 | 102 |
101 n = c->recv(c, &ch, 1); | 103 n = c->recv(c, &ch, 1); |
102 | 104 |
103 if (n == NGX_ERROR) { | 105 if (n == NGX_AGAIN) { |
106 break; | |
107 } | |
108 | |
109 if (n == 0) { | |
110 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; | |
104 goto failed; | 111 goto failed; |
105 } | 112 } |
106 | 113 |
107 if (n == NGX_AGAIN || n != 1) { | 114 if (n != 1) { |
108 break; | 115 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; |
116 goto failed; | |
109 } | 117 } |
110 | 118 |
111 switch (ch) { | 119 switch (ch) { |
112 | 120 |
113 case NGX_HTTP_V3_STREAM_ENCODER: | 121 case NGX_HTTP_V3_STREAM_ENCODER: |
152 } | 160 } |
153 | 161 |
154 if (index >= 0) { | 162 if (index >= 0) { |
155 if (h3c->known_streams[index]) { | 163 if (h3c->known_streams[index]) { |
156 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists"); | 164 ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists"); |
165 rc = NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR; | |
157 goto failed; | 166 goto failed; |
158 } | 167 } |
159 | 168 |
160 us->index = index; | 169 us->index = index; |
161 h3c->known_streams[index] = c; | 170 h3c->known_streams[index] = c; |
162 } | 171 } |
163 | 172 |
164 if (n) { | 173 if (n) { |
165 us->data = ngx_pcalloc(c->pool, n); | 174 us->data = ngx_pcalloc(c->pool, n); |
166 if (us->data == NULL) { | 175 if (us->data == NULL) { |
176 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; | |
167 goto failed; | 177 goto failed; |
168 } | 178 } |
169 } | 179 } |
170 | 180 |
171 rev->handler = ngx_http_v3_uni_read_handler; | 181 rev->handler = ngx_http_v3_uni_read_handler; |
172 ngx_http_v3_uni_read_handler(rev); | 182 ngx_http_v3_uni_read_handler(rev); |
173 return; | 183 return; |
174 } | 184 } |
175 | 185 |
176 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | 186 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
187 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; | |
177 goto failed; | 188 goto failed; |
178 } | 189 } |
179 | 190 |
180 return; | 191 return; |
181 | 192 |
182 failed: | 193 failed: |
183 | 194 |
195 ngx_http_v3_finalize_connection(c, rc, "could not read stream type"); | |
184 ngx_http_v3_close_uni_stream(c); | 196 ngx_http_v3_close_uni_stream(c); |
185 } | 197 } |
186 | 198 |
187 | 199 |
188 static void | 200 static void |
201 | 213 |
202 while (rev->ready) { | 214 while (rev->ready) { |
203 | 215 |
204 n = c->recv(c, buf, sizeof(buf)); | 216 n = c->recv(c, buf, sizeof(buf)); |
205 | 217 |
206 if (n == NGX_ERROR || n == 0) { | 218 if (n == NGX_ERROR) { |
219 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; | |
207 goto failed; | 220 goto failed; |
221 } | |
222 | |
223 if (n == 0) { | |
224 if (us->index >= 0) { | |
225 rc = NGX_HTTP_V3_ERR_CLOSED_CRITICAL_STREAM; | |
226 goto failed; | |
227 } | |
228 | |
229 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read eof"); | |
230 ngx_http_v3_close_uni_stream(c); | |
231 return; | |
208 } | 232 } |
209 | 233 |
210 if (n == NGX_AGAIN) { | 234 if (n == NGX_AGAIN) { |
211 break; | 235 break; |
212 } | 236 } |
217 | 241 |
218 for (i = 0; i < n; i++) { | 242 for (i = 0; i < n; i++) { |
219 | 243 |
220 rc = us->handler(c, us->data, buf[i]); | 244 rc = us->handler(c, us->data, buf[i]); |
221 | 245 |
222 if (rc == NGX_ERROR) { | 246 if (rc == NGX_DONE) { |
247 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
248 "http3 read done"); | |
249 ngx_http_v3_close_uni_stream(c); | |
250 return; | |
251 } | |
252 | |
253 if (rc > 0) { | |
223 goto failed; | 254 goto failed; |
224 } | 255 } |
225 | 256 |
226 if (rc == NGX_DONE) { | 257 if (rc != NGX_AGAIN) { |
227 goto done; | 258 rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR; |
259 goto failed; | |
228 } | 260 } |
229 | |
230 /* rc == NGX_AGAIN */ | |
231 } | 261 } |
232 } | 262 } |
233 | 263 |
234 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | 264 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
265 rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR; | |
235 goto failed; | 266 goto failed; |
236 } | 267 } |
237 | 268 |
238 return; | 269 return; |
239 | 270 |
240 done: | |
241 | |
242 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read done"); | |
243 | |
244 failed: | 271 failed: |
245 | 272 |
273 ngx_http_v3_finalize_connection(c, rc, "stream error"); | |
246 ngx_http_v3_close_uni_stream(c); | 274 ngx_http_v3_close_uni_stream(c); |
247 } | 275 } |
248 | 276 |
249 | 277 |
250 static void | 278 static void |
255 c = wev->data; | 283 c = wev->data; |
256 | 284 |
257 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy write handler"); | 285 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy write handler"); |
258 | 286 |
259 if (ngx_handle_write_event(wev, 0) != NGX_OK) { | 287 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
288 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, | |
289 NULL); | |
260 ngx_http_v3_close_uni_stream(c); | 290 ngx_http_v3_close_uni_stream(c); |
261 } | 291 } |
262 } | 292 } |
263 | 293 |
264 | 294 |