]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: htx: Return the good block address after a defrag
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 2 Jan 2019 10:23:44 +0000 (11:23 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 2 Jan 2019 19:14:31 +0000 (20:14 +0100)
When an HTX structure is defragmented, it is possible to retrieve the new block
corresponding to an old one. This is useful to do a defrag during a loop on
blocks, to be sure to continue looping on the good block. But, instead of
returning the address of the new block in the HTX structure, the one in the
temporary structure used to do the defrag was returned, leading to unexpected
behaviours.

This patch must be backported to 1.9.

src/htx.c

index bda293b43a9fdfe708f10133bf6b41b48f9b0114..83243e060db3922e265cf030c26e55695e0418bf 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -26,13 +26,15 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
        struct buffer *chunk = get_trash_chunk();
        struct htx *tmp = htxbuf(chunk);
        struct htx_blk *newblk, *oldblk;
-       uint32_t new, old;
+       uint32_t new, old, blkpos;
        uint32_t addr, blksz;
        int32_t sl_off = -1;
 
        if (!htx->used)
                return NULL;
 
+       blkpos = -1;
+
        new  = 0;
        addr = 0;
        tmp->size = htx->size;
@@ -54,13 +56,14 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
                if (htx->sl_off == oldblk->addr)
                        sl_off = addr;
 
+               /* if <blk> is defined, set its new position */
+               if (blk != NULL && blk == oldblk)
+                       blkpos = new;
+
                memcpy((void *)tmp->blocks + addr, htx_get_blk_ptr(htx, oldblk), blksz);
                new++;
                addr += blksz;
 
-               /* if <blk> is defined, set its new location */
-               if (blk != NULL && blk == oldblk)
-                       blk = newblk;
        } while (new < htx->used);
 
        htx->sl_off = sl_off;
@@ -68,7 +71,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
        htx->front = htx->tail = new - 1;
        memcpy((void *)htx->blocks, (void *)tmp->blocks, htx->size);
 
-       return blk;
+       return ((blkpos == -1) ? NULL : htx_get_blk(htx, blkpos));
 }
 
 /* Reserves a new block in the HTTP message <htx> with a content of <blksz>