MINOR: htx: Add an HTX flag to know when a message is fragmented
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 21 Sep 2021 13:39:30 +0000 (15:39 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 19 Oct 2021 13:44:15 +0000 (15:44 +0200)
HTX_FL_FRAGMENTED flag is now set on an HTX message when it is
fragmented. It happens when an HTX block is removed in the middle of the
message and flagged as unused. HTX_FL_FRAGMENTED flag is removed when all
data are removed from the message or when the message is defragmented.

Note that some optimisations are still possible because the flag can be
avoided in other situations. For instance when the last header of a bodyless
message is removed.

(cherry picked from commit 4697c92c9d7f875b30413a20bfeb56f318c182d1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 95bf88d719fa04bfa89808522971cabcbc6ffd4f)
[cf: Value of HTX_FL_FRAGMENTED flag was changed]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

include/haproxy/htx-t.h
src/htx.c

index 9ecc754..e580370 100644 (file)
 #define HTX_FL_EOI               0x00000010 /* Set when end-of-input is reached from the HTX point of view
                                             * (at worst, on the EOM block is missing)
                                             */
+#define HTX_FL_FRAGMENTED        0x00000020 /* Set when the HTX buffer is fragmented */
+
 
 /* HTX block's type (max 15). */
 enum htx_blk_type {
index 4b2a3f4..2662e25 100644 (file)
--- a/src/htx.c
+++ b/src/htx.c
@@ -79,6 +79,7 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk, uint32_t blkinf
        htx->tail = new - 1;
        htx->head_addr = htx->end_addr = 0;
        htx->tail_addr = addr;
+       htx->flags &= ~HTX_FL_FRAGMENTED;
        memcpy((void *)htx->blocks, (void *)tmp->blocks, htx->size);
 
        return ((blkpos == -1) ? NULL : htx_get_blk(htx, blkpos));
@@ -339,7 +340,10 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
 
        /* This is the last block in use */
        if (htx->head == htx->tail) {
+               uint32_t flags = (htx->flags & ~HTX_FL_FRAGMENTED); /* Preserve flags except FRAGMENTED */
+
                htx_reset(htx);
+               htx->flags = flags; /* restore flags */
                return NULL;
        }
 
@@ -365,6 +369,9 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
                blk = NULL;
                goto end;
        }
+       else
+               htx->flags |= HTX_FL_FRAGMENTED;
+
        blk = htx_get_blk(htx, pos+1);
 
   end:
@@ -456,7 +463,7 @@ struct htx_ret htx_drain(struct htx *htx, uint32_t count)
        struct htx_ret htxret = { .blk = NULL, .ret = 0 };
 
        if (count == htx->data) {
-               uint32_t flags = htx->flags;
+               uint32_t flags = (htx->flags & ~HTX_FL_FRAGMENTED); /* Preserve flags except FRAGMENTED */
 
                htx_reset(htx);
                htx->flags = flags; /* restore flags */