Mercurial > hg > nginx
comparison src/event/ngx_event_quic.c @ 8367: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
8366:3e894ace66ee | 8367: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 |