buf->analysers = 0;
buf->cons = NULL;
buf->flags = BF_OUT_EMPTY;
- buf->r = buf->lr = buf->w = buf->data;
+ buf->r = buf->lr = buf->p = buf->data;
}
/*****************************************************************/
if (buffer_len(buf) >= spare)
spare = 0;
else if (buffer_len(buf)) {
- spare = buf->w - res - buf->r;
+ spare = buffer_wrap_sub(buf, buf->p - buf->o) - res - buf->r;
if (spare <= 0)
spare += buf->size;
spare = buffer_contig_area(buf, buf->r, spare);
if (buffer_len(buf) >= spare)
spare = 0;
else if (buffer_len(buf)) {
- spare = buf->w - res - buf->r;
+ spare = buffer_wrap_sub(buf, buf->p - buf->o) - res - buf->r;
if (spare <= 0)
spare += buf->size;
spare = buffer_contig_area(buf, buf->r, spare);
/* Returns the size of the working area which the caller knows ends at <end>.
* If <end> equals buf->r (modulo size), then it means that the free area which
* follows is part of the working area. Otherwise, the working area stops at
- * <end>. It always starts at buf->w+o. The work area includes the
+ * <end>. It always starts at buf->p. The work area includes the
* reserved area.
*/
static inline int buffer_work_area(const struct buffer *buf, const char *end)
{
end = buffer_pointer(buf, end);
if (end == buf->r) /* pointer exactly at end, lets push forwards */
- end = buf->w;
- return buffer_count(buf, buffer_pointer(buf, buf->w + buf->o), end);
+ end = buffer_wrap_sub(buf, buf->p - buf->o);
+ return buffer_count(buf, buf->p, end);
}
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
*/
static inline void buffer_flush(struct buffer *buf)
{
+ buf->p = buf->r;
buf->o += buf->i;
buf->i = 0;
if (buf->o)
buf->o = 0;
buf->i = 0;
buf->to_forward = 0;
- buf->r = buf->lr = buf->w = buf->data;
+ buf->r = buf->lr = buf->p = buf->data;
buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
if (!buf->pipe)
buf->flags |= BF_OUT_EMPTY;
return;
buf->i = 0;
- buf->r = buf->w + buf->o;
+ buf->r = buf->p;
if (buf->r >= buf->data + buf->size)
buf->r -= buf->size;
buf->lr = buf->r;
static inline void buffer_ignore(struct buffer *buf, int n)
{
buf->i -= n;
- buf->w += n;
- if (buf->w >= buf->data + buf->size)
- buf->w -= buf->size;
+ buf->p = buffer_wrap_add(buf, buf->p + n);
buf->flags &= ~BF_FULL;
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
{
if (!(buf->i | buf->o)) {
/* let's realign the buffer to optimize I/O */
- buf->r = buf->w = buf->lr = buf->data;
+ buf->r = buf->p = buf->lr = buf->data;
}
return buffer_contig_space(buf);
}
*/
static inline void buffer_skip(struct buffer *buf, int len)
{
- buf->w += len;
- if (buf->w >= buf->data + buf->size)
- buf->w -= buf->size; /* wrap around the buffer */
-
buf->o -= len;
if (buffer_len(buf) == 0)
- buf->r = buf->w = buf->lr = buf->data;
+ buf->r = buf->p = buf->lr = buf->data;
if (buffer_len(buf) < buffer_max_len(buf))
buf->flags &= ~BF_FULL;
return -2;
return -1;
}
- return *buf->w;
+ return *buffer_wrap_sub(buf, buf->p - buf->o);
}
int wex; /* expiration date for a write or connect, in ticks */
int rto; /* read timeout, in ticks */
int wto; /* write timeout, in ticks */
- char *r, *w, *lr; /* read ptr, write ptr, last read */
+ char *r, *lr; /* read ptr, last read */
+ char *p; /* buffer's start pointer, separates in and out data */
unsigned int size; /* buffer size in bytes */
unsigned int i; /* number of input bytes pending for analysis in the buffer */
unsigned int o; /* number of out bytes the sender can consume from this buffer */
b = ((dir & ACL_DIR_MASK) == ACL_DIR_RTR) ? l4->rep : l4->req;
bleft = b->i;
- data = (const unsigned char *)b->w;
+ data = (const unsigned char *)b->p;
if (!bleft)
goto too_short;
if (!bleft)
goto too_short;
- data = (const unsigned char *)l4->req->w;
+ data = (const unsigned char *)l4->req->p;
if ((*data >= 0x14 && *data <= 0x17) || (*data == 0xFF)) {
/* SSLv3 header format */
if (bleft < 5)
* all the part of the request which fits in a buffer is already
* there.
*/
- if (msg_len > buffer_max_len(l4->req) + l4->req->data - l4->req->w)
- msg_len = buffer_max_len(l4->req) + l4->req->data - l4->req->w;
+ if (msg_len > buffer_max_len(l4->req) + l4->req->data - l4->req->p)
+ msg_len = buffer_max_len(l4->req) + l4->req->data - l4->req->p;
if (bleft < msg_len)
goto too_short;
b = ((dir & ACL_DIR_MASK) == ACL_DIR_RTR) ? l4->rep : l4->req;
bleft = b->i;
- data = (unsigned char *)b->w;
+ data = (unsigned char *)b->p;
/* Check for SSL/TLS Handshake */
if (!bleft)
if (bleft <= 11)
goto too_short;
- data = (const unsigned char *)l4->req->w + 11;
+ data = (const unsigned char *)l4->req->p + 11;
bleft -= 11;
if (bleft <= 7)
if (!bytes)
return 0;
if (bytes <= (unsigned long long)buf->i) {
+ buf->p = buffer_wrap_add(buf, buf->p + bytes);
buf->o += bytes;
buf->i -= bytes;
buf->flags &= ~BF_OUT_EMPTY;
}
forwarded = buf->i;
+ buf->p = buffer_wrap_add(buf, buf->p + forwarded);
buf->o += forwarded;
buf->i = 0;
memcpy(buf->r, msg, len);
buf->o += len;
- buf->r += len;
+ buf->p = buffer_wrap_add(buf, buf->p + len);
+ buf->r = buffer_wrap_add(buf, buf->r + len);
buf->total += len;
- if (buf->r == buf->data + buf->size)
- buf->r = buf->data;
buf->flags &= ~(BF_OUT_EMPTY|BF_FULL);
if (buffer_len(buf) >= buffer_max_len(buf))
}
buf->o += fwd;
buf->i -= fwd;
+ buf->p = buffer_wrap_add(buf, buf->p + fwd);
buf->flags &= ~BF_OUT_EMPTY;
}
goto out;
}
- p = buf->w;
+ p = buffer_wrap_sub(buf, buf->p - buf->o);
if (max > buf->o) {
max = buf->o;
if (*p == '\n')
break;
- p++;
- if (p == buf->data + buf->size)
- p = buf->data;
+ p = buffer_wrap_add(buf, p + 1);
}
if (ret > 0 && ret < len && ret < buf->o &&
*(str-1) != '\n' &&
return 0;
}
- firstblock = buf->data + buf->size - buf->w;
+ firstblock = buf->data + buf->size - buffer_wrap_sub(buf, buf->p - buf->o);
if (firstblock > offset) {
if (firstblock >= len + offset) {
- memcpy(blk, buf->w + offset, len);
+ memcpy(blk, buffer_wrap_sub(buf, buf->p - buf->o) + offset, len);
return len;
}
- memcpy(blk, buf->w + offset, firstblock - offset);
+ memcpy(blk, buffer_wrap_sub(buf, buf->p - buf->o) + offset, firstblock - offset);
memcpy(blk + firstblock - offset, buf->data, len - firstblock + offset);
return len;
}
if (delta + b->r >= b->data + b->size)
return 0; /* no space left */
- if (delta + b->r > b->w && b->w >= b->r && buffer_not_empty(b))
+ if (delta + b->r > buffer_wrap_sub(b, b->p - b->o) &&
+ buffer_wrap_sub(b, b->p - b->o) >= b->r && buffer_not_empty(b))
return 0; /* no space left before wrapping data */
/* first, protect the end of the buffer */
b->flags &= ~BF_FULL;
if (buffer_len(b) == 0)
- b->r = b->w = b->lr = b->data;
+ b->r = b->p = b->lr = b->data;
if (buffer_len(b) >= buffer_max_len(b))
b->flags |= BF_FULL;
int advance, to_move;
char *from, *to;
- advance = buf->data + buf->size - buf->w;
+ from = buffer_wrap_sub(buf, buf->p - buf->o);
+ advance = buf->data + buf->size - from;
if (!advance)
return;
- from = buf->w;
to_move = buffer_len(buf);
while (to_move) {
char last, save;
void buffer_dump(FILE *o, struct buffer *b, int from, int to)
{
fprintf(o, "Dumping buffer %p\n", b);
- fprintf(o, " data=%p o=%d i=%d r=%p w=%p lr=%p\n",
- b->data, b->o, b->i, b->r, b->w, b->lr);
+ fprintf(o, " data=%p o=%d i=%d r=%p p=%p lr=%p\n",
+ b->data, b->o, b->i, b->r, b->p, b->lr);
if (!to || to > buffer_len(b))
to = buffer_len(b);
chunk_printf(&msg,
" wex=%s\n"
- " data=%p r=%d w=%d lr=%d total=%lld\n",
+ " data=%p r=%d p=%d lr=%d total=%lld\n",
sess->req->wex ?
human_time(TICKS_TO_MS(sess->req->wex - now_ms),
TICKS_TO_MS(1000)) : "<NEVER>",
sess->req->data,
(int)(sess->req->r - sess->req->data),
- (int)(sess->req->w - sess->req->data),
+ (int)(sess->req->p - sess->req->data),
(int)(sess->req->lr - sess->req->data),
sess->req->total);
chunk_printf(&msg,
" wex=%s\n"
- " data=%p r=%d w=%d lr=%d total=%lld\n",
+ " data=%p r=%d p=%d lr=%d total=%lld\n",
sess->rep->wex ?
human_time(TICKS_TO_MS(sess->rep->wex - now_ms),
TICKS_TO_MS(1000)) : "<NEVER>",
sess->rep->data,
(int)(sess->rep->r - sess->rep->data),
- (int)(sess->rep->w - sess->rep->data),
+ (int)(sess->rep->p - sess->rep->data),
(int)(sess->rep->lr - sess->rep->data),
sess->rep->total);
* first if we need to remove some CRLF. We can only
* do this when o=0.
*/
- char *beg = buf->w + buf->o;
- if (beg >= buf->data + buf->size)
- beg -= buf->size;
+ char *beg = buf->p;
+
if (unlikely(ptr != beg)) {
if (buf->o)
goto http_msg_ood;
* first if we need to remove some CRLF. We can only
* do this when o=0.
*/
- char *beg = buf->w + buf->o;
- if (beg >= buf->data + buf->size)
- beg -= buf->size;
+ char *beg = buf->p;
+
if (likely(ptr != beg)) {
if (buf->o)
goto http_msg_ood;
return 1;
}
+/* This function may only be used when the buffer's o is empty */
void http_buffer_heavy_realign(struct buffer *buf, struct http_msg *msg)
{
char *end = buf->data + buf->size;
- int off = buf->data + buf->size - buf->w;
+ int off = buf->data + buf->size - buf->p;
/* two possible cases :
* - the buffer is in one contiguous block, we move it in-place
if (buf->i) {
int block1 = buf->i;
int block2 = 0;
- if (buf->r <= buf->w) {
+ if (buf->r <= buf->p) {
/* non-contiguous block */
- block1 = buf->data + buf->size - buf->w;
+ block1 = buf->data + buf->size - buf->p;
block2 = buf->r - buf->data;
}
if (block2)
memcpy(swap_buffer, buf->data, block2);
- memmove(buf->data, buf->w, block1);
+ memmove(buf->data, buf->p, block1);
if (block2)
memcpy(buf->data + block1, swap_buffer, block2);
}
/* adjust all known pointers */
- buf->w = buf->data;
+ buf->p = buf->data;
buf->lr += off; if (buf->lr >= end) buf->lr -= buf->size;
buf->r += off; if (buf->r >= end) buf->r -= buf->size;
msg->sol += off; if (msg->sol >= end) msg->sol -= buf->size;
buffer_auto_close(s->rep);
/* make ->lr point to the first non-forwarded byte */
- s->req->lr = s->req->w + s->req->o;
- if (s->req->lr >= s->req->data + s->req->size)
- s->req->lr -= s->req->size;
- s->rep->lr = s->rep->w + s->rep->o;
- if (s->rep->lr >= s->rep->data + s->rep->size)
- s->rep->lr -= s->req->size;
-
+ s->req->lr = s->req->p;
+ s->rep->lr = s->rep->p;
s->req->analysers = s->listener->analysers;
s->req->analysers &= ~AN_REQ_DECODE_PROXY;
s->rep->analysers = 0;
/* we want the CRLF after the data */
int ret;
- req->lr = req->w + req->o;
- if (req->lr >= req->data + req->size)
- req->lr -= req->size;
-
+ req->lr = req->p;
ret = http_skip_chunk_crlf(req, msg);
if (ret == 0)
/* we want the CRLF after the data */
int ret;
- res->lr = res->w + res->o;
- if (res->lr >= res->data + res->size)
- res->lr -= res->size;
-
+ res->lr = res->p;
ret = http_skip_chunk_crlf(res, msg);
if (!ret)
*/
if (unlikely(s->rep->i)) {
s->rep->i = 0;
- s->rep->r = s->rep->w + s->rep->o;
- if (s->rep->r >= s->rep->data + s->rep->size)
- s->rep->r -= s->rep->size;
+ s->rep->r = s->rep->p;
}
s->req->rto = s->fe->timeout.client;
return 0;
for (i = 0; i < len_size; i++) {
- buf_size = (buf_size << 8) + ((unsigned char *)b->w)[i + len_offset];
+ buf_size = (buf_size << 8) + ((unsigned char *)b->p)[i + len_offset];
}
if (!buf_size)
return 0;
/* init chunk as read only */
- chunk_initlen(&data->str, b->w + buf_offset, 0, buf_size);
+ chunk_initlen(&data->str, b->p + buf_offset, 0, buf_size);
return 1;
}
return 0;
/* init chunk as read only */
- chunk_initlen(&data->str, b->w + buf_offset, 0, buf_size);
+ chunk_initlen(&data->str, b->p + buf_offset, 0, buf_size);
return 1;
}
*/
if (buffer_empty(b)) {
/* let's realign the buffer to optimize I/O */
- b->r = b->w = b->lr = b->data;
+ b->r = b->p = b->lr = b->data;
}
- else if (b->r > b->w) {
+ else if (b->data + b->o < b->p &&
+ b->p + b->i < b->data + b->size) {
/* remaining space wraps at the end, with a moving limit */
if (max > b->data + b->size - b->r)
max = b->data + b->size - b->r;
}
b->o += fwd;
b->i -= fwd;
+ b->p = buffer_wrap_add(b, b->p + fwd);
b->flags &= ~BF_OUT_EMPTY;
}
* data left, and that there are sendable buffered data.
*/
while (1) {
- if (b->r > b->w)
- max = b->r - b->w;
- else
- max = b->data + b->size - b->w;
+ max = b->o;
- /* limit the amount of outgoing data if required */
- if (max > b->o)
- max = b->o;
+ /* outgoing data may wrap at the end */
+ if (b->data + max > b->p)
+ max = b->data + max - b->p;
/* check if we want to inform the kernel that we're interested in
* sending more data after this call. We want this if :
if (b->flags & BF_SEND_DONTWAIT)
send_flag &= ~MSG_MORE;
- ret = send(si->fd, b->w, max, send_flag);
+ ret = send(si->fd, buffer_wrap_sub(b, b->p - b->o), max, send_flag);
} else {
int skerr;
socklen_t lskerr = sizeof(skerr);
if (ret == -1 || skerr)
ret = -1;
else
- ret = send(si->fd, b->w, max, MSG_DONTWAIT);
+ ret = send(si->fd, buffer_wrap_sub(b, b->p - b->o), max, MSG_DONTWAIT);
}
if (ret > 0) {
b->flags |= BF_WRITE_PARTIAL;
- b->w += ret;
- if (b->w == b->data + b->size)
- b->w = b->data; /* wrap around the buffer */
-
b->o -= ret;
if (likely(!buffer_len(b)))
/* optimize data alignment in the buffer */
- b->r = b->w = b->lr = b->data;
+ b->r = b->p = b->lr = b->data;
if (likely(buffer_len(b) < buffer_max_len(b)))
b->flags &= ~BF_FULL;