comparison src/event/ngx_event_quic.c @ 7844:c10e7d48aa85 quic

Factored out sending ACK from payload handler. Now there's no need to annotate every frame in ACK-eliciting packet. Sending ACK was moved to the first place, so that queueing ACK frame no longer postponed up to the next packet after pushing STREAM frames.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 28 Apr 2020 18:23:56 +0300
parents fab75acb1f72
children 89ccb04736b9
comparison
equal deleted inserted replaced
7843:3e894ace66ee 7844:c10e7d48aa85
172 ngx_quic_header_t *pkt); 172 ngx_quic_header_t *pkt);
173 static ngx_int_t ngx_quic_app_input(ngx_connection_t *c, 173 static ngx_int_t ngx_quic_app_input(ngx_connection_t *c,
174 ngx_quic_header_t *pkt); 174 ngx_quic_header_t *pkt);
175 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, 175 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c,
176 ngx_quic_header_t *pkt); 176 ngx_quic_header_t *pkt);
177 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt);
177 static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c, 178 static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c,
178 enum ssl_encryption_level_t level, ngx_uint_t err); 179 enum ssl_encryption_level_t level, ngx_uint_t err);
179 180
180 static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c, 181 static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c,
181 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f); 182 ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f);
1326 static ngx_int_t 1327 static ngx_int_t
1327 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt) 1328 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
1328 { 1329 {
1329 u_char *end, *p; 1330 u_char *end, *p;
1330 ssize_t len; 1331 ssize_t len;
1331 ngx_uint_t ack_this, do_close; 1332 ngx_uint_t ack_sent, do_close;
1332 ngx_quic_frame_t frame, *ack_frame; 1333 ngx_quic_frame_t frame;
1333 ngx_quic_connection_t *qc; 1334 ngx_quic_connection_t *qc;
1334 1335
1335 qc = c->quic; 1336 qc = c->quic;
1336 1337
1337 if (qc->closing) { 1338 if (qc->closing) {
1347 } 1348 }
1348 1349
1349 p = pkt->payload.data; 1350 p = pkt->payload.data;
1350 end = p + pkt->payload.len; 1351 end = p + pkt->payload.len;
1351 1352
1352 ack_this = 0; 1353 ack_sent = 0;
1353 do_close = 0; 1354 do_close = 0;
1354 1355
1355 while (p < end) { 1356 while (p < end) {
1356 1357
1357 c->log->action = "parsing frames"; 1358 c->log->action = "parsing frames";
1378 case NGX_QUIC_FT_ACK: 1379 case NGX_QUIC_FT_ACK:
1379 if (ngx_quic_handle_ack_frame(c, pkt, &frame.u.ack) != NGX_OK) { 1380 if (ngx_quic_handle_ack_frame(c, pkt, &frame.u.ack) != NGX_OK) {
1380 return NGX_ERROR; 1381 return NGX_ERROR;
1381 } 1382 }
1382 1383
1383 break; 1384 continue;
1385
1386 case NGX_QUIC_FT_PADDING:
1387 /* no action required */
1388 continue;
1389
1390 case NGX_QUIC_FT_CONNECTION_CLOSE:
1391 case NGX_QUIC_FT_CONNECTION_CLOSE2:
1392 do_close = 1;
1393 continue;
1394 }
1395
1396 /* got there with ack-eliciting packet */
1397
1398 if (!ack_sent) {
1399 if (ngx_quic_send_ack(c, pkt) != NGX_OK) {
1400 return NGX_ERROR;
1401 }
1402
1403 ack_sent = 1;
1404 }
1405
1406 switch (frame.type) {
1384 1407
1385 case NGX_QUIC_FT_CRYPTO: 1408 case NGX_QUIC_FT_CRYPTO:
1386 1409
1387 if (ngx_quic_handle_crypto_frame(c, pkt, &frame) != NGX_OK) { 1410 if (ngx_quic_handle_crypto_frame(c, pkt, &frame) != NGX_OK) {
1388 return NGX_ERROR; 1411 return NGX_ERROR;
1389 } 1412 }
1390 1413
1391 ack_this = 1;
1392 break; 1414 break;
1393 1415
1394 case NGX_QUIC_FT_PADDING:
1395 /* no action required */
1396 break;
1397
1398 case NGX_QUIC_FT_PING: 1416 case NGX_QUIC_FT_PING:
1399 ack_this = 1;
1400 break;
1401
1402 case NGX_QUIC_FT_CONNECTION_CLOSE:
1403 case NGX_QUIC_FT_CONNECTION_CLOSE2:
1404 do_close = 1;
1405 break; 1417 break;
1406 1418
1407 case NGX_QUIC_FT_STREAM0: 1419 case NGX_QUIC_FT_STREAM0:
1408 case NGX_QUIC_FT_STREAM1: 1420 case NGX_QUIC_FT_STREAM1:
1409 case NGX_QUIC_FT_STREAM2: 1421 case NGX_QUIC_FT_STREAM2:
1415 1427
1416 if (ngx_quic_handle_stream_frame(c, pkt, &frame) != NGX_OK) { 1428 if (ngx_quic_handle_stream_frame(c, pkt, &frame) != NGX_OK) {
1417 return NGX_ERROR; 1429 return NGX_ERROR;
1418 } 1430 }
1419 1431
1420 ack_this = 1;
1421 break; 1432 break;
1422 1433
1423 case NGX_QUIC_FT_MAX_DATA: 1434 case NGX_QUIC_FT_MAX_DATA:
1424 1435
1425 if (ngx_quic_handle_max_data_frame(c, &frame.u.max_data) != NGX_OK) 1436 if (ngx_quic_handle_max_data_frame(c, &frame.u.max_data) != NGX_OK)
1426 { 1437 {
1427 return NGX_ERROR; 1438 return NGX_ERROR;
1428 } 1439 }
1429 1440
1430 ack_this = 1;
1431 break; 1441 break;
1432 1442
1433 case NGX_QUIC_FT_STREAMS_BLOCKED: 1443 case NGX_QUIC_FT_STREAMS_BLOCKED:
1434 case NGX_QUIC_FT_STREAMS_BLOCKED2: 1444 case NGX_QUIC_FT_STREAMS_BLOCKED2:
1435 1445
1438 != NGX_OK) 1448 != NGX_OK)
1439 { 1449 {
1440 return NGX_ERROR; 1450 return NGX_ERROR;
1441 } 1451 }
1442 1452
1443 ack_this = 1;
1444 break; 1453 break;
1445 1454
1446 case NGX_QUIC_FT_STREAM_DATA_BLOCKED: 1455 case NGX_QUIC_FT_STREAM_DATA_BLOCKED:
1447 1456
1448 if (ngx_quic_handle_stream_data_blocked_frame(c, pkt, 1457 if (ngx_quic_handle_stream_data_blocked_frame(c, pkt,
1450 != NGX_OK) 1459 != NGX_OK)
1451 { 1460 {
1452 return NGX_ERROR; 1461 return NGX_ERROR;
1453 } 1462 }
1454 1463
1455 ack_this = 1;
1456 break; 1464 break;
1457 1465
1458 case NGX_QUIC_FT_MAX_STREAM_DATA: 1466 case NGX_QUIC_FT_MAX_STREAM_DATA:
1459 1467
1460 if (ngx_quic_handle_max_stream_data_frame(c, pkt, 1468 if (ngx_quic_handle_max_stream_data_frame(c, pkt,
1462 != NGX_OK) 1470 != NGX_OK)
1463 { 1471 {
1464 return NGX_ERROR; 1472 return NGX_ERROR;
1465 } 1473 }
1466 1474
1467 ack_this = 1;
1468 break; 1475 break;
1469 1476
1470 case NGX_QUIC_FT_NEW_CONNECTION_ID: 1477 case NGX_QUIC_FT_NEW_CONNECTION_ID:
1471 case NGX_QUIC_FT_RETIRE_CONNECTION_ID: 1478 case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
1472 case NGX_QUIC_FT_NEW_TOKEN: 1479 case NGX_QUIC_FT_NEW_TOKEN:
1476 case NGX_QUIC_FT_PATH_RESPONSE: 1483 case NGX_QUIC_FT_PATH_RESPONSE:
1477 1484
1478 /* TODO: handle */ 1485 /* TODO: handle */
1479 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, 1486 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
1480 "quic frame handler not implemented"); 1487 "quic frame handler not implemented");
1481 ack_this = 1;
1482 break; 1488 break;
1483 1489
1484 default: 1490 default:
1485 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, 1491 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
1486 "quic missing frame handler"); 1492 "quic missing frame handler");
1495 } 1501 }
1496 1502
1497 if (do_close) { 1503 if (do_close) {
1498 qc->draining = 1; 1504 qc->draining = 1;
1499 ngx_quic_close_connection(c, NGX_OK); 1505 ngx_quic_close_connection(c, NGX_OK);
1500 return NGX_OK; 1506 }
1501 } 1507
1502 1508 return NGX_OK;
1503 if (ack_this == 0) { 1509 }
1504 /* do not ack packets with ACKs and PADDING */ 1510
1505 return NGX_OK; 1511
1506 } 1512 static ngx_int_t
1513 ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt)
1514 {
1515 ngx_quic_frame_t *frame;
1507 1516
1508 c->log->action = "generating acknowledgment"; 1517 c->log->action = "generating acknowledgment";
1509 1518
1510 // packet processed, ACK it now if required 1519 /* every ACK-eliciting packet is acknowledged, TODO ACK Ranges */
1511 // TODO: if (ack_required) ... - currently just ack each packet 1520
1512 1521 frame = ngx_quic_alloc_frame(c, 0);
1513 ack_frame = ngx_quic_alloc_frame(c, 0); 1522 if (frame == NULL) {
1514 if (ack_frame == NULL) { 1523 return NGX_ERROR;
1515 return NGX_ERROR; 1524 }
1516 } 1525
1517 1526 frame->level = (pkt->level == ssl_encryption_early_data)
1518 ack_frame->level = (pkt->level == ssl_encryption_early_data) 1527 ? ssl_encryption_application
1519 ? ssl_encryption_application 1528 : pkt->level;
1520 : pkt->level; 1529
1521 1530 frame->type = NGX_QUIC_FT_ACK;
1522 ack_frame->type = NGX_QUIC_FT_ACK; 1531 frame->u.ack.largest = pkt->pn;
1523 ack_frame->u.ack.largest = pkt->pn; 1532
1524 /* only ack immediate packet ]*/ 1533 ngx_sprintf(frame->info, "ACK for PN=%d from frame handler level=%d",
1525 ack_frame->u.ack.first_range = 0; 1534 pkt->pn, frame->level);
1526 1535 ngx_quic_queue_frame(c->quic, frame);
1527 ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, ack_frame->level);
1528 ngx_quic_queue_frame(qc, ack_frame);
1529 1536
1530 return NGX_OK; 1537 return NGX_OK;
1531 } 1538 }
1532 1539
1533 1540