From: Christopher Faulet Date: Thu, 16 May 2019 09:29:13 +0000 (+0200) Subject: BUG/MINOR: htx: Change htx_xfer_blk() to also count metadata X-Git-Tag: v2.0-dev5~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=156852b613596bdbf8fb67edc6e736d496c89a92;p=thirdparty%2Fhaproxy.git BUG/MINOR: htx: Change htx_xfer_blk() to also count metadata This patch makes the function more accurate. Thanks to the function htx_get_max_blksz(), the transfer of data has been simplified. Note that now the total number of bytes copied (metadata + payload) is returned. This slighly change how the function is used in the H2 multiplexer. --- diff --git a/src/htx.c b/src/htx.c index bdde868af3..3a2252febf 100644 --- a/src/htx.c +++ b/src/htx.c @@ -480,9 +480,9 @@ struct htx_blk *htx_replace_blk_value(struct htx *htx, struct htx_blk *blk, } /* Transfer HTX blocks from to , stopping on the first block of the - * type (typically EOH, EOD or EOM) or when bytes of data were - * moved. It returns the number of bytes of data moved and the last HTX block - * inserted in . + * type (typically EOH, EOD or EOM) or when bytes were moved + * (including payload and meta-data). It returns the number of bytes moved and + * the last HTX block inserted in . */ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, enum htx_blk_type mark) @@ -491,35 +491,29 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, enum htx_blk_type type; uint32_t info, max, sz, ret; - ret = 0; + ret = htx_used_space(dst); blk = htx_get_blk(src, htx_get_head(src)); dstblk = NULL; - while (blk && ret <= count) { + + while (blk && count) { type = htx_get_blk_type(blk); /* Ingore unused block */ if (type == HTX_BLK_UNUSED) goto next; - sz = htx_get_blksz(blk); - if (!sz) { - dstblk = htx_reserve_nxblk(dst, 0); - if (!dstblk) - break; - dstblk->info = blk->info; - goto next; - } + sz = htx_get_blksz(blk); info = blk->info; - max = htx_free_data_space(dst); - if (max > count - ret) - max = count - ret; + max = htx_get_max_blksz(dst, count); + if (!max) + break; if (sz > max) { - sz = max; - info = (type << 28) + sz; /* Headers and pseudo headers must be fully copied */ - if (type != HTX_BLK_DATA || !sz) + if (type != HTX_BLK_DATA) break; + sz = max; + info = (type << 28) + sz; } dstblk = htx_reserve_nxblk(dst, sz); @@ -528,13 +522,11 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, dstblk->info = info; memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz); - ret += sz; + count -= sizeof(dstblk) + sz; if (blk->info != info) { /* Partial move: don't remove from but * resize its content */ - blk->addr += sz; - htx_set_blk_value_len(blk, htx_get_blksz(blk) - sz); - src->data -= sz; + htx_cut_data_blk(src, blk, sz); break; } @@ -547,6 +539,8 @@ struct htx_ret htx_xfer_blks(struct htx *dst, struct htx *src, uint32_t count, } + end: + ret = htx_used_space(dst) - ret; return (struct htx_ret){.ret = ret, .blk = dstblk}; } diff --git a/src/mux_h2.c b/src/mux_h2.c index 6ecec4d624..b39896374d 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -5379,7 +5379,6 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun struct h2c *h2c = h2s->h2c; struct htx *h2s_htx = NULL; struct htx *buf_htx = NULL; - struct htx_ret htx_ret; size_t ret = 0; /* transfer possibly pending data to the upper layer */ @@ -5394,6 +5393,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun goto end; } + ret = h2s_htx->data; buf_htx = htx_from_buf(buf); count = htx_free_data_space(buf_htx); if (flags & CO_RFL_KEEP_RSV) { @@ -5402,7 +5402,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun count -= global.tune.maxrewrite; } - htx_ret = htx_xfer_blks(buf_htx, h2s_htx, count, HTX_BLK_EOM); + htx_xfer_blks(buf_htx, h2s_htx, count, HTX_BLK_EOM); if (h2s_htx->flags & HTX_FL_PARSING_ERROR) buf_htx->flags |= HTX_FL_PARSING_ERROR; @@ -5410,7 +5410,7 @@ static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t coun buf_htx->extra = (h2s_htx->extra ? (h2s_htx->data + h2s_htx->extra) : 0); htx_to_buf(buf_htx, buf); htx_to_buf(h2s_htx, &h2s->rxbuf); - ret = htx_ret.ret; + ret -= h2s_htx->data; } else { ret = b_xfer(buf, &h2s->rxbuf, count);