Mercurial > hg > nginx
comparison src/event/ngx_event_quic_transport.c @ 8522:fc89d02bdca2 quic
QUIC: added version negotiation support.
If a client attemtps to start a new connection with unsupported version,
a version negotiation packet is sent that contains a list of supported
versions (currently this is a single version, selected at compile time).
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 20 Aug 2020 17:11:04 +0300 |
parents | b0e74a54c98b |
children | c5a894bd4f53 |
comparison
equal
deleted
inserted
replaced
8521:a748095bf94e | 8522:fc89d02bdca2 |
---|---|
84 ngx_quic_max_data_frame_t *md); | 84 ngx_quic_max_data_frame_t *md); |
85 static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl); | 85 static size_t ngx_quic_create_close(u_char *p, ngx_quic_close_frame_t *cl); |
86 | 86 |
87 static ngx_int_t ngx_quic_parse_transport_param(u_char *p, u_char *end, | 87 static ngx_int_t ngx_quic_parse_transport_param(u_char *p, u_char *end, |
88 uint16_t id, ngx_quic_tp_t *dst); | 88 uint16_t id, ngx_quic_tp_t *dst); |
89 | |
90 | |
91 /* currently only single version (selected at compile-time) is supported */ | |
92 uint32_t ngx_quic_versions[] = { | |
93 NGX_QUIC_VERSION | |
94 }; | |
95 | |
96 #define NGX_QUIC_NVERSIONS \ | |
97 (sizeof(ngx_quic_versions) / sizeof(ngx_quic_versions[0])) | |
89 | 98 |
90 | 99 |
91 /* literal errors indexed by corresponding value */ | 100 /* literal errors indexed by corresponding value */ |
92 static char *ngx_quic_errors[] = { | 101 static char *ngx_quic_errors[] = { |
93 "NO_ERROR", | 102 "NO_ERROR", |
230 | 239 |
231 | 240 |
232 ngx_int_t | 241 ngx_int_t |
233 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) | 242 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) |
234 { | 243 { |
235 u_char *p, *end; | 244 u_char *p, *end; |
236 uint8_t idlen; | 245 uint8_t idlen; |
237 | 246 |
238 p = pkt->data; | 247 p = pkt->data; |
239 end = pkt->data + pkt->len; | 248 end = pkt->data + pkt->len; |
240 | 249 |
241 #ifdef NGX_QUIC_DEBUG_PACKETS | 250 #ifdef NGX_QUIC_DEBUG_PACKETS |
268 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { | 277 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { |
269 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); | 278 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); |
270 return NGX_DECLINED; | 279 return NGX_DECLINED; |
271 } | 280 } |
272 | 281 |
273 if (pkt->version != NGX_QUIC_VERSION) { | |
274 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
275 "quic unsupported version: 0x%xD", pkt->version); | |
276 return NGX_ERROR; | |
277 } | |
278 | |
279 p = ngx_quic_read_uint8(p, end, &idlen); | 282 p = ngx_quic_read_uint8(p, end, &idlen); |
280 if (p == NULL) { | 283 if (p == NULL) { |
281 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | 284 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, |
282 "quic packet is too small to read dcid len"); | 285 "quic packet is too small to read dcid len"); |
283 return NGX_ERROR; | 286 return NGX_ERROR; |
321 } | 324 } |
322 | 325 |
323 pkt->raw->pos = p; | 326 pkt->raw->pos = p; |
324 | 327 |
325 return NGX_OK; | 328 return NGX_OK; |
329 } | |
330 | |
331 | |
332 size_t | |
333 ngx_quic_create_version_negotiation(ngx_quic_header_t *pkt, u_char *out) | |
334 { | |
335 u_char *p, *start; | |
336 ngx_uint_t i; | |
337 | |
338 p = start = out; | |
339 | |
340 *p++ = pkt->flags; | |
341 | |
342 /* | |
343 * The Version field of a Version Negotiation packet | |
344 * MUST be set to 0x00000000 | |
345 */ | |
346 p = ngx_quic_write_uint32(p, 0); | |
347 | |
348 *p++ = pkt->dcid.len; | |
349 p = ngx_cpymem(p, pkt->dcid.data, pkt->dcid.len); | |
350 | |
351 *p++ = pkt->scid.len; | |
352 p = ngx_cpymem(p, pkt->scid.data, pkt->scid.len); | |
353 | |
354 for (i = 0; i < NGX_QUIC_NVERSIONS; i++) { | |
355 p = ngx_quic_write_uint32(p, ngx_quic_versions[i]); | |
356 } | |
357 | |
358 return p - start; | |
326 } | 359 } |
327 | 360 |
328 | 361 |
329 size_t | 362 size_t |
330 ngx_quic_create_long_header(ngx_quic_header_t *pkt, u_char *out, | 363 ngx_quic_create_long_header(ngx_quic_header_t *pkt, u_char *out, |