#include <haproxy/chunk.h>
#include <haproxy/htx.h>
+#include <haproxy/net_helper.h>
struct htx htx_empty = { .size = 0, .data = 0, .head = -1, .tail = -1, .first = -1 };
+/* tests show that 63% of these calls are for 64-bit chunks, so better avoid calling
+ * memcpy() for that!
+ */
+static inline __attribute__((always_inline)) void htx_memcpy(void *dst, void *src, size_t len)
+{
+ if (likely(len == 8))
+ write_u64(dst, read_u64(src));
+ else
+ memcpy(dst, src, len);
+}
+
/* Defragments an HTX message. It removes unused blocks and unwraps the payloads
* part. A temporary buffer is used to do so. This function never fails. Most of
* time, we need keep a ref on a specific HTX block. Thus is <blk> is set, the
continue;
blksz = htx_get_blksz(oldblk);
- memcpy((void *)tmp->blocks + addr, htx_get_blk_ptr(htx, oldblk), blksz);
+ htx_memcpy((void *)tmp->blocks + addr, htx_get_blk_ptr(htx, oldblk), blksz);
/* update the start-line position */
if (htx->first == old)
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);
+ htx_memcpy((void *)htx->blocks, (void *)tmp->blocks, htx->size);
return ((blkpos == -1) ? NULL : htx_get_blk(htx, blkpos));
}
append_data:
/* Append data and update the block itself */
ptr = htx_get_blk_ptr(htx, tailblk);
- memcpy(ptr+sz, data.ptr, len);
+ htx_memcpy(ptr+sz, data.ptr, len);
htx_change_blk_value_len(htx, tailblk, sz+len);
if (data.len == len) {
return NULL;
blk->info += data.len;
- memcpy(htx_get_blk_ptr(htx, blk), data.ptr, data.len);
+ htx_memcpy(htx_get_blk_ptr(htx, blk), data.ptr, data.len);
end:
BUG_ON((int32_t)htx->tail_addr < 0);
if (ret == 1) { /* Replace in place */
if (delta <= 0) {
/* compression: copy new data first then move the end */
- memcpy(old.ptr, new.ptr, new.len);
+ htx_memcpy(old.ptr, new.ptr, new.len);
memmove(old.ptr + new.len, istend(old),
istend(v) - istend(old));
}
/* expansion: move the end first then copy new data */
memmove(old.ptr + new.len, istend(old),
istend(v) - istend(old));
- memcpy(old.ptr, new.ptr, new.len);
+ htx_memcpy(old.ptr, new.ptr, new.len);
}
/* set the new block size and update HTX message */
void *ptr = htx_get_blk_ptr(htx, blk);
/* Copy the name, if any */
- memcpy(ptr, n.ptr, n.len);
+ htx_memcpy(ptr, n.ptr, n.len);
ptr += n.len;
/* Copy value before old part, if any */
- memcpy(ptr, v.ptr, old.ptr - v.ptr);
+ htx_memcpy(ptr, v.ptr, old.ptr - v.ptr);
ptr += old.ptr - v.ptr;
/* Copy new value */
- memcpy(ptr, new.ptr, new.len);
+ htx_memcpy(ptr, new.ptr, new.len);
ptr += new.len;
/* Copy value after old part, if any */
- memcpy(ptr, istend(old), istend(v) - istend(old));
+ htx_memcpy(ptr, istend(old), istend(v) - istend(old));
/* set the new block size and update HTX message */
htx_set_blk_value_len(blk, v.len + delta);
*/
memmove(old.ptr + offset + new.len, old.ptr + offset + old.len,
istend(v) - istend(old));
- memcpy(old.ptr + offset, new.ptr, new.len);
+ htx_memcpy(old.ptr + offset, new.ptr, new.len);
}
return blk;
}
if (!dstblk)
break;
dstblk->info = info;
- memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
+ htx_memcpy(htx_get_blk_ptr(dst, dstblk), htx_get_blk_ptr(src, blk), sz);
count -= sizeof(dstblk) + sz;
if (blk->info != info) {
/* Finally, copy data. */
ptr = htx_get_blk_ptr(htx, blk);
ist2bin_lc(ptr, name);
- memcpy(ptr + name.len, value.ptr, value.len);
+ htx_memcpy(ptr + name.len, value.ptr, value.len);
return blk;
}
HTX_SL_P2_LEN(sl) = p2.len;
HTX_SL_P3_LEN(sl) = p3.len;
- memcpy(HTX_SL_P1_PTR(sl), p1.ptr, p1.len);
- memcpy(HTX_SL_P2_PTR(sl), p2.ptr, p2.len);
- memcpy(HTX_SL_P3_PTR(sl), p3.ptr, p3.len);
+ htx_memcpy(HTX_SL_P1_PTR(sl), p1.ptr, p1.len);
+ htx_memcpy(HTX_SL_P2_PTR(sl), p2.ptr, p2.len);
+ htx_memcpy(HTX_SL_P3_PTR(sl), p3.ptr, p3.len);
return sl;
}
append_data:
/* Append data and update the block itself */
ptr = htx_get_blk_ptr(htx, tailblk);
- memcpy(ptr + sz, data.ptr, len);
+ htx_memcpy(ptr + sz, data.ptr, len);
htx_change_blk_value_len(htx, tailblk, sz+len);
BUG_ON((int32_t)htx->tail_addr < 0);
return 0;
blk->info += len;
- memcpy(htx_get_blk_ptr(htx, blk), data.ptr, len);
+ htx_memcpy(htx_get_blk_ptr(htx, blk), data.ptr, len);
return len;
}
if (!newblk)
goto error;
newblk->info = blk->info;
- memcpy(htx_get_blk_ptr(dst, newblk), htx_get_blk_ptr(src, blk), blksz);
+ htx_memcpy(htx_get_blk_ptr(dst, newblk), htx_get_blk_ptr(src, blk), blksz);
}
return 1;