Repository: nginx/nginx
File: src/event/quic/ngx_event_quic_output.c (C)

Code before:
    path = qc->path;

    ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);

    if (ngx_quic_generate_ack(c, ctx) != NGX_OK) {
        return NGX_ERROR;
    }

    segsize = ngx_min(path->mtu, NGX_QUIC_MAX_UDP_SEGMENT_BUF);
    p = dst;
    end = dst + sizeof(dst);

    nseg = 0;

#if (NGX_SUPPRESS_WARN)
    ngx_memzero(preserved_pnum, sizeof(preserved_pnum));
#endif

    level = 2; /* application */
    preserved_pnum[level] = ctx->pnum;

    for ( ;; ) {

        len = ngx_min(segsize, (size_t) (end - p));

        if (len && cg->in_flight + (p - dst) < cg->window) {

            n = ngx_quic_output_packet(c, ctx, p, len, len);
            if (n == NGX_ERROR) {
                return NGX_ERROR;
            }

            if (n) {
                p += n;
                nseg++;
            }

        } else {
            n = 0;
        }

        if (p == dst) {
            break;
        }

        if (n == 0 || nseg == NGX_QUIC_MAX_SEGMENTS) {
            n = ngx_quic_send_segments(c, dst, p - dst, path->sockaddr,
                                       path->socklen, segsize);
            if (n == NGX_ERROR) {
                return NGX_ERROR;
            }

Review comment (suggestion):
The function is always called under condition that only application level frames exist.
That said, we can initialize only certain parts of `preserved_pnum`.

```
diff --git a/src/event/quic/ngx_event_quic_output.c b/src/event/quic/ngx_event_quic_output.c
index e024fd012..a92a539f3 100644
--- a/src/event/quic/ngx_event_quic_output.c
+++ b/src/event/quic/ngx_event_quic_output.c
@@ -331,13 +331,13 @@ ngx_quic_create_segments(ngx_connection_t *c)
     size_t                  len, segsize;
     ssize_t                 n;
     u_char                 *p, *end;
-    uint64_t                preserved_pnum[NGX_QUIC_SEND_CTX_LAST];
     ngx_uint_t              nseg, level;
     ngx_quic_path_t        *path;
     ngx_quic_send_ctx_t    *ctx;
     ngx_quic_congestion_t  *cg;
     ngx_quic_connection_t  *qc;
     static u_char           dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF];
+    static uint64_t         preserved_pnum[NGX_QUIC_SEND_CTX_LAST];
 
     qc = ngx_quic_get_connection(c);
     cg = &qc->congestion;
@@ -355,11 +355,7 @@ ngx_quic_create_segments(ngx_connection_t *c)
 
     nseg = 0;
 
-#if (NGX_SUPPRESS_WARN)
-    ngx_memzero(preserved_pnum, sizeof(preserved_pnum));
-#endif
-
-    level = 2; /* application */
+    level = ctx - qc->send_ctx;
     preserved_pnum[level] = ctx->pnum;
 
     for ( ;; ) {
```


Code after:
    ngx_uint_t              nseg, level;
    ngx_quic_path_t        *path;
    ngx_quic_send_ctx_t    *ctx;
    ngx_quic_congestion_t  *cg;
    ngx_quic_connection_t  *qc;
    static u_char           dst[NGX_QUIC_MAX_UDP_SEGMENT_BUF];
    static uint64_t         preserved_pnum[NGX_QUIC_SEND_CTX_LAST];

    qc = ngx_quic_get_connection(c);
    cg = &qc->congestion;
    path = qc->path;

    ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_application);

    if (ngx_quic_generate_ack(c, ctx) != NGX_OK) {
        return NGX_ERROR;
    }

    segsize = ngx_min(path->mtu, NGX_QUIC_MAX_UDP_SEGMENT_BUF);
    p = dst;
    end = dst + sizeof(dst);

    nseg = 0;

    level = ctx - qc->send_ctx;
    preserved_pnum[level] = ctx->pnum;

    for ( ;; ) {

        len = ngx_min(segsize, (size_t) (end - p));

        if (len && cg->in_flight + (p - dst) < cg->window) {

            n = ngx_quic_output_packet(c, ctx, p, len, len);
            if (n == NGX_ERROR) {
                return NGX_ERROR;
            }

            if (n) {
                p += n;
                nseg++;
            }

        } else {
            n = 0;
        }

        if (p == dst) {
            break;
        }