comparison src/event/ngx_event_quic.c @ 8289:949b95e4d504 quic

Merged ngx_quic_send_packet() into ngx_quic_send_frames(). This allows to avoid extra allocation and use two static buffers instead. Adjusted maximum paket size calculation: need to account a tag.
author Vladimir Homutov <vl@nginx.com>
date Thu, 26 Mar 2020 18:29:38 +0300
parents ebd5c71b9f02
children 9895d0fa8756
comparison
equal deleted inserted replaced
8288:ebd5c71b9f02 8289:949b95e4d504
112 ngx_quic_frame_t *frame); 112 ngx_quic_frame_t *frame);
113 113
114 static ngx_int_t ngx_quic_output(ngx_connection_t *c); 114 static ngx_int_t ngx_quic_output(ngx_connection_t *c);
115 ngx_int_t ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start, 115 ngx_int_t ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
116 ngx_quic_frame_t *end, size_t total); 116 ngx_quic_frame_t *end, size_t total);
117 static ngx_int_t ngx_quic_send_packet(ngx_connection_t *c,
118 ngx_quic_connection_t *qc, enum ssl_encryption_level_t level,
119 ngx_str_t *payload);
120
121 117
122 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp, 118 static void ngx_quic_rbtree_insert_stream(ngx_rbtree_node_t *temp,
123 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); 119 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
124 static ngx_quic_stream_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree, 120 static ngx_quic_stream_t *ngx_quic_find_stream(ngx_rbtree_t *rbtree,
125 uint64_t id); 121 uint64_t id);
1281 do { 1277 do {
1282 len = 0; 1278 len = 0;
1283 1279
1284 hlen = (lvl == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER 1280 hlen = (lvl == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER
1285 : NGX_QUIC_MAX_LONG_HEADER; 1281 : NGX_QUIC_MAX_LONG_HEADER;
1282 hlen += EVP_GCM_TLS_TAG_LEN;
1286 1283
1287 do { 1284 do {
1288 /* process same-level group of frames */ 1285 /* process same-level group of frames */
1289 1286
1290 n = ngx_quic_create_frame(NULL, NULL, f); 1287 n = ngx_quic_create_frame(NULL, NULL, f);
1331 /* pack a group of frames [start; end) into memory p and send as single packet */ 1328 /* pack a group of frames [start; end) into memory p and send as single packet */
1332 ngx_int_t 1329 ngx_int_t
1333 ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start, 1330 ngx_quic_frames_send(ngx_connection_t *c, ngx_quic_frame_t *start,
1334 ngx_quic_frame_t *end, size_t total) 1331 ngx_quic_frame_t *end, size_t total)
1335 { 1332 {
1336 ssize_t len; 1333 ssize_t len;
1337 u_char *p; 1334 u_char *p;
1338 ngx_str_t out; 1335 ngx_str_t out, res;
1339 ngx_quic_frame_t *f; 1336 ngx_quic_frame_t *f;
1337 ngx_quic_header_t pkt;
1338 ngx_quic_connection_t *qc;
1339 static ngx_str_t initial_token = ngx_null_string;
1340 static u_char src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1341 static u_char dst[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1340 1342
1341 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 1343 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1342 "sending frames %p...%p", start, end); 1344 "sending frames %p...%p", start, end);
1343 1345
1344 p = ngx_pnalloc(c->pool, total); 1346 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
1345 if (p == NULL) { 1347
1346 return NGX_ERROR; 1348 p = src;
1347 } 1349 out.data = src;
1348
1349 out.data = p;
1350 1350
1351 for (f = start; f != end; f = f->next) { 1351 for (f = start; f != end; f = f->next) {
1352 1352
1353 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "frame: %s", f->info); 1353 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "frame: %s", f->info);
1354 1354
1364 1364
1365 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 1365 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1366 "packet ready: %ui bytes at level %d", 1366 "packet ready: %ui bytes at level %d",
1367 out.len, start->level); 1367 out.len, start->level);
1368 1368
1369 // IOVEC/sendmsg_chain ? 1369 qc = c->quic;
1370 if (ngx_quic_send_packet(c, c->quic, start->level, &out) != NGX_OK) { 1370
1371 return NGX_ERROR; 1371 if (start->level == ssl_encryption_initial) {
1372 }
1373
1374 return NGX_OK;
1375 }
1376
1377
1378 static ngx_int_t
1379 ngx_quic_send_packet(ngx_connection_t *c, ngx_quic_connection_t *qc,
1380 enum ssl_encryption_level_t level, ngx_str_t *payload)
1381 {
1382 ngx_str_t res;
1383 ngx_quic_header_t pkt;
1384 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1385
1386 static ngx_str_t initial_token = ngx_null_string;
1387
1388 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
1389 ngx_quic_hexdump0(c->log, "payload", payload->data, payload->len);
1390
1391 pkt.log = c->log;
1392 pkt.level = level;
1393 pkt.dcid = qc->dcid;
1394 pkt.scid = qc->scid;
1395 pkt.payload = *payload;
1396
1397 if (level == ssl_encryption_initial) {
1398 pkt.number = &qc->initial_pn; 1372 pkt.number = &qc->initial_pn;
1399 pkt.flags = NGX_QUIC_PKT_INITIAL; 1373 pkt.flags = NGX_QUIC_PKT_INITIAL;
1400 pkt.secret = &qc->secrets.server.in; 1374 pkt.secret = &qc->secrets.server.in;
1401 pkt.token = initial_token; 1375 pkt.token = initial_token;
1402 1376
1403 } else if (level == ssl_encryption_handshake) { 1377 } else if (start->level == ssl_encryption_handshake) {
1404 pkt.number = &qc->handshake_pn; 1378 pkt.number = &qc->handshake_pn;
1405 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; 1379 pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
1406 pkt.secret = &qc->secrets.server.hs; 1380 pkt.secret = &qc->secrets.server.hs;
1407 1381
1408 } else { 1382 } else {
1409 pkt.number = &qc->appdata_pn; 1383 pkt.number = &qc->appdata_pn;
1410 pkt.secret = &qc->secrets.server.ad; 1384 pkt.secret = &qc->secrets.server.ad;
1411 } 1385 }
1412 1386
1413 // TODO: ensure header size + payload.len + crypto tail fits into packet 1387 pkt.log = c->log;
1414 // (i.e. limit payload while pushing frames to < 65k) 1388 pkt.level = start->level;
1415 1389 pkt.dcid = qc->dcid;
1416 res.data = buf; 1390 pkt.scid = qc->scid;
1391 pkt.payload = out;
1392
1393 res.data = dst;
1417 1394
1418 if (ngx_quic_encrypt(&pkt, c->ssl->connection, &res) != NGX_OK) { 1395 if (ngx_quic_encrypt(&pkt, c->ssl->connection, &res) != NGX_OK) {
1419 return NGX_ERROR; 1396 return NGX_ERROR;
1420 } 1397 }
1421 1398