diff options
Diffstat (limited to 'src/event/quic/ngx_event_quic_frames.c')
-rw-r--r-- | src/event/quic/ngx_event_quic_frames.c | 116 |
1 files changed, 72 insertions, 44 deletions
diff --git a/src/event/quic/ngx_event_quic_frames.c b/src/event/quic/ngx_event_quic_frames.c index 71ed981e6..fe6d98043 100644 --- a/src/event/quic/ngx_event_quic_frames.c +++ b/src/event/quic/ngx_event_quic_frames.c @@ -13,10 +13,6 @@ #define NGX_QUIC_BUFFER_SIZE 4096 -static ngx_chain_t *ngx_quic_split_bufs(ngx_connection_t *c, ngx_chain_t *in, - size_t len); - - ngx_quic_frame_t * ngx_quic_alloc_frame(ngx_connection_t *c) { @@ -243,8 +239,8 @@ ngx_quic_split_frame(ngx_connection_t *c, ngx_quic_frame_t *f, size_t len) onf->length = shrink; nf->len = ngx_quic_create_frame(NULL, nf); - nf->data = ngx_quic_split_bufs(c, f->data, of->length); - if (nf->data == NGX_CHAIN_ERROR) { + f->data = ngx_quic_read_chain(c, &nf->data, of->length); + if (f->data == NGX_CHAIN_ERROR) { return NGX_ERROR; } @@ -254,37 +250,48 @@ ngx_quic_split_frame(ngx_connection_t *c, ngx_quic_frame_t *f, size_t len) } -static ngx_chain_t * -ngx_quic_split_bufs(ngx_connection_t *c, ngx_chain_t *in, size_t len) +ngx_chain_t * +ngx_quic_read_chain(ngx_connection_t *c, ngx_chain_t **chain, off_t limit) { - size_t n; + off_t n; ngx_buf_t *b; - ngx_chain_t *out; + ngx_chain_t *out, *in, *cl, **ll; ngx_quic_connection_t *qc; qc = ngx_quic_get_connection(c); - while (in) { - n = ngx_buf_size(in->buf); + out = *chain; + + for (ll = &out; *ll; ll = &(*ll)->next) { + b = (*ll)->buf; - if (n == len) { - out = in->next; - in->next = NULL; - return out; + if (b->sync) { + /* hole */ + break; } - if (n > len) { + if (limit == 0) { break; } - len -= n; - in = in->next; - } + n = b->last - b->pos; - if (in == NULL) { - return NULL; + if (n > limit) { + goto split; + } + + limit -= n; } + *chain = *ll; + *ll = NULL; + + return out; + +split: + + in = *ll; + /* split in->buf by creating shadow bufs which reference it */ if (in->buf->shadow == NULL) { @@ -305,8 +312,8 @@ ngx_quic_split_bufs(ngx_connection_t *c, ngx_chain_t *in, size_t len) in->buf = b; } - out = ngx_alloc_chain_link(c->pool); - if (out == NULL) { + cl = ngx_alloc_chain_link(c->pool); + if (cl == NULL) { return NGX_CHAIN_ERROR; } @@ -317,21 +324,23 @@ ngx_quic_split_bufs(ngx_connection_t *c, ngx_chain_t *in, size_t len) } else { b = ngx_alloc_buf(c->pool); if (b == NULL) { - ngx_free_chain(c->pool, out); + ngx_free_chain(c->pool, cl); return NGX_CHAIN_ERROR; } } - out->buf = b; - out->next = in->next; + cl->buf = b; + cl->next = in->next; in->next = NULL; + *chain = cl; *b = *in->buf; b->last_shadow = 0; - b->pos = b->pos + len; + b->pos += limit; in->buf->shadow = b; - in->buf->last = in->buf->pos + len; + in->buf->last = b->pos; + in->buf->last_buf = 0; return out; } @@ -480,8 +489,8 @@ done: } -ngx_int_t -ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, +ngx_chain_t * +ngx_quic_write_chain(ngx_connection_t *c, ngx_chain_t **chain, ngx_chain_t *in, off_t limit, off_t offset) { off_t n; @@ -490,18 +499,18 @@ ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, ngx_chain_t *cl, *sl; while (in && limit) { - cl = *out; + cl = *chain; if (cl == NULL) { cl = ngx_quic_alloc_buf(c); if (cl == NULL) { - return NGX_ERROR; + return NGX_CHAIN_ERROR; } cl->buf->last = cl->buf->end; cl->buf->sync = 1; /* hole */ cl->next = NULL; - *out = cl; + *chain = cl; } b = cl->buf; @@ -509,17 +518,25 @@ ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, if (n <= offset) { offset -= n; - out = &cl->next; + chain = &cl->next; continue; } if (b->sync && offset > 0) { - sl = ngx_quic_split_bufs(c, cl, offset); - if (sl == NGX_CHAIN_ERROR) { - return NGX_ERROR; + /* split hole at offset */ + + b->sync = 0; + + sl = ngx_quic_read_chain(c, &cl, offset); + if (cl == NGX_CHAIN_ERROR) { + return NGX_CHAIN_ERROR; } - cl->next = sl; + sl->buf->sync = 1; + cl->buf->sync = 1; + + *chain = sl; + sl->next = cl; continue; } @@ -541,18 +558,29 @@ ngx_quic_order_bufs(ngx_connection_t *c, ngx_chain_t **out, ngx_chain_t *in, } } + if (b->sync && p == b->last) { + b->sync = 0; + continue; + } + if (b->sync && p != b->pos) { - sl = ngx_quic_split_bufs(c, cl, p - b->pos); + /* split hole at p - b->pos */ + + b->sync = 0; + + sl = ngx_quic_read_chain(c, &cl, p - b->pos); if (sl == NGX_CHAIN_ERROR) { - return NGX_ERROR; + return NGX_CHAIN_ERROR; } - cl->next = sl; - cl->buf->sync = 0; + cl->buf->sync = 1; + + *chain = sl; + sl->next = cl; } } - return NGX_OK; + return in; } |