comparison src/event/ngx_event_quic.c @ 8239:5ad7bffd3850 quic

Send a FIN frame when QUIC stream is closed.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 19 Mar 2020 15:34:35 +0300
parents ff540f13d95d
children 1f002206a59b
comparison
equal deleted inserted replaced
8238:a3257a725b3d 8239:5ad7bffd3850
108 ngx_uint_t id); 108 ngx_uint_t id);
109 static ssize_t ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, 109 static ssize_t ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf,
110 size_t size); 110 size_t size);
111 static ssize_t ngx_quic_stream_send(ngx_connection_t *c, u_char *buf, 111 static ssize_t ngx_quic_stream_send(ngx_connection_t *c, u_char *buf,
112 size_t size); 112 size_t size);
113 static void ngx_quic_stream_cleanup_handler(void *data);
113 static ngx_chain_t *ngx_quic_stream_send_chain(ngx_connection_t *c, 114 static ngx_chain_t *ngx_quic_stream_send_chain(ngx_connection_t *c,
114 ngx_chain_t *in, off_t limit); 115 ngx_chain_t *in, off_t limit);
115 116
116 117
117 static SSL_QUIC_METHOD quic_method = { 118 static SSL_QUIC_METHOD quic_method = {
1284 ngx_quic_create_stream(ngx_connection_t *c, ngx_uint_t id) 1285 ngx_quic_create_stream(ngx_connection_t *c, ngx_uint_t id)
1285 { 1286 {
1286 ngx_log_t *log; 1287 ngx_log_t *log;
1287 ngx_pool_t *pool; 1288 ngx_pool_t *pool;
1288 ngx_event_t *rev, *wev; 1289 ngx_event_t *rev, *wev;
1290 ngx_pool_cleanup_t *cln;
1289 ngx_quic_connection_t *qc; 1291 ngx_quic_connection_t *qc;
1290 ngx_quic_stream_node_t *sn; 1292 ngx_quic_stream_node_t *sn;
1291 1293
1292 qc = c->quic; 1294 qc = c->quic;
1293 1295
1349 sn->c->qs = &sn->s; 1351 sn->c->qs = &sn->s;
1350 1352
1351 sn->c->recv = ngx_quic_stream_recv; 1353 sn->c->recv = ngx_quic_stream_recv;
1352 sn->c->send = ngx_quic_stream_send; 1354 sn->c->send = ngx_quic_stream_send;
1353 sn->c->send_chain = ngx_quic_stream_send_chain; 1355 sn->c->send_chain = ngx_quic_stream_send_chain;
1356
1357 cln = ngx_pool_cleanup_add(pool, 0);
1358 if (cln == NULL) {
1359 ngx_close_connection(sn->c);
1360 ngx_destroy_pool(pool);
1361 return NULL;
1362 }
1363
1364 cln->handler = ngx_quic_stream_cleanup_handler;
1365 cln->data = sn->c;
1354 1366
1355 return sn; 1367 return sn;
1356 } 1368 }
1357 1369
1358 1370
1455 1467
1456 return size; 1468 return size;
1457 } 1469 }
1458 1470
1459 1471
1472 static void
1473 ngx_quic_stream_cleanup_handler(void *data)
1474 {
1475 ngx_connection_t *c = data;
1476
1477 ngx_connection_t *pc;
1478 ngx_quic_frame_t *frame;
1479 ngx_quic_stream_t *qs;
1480 ngx_quic_connection_t *qc;
1481 ngx_quic_stream_node_t *sn;
1482
1483 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic send fin");
1484
1485 qs = c->qs;
1486 pc = qs->parent;
1487 qc = pc->quic;
1488
1489 if ((qs->id & 0x03) == 0x02) {
1490 /* do not send fin for client unidirectional streams */
1491 return;
1492 }
1493
1494 // XXX: get direct pointer from stream structure?
1495 sn = ngx_quic_find_stream(&qc->streams.tree, qs->id);
1496
1497 if (sn == NULL) {
1498 return;
1499 }
1500
1501 frame = ngx_pcalloc(pc->pool, sizeof(ngx_quic_frame_t));
1502 if (frame == NULL) {
1503 return;
1504 }
1505
1506 frame->level = ssl_encryption_application;
1507 frame->type = NGX_QUIC_FT_STREAM7; /* OFF=1 LEN=1 FIN=1 */
1508 frame->u.stream.off = 1;
1509 frame->u.stream.len = 1;
1510 frame->u.stream.fin = 1;
1511
1512 frame->u.stream.type = frame->type;
1513 frame->u.stream.stream_id = qs->id;
1514 frame->u.stream.offset = c->sent;
1515 frame->u.stream.length = 0;
1516 frame->u.stream.data = NULL;
1517
1518 ngx_sprintf(frame->info, "stream %xi fin=1 level=%d", qs->id, frame->level);
1519
1520 ngx_quic_queue_frame(qc, frame);
1521 }
1522
1523
1460 static ngx_chain_t * 1524 static ngx_chain_t *
1461 ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in, 1525 ngx_quic_stream_send_chain(ngx_connection_t *c, ngx_chain_t *in,
1462 off_t limit) 1526 off_t limit)
1463 { 1527 {
1464 size_t len; 1528 size_t len;