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,