/* Structure defining a buffer's head */
struct buffer {
- size_t head; /* start offset of remaining data relative to area */
- size_t data; /* amount of data after head including wrapping */
size_t size; /* buffer size in bytes */
- char area[0]; /* <size> bytes of stored data */
+ char *area; /* points to <size> bytes */
+ size_t data; /* amount of data after head including wrapping */
+ size_t head; /* start offset of remaining data relative to area */
};
+/* A buffer may be in 3 different states :
+ * - unallocated : size == 0, area == 0 (b_is_null() is true)
+ * - waiting : size == 0, area != 0
+ * - allocated : size > 0, area > 0
+ */
+
+/* initializers for certain buffer states. It is important that the NULL buffer
+ * remains the one with all fields initialized to zero so that a calloc() or a
+ * memset() on a struct automatically sets a NULL buffer.
+ */
+#define BUF_NULL ((struct buffer){ })
+#define BUF_WANTED ((struct buffer){ .area = (char *)1 })
+
/***************************************************************************/
/* Functions used to compute offsets and pointers. Most of them exist in */
/* offset relative to the storage area. */
/***************************************************************************/
+/* b_is_null() : returns true if (and only if) the buffer is not yet allocated
+ * and thus points to a NULL area.
+ */
+static inline int b_is_null(const struct buffer *buf)
+{
+ return buf->area == NULL;
+}
+
/* b_orig() : returns the pointer to the origin of the storage, which is the
* location of byte at offset zero. This is mostly used by functions which
* handle the wrapping by themselves.
*/
static inline char *b_orig(const struct buffer *b)
{
- return (char *)b->area;
+ return b->area;
}
/* b_size() : returns the size of the buffer. */
*/
static inline char *b_wrap(const struct buffer *b)
{
- return (char *)b->area + b->size;
+ return b->area + b->size;
}
/* b_data() : returns the number of bytes present in the buffer. */
};
extern struct pool_head *pool_head_buffer;
-extern struct buffer buf_empty;
-extern struct buffer buf_wanted;
extern struct list buffer_wq;
__decl_hathreads(extern HA_SPINLOCK_T buffer_wq_lock);
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
static inline int buffer_almost_full(const struct buffer *buf)
{
- if (buf == &buf_empty)
+ if (b_is_null(buf))
return 0;
return b_almost_full(buf);
/* Functions below are used for buffer allocation */
/**************************************************/
-/* Allocates a buffer and replaces *buf with this buffer. If no memory is
- * available, &buf_wanted is used instead. No control is made to check if *buf
- * already pointed to another buffer. The allocated buffer is returned, or
- * NULL in case no memory is available.
+/* Allocates a buffer and assigns it to *buf. If no memory is available,
+ * ((char *)1) is assigned instead with a zero size. No control is made to
+ * check if *buf already pointed to another buffer. The allocated buffer is
+ * returned, or NULL in case no memory is available.
*/
-static inline struct buffer *b_alloc(struct buffer **buf)
+static inline struct buffer *b_alloc(struct buffer *buf)
{
- struct buffer *b;
-
- *buf = &buf_wanted;
- b = pool_alloc_dirty(pool_head_buffer);
- if (likely(b)) {
- b->size = pool_head_buffer->size - sizeof(struct buffer);
- b_reset(b);
- *buf = b;
- }
- return b;
+ char *area;
+
+ *buf = BUF_WANTED;
+ area = pool_alloc_dirty(pool_head_buffer);
+ if (unlikely(!area))
+ return NULL;
+
+ buf->area = area;
+ buf->size = pool_head_buffer->size;
+ return buf;
}
-/* Allocates a buffer and replaces *buf with this buffer. If no memory is
- * available, &buf_wanted is used instead. No control is made to check if *buf
- * already pointed to another buffer. The allocated buffer is returned, or
- * NULL in case no memory is available. The difference with b_alloc() is that
- * this function only picks from the pool and never calls malloc(), so it can
- * fail even if some memory is available.
+/* Allocates a buffer and assigns it to *buf. If no memory is available,
+ * ((char *)1) is assigned instead with a zero size. No control is made to
+ * check if *buf already pointed to another buffer. The allocated buffer is
+ * returned, or NULL in case no memory is available. The difference with
+ * b_alloc() is that this function only picks from the pool and never calls
+ * malloc(), so it can fail even if some memory is available.
*/
-static inline struct buffer *b_alloc_fast(struct buffer **buf)
+static inline struct buffer *b_alloc_fast(struct buffer *buf)
{
- struct buffer *b;
-
- *buf = &buf_wanted;
- b = pool_get_first(pool_head_buffer);
- if (likely(b)) {
- b->size = pool_head_buffer->size - sizeof(struct buffer);
- b_reset(b);
- *buf = b;
- }
- return b;
+ char *area;
+
+ *buf = BUF_WANTED;
+ area = pool_get_first(pool_head_buffer);
+ if (unlikely(!area))
+ return NULL;
+
+ buf->area = area;
+ buf->size = pool_head_buffer->size;
+ return buf;
}
-/* Releases buffer *buf (no check of emptiness) */
-static inline void __b_drop(struct buffer **buf)
+/* Releases buffer <buf> (no check of emptiness) */
+static inline void __b_drop(struct buffer *buf)
{
- pool_free(pool_head_buffer, *buf);
+ pool_free(pool_head_buffer, buf->area);
}
-/* Releases buffer *buf if allocated. */
-static inline void b_drop(struct buffer **buf)
+/* Releases buffer <buf> if allocated. */
+static inline void b_drop(struct buffer *buf)
{
- if (!(*buf)->size)
- return;
- __b_drop(buf);
+ if (buf->size)
+ __b_drop(buf);
}
-/* Releases buffer *buf if allocated, and replaces it with &buf_empty. */
-static inline void b_free(struct buffer **buf)
+/* Releases buffer <buf> if allocated, and marks it empty. */
+static inline void b_free(struct buffer *buf)
{
b_drop(buf);
- *buf = &buf_empty;
+ *buf = BUF_NULL;
}
/* Ensures that <buf> is allocated. If an allocation is needed, it ensures that
* after the allocation, regardless how many threads that doing it in the same
* time. So, we use internal and lockless memory functions (prefixed with '__').
*/
-static inline struct buffer *b_alloc_margin(struct buffer **buf, int margin)
+static inline struct buffer *b_alloc_margin(struct buffer *buf, int margin)
{
- struct buffer *b;
+ char *area;
+
+ if (buf->size)
+ return buf;
- if ((*buf)->size)
- return *buf;
+ *buf = BUF_WANTED;
- *buf = &buf_wanted;
#ifndef CONFIG_HAP_LOCKLESS_POOLS
HA_SPIN_LOCK(POOL_LOCK, &pool_head_buffer->lock);
#endif
/* fast path */
if ((pool_head_buffer->allocated - pool_head_buffer->used) > margin) {
- b = __pool_get_first(pool_head_buffer);
- if (likely(b)) {
+ area = __pool_get_first(pool_head_buffer);
+ if (likely(area)) {
#ifndef CONFIG_HAP_LOCKLESS_POOLS
HA_SPIN_UNLOCK(POOL_LOCK, &pool_head_buffer->lock);
#endif
- b->size = pool_head_buffer->size - sizeof(struct buffer);
- b_reset(b);
- *buf = b;
- return b;
+ goto done;
}
}
/* slow path, uses malloc() */
- b = __pool_refill_alloc(pool_head_buffer, margin);
+ area = __pool_refill_alloc(pool_head_buffer, margin);
#ifndef CONFIG_HAP_LOCKLESS_POOLS
HA_SPIN_UNLOCK(POOL_LOCK, &pool_head_buffer->lock);
#endif
- if (b) {
- b->size = pool_head_buffer->size - sizeof(struct buffer);
- b_reset(b);
- *buf = b;
- }
- return b;
+ if (unlikely(!area))
+ return NULL;
+
+ done:
+ buf->area = area;
+ buf->size = pool_head_buffer->size;
+ return buf;
}
/* c_orig() : returns the pointer to the channel buffer's origin */
static inline char *c_orig(const struct channel *c)
{
- return b_orig(c->buf);
+ return b_orig(&c->buf);
}
/* c_size() : returns the size of the channel's buffer */
static inline size_t c_size(const struct channel *c)
{
- return b_size(c->buf);
+ return b_size(&c->buf);
}
/* c_wrap() : returns the pointer to the channel buffer's wrapping point */
static inline char *c_wrap(const struct channel *c)
{
- return b_wrap(c->buf);
+ return b_wrap(&c->buf);
}
/* c_data() : returns the amount of data in the channel's buffer */
static inline size_t c_data(const struct channel *c)
{
- return b_data(c->buf);
+ return b_data(&c->buf);
}
/* c_room() : returns the room left in the channel's buffer */
static inline size_t c_room(const struct channel *c)
{
- return b_size(c->buf) - b_data(c->buf);
+ return b_size(&c->buf) - b_data(&c->buf);
}
/* c_empty() : returns a boolean indicating if the channel's buffer is empty */
*/
static inline size_t ci_next_ofs(const struct channel *c, size_t o)
{
- return b_next_ofs(c->buf, o);
+ return b_next_ofs(&c->buf, o);
}
static inline char *ci_next(const struct channel *c, const char *p)
{
- return b_next(c->buf, p);
+ return b_next(&c->buf, p);
}
*/
static inline char *c_ptr(const struct channel *c, ssize_t ofs)
{
- return b_peek(c->buf, co_data(c) + ofs);
+ return b_peek(&c->buf, co_data(c) + ofs);
}
/* c_adv() : advances the channel's buffer by <adv> bytes, which means that the
/* c_realign_if_empty() : realign the channel's buffer if it's empty */
static inline void c_realign_if_empty(struct channel *chn)
{
- b_realign_if_empty(chn->buf);
+ b_realign_if_empty(&chn->buf);
}
/* Sets the amount of output for the channel */
static inline void co_set_data(struct channel *c, size_t output)
{
- c->buf->data += output - c->output;
+ c->buf.data += output - c->output;
c->output = output;
}
*/
static inline size_t __co_head_ofs(const struct channel *c)
{
- return __b_peek_ofs(c->buf, 0);
+ return __b_peek_ofs(&c->buf, 0);
}
static inline char *__co_head(const struct channel *c)
{
- return __b_peek(c->buf, 0);
+ return __b_peek(&c->buf, 0);
}
static inline size_t co_head_ofs(const struct channel *c)
{
- return b_peek_ofs(c->buf, 0);
+ return b_peek_ofs(&c->buf, 0);
}
static inline char *co_head(const struct channel *c)
{
- return b_peek(c->buf, 0);
+ return b_peek(&c->buf, 0);
}
*/
static inline size_t __co_tail_ofs(const struct channel *c)
{
- return __b_peek_ofs(c->buf, co_data(c));
+ return __b_peek_ofs(&c->buf, co_data(c));
}
static inline char *__co_tail(const struct channel *c)
{
- return __b_peek(c->buf, co_data(c));
+ return __b_peek(&c->buf, co_data(c));
}
static inline size_t co_tail_ofs(const struct channel *c)
{
- return b_peek_ofs(c->buf, co_data(c));
+ return b_peek_ofs(&c->buf, co_data(c));
}
static inline char *co_tail(const struct channel *c)
{
- return b_peek(c->buf, co_data(c));
+ return b_peek(&c->buf, co_data(c));
}
*/
static inline size_t __ci_head_ofs(const struct channel *c)
{
- return __b_peek_ofs(c->buf, co_data(c));
+ return __b_peek_ofs(&c->buf, co_data(c));
}
static inline char *__ci_head(const struct channel *c)
{
- return __b_peek(c->buf, co_data(c));
+ return __b_peek(&c->buf, co_data(c));
}
static inline size_t ci_head_ofs(const struct channel *c)
{
- return b_peek_ofs(c->buf, co_data(c));
+ return b_peek_ofs(&c->buf, co_data(c));
}
static inline char *ci_head(const struct channel *c)
{
- return b_peek(c->buf, co_data(c));
+ return b_peek(&c->buf, co_data(c));
}
*/
static inline size_t __ci_tail_ofs(const struct channel *c)
{
- return __b_peek_ofs(c->buf, c_data(c));
+ return __b_peek_ofs(&c->buf, c_data(c));
}
static inline char *__ci_tail(const struct channel *c)
{
- return __b_peek(c->buf, c_data(c));
+ return __b_peek(&c->buf, c_data(c));
}
static inline size_t ci_tail_ofs(const struct channel *c)
{
- return b_peek_ofs(c->buf, c_data(c));
+ return b_peek_ofs(&c->buf, c_data(c));
}
static inline char *ci_tail(const struct channel *c)
{
- return b_peek(c->buf, c_data(c));
+ return b_peek(&c->buf, c_data(c));
}
*/
static inline size_t __ci_stop_ofs(const struct channel *c)
{
- return __b_stop_ofs(c->buf);
+ return __b_stop_ofs(&c->buf);
}
static inline const char *__ci_stop(const struct channel *c)
{
- return __b_stop(c->buf);
+ return __b_stop(&c->buf);
}
static inline size_t ci_stop_ofs(const struct channel *c)
{
- return b_stop_ofs(c->buf);
+ return b_stop_ofs(&c->buf);
}
static inline const char *ci_stop(const struct channel *c)
{
- return b_stop(c->buf);
+ return b_stop(&c->buf);
}
/* Returns the amount of input data that can contiguously be read at once */
static inline size_t ci_contig_data(const struct channel *c)
{
- return b_contig_data(c->buf, co_data(c));
+ return b_contig_data(&c->buf, co_data(c));
}
/* Initialize all fields in the channel. */
static inline void channel_init(struct channel *chn)
{
- chn->buf = &buf_empty;
+ chn->buf = BUF_NULL;
chn->to_forward = 0;
chn->last_read = now_ms;
chn->xfer_small = chn->xfer_large = 0;
*/
static inline int channel_is_rewritable(const struct channel *chn)
{
- int rem = chn->buf->size;
+ int rem = chn->buf.size;
- rem -= b_data(chn->buf);
+ rem -= b_data(&chn->buf);
rem -= global.tune.maxrewrite;
return rem >= 0;
}
* decide when to stop reading into a buffer when we want to ensure that we
* leave the reserve untouched after all pending outgoing data are forwarded.
* The reserved space is taken into account if ->to_forward indicates that an
- * end of transfer is close to happen. Note that both ->buf->o and ->to_forward
+ * end of transfer is close to happen. Note that both ->buf.o and ->to_forward
* are considered as available since they're supposed to leave the buffer. The
* test is optimized to avoid as many operations as possible for the fast case
* and to be used as an "if" condition. Just like channel_recv_limit(), we
*/
static inline int channel_may_recv(const struct channel *chn)
{
- int rem = chn->buf->size;
+ int rem = chn->buf.size;
- if (chn->buf == &buf_empty)
+ if (b_is_null(&chn->buf))
return 1;
- rem -= b_data(chn->buf);
+ rem -= b_data(&chn->buf);
if (!rem)
return 0; /* buffer already full */
* the reserve, and we want to ensure they're covered by scheduled
* forwards.
*/
- rem = ci_data(chn) + global.tune.maxrewrite - chn->buf->size;
+ rem = ci_data(chn) + global.tune.maxrewrite - chn->buf.size;
return rem < 0 || (unsigned int)rem < chn->to_forward;
}
static inline void channel_erase(struct channel *chn)
{
chn->to_forward = 0;
- b_reset(chn->buf);
+ b_reset(&chn->buf);
}
/* marks the channel as "shutdown" ASAP for reads */
int reserve;
/* return zero if empty */
- reserve = chn->buf->size;
- if (chn->buf == &buf_empty)
+ reserve = chn->buf.size;
+ if (b_is_null(&chn->buf))
goto end;
/* return size - maxrewrite if we can't send */
reserve -= transit;
if (transit < chn->to_forward || // addition overflow
transit >= (unsigned)global.tune.maxrewrite) // enough transit data
- return chn->buf->size;
+ return chn->buf.size;
end:
- return chn->buf->size - reserve;
+ return chn->buf.size - reserve;
}
/* Returns non-zero if the channel's INPUT buffer's is considered full, which
*/
static inline int channel_full(const struct channel *c, unsigned int reserve)
{
- if (c->buf == &buf_empty)
+ if (b_is_null(&c->buf))
return 0;
return (ci_data(c) + reserve >= c_size(c));
{
int ret;
- ret = channel_recv_limit(chn) - b_data(chn->buf);
+ ret = channel_recv_limit(chn) - b_data(&chn->buf);
if (ret < 0)
ret = 0;
return ret;
*/
static inline int ci_space_for_replace(const struct channel *chn)
{
- const struct buffer *buf = chn->buf;
+ const struct buffer *buf = &chn->buf;
const char *end;
/* If the input side data overflows, we cannot insert data contiguously. */
if (!ci_data(chn))
return;
- chn->buf->data = co_data(chn);
+ chn->buf.data = co_data(chn);
}
/* This function realigns a possibly wrapping channel buffer so that the input
*/
static inline void channel_slow_realign(struct channel *chn, char *swap)
{
- return b_slow_realign(chn->buf, swap, co_data(chn));
+ return b_slow_realign(&chn->buf, swap, co_data(chn));
}
/*
*/
static inline void co_skip(struct channel *chn, int len)
{
- b_del(chn->buf, len);
+ b_del(&chn->buf, len);
chn->output -= len;
c_realign_if_empty(chn);
/* returns the buffer which receives data from this stream interface (input channel's buffer) */
static inline struct buffer *si_ib(struct stream_interface *si)
{
- return si_ic(si)->buf;
+ return &si_ic(si)->buf;
}
/* returns the buffer which feeds data to this stream interface (output channel's buffer) */
static inline struct buffer *si_ob(struct stream_interface *si)
{
- return si_oc(si)->buf;
+ return &si_oc(si)->buf;
}
/* returns the stream associated to a stream interface */
struct channel {
unsigned int flags; /* CF_* */
unsigned int analysers; /* bit field indicating what to do on the channel */
- struct buffer *buf; /* buffer attached to the channel, always present but may move */
+ struct buffer buf; /* buffer attached to the channel, always present but may move */
struct pipe *pipe; /* non-NULL only when data present */
size_t output; /* part of buffer which is to be forwarded */
unsigned int to_forward; /* number of bytes to forward after out without a wake-up */
#include <common/config.h>
#include <common/mini-clist.h>
#include <common/regex.h>
+#include <common/buffer.h>
#include <types/connection.h>
#include <types/obj_type.h>
struct check {
struct xprt_ops *xprt; /* transport layer operations for health checks */
struct conn_stream *cs; /* conn_stream state for health checks */
- struct buffer *bi, *bo; /* input and output buffers to send/recv check */
+ struct buffer bi, bo; /* input and output buffers to send/recv check */
struct task *task; /* the task associated to the health check processing, NULL if disabled */
struct timeval start; /* last health check start time */
long duration; /* time in ms took to finish last health check */
struct slz_stream strm;
const void *direct_ptr; /* NULL or pointer to beginning of data */
int direct_len; /* length of direct_ptr if not NULL */
- struct buffer *queued; /* if not NULL, data already queued */
+ struct buffer queued; /* if not NULL, data already queued */
#elif defined(USE_ZLIB)
z_stream strm; /* zlib stream */
void *zlib_deflate_state;
struct list *events; /* List of messages that will be sent during the stream processing */
struct list *groups; /* List of available SPOE group */
- struct buffer *buffer; /* Buffer used to store a encoded messages */
+ struct buffer buffer; /* Buffer used to store a encoded messages */
struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
struct list list;
int rlen; /* reason length */
#endif
- struct buffer *buffer; /* Buffer used to store a encoded messages */
+ struct buffer buffer; /* Buffer used to store a encoded messages */
struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
struct list waiting_queue; /* list of streams waiting for a ACK frame, in sync and pipelining mode */
struct list list; /* next spoe appctx for the same agent */
if (len == 0)
return NULL;
- if (len > b_wrap(req->buf) - p)
- len = b_wrap(req->buf) - p;
+ if (len > b_wrap(&req->buf) - p)
+ len = b_wrap(&req->buf) - p;
if (px->lbprm.tot_weight == 0)
return NULL;
struct pool_head *pool_head_buffer;
-/* These buffers are used to always have a valid pointer to an empty buffer in
- * channels. The first buffer is set once a buffer is empty. The second one is
- * set when a buffer is desired but no more are available. It helps knowing
- * what channel wants a buffer. They can reliably be exchanged, the split
- * between the two is only an optimization.
- */
-struct buffer buf_empty = { };
-struct buffer buf_wanted = { };
-
/* list of objects waiting for at least one buffer */
struct list buffer_wq = LIST_HEAD_INIT(buffer_wq);
__decl_hathreads(HA_SPINLOCK_T __attribute__((aligned(64))) buffer_wq_lock);
{
void *buffer;
- pool_head_buffer = create_pool("buffer", sizeof (struct buffer) + global.tune.bufsize, MEM_F_SHARED|MEM_F_EXACT);
+ pool_head_buffer = create_pool("buffer", global.tune.bufsize, MEM_F_SHARED|MEM_F_EXACT);
if (!pool_head_buffer)
return 0;
goto out;
/* Check if the input buffer is avalaible. */
- if (res->buf->size == 0) {
+ if (res->buf.size == 0) {
si_applet_cant_put(si);
goto out;
}
si_applet_cant_put(si);
goto out;
}
- b_add(res->buf, len);
+ b_add(&res->buf, len);
res->total += len;
appctx->st0 = HTTP_CACHE_FWD;
}
}
c_realign_if_empty(chn);
- max = b_contig_space(chn->buf);
+ max = b_contig_space(&chn->buf);
if (len > max)
return max;
memcpy(ci_tail(chn), msg, len);
- b_add(chn->buf, len);
+ b_add(&chn->buf, len);
c_adv(chn, len);
chn->total += len;
return -1;
*ci_tail(chn) = c;
- b_add(chn->buf, 1);
+ b_add(&chn->buf, 1);
chn->flags |= CF_READ_PARTIAL;
if (chn->to_forward >= 1) {
return 0;
/* OK so the data fits in the buffer in one or two blocks */
- max = b_contig_space(chn->buf);
+ max = b_contig_space(&chn->buf);
memcpy(ci_tail(chn), blk, MIN(len, max));
if (len > max)
memcpy(c_orig(chn), blk + max, len - max);
- b_add(chn->buf, len);
+ b_add(&chn->buf, len);
chn->total += len;
if (chn->to_forward) {
unsigned long fwd = len;
if (*p == '\n')
break;
- p = b_next(chn->buf, p);
+ p = b_next(&chn->buf, p);
}
if (ret > 0 && ret < len &&
(ret < co_data(chn) || channel_may_recv(chn)) &&
return 0;
}
- return b_getblk(chn->buf, blk, len, offset);
+ return b_getblk(&chn->buf, blk, len, offset);
}
/* Gets one or two blocks of data at once from a channel's output buffer.
return 0;
}
- return b_getblk_nc(chn->buf, blk1, len1, blk2, len2, 0, co_data(chn));
+ return b_getblk_nc(&chn->buf, blk1, len1, blk2, len2, 0, co_data(chn));
}
/* Gets one text line out of a channel's output buffer from a stream interface.
*/
int ci_insert_line2(struct channel *c, int pos, const char *str, int len)
{
- struct buffer *b = c->buf;
+ struct buffer *b = &c->buf;
char *dst = c_ptr(c, pos);
int delta;
if (check->type == PR_O2_TCPCHK_CHK)
goto out_unlock;
- if (b_data(check->bo)) {
- b_del(check->bo, conn->mux->snd_buf(cs, check->bo, b_data(check->bo), 0));
- b_realign_if_empty(check->bo);
+ if (b_data(&check->bo)) {
+ b_del(&check->bo, conn->mux->snd_buf(cs, &check->bo, b_data(&check->bo), 0));
+ b_realign_if_empty(&check->bo);
if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) {
chk_report_conn_err(check, errno, 0);
__cs_stop_both(cs);
goto out_wakeup;
}
- if (b_data(check->bo))
+ if (b_data(&check->bo))
goto out_unlock;
}
done = 0;
- conn->mux->rcv_buf(cs, check->bi, check->bi->size, 0);
+ conn->mux->rcv_buf(cs, &check->bi, b_size(&check->bi), 0);
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH) || cs->flags & CS_FL_ERROR) {
done = 1;
- if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !b_data(check->bi)) {
+ if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !b_data(&check->bi)) {
/* Report network errors only if we got no other data. Otherwise
* we'll let the upper layers decide whether the response is OK
* or not. It is very common that an RST sent by the server is
/* Intermediate or complete response received.
- * Terminate string in b_head(check->bi) buffer.
+ * Terminate string in b_head(&check->bi) buffer.
*/
- if (b_data(check->bi) < check->bi->size)
- b_head(check->bi)[b_data(check->bi)] = '\0';
+ if (b_data(&check->bi) < b_size(&check->bi))
+ b_head(&check->bi)[b_data(&check->bi)] = '\0';
else {
- b_head(check->bi)[b_data(check->bi) - 1] = '\0';
+ b_head(&check->bi)[b_data(&check->bi) - 1] = '\0';
done = 1; /* buffer full, don't wait for more data */
}
/* Run the checks... */
switch (check->type) {
case PR_O2_HTTP_CHK:
- if (!done && b_data(check->bi) < strlen("HTTP/1.0 000\r"))
+ if (!done && b_data(&check->bi) < strlen("HTTP/1.0 000\r"))
goto wait_more_data;
/* Check if the server speaks HTTP 1.X */
- if ((b_data(check->bi) < strlen("HTTP/1.0 000\r")) ||
- (memcmp(b_head(check->bi), "HTTP/1.", 7) != 0 ||
- (*(b_head(check->bi) + 12) != ' ' && *(b_head(check->bi) + 12) != '\r')) ||
- !isdigit((unsigned char) *(b_head(check->bi) + 9)) || !isdigit((unsigned char) *(b_head(check->bi) + 10)) ||
- !isdigit((unsigned char) *(b_head(check->bi) + 11))) {
- cut_crlf(b_head(check->bi));
- set_server_check_status(check, HCHK_STATUS_L7RSP, b_head(check->bi));
+ if ((b_data(&check->bi) < strlen("HTTP/1.0 000\r")) ||
+ (memcmp(b_head(&check->bi), "HTTP/1.", 7) != 0 ||
+ (*(b_head(&check->bi) + 12) != ' ' && *(b_head(&check->bi) + 12) != '\r')) ||
+ !isdigit((unsigned char) *(b_head(&check->bi) + 9)) || !isdigit((unsigned char) *(b_head(&check->bi) + 10)) ||
+ !isdigit((unsigned char) *(b_head(&check->bi) + 11))) {
+ cut_crlf(b_head(&check->bi));
+ set_server_check_status(check, HCHK_STATUS_L7RSP, b_head(&check->bi));
goto out_wakeup;
}
- check->code = str2uic(b_head(check->bi) + 9);
- desc = ltrim(b_head(check->bi) + 12, ' ');
+ check->code = str2uic(b_head(&check->bi) + 9);
+ desc = ltrim(b_head(&check->bi) + 12, ' ');
if ((s->proxy->options & PR_O_DISABLE404) &&
(s->next_state != SRV_ST_STOPPED) && (check->code == 404)) {
goto wait_more_data;
}
/* check the reply : HTTP/1.X 2xx and 3xx are OK */
- else if (*(b_head(check->bi) + 9) == '2' || *(b_head(check->bi) + 9) == '3') {
+ else if (*(b_head(&check->bi) + 9) == '2' || *(b_head(&check->bi) + 9) == '3') {
cut_crlf(desc);
set_server_check_status(check, HCHK_STATUS_L7OKD, desc);
}
break;
case PR_O2_SSL3_CHK:
- if (!done && b_data(check->bi) < 5)
+ if (!done && b_data(&check->bi) < 5)
goto wait_more_data;
/* Check for SSLv3 alert or handshake */
- if ((b_data(check->bi) >= 5) && (*b_head(check->bi) == 0x15 || *b_head(check->bi) == 0x16))
+ if ((b_data(&check->bi) >= 5) && (*b_head(&check->bi) == 0x15 || *b_head(&check->bi) == 0x16))
set_server_check_status(check, HCHK_STATUS_L6OK, NULL);
else
set_server_check_status(check, HCHK_STATUS_L6RSP, NULL);
break;
case PR_O2_SMTP_CHK:
- if (!done && b_data(check->bi) < strlen("000\r"))
+ if (!done && b_data(&check->bi) < strlen("000\r"))
goto wait_more_data;
/* Check if the server speaks SMTP */
- if ((b_data(check->bi) < strlen("000\r")) ||
- (*(b_head(check->bi) + 3) != ' ' && *(b_head(check->bi) + 3) != '\r') ||
- !isdigit((unsigned char) *b_head(check->bi)) || !isdigit((unsigned char) *(b_head(check->bi) + 1)) ||
- !isdigit((unsigned char) *(b_head(check->bi) + 2))) {
- cut_crlf(b_head(check->bi));
- set_server_check_status(check, HCHK_STATUS_L7RSP, b_head(check->bi));
+ if ((b_data(&check->bi) < strlen("000\r")) ||
+ (*(b_head(&check->bi) + 3) != ' ' && *(b_head(&check->bi) + 3) != '\r') ||
+ !isdigit((unsigned char) *b_head(&check->bi)) || !isdigit((unsigned char) *(b_head(&check->bi) + 1)) ||
+ !isdigit((unsigned char) *(b_head(&check->bi) + 2))) {
+ cut_crlf(b_head(&check->bi));
+ set_server_check_status(check, HCHK_STATUS_L7RSP, b_head(&check->bi));
goto out_wakeup;
}
- check->code = str2uic(b_head(check->bi));
+ check->code = str2uic(b_head(&check->bi));
- desc = ltrim(b_head(check->bi) + 3, ' ');
+ desc = ltrim(b_head(&check->bi) + 3, ' ');
cut_crlf(desc);
/* Check for SMTP code 2xx (should be 250) */
- if (*b_head(check->bi) == '2')
+ if (*b_head(&check->bi) == '2')
set_server_check_status(check, HCHK_STATUS_L7OKD, desc);
else
set_server_check_status(check, HCHK_STATUS_L7STS, desc);
* same category appear, the last one wins.
*/
- p = b_head(check->bi);
+ p = b_head(&check->bi);
while (*p && *p != '\n' && *p != '\r')
p++;
}
*p = 0;
- cmd = b_head(check->bi);
+ cmd = b_head(&check->bi);
while (*cmd) {
/* look for next word */
}
case PR_O2_PGSQL_CHK:
- if (!done && b_data(check->bi) < 9)
+ if (!done && b_data(&check->bi) < 9)
goto wait_more_data;
- if (b_head(check->bi)[0] == 'R') {
+ if (b_head(&check->bi)[0] == 'R') {
set_server_check_status(check, HCHK_STATUS_L7OKD, "PostgreSQL server is ok");
}
else {
- if ((b_head(check->bi)[0] == 'E') && (b_head(check->bi)[5]!=0) && (b_head(check->bi)[6]!=0))
- desc = &b_head(check->bi)[6];
+ if ((b_head(&check->bi)[0] == 'E') && (b_head(&check->bi)[5]!=0) && (b_head(&check->bi)[6]!=0))
+ desc = &b_head(&check->bi)[6];
else
desc = "PostgreSQL unknown error";
break;
case PR_O2_REDIS_CHK:
- if (!done && b_data(check->bi) < 7)
+ if (!done && b_data(&check->bi) < 7)
goto wait_more_data;
- if (strcmp(b_head(check->bi), "+PONG\r\n") == 0) {
+ if (strcmp(b_head(&check->bi), "+PONG\r\n") == 0) {
set_server_check_status(check, HCHK_STATUS_L7OKD, "Redis server is ok");
}
else {
- set_server_check_status(check, HCHK_STATUS_L7STS, b_head(check->bi));
+ set_server_check_status(check, HCHK_STATUS_L7STS, b_head(&check->bi));
}
break;
case PR_O2_MYSQL_CHK:
- if (!done && b_data(check->bi) < 5)
+ if (!done && b_data(&check->bi) < 5)
goto wait_more_data;
if (s->proxy->check_len == 0) { // old mode
- if (*(b_head(check->bi) + 4) != '\xff') {
+ if (*(b_head(&check->bi) + 4) != '\xff') {
/* We set the MySQL Version in description for information purpose
* FIXME : it can be cool to use MySQL Version for other purpose,
* like mark as down old MySQL server.
*/
- if (b_data(check->bi) > 51) {
- desc = ltrim(b_head(check->bi) + 5, ' ');
+ if (b_data(&check->bi) > 51) {
+ desc = ltrim(b_head(&check->bi) + 5, ' ');
set_server_check_status(check, HCHK_STATUS_L7OKD, desc);
}
else {
/* it seems we have a OK packet but without a valid length,
* it must be a protocol error
*/
- set_server_check_status(check, HCHK_STATUS_L7RSP, b_head(check->bi));
+ set_server_check_status(check, HCHK_STATUS_L7RSP, b_head(&check->bi));
}
}
else {
/* An error message is attached in the Error packet */
- desc = ltrim(b_head(check->bi) + 7, ' ');
+ desc = ltrim(b_head(&check->bi) + 7, ' ');
set_server_check_status(check, HCHK_STATUS_L7STS, desc);
}
} else {
- unsigned int first_packet_len = ((unsigned int) *b_head(check->bi)) +
- (((unsigned int) *(b_head(check->bi) + 1)) << 8) +
- (((unsigned int) *(b_head(check->bi) + 2)) << 16);
+ unsigned int first_packet_len = ((unsigned int) *b_head(&check->bi)) +
+ (((unsigned int) *(b_head(&check->bi) + 1)) << 8) +
+ (((unsigned int) *(b_head(&check->bi) + 2)) << 16);
- if (b_data(check->bi) == first_packet_len + 4) {
+ if (b_data(&check->bi) == first_packet_len + 4) {
/* MySQL Error packet always begin with field_count = 0xff */
- if (*(b_head(check->bi) + 4) != '\xff') {
+ if (*(b_head(&check->bi) + 4) != '\xff') {
/* We have only one MySQL packet and it is a Handshake Initialization packet
* but we need to have a second packet to know if it is alright
*/
- if (!done && b_data(check->bi) < first_packet_len + 5)
+ if (!done && b_data(&check->bi) < first_packet_len + 5)
goto wait_more_data;
}
else {
/* We have only one packet and it is an Error packet,
* an error message is attached, so we can display it
*/
- desc = &b_head(check->bi)[7];
+ desc = &b_head(&check->bi)[7];
//ha_warning("onlyoneERR: %s\n", desc);
set_server_check_status(check, HCHK_STATUS_L7STS, desc);
}
- } else if (b_data(check->bi) > first_packet_len + 4) {
- unsigned int second_packet_len = ((unsigned int) *(b_head(check->bi) + first_packet_len + 4)) +
- (((unsigned int) *(b_head(check->bi) + first_packet_len + 5)) << 8) +
- (((unsigned int) *(b_head(check->bi) + first_packet_len + 6)) << 16);
+ } else if (b_data(&check->bi) > first_packet_len + 4) {
+ unsigned int second_packet_len = ((unsigned int) *(b_head(&check->bi) + first_packet_len + 4)) +
+ (((unsigned int) *(b_head(&check->bi) + first_packet_len + 5)) << 8) +
+ (((unsigned int) *(b_head(&check->bi) + first_packet_len + 6)) << 16);
- if (b_data(check->bi) == first_packet_len + 4 + second_packet_len + 4 ) {
+ if (b_data(&check->bi) == first_packet_len + 4 + second_packet_len + 4 ) {
/* We have 2 packets and that's good */
/* Check if the second packet is a MySQL Error packet or not */
- if (*(b_head(check->bi) + first_packet_len + 8) != '\xff') {
+ if (*(b_head(&check->bi) + first_packet_len + 8) != '\xff') {
/* No error packet */
/* We set the MySQL Version in description for information purpose */
- desc = &b_head(check->bi)[5];
+ desc = &b_head(&check->bi)[5];
//ha_warning("2packetOK: %s\n", desc);
set_server_check_status(check, HCHK_STATUS_L7OKD, desc);
}
/* An error message is attached in the Error packet
* so we can display it ! :)
*/
- desc = &b_head(check->bi)[first_packet_len+11];
+ desc = &b_head(&check->bi)[first_packet_len+11];
//ha_warning("2packetERR: %s\n", desc);
set_server_check_status(check, HCHK_STATUS_L7STS, desc);
}
/* it seems we have a Handshake Initialization packet but without a valid length,
* it must be a protocol error
*/
- desc = &b_head(check->bi)[5];
+ desc = &b_head(&check->bi)[5];
//ha_warning("protoerr: %s\n", desc);
set_server_check_status(check, HCHK_STATUS_L7RSP, desc);
}
break;
case PR_O2_LDAP_CHK:
- if (!done && b_data(check->bi) < 14)
+ if (!done && b_data(&check->bi) < 14)
goto wait_more_data;
/* Check if the server speaks LDAP (ASN.1/BER)
/* http://tools.ietf.org/html/rfc4511#section-4.1.1
* LDAPMessage: 0x30: SEQUENCE
*/
- if ((b_data(check->bi) < 14) || (*(b_head(check->bi)) != '\x30')) {
+ if ((b_data(&check->bi) < 14) || (*(b_head(&check->bi)) != '\x30')) {
set_server_check_status(check, HCHK_STATUS_L7RSP, "Not LDAPv3 protocol");
}
else {
/* size of LDAPMessage */
- msglen = (*(b_head(check->bi) + 1) & 0x80) ? (*(b_head(check->bi) + 1) & 0x7f) : 0;
+ msglen = (*(b_head(&check->bi) + 1) & 0x80) ? (*(b_head(&check->bi) + 1) & 0x7f) : 0;
/* http://tools.ietf.org/html/rfc4511#section-4.2.2
* messageID: 0x02 0x01 0x01: INTEGER 1
* protocolOp: 0x61: bindResponse
*/
if ((msglen > 2) ||
- (memcmp(b_head(check->bi) + 2 + msglen, "\x02\x01\x01\x61", 4) != 0)) {
+ (memcmp(b_head(&check->bi) + 2 + msglen, "\x02\x01\x01\x61", 4) != 0)) {
set_server_check_status(check, HCHK_STATUS_L7RSP, "Not LDAPv3 protocol");
goto out_wakeup;
}
/* size of bindResponse */
- msglen += (*(b_head(check->bi) + msglen + 6) & 0x80) ? (*(b_head(check->bi) + msglen + 6) & 0x7f) : 0;
+ msglen += (*(b_head(&check->bi) + msglen + 6) & 0x80) ? (*(b_head(&check->bi) + msglen + 6) & 0x7f) : 0;
/* http://tools.ietf.org/html/rfc4511#section-4.1.9
* ldapResult: 0x0a 0x01: ENUMERATION
*/
if ((msglen > 4) ||
- (memcmp(b_head(check->bi) + 7 + msglen, "\x0a\x01", 2) != 0)) {
+ (memcmp(b_head(&check->bi) + 7 + msglen, "\x0a\x01", 2) != 0)) {
set_server_check_status(check, HCHK_STATUS_L7RSP, "Not LDAPv3 protocol");
goto out_wakeup;
}
/* http://tools.ietf.org/html/rfc4511#section-4.1.9
* resultCode
*/
- check->code = *(b_head(check->bi) + msglen + 9);
+ check->code = *(b_head(&check->bi) + msglen + 9);
if (check->code) {
set_server_check_status(check, HCHK_STATUS_L7STS, "See RFC: http://tools.ietf.org/html/rfc4511#section-4.1.9");
} else {
unsigned int framesz;
char err[HCHK_DESC_LEN];
- if (!done && b_data(check->bi) < 4)
+ if (!done && b_data(&check->bi) < 4)
goto wait_more_data;
- memcpy(&framesz, b_head(check->bi), 4);
+ memcpy(&framesz, b_head(&check->bi), 4);
framesz = ntohl(framesz);
- if (!done && b_data(check->bi) < (4+framesz))
+ if (!done && b_data(&check->bi) < (4+framesz))
goto wait_more_data;
- if (!spoe_handle_healthcheck_response(b_head(check->bi)+4, framesz, err, HCHK_DESC_LEN-1))
+ if (!spoe_handle_healthcheck_response(b_head(&check->bi)+4, framesz, err, HCHK_DESC_LEN-1))
set_server_check_status(check, HCHK_STATUS_L7OKD, "SPOA server is ok");
else
set_server_check_status(check, HCHK_STATUS_L7STS, err);
chk_report_conn_err(check, 0, 0);
/* Reset the check buffer... */
- *b_head(check->bi) = '\0';
- b_reset(check->bi);
+ *b_head(&check->bi) = '\0';
+ b_reset(&check->bi);
/* Close the connection... We still attempt to nicely close if,
* for instance, SSL needs to send a "close notify." Later, we perform
* its own strings.
*/
if (check->type && check->type != PR_O2_TCPCHK_CHK && !(check->state & CHK_ST_AGENT)) {
- b_putblk(check->bo, s->proxy->check_req, s->proxy->check_len);
+ b_putblk(&check->bo, s->proxy->check_req, s->proxy->check_len);
/* we want to check if this host replies to HTTP or SSLv3 requests
* so we'll send the request, and won't wake the checker up now.
if ((check->type) == PR_O2_SSL3_CHK) {
/* SSL requires that we put Unix time in the request */
int gmt_time = htonl(date.tv_sec);
- memcpy(b_head(check->bo) + 11, &gmt_time, 4);
+ memcpy(b_head(&check->bo) + 11, &gmt_time, 4);
}
else if ((check->type) == PR_O2_HTTP_CHK) {
if (s->proxy->options2 & PR_O2_CHK_SNDST)
- b_putblk(check->bo, trash.str, httpchk_build_status_header(s, trash.str, trash.size));
+ b_putblk(&check->bo, trash.str, httpchk_build_status_header(s, trash.str, trash.size));
/* prevent HTTP keep-alive when "http-check expect" is used */
if (s->proxy->options2 & PR_O2_EXP_TYPE)
- b_putist(check->bo, ist("Connection: close\r\n"));
- b_putist(check->bo, ist("\r\n"));
- *b_tail(check->bo) = '\0'; /* to make gdb output easier to read */
+ b_putist(&check->bo, ist("Connection: close\r\n"));
+ b_putist(&check->bo, ist("\r\n"));
+ *b_tail(&check->bo) = '\0'; /* to make gdb output easier to read */
}
}
if ((check->type & PR_O2_LB_AGENT_CHK) && check->send_string_len) {
- b_putblk(check->bo, check->send_string, check->send_string_len);
+ b_putblk(&check->bo, check->send_string, check->send_string_len);
}
/* for tcp-checks, the initial connection setup is handled separately as
set_server_check_status(check, HCHK_STATUS_START, NULL);
check->state |= CHK_ST_INPROGRESS;
- b_reset(check->bi);
- b_reset(check->bo);
+ b_reset(&check->bi);
+ b_reset(&check->bo);
ret = connect_conn_chk(t);
cs = check->cs;
switch (s->proxy->options2 & PR_O2_EXP_TYPE) {
case PR_O2_EXP_STS:
case PR_O2_EXP_RSTS:
- memcpy(status_code, b_head(s->check.bi) + 9, 3);
- memcpy(status_msg + strlen(status_msg) - 4, b_head(s->check.bi) + 9, 3);
+ memcpy(status_code, b_head(&s->check.bi) + 9, 3);
+ memcpy(status_msg + strlen(status_msg) - 4, b_head(&s->check.bi) + 9, 3);
if ((s->proxy->options2 & PR_O2_EXP_TYPE) == PR_O2_EXP_STS)
ret = strncmp(s->proxy->expect_str, status_code, 3) == 0;
* to '\0' if crlf < 2.
*/
crlf = 0;
- for (contentptr = b_head(s->check.bi); *contentptr; contentptr++) {
+ for (contentptr = b_head(&s->check.bi); *contentptr; contentptr++) {
if (crlf >= 2)
break;
if (*contentptr == '\r')
/* no step means first step initialisation */
if (check->current_step == NULL) {
check->last_started_step = NULL;
- b_reset(check->bo);
- b_reset(check->bi);
+ b_reset(&check->bo);
+ b_reset(&check->bi);
check->current_step = next;
t->expire = tick_add(now_ms, MS_TO_TICKS(check->inter));
if (s->proxy->timeout.check)
* in the remaining space. That explains why we break out of the
* loop after this control. If we have data, conn is valid.
*/
- if (b_data(check->bo) &&
+ if (b_data(&check->bo) &&
(&check->current_step->list == head ||
check->current_step->action != TCPCHK_ACT_SEND ||
- check->current_step->string_len >= b_room(check->bo))) {
+ check->current_step->string_len >= b_room(&check->bo))) {
int ret;
__cs_want_send(cs);
- ret = conn->mux->snd_buf(cs, check->bo, b_data(check->bo), 0);
- b_del(check->bo, ret);
- b_realign_if_empty(check->bo);
+ ret = conn->mux->snd_buf(cs, &check->bo, b_data(&check->bo), 0);
+ b_del(&check->bo, ret);
+ b_realign_if_empty(&check->bo);
if (ret <= 0) {
if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) {
check->last_started_step = check->current_step;
/* reset the read buffer */
- if (*b_head(check->bi) != '\0') {
- *b_head(check->bi) = '\0';
- b_reset(check->bi);
+ if (*b_head(&check->bi) != '\0') {
+ *b_head(&check->bi) = '\0';
+ b_reset(&check->bi);
}
if (conn->flags & CO_FL_SOCK_WR_SH) {
goto out_end_tcpcheck;
}
- if (check->current_step->string_len >= check->bo->size) {
+ if (check->current_step->string_len >= b_size(&check->bo)) {
chunk_printf(&trash, "tcp-check send : string too large (%d) for buffer size (%u) at step %d",
- check->current_step->string_len, (unsigned int)check->bo->size,
+ check->current_step->string_len, (unsigned int)b_size(&check->bo),
tcpcheck_get_step_id(check));
set_server_check_status(check, HCHK_STATUS_L7RSP, trash.str);
goto out_end_tcpcheck;
}
/* do not try to send if there is no space */
- if (check->current_step->string_len >= b_room(check->bo))
+ if (check->current_step->string_len >= b_room(&check->bo))
continue;
- b_putblk(check->bo, check->current_step->string, check->current_step->string_len);
- *b_tail(check->bo) = '\0'; /* to make gdb output easier to read */
+ b_putblk(&check->bo, check->current_step->string, check->current_step->string_len);
+ *b_tail(&check->bo) = '\0'; /* to make gdb output easier to read */
/* go to next rule and try to send */
check->current_step = LIST_NEXT(&check->current_step->list, struct tcpcheck_rule *, list);
goto out_end_tcpcheck;
__cs_want_recv(cs);
- if (conn->mux->rcv_buf(cs, check->bi, check->bi->size, 0) <= 0) {
+ if (conn->mux->rcv_buf(cs, &check->bi, b_size(&check->bi), 0) <= 0) {
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH) || cs->flags & CS_FL_ERROR) {
done = 1;
- if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !b_data(check->bi)) {
+ if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !b_data(&check->bi)) {
/* Report network errors only if we got no other data. Otherwise
* we'll let the upper layers decide whether the response is OK
* or not. It is very common that an RST sent by the server is
/* Intermediate or complete response received.
- * Terminate string in b_head(check->bi) buffer.
+ * Terminate string in b_head(&check->bi) buffer.
*/
- if (b_data(check->bi) < check->bi->size) {
- b_head(check->bi)[b_data(check->bi)] = '\0';
+ if (b_data(&check->bi) < b_size(&check->bi)) {
+ b_head(&check->bi)[b_data(&check->bi)] = '\0';
}
else {
- b_head(check->bi)[b_data(check->bi) - 1] = '\0';
+ b_head(&check->bi)[b_data(&check->bi) - 1] = '\0';
done = 1; /* buffer full, don't wait for more data */
}
- contentptr = b_head(check->bi);
+ contentptr = b_head(&check->bi);
/* Check that response body is not empty... */
- if (!b_data(check->bi)) {
+ if (!b_data(&check->bi)) {
if (!done)
continue;
goto out_end_tcpcheck;
}
- if (!done && (check->current_step->string != NULL) && (b_data(check->bi) < check->current_step->string_len) )
+ if (!done && (check->current_step->string != NULL) && (b_data(&check->bi) < check->current_step->string_len) )
continue; /* try to read more */
tcpcheck_expect:
if (check->current_step->string != NULL)
- ret = my_memmem(contentptr, b_data(check->bi), check->current_step->string, check->current_step->string_len) != NULL;
+ ret = my_memmem(contentptr, b_data(&check->bi), check->current_step->string, check->current_step->string_len) != NULL;
else if (check->current_step->expect_regex != NULL)
ret = regex_exec(check->current_step->expect_regex, contentptr);
/* We're waiting for some I/O to complete, we've reached the end of the
* rules, or both. Do what we have to do, otherwise we're done.
*/
- if (&check->current_step->list == head && !b_data(check->bo)) {
+ if (&check->current_step->list == head && !b_data(&check->bo)) {
set_server_check_status(check, HCHK_STATUS_L7OKD, "(tcp-check)");
goto out_end_tcpcheck;
}
/* warning, current_step may now point to the head */
- if (b_data(check->bo))
+ if (b_data(&check->bo))
__cs_want_send(cs);
if (&check->current_step->list != head &&
{
check->type = type;
- /* Allocate buffer for requests... */
- if ((check->bi = calloc(sizeof(struct buffer) + global.tune.chksize, sizeof(char))) == NULL) {
- return "out of memory while allocating check buffer";
- }
- check->bi->size = global.tune.chksize;
+ b_reset(&check->bi); check->bi.size = global.tune.chksize;
+ b_reset(&check->bo); check->bo.size = global.tune.chksize;
+
+ check->bi.area = calloc(check->bi.size, sizeof(char));
+ check->bo.area = calloc(check->bo.size, sizeof(char));
- /* Allocate buffer for responses... */
- if ((check->bo = calloc(sizeof(struct buffer) + global.tune.chksize, sizeof(char))) == NULL) {
+ if (!check->bi.area || !check->bo.area)
return "out of memory while allocating check buffer";
- }
- check->bo->size = global.tune.chksize;
+
return NULL;
}
void free_check(struct check *check)
{
- free(check->bi);
- check->bi = NULL;
- free(check->bo);
- check->bo = NULL;
+ free(check->bi.area);
+ free(check->bo.area);
if (check->cs) {
free(check->cs->conn);
check->cs->conn = NULL;
goto out;
/* Check if the input buffer is avalaible. */
- if (res->buf->size == 0) {
+ if (res->buf.size == 0) {
si_applet_cant_put(si);
goto out;
}
#if defined(USE_SLZ)
(*comp_ctx)->direct_ptr = NULL;
(*comp_ctx)->direct_len = 0;
- (*comp_ctx)->queued = NULL;
+ (*comp_ctx)->queued = BUF_NULL;
#elif defined(USE_ZLIB)
HA_ATOMIC_ADD(&zlib_used_memory, sizeof(struct comp_ctx));
*/
static int rfc195x_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out)
{
- static THREAD_LOCAL struct buffer *tmpbuf = &buf_empty;
+ static THREAD_LOCAL struct buffer tmpbuf = BUF_NULL;
if (in_len <= 0)
return 0;
- if (comp_ctx->direct_ptr && !comp_ctx->queued) {
+ if (comp_ctx->direct_ptr && b_is_null(&comp_ctx->queued)) {
/* data already being pointed to, we're in front of fragmented
* data and need a buffer now. We reuse the same buffer, as it's
* not used out of the scope of a series of add_data()*, end().
*/
- if (unlikely(!tmpbuf->size)) {
+ if (unlikely(!tmpbuf.size)) {
/* this is the first time we need the compression buffer */
if (b_alloc(&tmpbuf) == NULL)
return -1; /* no memory */
}
- b_reset(tmpbuf);
- memcpy(b_tail(tmpbuf), comp_ctx->direct_ptr, comp_ctx->direct_len);
- b_add(tmpbuf, comp_ctx->direct_len);
+ b_reset(&tmpbuf);
+ memcpy(b_tail(&tmpbuf), comp_ctx->direct_ptr, comp_ctx->direct_len);
+ b_add(&tmpbuf, comp_ctx->direct_len);
comp_ctx->direct_ptr = NULL;
comp_ctx->direct_len = 0;
comp_ctx->queued = tmpbuf;
/* fall through buffer copy */
}
- if (comp_ctx->queued) {
+ if (!b_is_null(&comp_ctx->queued)) {
/* data already pending */
- memcpy(b_tail(comp_ctx->queued), in_data, in_len);
- b_add(comp_ctx->queued, in_len);
+ memcpy(b_tail(&comp_ctx->queued), in_data, in_len);
+ b_add(&comp_ctx->queued, in_len);
return in_len;
}
in_ptr = comp_ctx->direct_ptr;
in_len = comp_ctx->direct_len;
- if (comp_ctx->queued) {
- in_ptr = b_head(comp_ctx->queued);
- in_len = b_data(comp_ctx->queued);
+ if (!b_is_null(&comp_ctx->queued)) {
+ in_ptr = b_head(&comp_ctx->queued);
+ in_len = b_data(&comp_ctx->queued);
}
out_len = b_data(out);
/* very important, we must wipe the data we've just flushed */
comp_ctx->direct_len = 0;
comp_ctx->direct_ptr = NULL;
- comp_ctx->queued = NULL;
+ comp_ctx->queued = BUF_NULL;
/* Verify compression rate limiting and CPU usage */
if ((global.comp_rate_lim > 0 && (read_freq_ctr(&global.comp_bps_out) > global.comp_rate_lim)) || /* rate */
/* And set this value as the bound for the next
* filter. It will not able to parse more data than this
* one. */
- b_set_data(msg->chn->buf, co_data(msg->chn) + *nxt);
+ b_set_data(&msg->chn->buf, co_data(msg->chn) + *nxt);
}
else {
/* Consume all available data and update the next offset
}
/* Restore the original buffer state */
- b_set_data(msg->chn->buf, co_data(msg->chn) + buf_i + delta);
+ b_set_data(&msg->chn->buf, co_data(msg->chn) + buf_i + delta);
return ret;
}
/* And set this value as the bound for the next
* filter. It will not able to parse more data than the
* current one. */
- b_set_data(chn->buf, co_data(chn) + *nxt);
+ b_set_data(&chn->buf, co_data(chn) + *nxt);
}
else {
/* Consume all available data */
}
/* Restore the original buffer state */
- b_set_data(chn->buf, co_data(chn) + buf_i + delta);
+ b_set_data(&chn->buf, co_data(chn) + buf_i + delta);
return ret;
}
/* Pools used to allocate comp_state structs */
static struct pool_head *pool_head_comp_state = NULL;
-static THREAD_LOCAL struct buffer *tmpbuf = &buf_empty;
-static THREAD_LOCAL struct buffer *zbuf = &buf_empty;
+static THREAD_LOCAL struct buffer tmpbuf;
+static THREAD_LOCAL struct buffer zbuf;
static THREAD_LOCAL unsigned int buf_output;
struct comp_state {
int in_out,
struct buffer *out, int sz);
static int http_compression_buffer_end(struct comp_state *st, struct stream *s,
- struct channel *chn, struct buffer **out,
+ struct channel *chn, struct buffer *out,
unsigned int *out_len, int end);
/***********************************************************************/
static int
comp_flt_init_per_thread(struct proxy *px, struct flt_conf *fconf)
{
- if (!tmpbuf->size && b_alloc(&tmpbuf) == NULL)
+ if (!tmpbuf.size && b_alloc(&tmpbuf) == NULL)
return -1;
- if (!zbuf->size && b_alloc(&zbuf) == NULL)
+ if (!zbuf.size && b_alloc(&zbuf) == NULL)
return -1;
return 0;
}
static void
comp_flt_deinit_per_thread(struct proxy *px, struct flt_conf *fconf)
{
- if (tmpbuf->size)
+ if (tmpbuf.size)
b_free(&tmpbuf);
- if (zbuf->size)
+ if (zbuf.size)
b_free(&zbuf);
}
if (!st->initialized) {
unsigned int fwd = flt_rsp_fwd(filter) + st->hdrs_len;
- b_reset(tmpbuf);
+ b_reset(&tmpbuf);
c_adv(chn, fwd);
- ret = http_compression_buffer_init(chn, zbuf, &buf_output);
+ ret = http_compression_buffer_init(chn, &zbuf, &buf_output);
c_rew(chn, fwd);
if (ret < 0) {
msg->chn->flags |= CF_WAKE_WRITE;
if (msg->flags & HTTP_MSGF_TE_CHNK) {
int block;
- len = MIN(b_room(tmpbuf), len);
+ len = MIN(b_room(&tmpbuf), len);
c_adv(chn, *nxt);
block = ci_contig_data(chn);
- memcpy(b_tail(tmpbuf), ci_head(chn), block);
+ memcpy(b_tail(&tmpbuf), ci_head(chn), block);
if (len > block)
- memcpy(b_tail(tmpbuf)+block, b_orig(chn->buf), len-block);
+ memcpy(b_tail(&tmpbuf)+block, b_orig(&chn->buf), len-block);
c_rew(chn, *nxt);
- b_add(tmpbuf, len);
+ b_add(&tmpbuf, len);
ret = len;
}
else {
c_adv(chn, *nxt);
- ret = http_compression_buffer_add_data(st, chn->buf, co_data(chn), zbuf, len);
+ ret = http_compression_buffer_add_data(st, &chn->buf, co_data(chn), &zbuf, len);
c_rew(chn, *nxt);
if (ret < 0)
return ret;
struct channel *chn = msg->chn;
unsigned int fwd = flt_rsp_fwd(filter) + st->hdrs_len;
- b_reset(tmpbuf);
+ b_reset(&tmpbuf);
c_adv(chn, fwd);
- http_compression_buffer_init(chn, zbuf, &buf_output);
+ http_compression_buffer_init(chn, &zbuf, &buf_output);
c_rew(chn, fwd);
st->initialized = 1;
}
}
if (msg->flags & HTTP_MSGF_TE_CHNK) {
- ret = http_compression_buffer_add_data(st, tmpbuf, 0,
- zbuf, b_data(tmpbuf));
- if (ret != b_data(tmpbuf)) {
+ ret = http_compression_buffer_add_data(st, &tmpbuf, 0,
+ &zbuf, b_data(&tmpbuf));
+ if (ret != b_data(&tmpbuf)) {
ha_warning("HTTP compression failed: Must consume %u bytes but only %d bytes consumed\n",
- (unsigned int)b_data(tmpbuf), ret);
+ (unsigned int)b_data(&tmpbuf), ret);
return -1;
}
}
*/
static int
http_compression_buffer_end(struct comp_state *st, struct stream *s,
- struct channel *chn, struct buffer **out,
+ struct channel *chn, struct buffer *out,
unsigned int *buf_out, int end)
{
- struct buffer *ob = *out;
+ struct buffer tmp_buf;
char *tail;
int to_forward, left;
unsigned int tmp_out;
/* flush data here */
if (end)
- ret = st->comp_algo->finish(st->comp_ctx, ob); /* end of data */
+ ret = st->comp_algo->finish(st->comp_ctx, out); /* end of data */
else
- ret = st->comp_algo->flush(st->comp_ctx, ob); /* end of buffer */
+ ret = st->comp_algo->flush(st->comp_ctx, out); /* end of buffer */
if (ret < 0)
return -1; /* flush failed */
#endif /* USE_ZLIB */
- if (b_data(ob) == 0) {
+ if (b_data(out) == 0) {
/* No data were appended, let's drop the output buffer and
* keep the input buffer unchanged.
*/
return 0;
}
- /* OK so at this stage, we have an output buffer <ob> looking like this :
+ /* OK so at this stage, we have an output buffer <out> looking like this :
*
* <-- o --> <------ i ----->
* +---------+---+------------+-----------+
* data p size
*
* <out> is the room reserved to copy the channel output. It starts at
- * ob->area and has not yet been filled. <c> is the room reserved to
+ * out->area and has not yet been filled. <c> is the room reserved to
* write the chunk size (10 bytes). <comp_in> is the compressed
* equivalent of the data part of ib->len. <empty> is the amount of
* empty bytes at the end of the buffer, into which we may have to
*/
/* Write real size at the begining of the chunk, no need of wrapping.
- * We write the chunk using a dynamic length and adjust ob->p and ob->i
+ * We write the chunk using a dynamic length and adjust out->p and out->i
* accordingly afterwards. That will move <out> away from <data>.
*/
- left = http_emit_chunk_size(b_head(ob), b_data(ob));
- b_add(ob, left);
- ob->head -= *buf_out + (left);
- /* Copy previous data from chn into ob */
+ left = http_emit_chunk_size(b_head(out), b_data(out));
+ b_add(out, left);
+ out->head -= *buf_out + (left);
+ /* Copy previous data from chn into out */
if (co_data(chn) > 0) {
- left = b_contig_data(chn->buf, 0);
+ left = b_contig_data(&chn->buf, 0);
if (left > *buf_out)
left = *buf_out;
- memcpy(b_head(ob), co_head(chn), left);
- b_add(ob, left);
+ memcpy(b_head(out), co_head(chn), left);
+ b_add(out, left);
if (co_data(chn) - left) {/* second part of the buffer */
- memcpy(b_head(ob) + left, b_orig(chn->buf), co_data(chn) - left);
- b_add(ob, co_data(chn) - left);
+ memcpy(b_head(out) + left, b_orig(&chn->buf), co_data(chn) - left);
+ b_add(out, co_data(chn) - left);
}
}
/* chunked encoding requires CRLF after data */
- tail = b_tail(ob);
+ tail = b_tail(out);
*tail++ = '\r';
*tail++ = '\n';
}
}
- b_add(ob, tail - b_tail(ob));
- to_forward = b_data(ob) - *buf_out;
+ b_add(out, tail - b_tail(out));
+ to_forward = b_data(out) - *buf_out;
/* update input rate */
if (st->comp_ctx && st->comp_ctx->cur_lvl > 0) {
/* copy the remaining data in the tmp buffer. */
c_adv(chn, st->consumed);
- if (b_data(chn->buf) - co_data(chn) > 0) {
+ if (b_data(&chn->buf) - co_data(chn) > 0) {
left = ci_contig_data(chn);
- memcpy(b_tail(ob), ci_head(chn), left);
- b_add(ob, left);
- if (b_data(chn->buf) - (co_data(chn) + left)) {
- memcpy(b_tail(ob), b_orig(chn->buf), b_data(chn->buf) - left);
- b_add(ob, b_data(chn->buf) - left);
+ memcpy(b_tail(out), ci_head(chn), left);
+ b_add(out, left);
+ if (b_data(&chn->buf) - (co_data(chn) + left)) {
+ memcpy(b_tail(out), b_orig(&chn->buf), b_data(&chn->buf) - left);
+ b_add(out, b_data(&chn->buf) - left);
}
}
/* swap the buffers */
- *out = chn->buf;
- chn->buf = ob;
+ tmp_buf = chn->buf;
+ chn->buf = *out;
+ *out = tmp_buf;
+
tmp_out = chn->output;
chn->output = *buf_out;
*buf_out = tmp_out;
struct flt_ops spoe_ops;
static int spoe_queue_context(struct spoe_context *ctx);
-static int spoe_acquire_buffer(struct buffer **buf, struct buffer_wait *buffer_wait);
-static void spoe_release_buffer(struct buffer **buf, struct buffer_wait *buffer_wait);
+static int spoe_acquire_buffer(struct buffer *buf, struct buffer_wait *buffer_wait);
+static void spoe_release_buffer(struct buffer *buf, struct buffer_wait *buffer_wait);
/********************************************************************
* helper functions/globals
goto too_big;
/* Copy encoded messages, if possible */
- sz = b_data(ctx->buffer);
+ sz = b_data(&ctx->buffer);
if (p + sz >= end)
goto too_big;
- memcpy(p, b_head(ctx->buffer), sz);
+ memcpy(p, b_head(&ctx->buffer), sz);
p += sz;
return (p - frame);
goto end;
/* Copy encoded messages, if possible */
- sz = b_data(ctx->buffer);
+ sz = b_data(&ctx->buffer);
if (p + sz >= end)
goto too_big;
- memcpy(p, b_head(ctx->buffer), sz);
+ memcpy(p, b_head(&ctx->buffer), sz);
p += sz;
end:
/* Copy encoded actions */
len = (end - p);
- memcpy(b_head(SPOE_APPCTX(appctx)->buffer), p, len);
- b_set_data(SPOE_APPCTX(appctx)->buffer, len);
+ memcpy(b_head(&SPOE_APPCTX(appctx)->buffer), p, len);
+ b_set_data(&SPOE_APPCTX(appctx)->buffer, len);
p += len;
/* Transfer the buffer ownership to the SPOE context */
(*ctx)->buffer = SPOE_APPCTX(appctx)->buffer;
- SPOE_APPCTX(appctx)->buffer = &buf_empty;
+ SPOE_APPCTX(appctx)->buffer = BUF_NULL;
(*ctx)->state = SPOE_CTX_ST_DONE;
memcpy(buf, (char *)&netint, 4);
ret = ci_putblk(si_ic(si), buf, framesz+4);
if (ret <= 0) {
- if ((ret == -3 && si_ic(si)->buf == &buf_empty) || ret == -1) {
+ if ((ret == -3 && b_is_null(&si_ic(si)->buf)) || ret == -1) {
si_applet_cant_put(si);
return 1; /* retry */
}
SPOE_APPCTX(appctx)->max_frame_size = conf->agent->max_frame_size;
SPOE_APPCTX(appctx)->flags = 0;
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_NONE;
- SPOE_APPCTX(appctx)->buffer = &buf_empty;
+ SPOE_APPCTX(appctx)->buffer = BUF_NULL;
SPOE_APPCTX(appctx)->cur_fpa = 0;
LIST_INIT(&SPOE_APPCTX(appctx)->buffer_wait.list);
struct spoe_message *msg;
char *p, *end;
- p = b_head(ctx->buffer);
+ p = b_head(&ctx->buffer);
end = p + agent->rt[tid].frame_size - FRAME_HDR_SIZE;
if (type == SPOE_MSGS_BY_EVENT) { /* Loop on messages by event */
/* nothing has been encoded for an unfragmented payload */
- if (!(ctx->flags & SPOE_CTX_FL_FRAGMENTED) && p == b_head(ctx->buffer))
+ if (!(ctx->flags & SPOE_CTX_FL_FRAGMENTED) && p == b_head(&ctx->buffer))
goto skip;
SPOE_PRINTF(stderr, "%d.%06d [SPOE/%-15s] %s: stream=%p"
ctx->spoe_appctx, (agent->rt[tid].frame_size - FRAME_HDR_SIZE),
p - ctx->buffer->p);
- b_set_data(ctx->buffer, p - b_head(ctx->buffer));
+ b_set_data(&ctx->buffer, p - b_head(&ctx->buffer));
ctx->frag_ctx.curmsg = NULL;
ctx->frag_ctx.curarg = NULL;
ctx->frag_ctx.curoff = 0;
(int)now.tv_sec, (int)now.tv_usec,
agent->id, __FUNCTION__, s, ctx->spoe_appctx,
ctx->frag_ctx.curmsg, ctx->frag_ctx.curarg, ctx->frag_ctx.curoff,
- (agent->rt[tid].frame_size - FRAME_HDR_SIZE), p - b_head(ctx->buffer));
+ (agent->rt[tid].frame_size - FRAME_HDR_SIZE), p - b_head(&ctx->buffer));
- b_set_data(ctx->buffer, p - b_head(ctx->buffer));
+ b_set_data(&ctx->buffer, p - b_head(&ctx->buffer));
ctx->flags |= SPOE_CTX_FL_FRAGMENTED;
ctx->frag_ctx.flags &= ~SPOE_FRM_FL_FIN;
return 1;
char *p, *end;
int ret;
- p = b_head(ctx->buffer);
- end = p + b_data(ctx->buffer);
+ p = b_head(&ctx->buffer);
+ end = p + b_data(&ctx->buffer);
while (p < end) {
enum spoe_action_type type;
* Functions that create/destroy SPOE contexts
**************************************************************************/
static int
-spoe_acquire_buffer(struct buffer **buf, struct buffer_wait *buffer_wait)
+spoe_acquire_buffer(struct buffer *buf, struct buffer_wait *buffer_wait)
{
- if ((*buf)->size)
+ if (buf->size)
return 1;
if (!LIST_ISEMPTY(&buffer_wait->list)) {
}
static void
-spoe_release_buffer(struct buffer **buf, struct buffer_wait *buffer_wait)
+spoe_release_buffer(struct buffer *buf, struct buffer_wait *buffer_wait)
{
if (!LIST_ISEMPTY(&buffer_wait->list)) {
HA_SPIN_LOCK(BUF_WQ_LOCK, &buffer_wq_lock);
}
/* Release the buffer if needed */
- if ((*buf)->size) {
+ if (buf->size) {
b_free(buf);
offer_buffers(buffer_wait->target, tasks_run_queue);
}
ctx->flags = 0;
ctx->events = conf->agent->events;
ctx->groups = &conf->agent->groups;
- ctx->buffer = &buf_empty;
+ ctx->buffer = BUF_NULL;
LIST_INIT(&ctx->buffer_wait.list);
ctx->buffer_wait.target = ctx;
ctx->buffer_wait.wakeup_cb = (int (*)(void *))spoe_wakeup_context;
if (conf->hexdump) {
c_adv(msg->chn, FLT_FWD(filter, msg->chn));
- trace_hexdump(msg->chn->buf, ret, co_data(msg->chn));
+ trace_hexdump(&msg->chn->buf, ret, co_data(msg->chn));
c_rew(msg->chn, FLT_FWD(filter, msg->chn));
}
if (conf->hexdump) {
c_adv(chn, FLT_FWD(filter, chn));
- trace_hexdump(chn->buf, ret, co_data(chn));
+ trace_hexdump(&chn->buf, ret, co_data(chn));
c_rew(chn, FLT_FWD(filter, chn));
}
struct buffer *buf;
state = msg->msg_state;
- buf = msg->chn->buf;
+ buf = &msg->chn->buf;
ptr = input + msg->next;
end = b_stop(buf);
*/
int http_forward_trailers(struct http_msg *msg)
{
- const struct buffer *buf = msg->chn->buf;
+ const struct buffer *buf = &msg->chn->buf;
const char *parse = ci_head(msg->chn);
const char *stop = b_tail(buf);
free(s->id);
free(s->cookie);
- free(s->check.bi);
- free(s->check.bo);
- free(s->agent.bi);
- free(s->agent.bo);
+ free(s->check.bi.area);
+ free(s->check.bo.area);
+ free(s->agent.bi.area);
+ free(s->agent.bo.area);
free(s->agent.send_string);
free(s->hostname_dn);
free((char*)s->conf.file);
/* Check if the buffer is avalaible because HAProxy doesn't allocate
* the request buffer if its not required.
*/
- if (s->req.buf->size == 0) {
+ if (s->req.buf.size == 0) {
if (!channel_alloc_buffer(&s->req, &appctx->buffer_wait))
goto hlua_socket_write_yield_return;
}
/* Check for avalaible space. */
- len = b_room(s->req.buf);
+ len = b_room(&s->req.buf);
if (len <= 0) {
goto hlua_socket_write_yield_return;
}
if (unlikely(ret == -1))
return 1;
- b_sub(chn->buf, ret);
+ b_sub(&chn->buf, ret);
hlua_resynchonize_proto(chn_strm(chn), !!(chn->flags & CF_ISRESP));
return 1;
}
len += len2;
}
luaL_pushresult(&b);
- b_rep_blk(chn->buf, ci_head(chn), ci_head(chn) + len, NULL, 0);
+ b_rep_blk(&chn->buf, ci_head(chn), ci_head(chn) + len, NULL, 0);
hlua_resynchonize_proto(chn_strm(chn), !!(chn->flags & CF_ISRESP));
return 1;
}
/* Check if the buffer is avalaible because HAProxy doesn't allocate
* the request buffer if its not required.
*/
- if (chn->buf->size == 0) {
+ if (chn->buf.size == 0) {
si_applet_cant_put(chn_prod(chn));
WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
}
- max = channel_recv_limit(chn) - b_data(chn->buf);
+ max = channel_recv_limit(chn) - b_data(&chn->buf);
if (max > len - l)
max = len - l;
lua_pushinteger(L, l);
hlua_resynchonize_proto(chn_strm(chn), !!(chn->flags & CF_ISRESP));
- max = channel_recv_limit(chn) - b_data(chn->buf);
+ max = channel_recv_limit(chn) - b_data(&chn->buf);
if (max == 0 && co_data(chn) == 0) {
/* There are no space avalaible, and the output buffer is empty.
* in this case, we cannot add more data, so we cannot yield,
chn = MAY_LJMP(hlua_checkchannel(L, 1));
lua_pushinteger(L, 0);
- b_set_data(chn->buf, co_data(chn));
+ b_set_data(&chn->buf, co_data(chn));
return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
}
/* Check if the buffer is avalaible because HAProxy doesn't allocate
* the request buffer if its not required.
*/
- if (chn->buf->size == 0) {
+ if (chn->buf.size == 0) {
si_applet_cant_put(chn_prod(chn));
WILL_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
}
* The reserve is guaranted for the processing of incoming
* data, because the buffer will be flushed.
*/
- max = b_room(chn->buf);
+ max = b_room(&chn->buf);
/* If there are no space avalaible, and the output buffer is empty.
* in this case, we cannot add more data, so we cannot yield,
channel_slow_realign(chn, trash.str);
/* Copy input data in the buffer. */
- max = b_rep_blk(chn->buf, ci_head(chn), ci_head(chn), str + l, max);
+ max = b_rep_blk(&chn->buf, ci_head(chn), ci_head(chn), str + l, max);
/* buffer replace considers that the input part is filled.
* so, I must forward these new data in the output part.
* in this case, we cannot add more data, so we cannot yield,
* we return the amount of copyied data.
*/
- max = b_room(chn->buf);
+ max = b_room(&chn->buf);
if (max == 0 && co_data(chn) == 0)
return 1;
MAY_LJMP(check_args(L, 1, "is_full"));
chn = MAY_LJMP(hlua_checkchannel(L, 1));
- rem = b_room(chn->buf);
+ rem = b_room(&chn->buf);
rem -= global.tune.maxrewrite; /* Rewrite reserved size */
lua_pushboolean(L, rem <= 0);
if (htxn->s->txn) {
/* HTTP mode, let's stay in sync with the stream */
- b_del(ic->buf, htxn->s->txn->req.sov);
+ b_del(&ic->buf, htxn->s->txn->req.sov);
htxn->s->txn->req.next -= htxn->s->txn->req.sov;
htxn->s->txn->req.sov = 0;
ic->analysers &= AN_REQ_HTTP_XFER_BODY;
/* states for the demux direction */
struct hpack_dht *ddht; /* demux dynamic header table */
- struct buffer *dbuf; /* demux buffer */
+ struct buffer dbuf; /* demux buffer */
int32_t dsi; /* demux stream ID (<0 = idle) */
int32_t dfl; /* demux frame length (if dsi >= 0) */
int32_t last_sid; /* last processed stream ID for GOAWAY, <0 before preface */
/* states for the mux direction */
- struct buffer *mbuf; /* mux buffer */
+ struct buffer mbuf; /* mux buffer */
int32_t msi; /* mux stream ID (<0 = idle) */
int32_t mfl; /* mux frame length (if dsi >= 0) */
int8_t mft; /* mux frame type (if dsi >= 0) */
*/
static inline int h2_recv_allowed(const struct h2c *h2c)
{
- if (b_data(h2c->dbuf) == 0 &&
+ if (b_data(&h2c->dbuf) == 0 &&
(h2c->st0 >= H2_CS_ERROR ||
h2c->conn->flags & CO_FL_ERROR ||
conn_xprt_read0_pending(h2c->conn)))
return 0;
}
-static inline struct buffer *h2_get_buf(struct h2c *h2c, struct buffer **bptr)
+static inline struct buffer *h2_get_buf(struct h2c *h2c, struct buffer *bptr)
{
struct buffer *buf = NULL;
return buf;
}
-static inline void h2_release_buf(struct h2c *h2c, struct buffer **bptr)
+static inline void h2_release_buf(struct h2c *h2c, struct buffer *bptr)
{
- if ((*bptr)->size) {
+ if (bptr->size) {
b_free(bptr);
offer_buffers(h2c->buf_wait.target, tasks_run_queue);
}
h2c->nb_streams = 0;
h2c->nb_cs = 0;
- h2c->dbuf = &buf_empty;
+ h2c->dbuf = BUF_NULL;
h2c->dsi = -1;
h2c->msi = -1;
h2c->last_sid = -1;
- h2c->mbuf = &buf_empty;
+ h2c->mbuf = BUF_NULL;
h2c->miw = 65535; /* mux initial window size */
h2c->mws = 65535; /* mux window size */
h2c->mfs = 16384; /* initial max frame size */
int ret1;
int ret2;
- ret1 = b_isteq(h2c->dbuf, 0, b_data(h2c->dbuf), ist(H2_CONN_PREFACE));
+ ret1 = b_isteq(&h2c->dbuf, 0, b_data(&h2c->dbuf), ist(H2_CONN_PREFACE));
if (unlikely(ret1 <= 0)) {
if (ret1 < 0 || conn_xprt_read0_pending(h2c->conn))
ret2 = h2c_snd_settings(h2c);
if (ret2 > 0)
- b_del(h2c->dbuf, ret1);
+ b_del(&h2c->dbuf, ret1);
return ret2;
}
}
/* process full frame only */
- if (b_data(h2c->dbuf) < h2c->dfl)
+ if (b_data(&h2c->dbuf) < h2c->dfl)
return 0;
/* parse the frame */
for (offset = 0; offset < h2c->dfl; offset += 6) {
- uint16_t type = h2_get_n16(h2c->dbuf, offset);
- int32_t arg = h2_get_n32(h2c->dbuf, offset + 2);
+ uint16_t type = h2_get_n16(&h2c->dbuf, offset);
+ int32_t arg = h2_get_n32(&h2c->dbuf, offset + 2);
switch (type) {
case H2_SETTINGS_INITIAL_WINDOW_SIZE:
char str[17];
int ret = -1;
- if (b_data(h2c->dbuf) < 8)
+ if (b_data(&h2c->dbuf) < 8)
return 0;
if (h2c_mux_busy(h2c, NULL)) {
"\x00\x00\x00\x00" /* stream ID */, 9);
/* copy the original payload */
- h2_get_buf_bytes(str + 9, 8, h2c->dbuf, 0);
+ h2_get_buf_bytes(str + 9, 8, &h2c->dbuf, 0);
ret = b_istput(res, ist2(str, 17));
if (unlikely(ret <= 0)) {
}
/* process full frame only */
- if (b_data(h2c->dbuf) < h2c->dfl)
+ if (b_data(&h2c->dbuf) < h2c->dfl)
return 0;
- inc = h2_get_n32(h2c->dbuf, 0);
+ inc = h2_get_n32(&h2c->dbuf, 0);
if (h2c->dsi != 0) {
/* stream window update */
}
/* process full frame only */
- if (b_data(h2c->dbuf) < h2c->dfl)
+ if (b_data(&h2c->dbuf) < h2c->dfl)
return 0;
- last = h2_get_n32(h2c->dbuf, 0);
- h2c->errcode = h2_get_n32(h2c->dbuf, 4);
+ last = h2_get_n32(&h2c->dbuf, 0);
+ h2c->errcode = h2_get_n32(&h2c->dbuf, 4);
h2_wake_some_streams(h2c, last, CS_FL_ERROR);
if (h2c->last_sid < 0)
h2c->last_sid = last;
}
/* process full frame only */
- if (b_data(h2c->dbuf) < h2c->dfl)
+ if (b_data(&h2c->dbuf) < h2c->dfl)
return 0;
- if (h2_get_n32(h2c->dbuf, 0) == h2c->dsi) {
+ if (h2_get_n32(&h2c->dbuf, 0) == h2c->dsi) {
/* 7540#5.3 : can't depend on itself */
error = H2_ERR_PROTOCOL_ERROR;
goto conn_err;
}
/* process full frame only */
- if (b_data(h2c->dbuf) < h2c->dfl)
+ if (b_data(&h2c->dbuf) < h2c->dfl)
return 0;
/* late RST, already handled */
if (h2s->st == H2_SS_CLOSED)
return 1;
- h2s->errcode = h2_get_n32(h2c->dbuf, 0);
+ h2s->errcode = h2_get_n32(&h2c->dbuf, 0);
h2s_close(h2s);
if (h2s->cs) {
goto strm_err;
}
- if (!b_size(h2c->dbuf))
+ if (!b_size(&h2c->dbuf))
return 0; // empty buffer
- if (b_data(h2c->dbuf) < h2c->dfl && !b_full(h2c->dbuf))
+ if (b_data(&h2c->dbuf) < h2c->dfl && !b_full(&h2c->dbuf))
return 0; // incomplete frame
if (h2c->flags & H2_CF_DEM_TOOMANY)
* to signal an end of stream (with the ES flag).
*/
- if (!b_size(h2c->dbuf) && h2c->dfl)
+ if (!b_size(&h2c->dbuf) && h2c->dfl)
return 0; // empty buffer
- if (b_data(h2c->dbuf) < h2c->dfl && !b_full(h2c->dbuf))
+ if (b_data(&h2c->dbuf) < h2c->dfl && !b_full(&h2c->dbuf))
return 0; // incomplete frame
/* now either the frame is complete or the buffer is complete */
/* ensure that what is pending is a valid SETTINGS frame
* without an ACK.
*/
- if (!h2_get_frame_hdr(h2c->dbuf, &hdr)) {
+ if (!h2_get_frame_hdr(&h2c->dbuf, &hdr)) {
/* RFC7540#3.5: a GOAWAY frame MAY be omitted */
if (h2c->st0 == H2_CS_ERROR)
h2c->st0 = H2_CS_ERROR2;
}
/* process as many incoming frames as possible below */
- while (b_data(h2c->dbuf)) {
+ while (b_data(&h2c->dbuf)) {
int ret = 0;
if (h2c->st0 >= H2_CS_ERROR)
if (h2c->st0 == H2_CS_FRAME_H) {
struct h2_fh hdr;
- if (!h2_peek_frame_hdr(h2c->dbuf, &hdr))
+ if (!h2_peek_frame_hdr(&h2c->dbuf, &hdr))
break;
if ((int)hdr.len < 0 || (int)hdr.len > global.tune.bufsize) {
h2c->dff = hdr.ff;
h2c->dpl = 0;
h2c->st0 = H2_CS_FRAME_P;
- h2_skip_frame_hdr(h2c->dbuf);
+ h2_skip_frame_hdr(&h2c->dbuf);
}
/* Only H2_CS_FRAME_P and H2_CS_FRAME_A here */
* the one advertised in GOAWAY. RFC7540#6.8.
*/
if (unlikely(h2c->last_sid >= 0) && h2c->dsi > h2c->last_sid) {
- ret = MIN(b_data(h2c->dbuf), h2c->dfl);
- b_del(h2c->dbuf, ret);
+ ret = MIN(b_data(&h2c->dbuf), h2c->dfl);
+ b_del(&h2c->dbuf, ret);
h2c->dfl -= ret;
ret = h2c->dfl == 0;
goto strm_err;
* the buffer so we drain all of their contents until
* we reach the end.
*/
- ret = MIN(b_data(h2c->dbuf), h2c->dfl);
- b_del(h2c->dbuf, ret);
+ ret = MIN(b_data(&h2c->dbuf), h2c->dfl);
+ b_del(&h2c->dbuf, ret);
h2c->dfl -= ret;
ret = h2c->dfl == 0;
}
break;
if (h2c->st0 != H2_CS_FRAME_H) {
- b_del(h2c->dbuf, h2c->dfl);
+ b_del(&h2c->dbuf, h2c->dfl);
h2c->st0 = H2_CS_FRAME_H;
}
}
if (h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))
flags |= CO_SFL_MSG_MORE;
- if (b_data(h2c->mbuf)) {
- int ret = conn->xprt->snd_buf(conn, h2c->mbuf, b_data(h2c->mbuf), flags);
+ if (b_data(&h2c->mbuf)) {
+ int ret = conn->xprt->snd_buf(conn, &h2c->mbuf, b_data(&h2c->mbuf), flags);
if (!ret)
break;
- b_del(h2c->mbuf, ret);
- b_realign_if_empty(h2c->mbuf);
+ b_del(&h2c->mbuf, ret);
+ b_realign_if_empty(&h2c->mbuf);
}
/* wrote at least one byte, the buffer is not full anymore */
if (conn->flags & CO_FL_SOCK_WR_SH) {
/* output closed, nothing to send, clear the buffer to release it */
- b_reset(h2c->mbuf);
+ b_reset(&h2c->mbuf);
}
}
struct h2c *h2c = conn->mux_ctx;
struct session *sess = conn->owner;
- if (b_data(h2c->dbuf) && !(h2c->flags & H2_CF_DEM_BLOCK_ANY)) {
+ if (b_data(&h2c->dbuf) && !(h2c->flags & H2_CF_DEM_BLOCK_ANY)) {
h2_process_demux(h2c);
if (h2c->st0 >= H2_CS_ERROR || conn->flags & CO_FL_ERROR)
- b_reset(h2c->dbuf);
+ b_reset(&h2c->dbuf);
- if (!b_full(h2c->dbuf))
+ if (!b_full(&h2c->dbuf))
h2c->flags &= ~H2_CF_DEM_DFULL;
}
}
}
- if (!b_data(h2c->dbuf))
+ if (!b_data(&h2c->dbuf))
h2_release_buf(h2c, &h2c->dbuf);
/* stop being notified of incoming data if we can't process them */
/* adjust output polling */
if (!(conn->flags & CO_FL_SOCK_WR_SH) &&
(h2c->st0 == H2_CS_ERROR ||
- b_data(h2c->mbuf) ||
+ b_data(&h2c->mbuf) ||
(h2c->mws > 0 && !LIST_ISEMPTY(&h2c->fctl_list)) ||
(!(h2c->flags & H2_CF_MUX_BLOCK_ANY) && !LIST_ISEMPTY(&h2c->send_list)))) {
__conn_xprt_want_send(conn);
}
if (h2c->task) {
- if (eb_is_empty(&h2c->streams_by_id) || b_data(h2c->mbuf)) {
+ if (eb_is_empty(&h2c->streams_by_id) || b_data(&h2c->mbuf)) {
h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
task_queue(h2c->task);
}
h2c_error(h2c, H2_ERR_NO_ERROR);
h2_wake_some_streams(h2c, 0, 0);
- if (b_data(h2c->mbuf)) {
+ if (b_data(&h2c->mbuf)) {
/* don't even try to send a GOAWAY, the buffer is stuck */
h2c->flags |= H2_CF_GOAWAY_FAILED;
}
if (h2c_send_goaway_error(h2c, NULL) <= 0)
h2c->flags |= H2_CF_GOAWAY_FAILED;
- if (b_data(h2c->mbuf) && !(h2c->flags & H2_CF_GOAWAY_FAILED) && conn_xprt_ready(h2c->conn)) {
- int ret = h2c->conn->xprt->snd_buf(h2c->conn, h2c->mbuf, b_data(h2c->mbuf), 0);
+ if (b_data(&h2c->mbuf) && !(h2c->flags & H2_CF_GOAWAY_FAILED) && conn_xprt_ready(h2c->conn)) {
+ int ret = h2c->conn->xprt->snd_buf(h2c->conn, &h2c->mbuf, b_data(&h2c->mbuf), 0);
if (ret > 0) {
- b_del(h2c->mbuf, ret);
- b_realign_if_empty(h2c->mbuf);
+ b_del(&h2c->mbuf, ret);
+ b_realign_if_empty(&h2c->mbuf);
}
}
if (cs->flags & CS_FL_DATA_WR_ENA) {
if (LIST_ISEMPTY(&h2s->list)) {
if (LIST_ISEMPTY(&h2s->h2c->send_list) &&
- !b_data(h2s->h2c->mbuf) && // not yet subscribed
+ !b_data(&h2s->h2c->mbuf) && // not yet subscribed
!(cs->conn->flags & CO_FL_SOCK_WR_SH))
conn_xprt_want_send(cs->conn);
LIST_ADDQ(&h2s->h2c->send_list, &h2s->list);
}
/* this can happen from within si_chk_snd() */
- if (b_data(h2s->h2c->mbuf) && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
+ if (b_data(&h2s->h2c->mbuf) && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
conn_xprt_want_send(cs->conn);
}
((h2c->conn->flags & CO_FL_ERROR) || /* errors close immediately */
(h2c->st0 >= H2_CS_ERROR && !h2c->task) || /* a timeout stroke earlier */
(h2c->flags & H2_CF_GOAWAY_FAILED) ||
- (!b_data(h2c->mbuf) && /* mux buffer empty, also process clean events below */
+ (!b_data(&h2c->mbuf) && /* mux buffer empty, also process clean events below */
(conn_xprt_read0_pending(h2c->conn) ||
(h2c->last_sid >= 0 && h2c->max_id >= h2c->last_sid))))) {
/* no more stream will come, kill it now */
h2_release(h2c->conn);
}
else if (h2c->task) {
- if (eb_is_empty(&h2c->streams_by_id) || b_data(h2c->mbuf)) {
+ if (eb_is_empty(&h2c->streams_by_id) || b_data(&h2c->mbuf)) {
h2c->task->expire = tick_add(now_ms, h2c->last_sid < 0 ? h2c->timeout : h2c->shut_timeout);
task_queue(h2c->task);
}
h2c_send_goaway_error(h2s->h2c, h2s) <= 0)
goto add_to_list;
- if (b_data(h2s->h2c->mbuf) && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
+ if (b_data(&h2s->h2c->mbuf) && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
conn_xprt_want_send(cs->conn);
h2s_close(h2s);
h2s_close(h2s);
}
- if (b_data(h2s->h2c->mbuf) && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
+ if (b_data(&h2s->h2c->mbuf) && !(cs->conn->flags & CO_FL_XPRT_WR_ENA))
conn_xprt_want_send(cs->conn);
add_to_list:
static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count, int flags)
{
struct h2c *h2c = h2s->h2c;
- const uint8_t *hdrs = (uint8_t *)b_head(h2c->dbuf);
+ const uint8_t *hdrs = (uint8_t *)b_head(&h2c->dbuf);
struct chunk *tmp = get_trash_chunk();
struct http_hdr list[MAX_HTTP_HDR * 2];
struct chunk *copy = NULL;
return 0;
}
- if (b_data(h2c->dbuf) < h2c->dfl && !b_full(h2c->dbuf))
+ if (b_data(&h2c->dbuf) < h2c->dfl && !b_full(&h2c->dbuf))
return 0; // incomplete input frame
/* if the input buffer wraps, take a temporary copy of it (rare) */
- wrap = b_wrap(h2c->dbuf) - b_head(h2c->dbuf);
+ wrap = b_wrap(&h2c->dbuf) - b_head(&h2c->dbuf);
if (wrap < h2c->dfl) {
copy = alloc_trash_chunk();
if (!copy) {
h2c_error(h2c, H2_ERR_INTERNAL_ERROR);
goto fail;
}
- memcpy(copy->str, b_head(h2c->dbuf), wrap);
- memcpy(copy->str + wrap, b_orig(h2c->dbuf), h2c->dfl - wrap);
+ memcpy(copy->str, b_head(&h2c->dbuf), wrap);
+ memcpy(copy->str + wrap, b_orig(&h2c->dbuf), h2c->dfl - wrap);
hdrs = (uint8_t *)copy->str;
}
}
/* now consume the input data */
- b_del(h2c->dbuf, h2c->dfl);
+ b_del(&h2c->dbuf, h2c->dfl);
h2c->st0 = H2_CS_FRAME_H;
b_add(buf, outlen);
* after data. padlen+data+padding are included in flen.
*/
if (h2c->dff & H2_F_DATA_PADDED) {
- if (b_data(h2c->dbuf) < 1)
+ if (b_data(&h2c->dbuf) < 1)
return 0;
- h2c->dpl = *(uint8_t *)b_head(h2c->dbuf);
+ h2c->dpl = *(uint8_t *)b_head(&h2c->dbuf);
if (h2c->dpl >= h2c->dfl) {
/* RFC7540#6.1 : pad length = length of frame payload or greater */
h2c_error(h2c, H2_ERR_PROTOCOL_ERROR);
}
/* skip the padlen byte */
- b_del(h2c->dbuf, 1);
+ b_del(&h2c->dbuf, 1);
h2c->dfl--;
h2c->rcvd_c++; h2c->rcvd_s++;
h2c->dff &= ~H2_F_DATA_PADDED;
if (!flen)
goto end_transfer;
- if (flen > b_data(h2c->dbuf)) {
- flen = b_data(h2c->dbuf);
+ if (flen > b_data(&h2c->dbuf)) {
+ flen = b_data(&h2c->dbuf);
if (!flen)
return 0;
}
/* Block1 is the length of the first block before the buffer wraps,
* block2 is the optional second block to reach the end of the frame.
*/
- block1 = b_contig_data(h2c->dbuf, 0);
+ block1 = b_contig_data(&h2c->dbuf, 0);
if (block1 > flen)
block1 = flen;
block2 = flen - block1;
if (block1)
- b_putblk(buf, b_head(h2c->dbuf), block1);
+ b_putblk(buf, b_head(&h2c->dbuf), block1);
if (block2)
- b_putblk(buf, b_peek(h2c->dbuf, block1), block2);
+ b_putblk(buf, b_peek(&h2c->dbuf, block1), block2);
if (h2s->flags & H2_SF_DATA_CHNK) {
/* emit the CRLF */
/* now mark the input data as consumed (will be deleted from the buffer
* by the caller when seeing FRAME_A after sending the window update).
*/
- b_del(h2c->dbuf, flen);
+ b_del(&h2c->dbuf, flen);
h2c->dfl -= flen;
h2c->rcvd_c += flen;
h2c->rcvd_s += flen; // warning, this can also affect the closed streams!
if (h2c->dsi != h2s->id)
return 0; // not for us
- if (!b_size(h2c->dbuf))
+ if (!b_size(&h2c->dbuf))
return 0; // empty buffer
switch (h2c->dft) {
chunk_reset(&outbuf);
while (1) {
- outbuf.str = b_tail(h2c->mbuf);
- outbuf.size = b_contig_space(h2c->mbuf);
+ outbuf.str = b_tail(&h2c->mbuf);
+ outbuf.size = b_contig_space(&h2c->mbuf);
outbuf.len = 0;
- if (outbuf.size >= 9 || !b_space_wraps(h2c->mbuf))
+ if (outbuf.size >= 9 || !b_space_wraps(&h2c->mbuf))
break;
realign_again:
- b_slow_realign(h2c->mbuf, trash.str, b_data(h2c->mbuf));
+ b_slow_realign(&h2c->mbuf, trash.str, b_data(&h2c->mbuf));
}
if (outbuf.size < 9) {
outbuf.str[outbuf.len++] = list[0].v.ptr[2];
}
else {
- if (b_space_wraps(h2c->mbuf))
+ if (b_space_wraps(&h2c->mbuf))
goto realign_again;
h2c->flags |= H2_CF_MUX_MFULL;
if (!hpack_encode_header(&outbuf, list[hdr].n, list[hdr].v)) {
/* output full */
- if (b_space_wraps(h2c->mbuf))
+ if (b_space_wraps(&h2c->mbuf))
goto realign_again;
h2c->flags |= H2_CF_MUX_MFULL;
max -= ret;
/* commit the H2 response */
- b_add(h2c->mbuf, outbuf.len);
+ b_add(&h2c->mbuf, outbuf.len);
h2s->flags |= H2_SF_HEADERS_SENT;
/* for now we don't implemented CONTINUATION, so we wait for a
chunk_reset(&outbuf);
while (1) {
- outbuf.str = b_tail(h2c->mbuf);
- outbuf.size = b_contig_space(h2c->mbuf);
+ outbuf.str = b_tail(&h2c->mbuf);
+ outbuf.size = b_contig_space(&h2c->mbuf);
outbuf.len = 0;
- if (outbuf.size >= 9 || !b_space_wraps(h2c->mbuf))
+ if (outbuf.size >= 9 || !b_space_wraps(&h2c->mbuf))
break;
realign_again:
- b_slow_realign(h2c->mbuf, trash.str, b_data(h2c->mbuf));
+ b_slow_realign(&h2c->mbuf, trash.str, b_data(&h2c->mbuf));
}
if (outbuf.size < 9) {
/* we have an opportunity for enlarging the too small
* available space, let's try.
*/
- if (b_space_wraps(h2c->mbuf))
+ if (b_space_wraps(&h2c->mbuf))
goto realign_again;
size = outbuf.size - 9;
}
outbuf.str[4] |= H2_F_DATA_END_STREAM;
/* commit the H2 response */
- b_add(h2c->mbuf, size + 9);
+ b_add(&h2c->mbuf, size + 9);
/* consume incoming H1 response */
if (size > 0) {
}
chunk_appendf(msg, " st0=%d flg=0x%08x nbst=%u nbcs=%u fctl_cnt=%d send_cnt=%d tree_cnt=%d orph_cnt=%d dbuf=%u/%u mbuf=%u/%u",
- h2c->st0, h2c->flags, h2c->nb_streams, h2c->nb_cs, fctl_cnt, send_cnt, tree_cnt, orph_cnt, (unsigned int)b_data(h2c->dbuf), (unsigned int)b_size(h2c->dbuf), (unsigned int)b_data(h2c->mbuf), (unsigned int)b_size(h2c->mbuf));
+ h2c->st0, h2c->flags, h2c->nb_streams, h2c->nb_cs, fctl_cnt, send_cnt, tree_cnt, orph_cnt, (unsigned int)b_data(&h2c->dbuf), (unsigned int)b_size(&h2c->dbuf), (unsigned int)b_data(&h2c->mbuf), (unsigned int)b_size(&h2c->mbuf));
}
/*******************************************************/
* all the part of the request which fits in a buffer is already
* there.
*/
- if (msg_len > channel_recv_limit(req) + b_orig(req->buf) - ci_head(req))
- msg_len = channel_recv_limit(req) + b_orig(req->buf) - ci_head(req);
+ if (msg_len > channel_recv_limit(req) + b_orig(&req->buf) - ci_head(req))
+ msg_len = channel_recv_limit(req) + b_orig(&req->buf) - ci_head(req);
if (bleft < msg_len)
goto too_short;
while (1) {
if (ofs + 12 > ci_data(chn)) {
/* not there yet but could it at least fit ? */
- if (!chn->buf->size)
+ if (!chn->buf.size)
goto too_short;
- if (ofs + 12 <= channel_recv_limit(chn) + b_orig(chn->buf) - ci_head(chn))
+ if (ofs + 12 <= channel_recv_limit(chn) + b_orig(&chn->buf) - ci_head(chn))
goto too_short;
goto no_match;
ofs = 0; occ = 0;
while (1) {
if (ofs + 12 > ci_data(chn)) {
- if (!chn->buf->size)
+ if (!chn->buf.size)
goto too_short;
- if (ofs + 12 <= channel_recv_limit(chn) + b_orig(chn->buf) - ci_head(chn))
+ if (ofs + 12 <= channel_recv_limit(chn) + b_orig(&chn->buf) - ci_head(chn))
goto too_short;
goto no_match;
smp->data.type = SMP_T_BIN;
smp->flags = SMP_F_VOLATILE | SMP_F_CONST;
- if (ofs + body > ci_head(chn) - b_orig(chn->buf) + ci_data(chn)) {
+ if (ofs + body > ci_head(chn) - b_orig(&chn->buf) + ci_data(chn)) {
/* incomplete body */
- if (ofs + body > channel_recv_limit(chn) + b_orig(chn->buf) - ci_head(chn)) {
+ if (ofs + body > channel_recv_limit(chn) + b_orig(&chn->buf) - ci_head(chn)) {
/* truncate it to whatever will fit */
smp->flags |= SMP_F_MAY_CHANGE;
- body = channel_recv_limit(chn) + b_orig(chn->buf) - ci_head(chn) - ofs;
+ body = channel_recv_limit(chn) + b_orig(&chn->buf) - ci_head(chn) - ofs;
}
}
unsigned int maj_ver, min_ver;
/* Check if the input buffer is avalaible. */
- if (si_ic(si)->buf->size == 0)
+ if (si_ic(si)->buf.size == 0)
goto full;
while (1) {
hdr = &idx->v[cur_idx];
if (sol[ctx->del] == ':' && ctx->val + ctx->vlen + ctx->tws == hdr->len) {
/* This was the only value of the header, we must now remove it entirely. */
- delta = b_rep_blk(msg->chn->buf, sol, sol + hdr->len + hdr->cr + 1, NULL, 0);
+ delta = b_rep_blk(&msg->chn->buf, sol, sol + hdr->len + hdr->cr + 1, NULL, 0);
http_msg_move_end(msg, delta);
idx->used--;
hdr->len = 0; /* unused entry */
*/
skip_comma = (ctx->val + ctx->vlen + ctx->tws == hdr->len) ? 0 : 1;
- delta = b_rep_blk(msg->chn->buf, sol + ctx->del + skip_comma,
+ delta = b_rep_blk(&msg->chn->buf, sol + ctx->del + skip_comma,
sol + ctx->val + ctx->vlen + ctx->tws + skip_comma,
NULL, 0);
hdr->len += delta;
c_rew(&s->req, rewind = http_hdr_rewind(&txn->req));
path = http_get_path(txn);
- len = b_dist(s->req.buf, path, c_ptr(&s->req, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
+ len = b_dist(&s->req.buf, path, c_ptr(&s->req, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
c_adv(&s->req, rewind);
return 0;
}
/* add HTTP version */
- delta = b_rep_blk(msg->chn->buf, cur_end, cur_end, " HTTP/1.0\r\n", 11);
+ delta = b_rep_blk(&msg->chn->buf, cur_end, cur_end, " HTTP/1.0\r\n", 11);
http_msg_move_end(msg, delta);
cur_end += delta;
cur_end = (char *)http_parse_reqline(msg,
req,
req->rex, req->wex,
req->flags,
- req->buf->i,
+ req->buf.i,
req->analysers);
/* we're speaking HTTP here, so let's speak HTTP to the client */
return 0;
}
if (unlikely(ci_tail(req) < c_ptr(req, msg->next) ||
- ci_tail(req) > b_wrap(req->buf) - global.tune.maxrewrite))
+ ci_tail(req) > b_wrap(&req->buf) - global.tune.maxrewrite))
channel_slow_realign(req, trash.str);
}
/* OK now we have a complete HTTP request with indexed headers. Let's
* complete the request parsing by setting a few fields we will need
- * later. At this point, we have the last CRLF at req->buf->data + msg->eoh.
+ * later. At this point, we have the last CRLF at req->buf.data + msg->eoh.
* If the request is in HTTP/0.9 form, the rule is still true, and eoh
* points to the CRLF of the request line. msg->next points to the first
* byte after the last LF. msg->sov points to the first byte of data.
if (output->len == -1)
return -1;
- delta = b_rep_blk(msg->chn->buf, val, val_end, output->str, output->len);
+ delta = b_rep_blk(&msg->chn->buf, val, val_end, output->str, output->len);
hdr->len += delta;
http_msg_move_end(msg, delta);
FLT_STRM_CB(s, flt_http_reply(s, txn->status, chunk));
co_inject(res->chn, chunk->str, chunk->len);
/* "eat" the request */
- b_del(req->chn->buf, req->sov);
+ b_del(&req->chn->buf, req->sov);
req->next -= req->sov;
req->sov = 0;
s->req.analysers = AN_REQ_HTTP_XFER_BODY | (s->req.analysers & AN_REQ_FLT_END);
req->msg_state = HTTP_MSG_CLOSED;
res->msg_state = HTTP_MSG_DONE;
/* Trim any possible response */
- b_set_data(res->chn->buf, co_data(res->chn));
+ b_set_data(&res->chn->buf, co_data(res->chn));
res->next = res->sov = 0;
/* let the server side turn to SI_ST_CLO */
channel_shutw_now(req->chn);
req,
req->rex, req->wex,
req->flags,
- req->buf->i,
+ req->buf.i,
req->analysers);
/* just in case we have some per-backend tracking */
req,
req->rex, req->wex,
req->flags,
- req->buf->i,
+ req->buf.i,
req->analysers);
/*
char *cur_end = cur_ptr + txn->req.sl.rq.l;
int delta;
- delta = b_rep_blk(req->buf, cur_ptr + msg->sl.rq.u, path, NULL, 0);
+ delta = b_rep_blk(&req->buf, cur_ptr + msg->sl.rq.u, path, NULL, 0);
http_msg_move_end(&txn->req, delta);
cur_end += delta;
if (http_parse_reqline(&txn->req, HTTP_MSG_RQMETH, cur_ptr, cur_end + 1, NULL, NULL) == NULL)
char *cur_end = cur_ptr + txn->req.sl.rq.l;
int delta;
- delta = b_rep_blk(req->buf, cur_ptr + msg->sl.rq.u,
+ delta = b_rep_blk(&req->buf, cur_ptr + msg->sl.rq.u,
cur_ptr + msg->sl.rq.u + msg->sl.rq.u_l, "/", 1);
http_msg_move_end(&txn->req, delta);
cur_end += delta;
* TRAILERS state.
*/
unsigned int chunk;
- int ret = h1_parse_chunk_size(req->buf, co_data(req) + msg->next, c_data(req), &chunk);
+ int ret = h1_parse_chunk_size(&req->buf, co_data(req) + msg->next, c_data(req), &chunk);
if (!ret)
goto missing_data;
else if (ret < 0) {
msg->err_pos = ci_data(req) + ret;
if (msg->err_pos < 0)
- msg->err_pos += req->buf->size;
+ msg->err_pos += req->buf.size;
stream_inc_http_err_ctr(s);
goto return_bad_req;
}
req,
req->rex, req->wex,
req->flags,
- req->buf->i,
+ req->buf.i,
req->analysers);
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
}
if (unlikely(ci_tail(rep) < c_ptr(rep, msg->next) ||
- ci_tail(rep) > b_wrap(rep->buf) - global.tune.maxrewrite))
+ ci_tail(rep) > b_wrap(&rep->buf) - global.tune.maxrewrite))
channel_slow_realign(rep, trash.str);
if (likely(msg->next < ci_data(rep)))
res,
res->rex, res->wex,
res->flags,
- res->buf->i,
+ res->buf.i,
res->analysers);
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
msg->msg_state = HTTP_MSG_ENDING;
ending:
- /* we may have some pending data starting at res->buf->p such as a last
+ /* we may have some pending data starting at res->buf.p such as a last
* chunk of data or trailers. */
ret = FLT_STRM_DATA_CB(s, chn, flt_http_forward_data(s, msg, msg->next),
/* default_ret */ msg->next,
return 1;
missing_data_or_waiting:
- /* we may have some pending data starting at chn->buf->p */
+ /* we may have some pending data starting at chn->buf.p */
ret = FLT_STRM_DATA_CB(s, chn, flt_http_forward_data(s, msg, msg->next),
/* default_ret */ msg->next,
/* on_error */ goto error);
case HTTP_MSG_CHUNK_CRLF:
/* we want the CRLF after the data */
- ret = h1_skip_chunk_crlf(chn->buf, co_data(chn) + msg->next, c_data(chn));
+ ret = h1_skip_chunk_crlf(&chn->buf, co_data(chn) + msg->next, c_data(chn));
if (ret == 0)
goto missing_data_or_waiting;
if (ret < 0) {
msg->err_pos = ci_data(chn) + ret;
if (msg->err_pos < 0)
- msg->err_pos += chn->buf->size;
+ msg->err_pos += chn->buf.size;
goto chunk_parsing_error;
}
msg->next += ret;
* then set ->next to point to the body and switch to
* DATA or TRAILERS state.
*/
- ret = h1_parse_chunk_size(chn->buf, co_data(chn) + msg->next, c_data(chn), &chunk);
+ ret = h1_parse_chunk_size(&chn->buf, co_data(chn) + msg->next, c_data(chn), &chunk);
if (ret == 0)
goto missing_data_or_waiting;
if (ret < 0) {
msg->err_pos = ci_data(chn) + ret;
if (msg->err_pos < 0)
- msg->err_pos += chn->buf->size;
+ msg->err_pos += chn->buf.size;
goto chunk_parsing_error;
}
msg->msg_state = HTTP_MSG_ENDING;
ending:
- /* we may have some pending data starting at res->buf->p such as a last
+ /* we may have some pending data starting at res->buf.p such as a last
* chunk of data or trailers. */
ret = FLT_STRM_DATA_CB(s, chn, flt_http_forward_data(s, msg, msg->next),
/* default_ret */ msg->next,
return 1;
missing_data_or_waiting:
- /* we may have some pending data starting at chn->buf->p */
+ /* we may have some pending data starting at chn->buf.p */
ret = FLT_STRM_DATA_CB(s, chn, flt_http_forward_data(s, msg, msg->next),
/* default_ret */ msg->next,
/* on_error */ goto error);
if (trash.len < 0)
return -1;
- delta = b_rep_blk(req->buf, cur_ptr, cur_end, trash.str, trash.len);
+ delta = b_rep_blk(&req->buf, cur_ptr, cur_end, trash.str, trash.len);
/* FIXME: if the user adds a newline in the replacement, the
* index will not be recalculated for now, and the new line
* will not be counted as a new header.
break;
case ACT_REMOVE:
- delta = b_rep_blk(req->buf, cur_ptr, cur_next, NULL, 0);
+ delta = b_rep_blk(&req->buf, cur_ptr, cur_next, NULL, 0);
cur_next += delta;
http_msg_move_end(&txn->req, delta);
if (trash.len < 0)
return -1;
- delta = b_rep_blk(req->buf, cur_ptr, cur_end, trash.str, trash.len);
+ delta = b_rep_blk(&req->buf, cur_ptr, cur_end, trash.str, trash.len);
/* FIXME: if the user adds a newline in the replacement, the
* index will not be recalculated for now, and the new line
* will not be counted as a new header.
*/
preserve_hdr = 1;
if (del_from != NULL) {
- int delta = del_hdr_value(req->buf, &del_from, prev);
+ int delta = del_hdr_value(&req->buf, &del_from, prev);
val_end += delta;
next += delta;
hdr_end += delta;
int stripped_after = 0;
if (att_end != equal) {
- stripped_before = b_rep_blk(req->buf, att_end, equal, NULL, 0);
+ stripped_before = b_rep_blk(&req->buf, att_end, equal, NULL, 0);
equal += stripped_before;
val_beg += stripped_before;
}
if (val_beg > equal + 1) {
- stripped_after = b_rep_blk(req->buf, equal + 1, val_beg, NULL, 0);
+ stripped_after = b_rep_blk(&req->buf, equal + 1, val_beg, NULL, 0);
val_beg += stripped_after;
stripped_before += stripped_after;
}
if ((s->be->ck_opts & PR_CK_PFX) && (delim != val_end)) {
int delta; /* negative */
- delta = b_rep_blk(req->buf, val_beg, delim + 1, NULL, 0);
+ delta = b_rep_blk(&req->buf, val_beg, delim + 1, NULL, 0);
val_end += delta;
next += delta;
hdr_end += delta;
preserve_hdr = 1;
if (del_from != NULL) {
- int delta = del_hdr_value(req->buf, &del_from, prev);
+ int delta = del_hdr_value(&req->buf, &del_from, prev);
if (att_beg >= del_from)
att_beg += delta;
if (att_end >= del_from)
if (del_from) {
int delta;
if (preserve_hdr) {
- delta = del_hdr_value(req->buf, &del_from, hdr_end);
+ delta = del_hdr_value(&req->buf, &del_from, hdr_end);
hdr_end = del_from;
cur_hdr->len += delta;
} else {
- delta = b_rep_blk(req->buf, hdr_beg, hdr_next, NULL, 0);
+ delta = b_rep_blk(&req->buf, hdr_beg, hdr_next, NULL, 0);
/* FIXME: this should be a separate function */
txn->hdr_idx.v[old_idx].next = cur_hdr->next;
if (trash.len < 0)
return -1;
- delta = b_rep_blk(rtr->buf, cur_ptr, cur_end, trash.str, trash.len);
+ delta = b_rep_blk(&rtr->buf, cur_ptr, cur_end, trash.str, trash.len);
/* FIXME: if the user adds a newline in the replacement, the
* index will not be recalculated for now, and the new line
* will not be counted as a new header.
break;
case ACT_REMOVE:
- delta = b_rep_blk(rtr->buf, cur_ptr, cur_next, NULL, 0);
+ delta = b_rep_blk(&rtr->buf, cur_ptr, cur_next, NULL, 0);
cur_next += delta;
http_msg_move_end(&txn->rsp, delta);
if (trash.len < 0)
return -1;
- delta = b_rep_blk(rtr->buf, cur_ptr, cur_end, trash.str, trash.len);
+ delta = b_rep_blk(&rtr->buf, cur_ptr, cur_end, trash.str, trash.len);
/* FIXME: if the user adds a newline in the replacement, the
* index will not be recalculated for now, and the new line
* will not be counted as a new header.
int stripped_after = 0;
if (att_end != equal) {
- stripped_before = b_rep_blk(res->buf, att_end, equal, NULL, 0);
+ stripped_before = b_rep_blk(&res->buf, att_end, equal, NULL, 0);
equal += stripped_before;
val_beg += stripped_before;
}
if (val_beg > equal + 1) {
- stripped_after = b_rep_blk(res->buf, equal + 1, val_beg, NULL, 0);
+ stripped_after = b_rep_blk(&res->buf, equal + 1, val_beg, NULL, 0);
val_beg += stripped_after;
stripped_before += stripped_after;
}
/* this cookie must be deleted */
if (*prev == ':' && next == hdr_end) {
/* whole header */
- delta = b_rep_blk(res->buf, hdr_beg, hdr_next, NULL, 0);
+ delta = b_rep_blk(&res->buf, hdr_beg, hdr_next, NULL, 0);
txn->hdr_idx.v[old_idx].next = cur_hdr->next;
txn->hdr_idx.used--;
cur_hdr->len = 0;
*/
} else {
/* just remove the value */
- int delta = del_hdr_value(res->buf, &prev, next);
+ int delta = del_hdr_value(&res->buf, &prev, next);
next = prev;
hdr_end += delta;
hdr_next += delta;
/* replace bytes val_beg->val_end with the cookie name associated
* with this server since we know it.
*/
- delta = b_rep_blk(res->buf, val_beg, val_end, srv->cookie, srv->cklen);
+ delta = b_rep_blk(&res->buf, val_beg, val_end, srv->cookie, srv->cklen);
next += delta;
hdr_end += delta;
hdr_next += delta;
/* insert the cookie name associated with this server
* before existing cookie, and insert a delimiter between them..
*/
- delta = b_rep_blk(res->buf, val_beg, val_beg, srv->cookie, srv->cklen + 1);
+ delta = b_rep_blk(&res->buf, val_beg, val_beg, srv->cookie, srv->cklen + 1);
next += delta;
hdr_end += delta;
hdr_next += delta;
HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
es->len = MIN(ci_data(chn), global.tune.bufsize);
- len1 = b_wrap(chn->buf) - ci_head(chn);
+ len1 = b_wrap(&chn->buf) - ci_head(chn);
len1 = MIN(len1, es->len);
len2 = es->len - len1; /* remaining data if buffer wraps */
if (es->buf) {
memcpy(es->buf, ci_head(chn), len1);
if (len2)
- memcpy(es->buf + len1, b_orig(chn->buf), len2);
+ memcpy(es->buf + len1, b_orig(&chn->buf), len2);
}
if (msg->err_pos >= 0)
es->t_flags = s->txn->flags;
es->m_flags = msg->flags;
es->b_out = co_data(chn);
- es->b_wrap = b_wrap(chn->buf) - ci_head(chn);
+ es->b_wrap = b_wrap(&chn->buf) - ci_head(chn);
es->b_tot = chn->total;
es->m_clen = msg->chunk_len;
es->m_blen = msg->body_len;
* content-length.
*/
if (unlikely(ci_data(&s->res)))
- b_set_data(s->res.buf, co_data(&s->res));
+ b_set_data(&s->res.buf, co_data(&s->res));
/* Now we can realign the response buffer */
c_realign_if_empty(&s->res);
/* If the buffer does not leave enough free space at the end,
* we must first realign it.
*/
- if (ci_head(&s->req) > b_orig(s->req.buf) &&
- ci_head(&s->req) + ci_data(&s->req) > b_wrap(s->req.buf) - global.tune.maxrewrite)
+ if (ci_head(&s->req) > b_orig(&s->req.buf) &&
+ ci_head(&s->req) + ci_data(&s->req) > b_wrap(&s->req.buf) - global.tune.maxrewrite)
channel_slow_realign(&s->req, trash.str);
if (unlikely(txn->req.msg_state < HTTP_MSG_BODY)) {
* we want this check to be maintained.
*/
if (unlikely(ci_head(&s->req) + ci_data(&s->req) >
- b_wrap(s->req.buf) - global.tune.maxrewrite)) {
+ b_wrap(&s->req.buf) - global.tune.maxrewrite)) {
msg->err_state = msg->msg_state;
msg->msg_state = HTTP_MSG_ERROR;
smp->data.u.sint = 1;
body = c_ptr(msg->chn, -http_data_rewind(msg));
block1 = len;
- if (block1 > b_wrap(msg->chn->buf) - body)
- block1 = b_wrap(msg->chn->buf) - body;
+ if (block1 > b_wrap(&msg->chn->buf) - body)
+ block1 = b_wrap(&msg->chn->buf) - body;
if (block1 == len) {
/* buffer is not wrapped (or empty) */
/* buffer is wrapped, we need to defragment it */
temp = get_trash_chunk();
memcpy(temp->str, body, block1);
- memcpy(temp->str + block1, b_orig(msg->chn->buf), len - block1);
+ memcpy(temp->str + block1, b_orig(&msg->chn->buf), len - block1);
smp->data.type = SMP_T_BIN;
smp->data.u.str.str = temp->str;
smp->data.u.str.len = len;
body = c_ptr(msg->chn, -http_data_rewind(msg));
block1 = len;
- if (block1 > b_wrap(msg->chn->buf) - body)
- block1 = b_wrap(msg->chn->buf) - body;
+ if (block1 > b_wrap(&msg->chn->buf) - body)
+ block1 = b_wrap(&msg->chn->buf) - body;
if (block1 == len) {
/* buffer is not wrapped (or empty) */
/* buffer is wrapped, we need to defragment it */
smp->ctx.a[0] = body;
smp->ctx.a[1] = body + block1;
- smp->ctx.a[2] = b_orig(msg->chn->buf);
- smp->ctx.a[3] = b_orig(msg->chn->buf) + ( len - block1 );
+ smp->ctx.a[2] = b_orig(&msg->chn->buf);
+ smp->ctx.a[3] = b_orig(&msg->chn->buf) + ( len - block1 );
}
}
return smp_fetch_param('&', name, name_len, args, smp, kw, private);
}
/* commit changes and adjust end of message */
- delta = b_rep_blk(s->req.buf, cur_ptr, cur_end, replace + offset, len - offset);
+ delta = b_rep_blk(&s->req.buf, cur_ptr, cur_end, replace + offset, len - offset);
txn->req.sl.rq.l += delta;
txn->hdr_idx.v[0].len += delta;
http_msg_move_end(&txn->req, delta);
cur_end = ci_head(&s->res) + txn->rsp.sl.st.r + txn->rsp.sl.st.r_l;
/* commit changes and adjust message */
- delta = b_rep_blk(s->res.buf, cur_ptr, cur_end, trash.str, trash.len);
+ delta = b_rep_blk(&s->res.buf, cur_ptr, cur_end, trash.str, trash.len);
/* adjust res line offsets and lengths */
txn->rsp.sl.st.r += c_l - txn->rsp.sl.st.c_l;
case STAT_PX_ST_LI:
/* stats.l has been initialized above */
for (; appctx->ctx.stats.l != &px->conf.listeners; appctx->ctx.stats.l = l->by_fe.n) {
- if (buffer_almost_full(rep->buf)) {
+ if (buffer_almost_full(&rep->buf)) {
si_applet_cant_put(si);
return 0;
}
case STAT_PX_ST_SV:
/* stats.sv has been initialized above */
for (; appctx->ctx.stats.sv != NULL; appctx->ctx.stats.sv = sv->next) {
- if (buffer_almost_full(rep->buf)) {
+ if (buffer_almost_full(&rep->buf)) {
si_applet_cant_put(si);
return 0;
}
case STAT_ST_LIST:
/* dump proxies */
while (appctx->ctx.stats.px) {
- if (buffer_almost_full(rep->buf)) {
+ if (buffer_almost_full(&rep->buf)) {
si_applet_cant_put(si);
return 0;
}
goto out;
/* Check if the input buffer is avalaible. */
- if (res->buf->size == 0) {
+ if (res->buf.size == 0) {
si_applet_cant_put(si);
goto out;
}
* when the default backend is assigned.
*/
s->be = sess->fe;
- s->req.buf = s->res.buf = NULL;
+ s->req.buf = BUF_NULL;
+ s->res.buf = BUF_NULL;
s->req_cap = NULL;
s->res_cap = NULL;
LIST_INIT(&s->buffer_wait.list);
HA_SPIN_UNLOCK(BUF_WQ_LOCK, &buffer_wq_lock);
}
- if (s->req.buf->size || s->res.buf->size) {
+ if (s->req.buf.size || s->res.buf.size) {
b_drop(&s->req.buf);
b_drop(&s->res.buf);
offer_buffers(NULL, tasks_run_queue);
req, &s->res,
req->rex, s->res.wex,
req->flags, s->res.flags,
- req->buf->i, req->buf->o, s->res.buf->i, s->res.buf->o, s->si[0].state, s->si[1].state);
+ req->buf->i, req->buf->o, s->res.buf.i, s->res.buf.o, s->si[0].state, s->si[1].state);
if (si->state == SI_ST_ASS) {
/* Server assigned to connection request, we have to try to connect now */
&s->req, &s->res,
s->req.rex, s->res.wex,
s->req.flags, s->res.flags,
- s->req.buf->i, s->req.buf->o, s->res.buf->i, s->res.buf->o, s->si[0].state, s->si[1].state);
+ s->req.buf.i, s->req.buf.o, s->res.buf.i, s->res.buf.o, s->si[0].state, s->si[1].state);
if (si->state != SI_ST_REQ)
return;
strm->req.wex ?
human_time(TICKS_TO_MS(strm->req.wex - now_ms),
TICKS_TO_MS(1000)) : "<NEVER>",
- strm->req.buf,
- b_orig(strm->req.buf), (unsigned int)co_data(&strm->req),
+ &strm->req.buf,
+ b_orig(&strm->req.buf), (unsigned int)co_data(&strm->req),
(unsigned int)ci_head_ofs(&strm->req),
strm->txn ? strm->txn->req.next : 0, (unsigned int)ci_data(&strm->req),
- (unsigned int)strm->req.buf->size);
+ (unsigned int)strm->req.buf.size);
chunk_appendf(&trash,
" res=%p (f=0x%06x an=0x%x pipe=%d tofwd=%d total=%lld)\n"
strm->res.wex ?
human_time(TICKS_TO_MS(strm->res.wex - now_ms),
TICKS_TO_MS(1000)) : "<NEVER>",
- strm->res.buf,
- b_orig(strm->res.buf), (unsigned int)co_data(&strm->res),
+ &strm->res.buf,
+ b_orig(&strm->res.buf), (unsigned int)co_data(&strm->res),
(unsigned int)ci_head_ofs(&strm->res),
strm->txn ? strm->txn->rsp.next : 0, (unsigned int)ci_data(&strm->res),
- (unsigned int)strm->res.buf->size);
+ (unsigned int)strm->res.buf.size);
if (ci_putchk(si_ic(si), &trash) == -1) {
si_applet_cant_put(si);
if (oc->flags & CF_STREAMER)
send_flag |= CO_SFL_STREAMER;
- ret = conn->mux->snd_buf(cs, oc->buf, co_data(oc), send_flag);
+ ret = conn->mux->snd_buf(cs, &oc->buf, co_data(oc), send_flag);
if (ret > 0) {
oc->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA | CF_WRITE_EVENT;
break;
}
- ret = conn->mux->rcv_buf(cs, ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
+ ret = conn->mux->rcv_buf(cs, &ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
if (cs->flags & CS_FL_RCV_MORE)
si->flags |= SI_FL_WAIT_ROOM;
if (cur_read) {
if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
- (cur_read <= ic->buf->size / 2)) {
+ (cur_read <= ic->buf.size / 2)) {
ic->xfer_large = 0;
ic->xfer_small++;
if (ic->xfer_small >= 3) {
}
}
else if (!(ic->flags & CF_STREAMER_FAST) &&
- (cur_read >= ic->buf->size - global.tune.maxrewrite)) {
+ (cur_read >= ic->buf.size - global.tune.maxrewrite)) {
/* we read a full buffer at once */
ic->xfer_small = 0;
ic->xfer_large++;