comparison src/event/ngx_event_quic.c @ 7713:e9891e8ee975 quic

Configurable transport parameters. - integer parameters can be configured using the following directives: quic_max_idle_timeout quic_max_ack_delay quic_max_packet_size quic_initial_max_data quic_initial_max_stream_data_bidi_local quic_initial_max_stream_data_bidi_remote quic_initial_max_stream_data_uni quic_initial_max_streams_bidi quic_initial_max_streams_uni quic_ack_delay_exponent quic_active_migration quic_active_connection_id_limit - only following parameters are actually sent: active_connection_id_limit initial_max_streams_uni initial_max_streams_bidi initial_max_stream_data_bidi_local initial_max_stream_data_bidi_remote initial_max_stream_data_uni (other parameters are to be added into ngx_quic_create_transport_params() function as needed, should be easy now) - draft 24 and draft 27 are now supported (at compile-time using quic_version macro)
author Vladimir Homutov <vl@nginx.com>
date Fri, 20 Mar 2020 13:47:44 +0300
parents 0d9bc77ae30d
children c217a907ce42
comparison
equal deleted inserted replaced
7712:0d9bc77ae30d 7713:e9891e8ee975
29 29
30 struct ngx_quic_connection_s { 30 struct ngx_quic_connection_s {
31 ngx_str_t scid; 31 ngx_str_t scid;
32 ngx_str_t dcid; 32 ngx_str_t dcid;
33 ngx_str_t token; 33 ngx_str_t token;
34
35 ngx_quic_tp_t tp;
34 36
35 /* current packet numbers for each namespace */ 37 /* current packet numbers for each namespace */
36 ngx_uint_t initial_pn; 38 ngx_uint_t initial_pn;
37 ngx_uint_t handshake_pn; 39 ngx_uint_t handshake_pn;
38 ngx_uint_t appdata_pn; 40 ngx_uint_t appdata_pn;
65 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, 67 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
66 enum ssl_encryption_level_t level, uint8_t alert); 68 enum ssl_encryption_level_t level, uint8_t alert);
67 69
68 70
69 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 71 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
70 ngx_quic_header_t *pkt); 72 ngx_quic_tp_t *tp, ngx_quic_header_t *pkt);
71 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); 73 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c);
72 static void ngx_quic_handshake_handler(ngx_event_t *rev); 74 static void ngx_quic_handshake_handler(ngx_event_t *rev);
73 static void ngx_quic_close_connection(ngx_connection_t *c); 75 static void ngx_quic_close_connection(ngx_connection_t *c);
74 76
75 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b); 77 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b);
281 return 1; 283 return 1;
282 } 284 }
283 285
284 286
285 void 287 void
286 ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_msec_t timeout, 288 ngx_quic_run(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
287 ngx_connection_handler_pt handler) 289 ngx_msec_t timeout, ngx_connection_handler_pt handler)
288 { 290 {
289 ngx_buf_t *b; 291 ngx_buf_t *b;
290 ngx_quic_header_t pkt; 292 ngx_quic_header_t pkt;
291 293
292 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic handshake"); 294 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic handshake");
300 pkt.log = c->log; 302 pkt.log = c->log;
301 pkt.raw = b; 303 pkt.raw = b;
302 pkt.data = b->start; 304 pkt.data = b->start;
303 pkt.len = b->last - b->start; 305 pkt.len = b->last - b->start;
304 306
305 if (ngx_quic_new_connection(c, ssl, &pkt) != NGX_OK) { 307 if (ngx_quic_new_connection(c, ssl, tp, &pkt) != NGX_OK) {
306 ngx_quic_close_connection(c); 308 ngx_quic_close_connection(c);
307 return; 309 return;
308 } 310 }
309 311
310 // we don't need stream handler for initial packet processing 312 // we don't need stream handler for initial packet processing
318 return; 320 return;
319 } 321 }
320 322
321 323
322 static ngx_int_t 324 static ngx_int_t
323 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 325 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
324 ngx_quic_header_t *pkt) 326 ngx_quic_header_t *pkt)
325 { 327 {
326 ngx_quic_connection_t *qc; 328 ngx_quic_connection_t *qc;
327 329
328 if (ngx_buf_size(pkt->raw) < 1200) { 330 if (ngx_buf_size(pkt->raw) < 1200) {
352 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel, 354 ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel,
353 ngx_quic_rbtree_insert_stream); 355 ngx_quic_rbtree_insert_stream);
354 356
355 c->quic = qc; 357 c->quic = qc;
356 qc->ssl = ssl; 358 qc->ssl = ssl;
359 qc->tp = *tp;
357 360
358 qc->dcid.len = pkt->dcid.len; 361 qc->dcid.len = pkt->dcid.len;
359 qc->dcid.data = ngx_pnalloc(c->pool, pkt->dcid.len); 362 qc->dcid.data = ngx_pnalloc(c->pool, pkt->dcid.len);
360 if (qc->dcid.data == NULL) { 363 if (qc->dcid.data == NULL) {
361 return NGX_ERROR; 364 return NGX_ERROR;
400 403
401 static ngx_int_t 404 static ngx_int_t
402 ngx_quic_init_connection(ngx_connection_t *c) 405 ngx_quic_init_connection(ngx_connection_t *c)
403 { 406 {
404 int n, sslerr; 407 int n, sslerr;
408 u_char *p;
409 ssize_t len;
405 ngx_ssl_conn_t *ssl_conn; 410 ngx_ssl_conn_t *ssl_conn;
406 ngx_quic_connection_t *qc; 411 ngx_quic_connection_t *qc;
407
408 static const uint8_t params[] =
409 "\x00\x29" /* parameters length: 41 bytes */
410 "\x00\x0e\x00\x01\x05" /* active connection id limit: 5 */
411 "\x00\x04\x00\x04\x80\x98\x96\x80" /* initial max data = 10000000 */
412 "\x00\x09\x00\x01\x03" /* initial max streams uni: 3 */
413 "\x00\x08\x00\x01\x10" /* initial max streams bidi: 16 */
414 "\x00\x05\x00\x02\x40\xff" /* initial max stream bidi local: 255 */
415 "\x00\x06\x00\x02\x40\xff" /* initial max stream bidi remote: 255 */
416 "\x00\x07\x00\x02\x40\xff"; /* initial max stream data uni: 255 */
417 412
418 qc = c->quic; 413 qc = c->quic;
419 414
420 if (ngx_ssl_create_connection(qc->ssl, c, NGX_SSL_BUFFER) != NGX_OK) { 415 if (ngx_ssl_create_connection(qc->ssl, c, NGX_SSL_BUFFER) != NGX_OK) {
421 return NGX_ERROR; 416 return NGX_ERROR;
427 ngx_log_error(NGX_LOG_INFO, c->log, 0, 422 ngx_log_error(NGX_LOG_INFO, c->log, 0,
428 "SSL_set_quic_method() failed"); 423 "SSL_set_quic_method() failed");
429 return NGX_ERROR; 424 return NGX_ERROR;
430 } 425 }
431 426
432 if (SSL_set_quic_transport_params(ssl_conn, params, sizeof(params) - 1) == 0) { 427 len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp);
428 /* always succeeds */
429
430 p = ngx_pnalloc(c->pool, len);
431 if (p == NULL) {
432 return NGX_ERROR;
433 }
434
435 len = ngx_quic_create_transport_params(p, p + len, &qc->tp);
436 if (len < 0) {
437 return NGX_ERROR;
438 }
439
440 if (SSL_set_quic_transport_params(ssl_conn, p, len) == 0) {
433 ngx_log_error(NGX_LOG_INFO, c->log, 0, 441 ngx_log_error(NGX_LOG_INFO, c->log, 0,
434 "SSL_set_quic_transport_params() failed"); 442 "SSL_set_quic_transport_params() failed");
435 return NGX_ERROR; 443 return NGX_ERROR;
436 } 444 }
437 445