comparison src/event/ngx_event_quic.c @ 8604:b3d9e57d0f62 quic

QUIC: single function for frame debug logging. The function may be called for any initialized frame, both rx and tx. While there, shortened level names.
author Vladimir Homutov <vl@nginx.com>
date Tue, 27 Oct 2020 14:32:08 +0300
parents c5ea341f705a
children eed49b83e18f
comparison
equal deleted inserted replaced
8603:c5ea341f705a 8604:b3d9e57d0f62
49 #define NGX_QUIC_MAX_SR_PACKET 1200 49 #define NGX_QUIC_MAX_SR_PACKET 1200
50 50
51 #define NGX_QUIC_MAX_ACK_GAP 2 51 #define NGX_QUIC_MAX_ACK_GAP 2
52 52
53 #define ngx_quic_level_name(lvl) \ 53 #define ngx_quic_level_name(lvl) \
54 (lvl == ssl_encryption_application) ? "application" \ 54 (lvl == ssl_encryption_application) ? "app" \
55 : (lvl == ssl_encryption_initial) ? "initial" \ 55 : (lvl == ssl_encryption_initial) ? "init" \
56 : (lvl == ssl_encryption_handshake) ? "handshake" : "early_data" 56 : (lvl == ssl_encryption_handshake) ? "hs" : "early"
57 57
58 58
59 typedef struct { 59 typedef struct {
60 ngx_rbtree_t tree; 60 ngx_rbtree_t tree;
61 ngx_rbtree_node_t sentinel; 61 ngx_rbtree_node_t sentinel;
364 ngx_quic_flush_flight, 364 ngx_quic_flush_flight,
365 ngx_quic_send_alert, 365 ngx_quic_send_alert,
366 }; 366 };
367 367
368 368
369 #if (NGX_DEBUG)
370
371 static void
372 ngx_quic_log_frame(ngx_log_t *log, ngx_quic_frame_t *f, ngx_uint_t tx)
373 {
374 u_char *p, *last, *pos, *end;
375 ssize_t n;
376 uint64_t gap, range;
377 ngx_uint_t i;
378 ngx_quic_ack_range_t *ranges;
379 u_char buf[NGX_MAX_ERROR_STR];
380
381 p = buf;
382 last = buf + sizeof(buf);
383
384 switch (f->type) {
385
386 case NGX_QUIC_FT_CRYPTO:
387 p = ngx_slprintf(p, last, "CRYPTO len:%uL off:%uL",
388 f->u.crypto.length, f->u.crypto.offset);
389 break;
390
391 case NGX_QUIC_FT_PADDING:
392 p = ngx_slprintf(p, last, "PADDING");
393 break;
394
395 case NGX_QUIC_FT_ACK:
396 case NGX_QUIC_FT_ACK_ECN:
397
398 p = ngx_slprintf(p, last,
399 "ACK largest:%uL fr:%uL nranges:%ui delay:%uL",
400 f->u.ack.largest, f->u.ack.first_range,
401 f->u.ack.range_count, f->u.ack.delay);
402
403 if (tx) {
404 ranges = (ngx_quic_ack_range_t *) f->u.ack.ranges_start;
405
406 for (i = 0; i < f->u.ack.range_count; i++) {
407 p = ngx_slprintf(p, last, " %uL,%uL",
408 ranges[i].gap, ranges[i].range);
409 }
410
411 } else {
412 pos = f->u.ack.ranges_start;
413 end = f->u.ack.ranges_end;
414
415 for (i = 0; i < f->u.ack.range_count; i++) {
416 n = ngx_quic_parse_ack_range(log, pos, end, &gap, &range);
417 if (n == NGX_ERROR) {
418 break;
419 }
420
421 pos += n;
422
423 p = ngx_slprintf(p, last, " %uL,%uL", gap, range);
424 }
425 }
426
427 if (f->type == NGX_QUIC_FT_ACK_ECN) {
428 p = ngx_slprintf(p, last, " ECN counters ect0:%uL ect1:%uL ce:%uL",
429 f->u.ack.ect0, f->u.ack.ect1, f->u.ack.ce);
430 }
431 break;
432
433 case NGX_QUIC_FT_PING:
434 p = ngx_slprintf(p, last, "PING");
435 break;
436
437 case NGX_QUIC_FT_NEW_CONNECTION_ID:
438 p = ngx_slprintf(p, last, "NCID seq:%uL retire:%uL len:%ud",
439 f->u.ncid.seqnum, f->u.ncid.retire, f->u.ncid.len);
440 break;
441
442 case NGX_QUIC_FT_RETIRE_CONNECTION_ID:
443 p = ngx_slprintf(p, last, "RETIRE_CONNECTION_ID seqnum:%uL",
444 f->u.retire_cid.sequence_number);
445 break;
446
447 case NGX_QUIC_FT_CONNECTION_CLOSE:
448 case NGX_QUIC_FT_CONNECTION_CLOSE_APP:
449 p = ngx_slprintf(p, last, "CONNECTION_CLOSE%s err:%ui",
450 f->u.close.app ? "_APP" : "", f->u.close.error_code);
451
452 if (f->u.close.reason.len) {
453 p = ngx_slprintf(p, last, " %V", &f->u.close.reason);
454 }
455
456 if (f->type == NGX_QUIC_FT_CONNECTION_CLOSE) {
457 p = ngx_slprintf(p, last, " ft:%ui", f->u.close.frame_type);
458 }
459
460
461 break;
462
463 case NGX_QUIC_FT_STREAM0:
464 case NGX_QUIC_FT_STREAM1:
465 case NGX_QUIC_FT_STREAM2:
466 case NGX_QUIC_FT_STREAM3:
467 case NGX_QUIC_FT_STREAM4:
468 case NGX_QUIC_FT_STREAM5:
469 case NGX_QUIC_FT_STREAM6:
470 case NGX_QUIC_FT_STREAM7:
471
472 p = ngx_slprintf(p, last,
473 "STREAM type:0x%xi id:0x%xL offset:0x%xL "
474 "len:0x%xL bits off:%d len:%d fin:%d",
475 f->type, f->u.stream.stream_id, f->u.stream.offset,
476 f->u.stream.length, f->u.stream.off, f->u.stream.len,
477 f->u.stream.fin);
478 break;
479
480 case NGX_QUIC_FT_MAX_DATA:
481 p = ngx_slprintf(p, last, "MAX_DATA max_data:%uL on recv",
482 f->u.max_data.max_data);
483 break;
484
485 case NGX_QUIC_FT_RESET_STREAM:
486 p = ngx_slprintf(p, last, "RESET_STREAM"
487 " id:0x%xL error_code:0x%xL final_size:0x%xL",
488 f->u.reset_stream.id, f->u.reset_stream.error_code,
489 f->u.reset_stream.final_size);
490 break;
491
492 case NGX_QUIC_FT_STOP_SENDING:
493 p = ngx_slprintf(p, last, "STOP_SENDING id:0x%xL err:0x%xL",
494 f->u.stop_sending.id, f->u.stop_sending.error_code);
495 break;
496
497 case NGX_QUIC_FT_STREAMS_BLOCKED:
498 case NGX_QUIC_FT_STREAMS_BLOCKED2:
499 p = ngx_slprintf(p, last, "STREAMS_BLOCKED limit:%uL bidi:%ui",
500 f->u.streams_blocked.limit, f->u.streams_blocked.bidi);
501 break;
502
503 case NGX_QUIC_FT_MAX_STREAMS:
504 case NGX_QUIC_FT_MAX_STREAMS2:
505 p = ngx_slprintf(p, last, "MAX_STREAMS limit:%uL bidi:%ui",
506 f->u.max_streams.limit, f->u.max_streams.bidi);
507 break;
508
509 case NGX_QUIC_FT_MAX_STREAM_DATA:
510 p = ngx_slprintf(p, last, "MAX_STREAM_DATA id:0x%xL limit:%uL",
511 f->u.max_stream_data.id, f->u.max_stream_data.limit);
512 break;
513
514
515 case NGX_QUIC_FT_DATA_BLOCKED:
516 p = ngx_slprintf(p, last, "DATA_BLOCKED limit:%uL",
517 f->u.data_blocked.limit);
518 break;
519
520 case NGX_QUIC_FT_STREAM_DATA_BLOCKED:
521 p = ngx_slprintf(p, last, "STREAM_DATA_BLOCKED id:0x%xL limit:%uL",
522 f->u.stream_data_blocked.id,
523 f->u.stream_data_blocked.limit);
524 break;
525
526 case NGX_QUIC_FT_PATH_CHALLENGE:
527 p = ngx_slprintf(p, last, "PATH_CHALLENGE data:0x%xL",
528 *(uint64_t *) &f->u.path_challenge.data);
529 break;
530
531 case NGX_QUIC_FT_PATH_RESPONSE:
532 p = ngx_slprintf(p, last, "PATH_RESPONSE data:0x%xL",
533 f->u.path_response);
534 break;
535
536 case NGX_QUIC_FT_NEW_TOKEN:
537 p = ngx_slprintf(p, last, "NEW_TOKEN");
538 break;
539
540 case NGX_QUIC_FT_HANDSHAKE_DONE:
541 p = ngx_slprintf(p, last, "HANDSHAKE DONE");
542 break;
543
544 default:
545 p = ngx_slprintf(p, last, "unknown type 0x%xi", f->type);
546 break;
547 }
548
549 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0, "quic frame %s %s %*s",
550 tx ? "tx" : "rx", ngx_quic_level_name(f->level),
551 p - buf, buf);
552 }
553
554 #else
555
556 #define ngx_quic_log_frame(log, f, tx)
557
558 #endif
559
560
369 #if BORINGSSL_API_VERSION >= 10 561 #if BORINGSSL_API_VERSION >= 10
370 562
371 static int 563 static int
372 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, 564 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
373 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, 565 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
601 frame->u.crypto.length = fsize; 793 frame->u.crypto.length = fsize;
602 frame->u.crypto.data = frame->data; 794 frame->u.crypto.data = frame->data;
603 795
604 fs->sent += fsize; 796 fs->sent += fsize;
605 p += fsize; 797 p += fsize;
606
607 ngx_sprintf(frame->info, "crypto, generated by SSL len=%ui level=%d",
608 fsize, level);
609 798
610 ngx_quic_queue_frame(qc, frame); 799 ngx_quic_queue_frame(qc, frame);
611 } 800 }
612 801
613 return 1; 802 return 1;
2104 if (len < 0) { 2293 if (len < 0) {
2105 qc->error = pkt->error; 2294 qc->error = pkt->error;
2106 return NGX_ERROR; 2295 return NGX_ERROR;
2107 } 2296 }
2108 2297
2298 ngx_quic_log_frame(c->log, &frame, 0);
2299
2109 c->log->action = "handling frames"; 2300 c->log->action = "handling frames";
2110 2301
2111 p += len; 2302 p += len;
2112 2303
2113 switch (frame.type) { 2304 switch (frame.type) {
2544 frame->u.ack.largest = largest; 2735 frame->u.ack.largest = largest;
2545 frame->u.ack.delay = 0; 2736 frame->u.ack.delay = 0;
2546 frame->u.ack.range_count = 0; 2737 frame->u.ack.range_count = 0;
2547 frame->u.ack.first_range = largest - smallest; 2738 frame->u.ack.first_range = largest - smallest;
2548 2739
2549 ngx_sprintf(frame->info, "ACK for PN=%uL..%uL 0 ranges level=%d",
2550 largest, smallest, frame->level);
2551
2552 return NGX_OK; 2740 return NGX_OK;
2553 } 2741 }
2554 2742
2555 2743
2556 static void 2744 static void
2643 frame->u.ack.range_count = ctx->nranges; 2831 frame->u.ack.range_count = ctx->nranges;
2644 frame->u.ack.first_range = ctx->first_range; 2832 frame->u.ack.first_range = ctx->first_range;
2645 frame->u.ack.ranges_start = frame->data; 2833 frame->u.ack.ranges_start = frame->data;
2646 frame->u.ack.ranges_end = frame->data + ranges_len; 2834 frame->u.ack.ranges_end = frame->data + ranges_len;
2647 2835
2648 ngx_sprintf(frame->info, "ACK for PN=%uL %ui ranges level=%d",
2649 ctx->largest_range, ctx->nranges, frame->level);
2650
2651 ngx_quic_queue_frame(c->quic, frame); 2836 ngx_quic_queue_frame(c->quic, frame);
2652 2837
2653 return NGX_OK; 2838 return NGX_OK;
2654 } 2839 }
2655 2840
2694 if (qc->error_reason) { 2879 if (qc->error_reason) {
2695 frame->u.close.reason.len = ngx_strlen(qc->error_reason); 2880 frame->u.close.reason.len = ngx_strlen(qc->error_reason);
2696 frame->u.close.reason.data = (u_char *) qc->error_reason; 2881 frame->u.close.reason.data = (u_char *) qc->error_reason;
2697 } 2882 }
2698 2883
2699 ngx_snprintf(frame->info, sizeof(frame->info) - 1,
2700 "CONNECTION_CLOSE%s err:%ui level:%d ft:%ui reason:\"%s\"",
2701 qc->error_app ? "_APP" : "", qc->error, qc->error_level,
2702 qc->error_ftype, qc->error_reason ? qc->error_reason : "-");
2703
2704 ngx_quic_queue_frame(c->quic, frame); 2884 ngx_quic_queue_frame(c->quic, frame);
2705 2885
2706 qc->last_cc = ngx_current_msec; 2886 qc->last_cc = ngx_current_msec;
2707 2887
2708 return ngx_quic_output(c); 2888 return ngx_quic_output(c);
2730 2910
2731 frame->level = ssl_encryption_application; 2911 frame->level = ssl_encryption_application;
2732 frame->type = NGX_QUIC_FT_NEW_TOKEN; 2912 frame->type = NGX_QUIC_FT_NEW_TOKEN;
2733 frame->u.token.length = token.len; 2913 frame->u.token.length = token.len;
2734 frame->u.token.data = token.data; 2914 frame->u.token.data = token.data;
2735 ngx_sprintf(frame->info, "NEW_TOKEN"); 2915
2736 ngx_quic_queue_frame(c->quic, frame); 2916 ngx_quic_queue_frame(c->quic, frame);
2737 2917
2738 return NGX_OK; 2918 return NGX_OK;
2739 } 2919 }
2740 2920
2802 pos = ack->ranges_start; 2982 pos = ack->ranges_start;
2803 end = ack->ranges_end; 2983 end = ack->ranges_end;
2804 2984
2805 for (i = 0; i < ack->range_count; i++) { 2985 for (i = 0; i < ack->range_count; i++) {
2806 2986
2807 n = ngx_quic_parse_ack_range(pkt, pos, end, &gap, &range); 2987 n = ngx_quic_parse_ack_range(pkt->log, pos, end, &gap, &range);
2808 if (n == NGX_ERROR) { 2988 if (n == NGX_ERROR) {
2809 return NGX_ERROR; 2989 return NGX_ERROR;
2810 } 2990 }
2811 pos += n; 2991 pos += n;
2812 2992
3332 } 3512 }
3333 3513
3334 /* 12.4 Frames and frame types, figure 8 */ 3514 /* 12.4 Frames and frame types, figure 8 */
3335 frame->level = ssl_encryption_application; 3515 frame->level = ssl_encryption_application;
3336 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; 3516 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE;
3337 ngx_sprintf(frame->info, "HANDSHAKE DONE on handshake completed");
3338 ngx_quic_queue_frame(c->quic, frame); 3517 ngx_quic_queue_frame(c->quic, frame);
3339 3518
3340 if (ngx_quic_send_new_token(c) != NGX_OK) { 3519 if (ngx_quic_send_new_token(c) != NGX_OK) {
3341 return NGX_ERROR; 3520 return NGX_ERROR;
3342 } 3521 }
3602 frame->level = pkt->level; 3781 frame->level = pkt->level;
3603 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; 3782 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA;
3604 frame->u.max_stream_data.id = f->id; 3783 frame->u.max_stream_data.id = f->id;
3605 frame->u.max_stream_data.limit = n; 3784 frame->u.max_stream_data.limit = n;
3606 3785
3607 ngx_sprintf(frame->info, "MAX_STREAM_DATA id:0x%xL limit:%uL level=%d",
3608 frame->u.max_stream_data.id,
3609 frame->u.max_stream_data.limit,
3610 frame->level);
3611
3612 ngx_quic_queue_frame(c->quic, frame); 3786 ngx_quic_queue_frame(c->quic, frame);
3613 3787
3614 return NGX_OK; 3788 return NGX_OK;
3615 } 3789 }
3616 3790
3825 } 3999 }
3826 4000
3827 frame->level = pkt->level; 4001 frame->level = pkt->level;
3828 frame->type = NGX_QUIC_FT_PATH_RESPONSE; 4002 frame->type = NGX_QUIC_FT_PATH_RESPONSE;
3829 frame->u.path_response = *f; 4003 frame->u.path_response = *f;
3830
3831 ngx_sprintf(frame->info, "PATH_RESPONSE data:0x%xL level:%d",
3832 *(uint64_t *) &f->data, frame->level);
3833 4004
3834 ngx_quic_queue_frame(c->quic, frame); 4005 ngx_quic_queue_frame(c->quic, frame);
3835 4006
3836 return NGX_OK; 4007 return NGX_OK;
3837 } 4008 }
3991 } 4162 }
3992 4163
3993 frame->level = level; 4164 frame->level = level;
3994 frame->type = NGX_QUIC_FT_RETIRE_CONNECTION_ID; 4165 frame->type = NGX_QUIC_FT_RETIRE_CONNECTION_ID;
3995 frame->u.retire_cid.sequence_number = seqnum; 4166 frame->u.retire_cid.sequence_number = seqnum;
3996
3997 ngx_sprintf(frame->info, "RETIRE_CONNECTION_ID seqnum=%uL level=%d",
3998 seqnum, frame->level);
3999 4167
4000 ngx_quic_queue_frame(c->quic, frame); 4168 ngx_quic_queue_frame(c->quic, frame);
4001 4169
4002 return NGX_OK; 4170 return NGX_OK;
4003 } 4171 }
4252 q != ngx_queue_sentinel(frames); 4420 q != ngx_queue_sentinel(frames);
4253 q = ngx_queue_next(q)) 4421 q = ngx_queue_next(q))
4254 { 4422 {
4255 f = ngx_queue_data(q, ngx_quic_frame_t, queue); 4423 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
4256 4424
4257 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, 4425 ngx_quic_log_frame(c->log, f, 1);
4258 "quic frame out: %s", f->info);
4259 4426
4260 len = ngx_quic_create_frame(p, f); 4427 len = ngx_quic_create_frame(p, f);
4261 if (len == -1) { 4428 if (len == -1) {
4262 ngx_quic_free_frames(c, frames); 4429 ngx_quic_free_frames(c, frames);
4263 return NGX_ERROR; 4430 return NGX_ERROR;
4964 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA; 5131 frame->type = NGX_QUIC_FT_MAX_STREAM_DATA;
4965 frame->u.max_stream_data.id = qs->id; 5132 frame->u.max_stream_data.id = qs->id;
4966 frame->u.max_stream_data.limit = qs->fs.received + (b->pos - b->start) 5133 frame->u.max_stream_data.limit = qs->fs.received + (b->pos - b->start)
4967 + (b->end - b->last); 5134 + (b->end - b->last);
4968 5135
4969 ngx_sprintf(frame->info,
4970 "MAX_STREAM_DATA id:0x%xL limit:%uL l=%d on recv",
4971 frame->u.max_stream_data.id,
4972 frame->u.max_stream_data.limit,
4973 frame->level);
4974
4975 ngx_quic_queue_frame(pc->quic, frame); 5136 ngx_quic_queue_frame(pc->quic, frame);
4976 } 5137 }
4977 5138
4978 if ((qc->streams.recv_max_data / 2) < qc->streams.received) { 5139 if ((qc->streams.recv_max_data / 2) < qc->streams.received) {
4979 5140
4986 qc->streams.recv_max_data *= 2; 5147 qc->streams.recv_max_data *= 2;
4987 5148
4988 frame->level = ssl_encryption_application; 5149 frame->level = ssl_encryption_application;
4989 frame->type = NGX_QUIC_FT_MAX_DATA; 5150 frame->type = NGX_QUIC_FT_MAX_DATA;
4990 frame->u.max_data.max_data = qc->streams.recv_max_data; 5151 frame->u.max_data.max_data = qc->streams.recv_max_data;
4991
4992 ngx_sprintf(frame->info, "MAX_DATA max_data:%uL level=%d on recv",
4993 frame->u.max_data.max_data, frame->level);
4994 5152
4995 ngx_quic_queue_frame(pc->quic, frame); 5153 ngx_quic_queue_frame(pc->quic, frame);
4996 5154
4997 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 5155 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
4998 "quic stream id 0x%xL recv: increased max data: %uL", 5156 "quic stream id 0x%xL recv: increased max data: %uL",
5108 frame->u.stream.stream_id = qs->id; 5266 frame->u.stream.stream_id = qs->id;
5109 frame->u.stream.offset = c->sent; 5267 frame->u.stream.offset = c->sent;
5110 frame->u.stream.length = n; 5268 frame->u.stream.length = n;
5111 frame->u.stream.data = frame->data; 5269 frame->u.stream.data = frame->data;
5112 5270
5113 ngx_sprintf(frame->info, "STREAM id:0x%xL offset:%O len:%uz level:%d",
5114 qs->id, c->sent, n, frame->level);
5115
5116 c->sent += n; 5271 c->sent += n;
5117 qc->streams.sent += n; 5272 qc->streams.sent += n;
5118 max_flow -= n; 5273 max_flow -= n;
5119 5274
5120 if (limit) { 5275 if (limit) {
5257 frame->level = ssl_encryption_application; 5412 frame->level = ssl_encryption_application;
5258 frame->type = NGX_QUIC_FT_STOP_SENDING; 5413 frame->type = NGX_QUIC_FT_STOP_SENDING;
5259 frame->u.stop_sending.id = qs->id; 5414 frame->u.stop_sending.id = qs->id;
5260 frame->u.stop_sending.error_code = 0x100; /* HTTP/3 no error */ 5415 frame->u.stop_sending.error_code = 0x100; /* HTTP/3 no error */
5261 5416
5262 ngx_sprintf(frame->info, "STOP_SENDING id:0x%xL err:0x%xL level:%d",
5263 qs->id, frame->u.stop_sending.error_code, frame->level);
5264
5265 ngx_quic_queue_frame(qc, frame); 5417 ngx_quic_queue_frame(qc, frame);
5266 } 5418 }
5267 } 5419 }
5268 5420
5269 if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0) { 5421 if ((qs->id & NGX_QUIC_STREAM_SERVER_INITIATED) == 0) {
5281 5433
5282 } else { 5434 } else {
5283 frame->u.max_streams.limit = ++qc->streams.client_max_streams_bidi; 5435 frame->u.max_streams.limit = ++qc->streams.client_max_streams_bidi;
5284 frame->u.max_streams.bidi = 1; 5436 frame->u.max_streams.bidi = 1;
5285 } 5437 }
5286
5287 ngx_sprintf(frame->info, "MAX_STREAMS limit:%uL bidi:%ui level=%d",
5288 frame->u.max_streams.limit,
5289 frame->u.max_streams.bidi,
5290 (int) frame->level);
5291 5438
5292 ngx_quic_queue_frame(qc, frame); 5439 ngx_quic_queue_frame(qc, frame);
5293 5440
5294 if (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) { 5441 if (qs->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
5295 /* do not send fin for client unidirectional streams */ 5442 /* do not send fin for client unidirectional streams */
5315 frame->u.stream.stream_id = qs->id; 5462 frame->u.stream.stream_id = qs->id;
5316 frame->u.stream.offset = c->sent; 5463 frame->u.stream.offset = c->sent;
5317 frame->u.stream.length = 0; 5464 frame->u.stream.length = 0;
5318 frame->u.stream.data = NULL; 5465 frame->u.stream.data = NULL;
5319 5466
5320 ngx_sprintf(frame->info, "STREAM id:0x%xL offset:%O fin:1 level:%d",
5321 qs->id, c->sent, frame->level);
5322
5323 ngx_quic_queue_frame(qc, frame); 5467 ngx_quic_queue_frame(qc, frame);
5324 5468
5325 (void) ngx_quic_output(pc); 5469 (void) ngx_quic_output(pc);
5326 } 5470 }
5327 5471