MAJOR: buffer: replace buf->l with buf->{o+i}

We don't have buf->l anymore. We have buf->i for pending data and
the total length is retrieved by adding buf->o. Some computation
already become simpler.

Despite extreme care, bugs are not excluded.

It's worth noting that msg->err_pos as set by HTTP request/response
analysers becomes relative to pending data and not to the beginning
of the buffer. This has not been completed yet so differences might
occur when outgoing data are left in the buffer.
This commit is contained in:
Willy Tarreau 2012-03-01 18:19:58 +01:00
parent 2e046c6017
commit 02d6cfc1d7
11 changed files with 182 additions and 159 deletions

View File

@ -55,8 +55,9 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes);
static inline void buffer_init(struct buffer *buf)
{
buf->o = 0;
buf->i = 0;
buf->to_forward = 0;
buf->l = buf->total = 0;
buf->total = 0;
buf->pipe = NULL;
buf->analysers = 0;
buf->cons = NULL;
@ -68,6 +69,24 @@ static inline void buffer_init(struct buffer *buf)
/* These functions are used to compute various buffer area sizes */
/*****************************************************************/
/* Return the buffer's length in bytes by summing the input and the output */
static inline int buffer_len(const struct buffer *buf)
{
return buf->i + buf->o;
}
/* Return non-zero only if the buffer is not empty */
static inline int buffer_not_empty(const struct buffer *buf)
{
return buf->i | buf->o;
}
/* Return non-zero only if the buffer is empty */
static inline int buffer_empty(const struct buffer *buf)
{
return !buffer_not_empty(buf);
}
/* Return the number of reserved bytes in the buffer, which ensures that once
* all pending data are forwarded, the buffer still has global.tune.maxrewrite
* bytes free. The result is between 0 and global.maxrewrite, which is itself
@ -98,7 +117,7 @@ static inline int buffer_max_len(const struct buffer *buf)
*/
static inline int buffer_total_space(const struct buffer *buf)
{
return buf->size - buf->l;
return buf->size - buffer_len(buf);
}
/* Return the maximum amount of bytes that can be written into the buffer,
@ -107,7 +126,7 @@ static inline int buffer_total_space(const struct buffer *buf)
*/
static inline int buffer_total_space_res(const struct buffer *buf)
{
int len = buffer_max_len(buf) - buf->l;
int len = buffer_max_len(buf) - buffer_len(buf);
return len < 0 ? 0 : len;
}
@ -129,7 +148,7 @@ static inline int buffer_contig_area(const struct buffer *buf, const char *start
*/
static inline int buffer_contig_space(const struct buffer *buf)
{
int space_from_end = buf->l - (buf->r - buf->data);
int space_from_end = buffer_len(buf) - (buf->r - buf->data);
if (space_from_end < 0) /* data does not wrap */
space_from_end = buf->r - buf->data;
return buf->size - space_from_end;
@ -148,9 +167,9 @@ static inline int buffer_contig_space_res(const struct buffer *buf)
int res = buffer_reserved(buf);
int spare = buf->size - res;
if (buf->l >= spare)
if (buffer_len(buf) >= spare)
spare = 0;
else if (buf->l) {
else if (buffer_len(buf)) {
spare = buf->w - res - buf->r;
if (spare <= 0)
spare += buf->size;
@ -171,9 +190,9 @@ static inline int buffer_contig_space_with_res(const struct buffer *buf, int res
*/
int spare = buf->size - res;
if (buf->l >= spare)
if (buffer_len(buf) >= spare)
spare = 0;
else if (buf->l) {
else if (buffer_len(buf)) {
spare = buf->w - res - buf->r;
if (spare <= 0)
spare += buf->size;
@ -213,7 +232,7 @@ static inline int buffer_count(const struct buffer *buf, const char *from, const
*/
static inline int buffer_pending(const struct buffer *buf)
{
return buf->l - buf->o;
return buf->i;
}
/* Returns the size of the working area which the caller knows ends at <end>.
@ -248,7 +267,7 @@ static inline int buffer_contig_data(struct buffer *buf)
{
int ret;
if (!buf->o || !buf->l)
if (!buf->o)
return 0;
if (buf->r > buf->w)
@ -302,8 +321,8 @@ static inline void buffer_check_timeouts(struct buffer *b)
*/
static inline void buffer_flush(struct buffer *buf)
{
if (buf->o < buf->l)
buf->o = buf->l;
buf->o += buf->i;
buf->i = 0;
if (buf->o)
buf->flags &= ~BF_OUT_EMPTY;
}
@ -315,9 +334,9 @@ static inline void buffer_flush(struct buffer *buf)
static inline void buffer_erase(struct buffer *buf)
{
buf->o = 0;
buf->i = 0;
buf->to_forward = 0;
buf->r = buf->lr = buf->w = buf->data;
buf->l = 0;
buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
if (!buf->pipe)
buf->flags |= BF_OUT_EMPTY;
@ -334,16 +353,16 @@ static inline void buffer_cut_tail(struct buffer *buf)
return buffer_erase(buf);
buf->to_forward = 0;
if (buf->l == buf->o)
if (!buf->i)
return;
buf->l = buf->o;
buf->r = buf->w + buf->l;
buf->i = 0;
buf->r = buf->w + buf->o;
if (buf->r >= buf->data + buf->size)
buf->r -= buf->size;
buf->lr = buf->r;
buf->flags &= ~BF_FULL;
if (buf->l >= buffer_max_len(buf))
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
}
@ -353,12 +372,12 @@ static inline void buffer_cut_tail(struct buffer *buf)
*/
static inline void buffer_ignore(struct buffer *buf, int n)
{
buf->l -= n;
buf->i -= n;
buf->w += n;
if (buf->w >= buf->data + buf->size)
buf->w -= buf->size;
buf->flags &= ~BF_FULL;
if (buf->l >= buffer_max_len(buf))
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
}
@ -445,7 +464,7 @@ static inline void buffer_dont_read(struct buffer *buf)
*/
static inline int buffer_realign(struct buffer *buf)
{
if (buf->l == 0) {
if (!(buf->i | buf->o)) {
/* let's realign the buffer to optimize I/O */
buf->r = buf->w = buf->lr = buf->data;
}
@ -464,14 +483,13 @@ static inline void buffer_skip(struct buffer *buf, int len)
if (buf->w >= buf->data + buf->size)
buf->w -= buf->size; /* wrap around the buffer */
buf->l -= len;
if (!buf->l)
buf->o -= len;
if (buffer_len(buf) == 0)
buf->r = buf->w = buf->lr = buf->data;
if (buf->l < buffer_max_len(buf))
if (buffer_len(buf) < buffer_max_len(buf))
buf->flags &= ~BF_FULL;
buf->o -= len;
if (!buf->o && !buf->pipe)
buf->flags |= BF_OUT_EMPTY;

View File

@ -180,9 +180,9 @@ struct buffer {
int wex; /* expiration date for a write or connect, in ticks */
int rto; /* read timeout, in ticks */
int wto; /* write timeout, in ticks */
unsigned int l; /* data length */
char *r, *w, *lr; /* read ptr, write ptr, last read */
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 */
unsigned int to_forward; /* number of bytes to forward after out without a wake-up */
unsigned int analysers; /* bit field indicating what to do on the buffer */

View File

@ -102,7 +102,7 @@ acl_fetch_req_len(struct proxy *px, struct session *l4, void *l7, int dir,
if (!l4 || !l4->req)
return 0;
temp_pattern.data.integer = l4->req->l;
temp_pattern.data.integer = l4->req->i;
test->flags = ACL_TEST_F_VOLATILE | ACL_TEST_F_MAY_CHANGE;
return 1;
}
@ -122,7 +122,7 @@ acl_fetch_ssl_hello_type(struct proxy *px, struct session *l4, void *l7, int dir
b = ((dir & ACL_DIR_MASK) == ACL_DIR_RTR) ? l4->rep : l4->req;
bleft = b->l;
bleft = b->i;
data = (const unsigned char *)b->w;
if (!bleft)
@ -187,7 +187,7 @@ acl_fetch_req_ssl_ver(struct proxy *px, struct session *l4, void *l7, int dir,
return 0;
msg_len = 0;
bleft = l4->req->l;
bleft = l4->req->i;
if (!bleft)
goto too_short;
@ -324,7 +324,7 @@ acl_fetch_ssl_hello_sni(struct proxy *px, struct session *l4, void *l7, int dir,
b = ((dir & ACL_DIR_MASK) == ACL_DIR_RTR) ? l4->rep : l4->req;
bleft = b->l;
bleft = b->i;
data = (unsigned char *)b->w;
/* Check for SSL/TLS Handshake */
@ -459,7 +459,7 @@ acl_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
test->flags = 0;
bleft = l4->req->l;
bleft = l4->req->i;
if (bleft <= 11)
goto too_short;

View File

@ -257,8 +257,8 @@ struct server *get_server_ph_post(struct session *s)
const char *params = req->data + msg->sov;
const char *p = params;
if (len > req->l - (msg->sov - msg->som))
len = req->l - (msg->sov - msg->som);
if (len > req->i - (msg->sov - msg->som))
len = req->i - (msg->sov - msg->som);
if (len == 0)
return NULL;
@ -1112,13 +1112,13 @@ int tcp_persist_rdp_cookie(struct session *s, struct buffer *req, int an_bit)
struct sockaddr_in addr;
char *p;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
if (s->flags & SN_ASSIGNED)

View File

@ -40,40 +40,43 @@ int init_buffer()
*/
unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
{
unsigned int data_left;
unsigned int new_forward;
unsigned int forwarded;
if (!bytes)
return 0;
data_left = buf->l - buf->o;
if (bytes <= (unsigned long long)data_left) {
if (bytes <= (unsigned long long)buf->i) {
buf->o += bytes;
buf->i -= bytes;
buf->flags &= ~BF_OUT_EMPTY;
return bytes;
}
buf->o += data_left;
forwarded = buf->i;
buf->o += forwarded;
buf->i = 0;
if (buf->o)
buf->flags &= ~BF_OUT_EMPTY;
if (buf->l < buffer_max_len(buf))
if (buf->o < buffer_max_len(buf))
buf->flags &= ~BF_FULL;
else
buf->flags |= BF_FULL;
if (likely(bytes == BUF_INFINITE_FORWARD)) {
buf->to_forward = bytes;
return bytes;
}
/* Note: the case below is the only case where we may return
* a byte count that does not fit into a 32-bit number.
*/
if (likely(buf->to_forward == BUF_INFINITE_FORWARD))
return bytes;
new_forward = buf->to_forward + bytes - data_left;
bytes = data_left; /* at least those bytes were scheduled */
if (likely(bytes == BUF_INFINITE_FORWARD)) {
buf->to_forward = bytes;
return bytes;
}
new_forward = buf->to_forward + bytes - forwarded;
bytes = forwarded; /* at least those bytes were scheduled */
if (new_forward <= buf->to_forward) {
/* integer overflow detected, let's assume no more than 2G at once */
@ -114,7 +117,6 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
return max;
memcpy(buf->r, msg, len);
buf->l += len;
buf->o += len;
buf->r += len;
buf->total += len;
@ -122,7 +124,7 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
buf->r = buf->data;
buf->flags &= ~(BF_OUT_EMPTY|BF_FULL);
if (buf->l >= buffer_max_len(buf))
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
return -1;
@ -145,8 +147,8 @@ int buffer_put_char(struct buffer *buf, char c)
*buf->r = c;
buf->l++;
if (buf->l >= buffer_max_len(buf))
buf->i++;
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
buf->flags |= BF_READ_PARTIAL;
@ -158,6 +160,7 @@ int buffer_put_char(struct buffer *buf, char c)
if (buf->to_forward != BUF_INFINITE_FORWARD)
buf->to_forward--;
buf->o++;
buf->i--;
buf->flags &= ~BF_OUT_EMPTY;
}
@ -181,7 +184,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
return -2;
max = buffer_max_len(buf);
if (unlikely(len > max - buf->l)) {
if (unlikely(len > max - buffer_len(buf))) {
/* we can't write this chunk right now because the buffer is
* almost full or because the block is too large. Return the
* available space or -2 if impossible.
@ -201,7 +204,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
if (len > max)
memcpy(buf->data, blk + max, len - max);
buf->l += len;
buf->i += len;
buf->r += len;
buf->total += len;
if (buf->to_forward) {
@ -212,6 +215,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
buf->to_forward -= fwd;
}
buf->o += fwd;
buf->i -= fwd;
buf->flags &= ~BF_OUT_EMPTY;
}
@ -219,7 +223,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
buf->r -= buf->size;
buf->flags &= ~BF_FULL;
if (buf->l >= buffer_max_len(buf))
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
/* notify that some data was read from the SI into the buffer */
@ -334,7 +338,7 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
if (delta + b->r >= b->data + b->size)
return 0; /* no space left */
if (delta + b->r > b->w && b->w >= b->r && b->l)
if (delta + b->r > b->w && b->w >= b->r && buffer_not_empty(b))
return 0; /* no space left before wrapping data */
/* first, protect the end of the buffer */
@ -347,12 +351,12 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
/* we only move data after the displaced zone */
if (b->r > pos) b->r += delta;
if (b->lr > pos) b->lr += delta;
b->l += delta;
b->i += delta;
b->flags &= ~BF_FULL;
if (b->l == 0)
if (buffer_len(b) == 0)
b->r = b->w = b->lr = b->data;
if (b->l >= buffer_max_len(b))
if (buffer_len(b) >= buffer_max_len(b))
b->flags |= BF_FULL;
return delta;
@ -389,10 +393,10 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len)
/* we only move data after the displaced zone */
if (b->r > pos) b->r += delta;
if (b->lr > pos) b->lr += delta;
b->l += delta;
b->i += delta;
b->flags &= ~BF_FULL;
if (b->l >= buffer_max_len(b))
if (buffer_len(b) >= buffer_max_len(b))
b->flags |= BF_FULL;
return delta;
@ -415,7 +419,7 @@ void buffer_bounce_realign(struct buffer *buf)
return;
from = buf->w;
to_move = buf->l;
to_move = buffer_len(buf);
while (to_move) {
char last, save;
@ -572,11 +576,11 @@ int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc) {
void buffer_dump(FILE *o, struct buffer *b, int from, int to)
{
fprintf(o, "Dumping buffer %p\n", b);
fprintf(o, " data=%p l=%d r=%p w=%p lr=%p\n",
b->data, b->l, b->r, b->w, b->lr);
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);
if (!to || to > b->l)
to = b->l;
if (!to || to > buffer_len(b))
to = buffer_len(b);
fprintf(o, "Dumping contents from byte %d to byte %d\n", from, to);
for (; from < to; from++) {

View File

@ -1540,9 +1540,9 @@ static void cli_io_handler(struct stream_interface *si)
si->ob->wex = TICK_ETERNITY;
out:
DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rql=%d, rqs=%d, rl=%d, rs=%d\n",
DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%d, rqs=%d, rh=%d, rs=%d\n",
__FUNCTION__, __LINE__,
si->state, req->flags, res->flags, req->l, req->o, res->l, res->o);
si->state, req->flags, res->flags, req->i, req->o, res->i, res->o);
if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO)) {
/* check that we have released everything then unregister */
@ -3370,11 +3370,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
chunk_printf(&msg,
" req=%p (f=0x%06x an=0x%x l=%d o=%d pipe=%d fwd=%d)\n"
" req=%p (f=0x%06x an=0x%x i=%d o=%d pipe=%d fwd=%d)\n"
" an_exp=%s",
sess->req,
sess->req->flags, sess->req->analysers,
sess->req->l, sess->req->o,
sess->req->i, sess->req->o,
sess->req->pipe ? sess->req->pipe->data : 0,
sess->req->to_forward,
sess->req->analyse_exp ?
@ -3400,11 +3400,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
sess->req->total);
chunk_printf(&msg,
" res=%p (f=0x%06x an=0x%x l=%d o=%d pipe=%d fwd=%d)\n"
" res=%p (f=0x%06x an=0x%x i=%d o=%d pipe=%d fwd=%d)\n"
" an_exp=%s",
sess->rep,
sess->rep->flags, sess->rep->analysers,
sess->rep->l, sess->rep->o,
sess->rep->i, sess->rep->o,
sess->rep->pipe ? sess->rep->pipe->data : 0,
sess->rep->to_forward,
sess->rep->analyse_exp ?
@ -3544,9 +3544,9 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
curr_sess->task->calls);
chunk_printf(&msg,
" rq[f=%06xh,l=%d,an=%02xh,rx=%s",
" rq[f=%06xh,i=%d,an=%02xh,rx=%s",
curr_sess->req->flags,
curr_sess->req->l,
curr_sess->req->i,
curr_sess->req->analysers,
curr_sess->req->rex ?
human_time(TICKS_TO_MS(curr_sess->req->rex - now_ms),
@ -3565,9 +3565,9 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
TICKS_TO_MS(1000)) : "");
chunk_printf(&msg,
" rp[f=%06xh,l=%d,an=%02xh,rx=%s",
" rp[f=%06xh,i=%d,an=%02xh,rx=%s",
curr_sess->rep->flags,
curr_sess->rep->l,
curr_sess->rep->i,
curr_sess->rep->analysers,
curr_sess->rep->rex ?
human_time(TICKS_TO_MS(curr_sess->rep->rex - now_ms),

View File

@ -253,22 +253,22 @@ int frontend_accept(struct session *s)
int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_bit)
{
char *line = req->data;
char *end = req->data + req->l;
char *end = req->data + req->i;
int len;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
if (req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT))
goto fail;
len = MIN(req->l, 6);
len = MIN(req->i, 6);
if (!len)
goto missing;
@ -277,7 +277,7 @@ int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_
goto fail;
line += 6;
if (req->l < 18) /* shortest possible line */
if (req->i < 18) /* shortest possible line */
goto missing;
if (!memcmp(line, "TCP4 ", 5) != 0) {

View File

@ -1944,7 +1944,7 @@ int http_skip_chunk_crlf(struct buffer *buf, struct http_msg *msg)
ptr = buf->data;
}
if (bytes > buf->l - buf->o)
if (bytes > buf->i)
return 0;
if (*ptr != '\n') {
@ -1972,8 +1972,8 @@ void http_buffer_heavy_realign(struct buffer *buf, struct http_msg *msg)
* - the buffer is in one contiguous block, we move it in-place
* - the buffer is in two blocks, we move it via the swap_buffer
*/
if (buf->l) {
int block1 = buf->l;
if (buf->i) {
int block1 = buf->i;
int block2 = 0;
if (buf->r <= buf->w) {
/* non-contiguous block */
@ -2007,7 +2007,7 @@ void http_buffer_heavy_realign(struct buffer *buf, struct http_msg *msg)
}
buf->flags &= ~BF_FULL;
if (buf->l >= buffer_max_len(buf))
if (buffer_len(buf) >= buffer_max_len(buf))
buf->flags |= BF_FULL;
}
@ -2047,13 +2047,13 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
struct http_msg *msg = &txn->req;
struct hdr_ctx ctx;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
/* we're speaking HTTP here, so let's speak HTTP to the client */
@ -2064,7 +2064,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
* protected area is affected, because we may have to move processed
* data later, which is much more complicated.
*/
if (req->l && msg->msg_state < HTTP_MSG_ERROR) {
if (buffer_not_empty(req) && msg->msg_state < HTTP_MSG_ERROR) {
if ((txn->flags & TX_NOT_FIRST) &&
unlikely((req->flags & BF_FULL) ||
req->r < req->lr ||
@ -2170,7 +2170,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
session_inc_http_err_ctr(s);
proxy_inc_fe_req_ctr(s->fe);
if (msg->err_pos < 0)
msg->err_pos = req->l;
msg->err_pos = req->i;
goto return_bad_req;
}
@ -2592,7 +2592,7 @@ int http_process_req_stat_post(struct stream_interface *si, struct http_txn *txn
si->applet.ctx.stats.st_code = STAT_STATUS_EXCD;
return 1;
}
else if (end_params > req->data + req->l) {
else if (end_params > req->data + req->i) {
/* we need more data */
si->applet.ctx.stats.st_code = STAT_STATUS_NONE;
return 0;
@ -2785,13 +2785,13 @@ int http_process_req_common(struct session *s, struct buffer *req, int an_bit, s
req->analysers &= ~an_bit;
req->analyse_exp = TICK_ETERNITY;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
/* first check whether we have some ACLs set to block this request */
@ -3242,13 +3242,13 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit)
return 0;
}
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
/*
@ -3464,7 +3464,7 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit)
*/
if ((s->listener->options & LI_O_NOQUICKACK) &&
((msg->flags & HTTP_MSGF_TE_CHNK) ||
(msg->body_len > req->l - txn->req.eoh - 2)))
(msg->body_len > req->i - txn->req.eoh - 2)))
setsockopt(s->si[0].fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
#endif
}
@ -3623,7 +3623,7 @@ int http_process_request_body(struct session *s, struct buffer *req, int an_bit)
if (msg->body_len < limit)
limit = msg->body_len;
if (req->l - (msg->sov - msg->som) >= limit) /* we have enough bytes now */
if (req->i - (msg->sov - msg->som) >= limit) /* we have enough bytes now */
goto http_end;
missing_data:
@ -3755,8 +3755,8 @@ void http_end_txn_clean_session(struct session *s)
}
/* don't count other requests' data */
s->logs.bytes_in -= s->req->l - s->req->o;
s->logs.bytes_out -= s->rep->l - s->rep->o;
s->logs.bytes_in -= s->req->i;
s->logs.bytes_out -= s->rep->i;
/* let's do a final log if we need it */
if (s->logs.logwait &&
@ -3775,8 +3775,8 @@ void http_end_txn_clean_session(struct session *s)
s->logs.prx_queue_size = 0; /* we get the number of pending conns before us */
s->logs.srv_queue_size = 0; /* we will get this number soon */
s->logs.bytes_in = s->req->total = s->req->l - s->req->o;
s->logs.bytes_out = s->rep->total = s->rep->l - s->rep->o;
s->logs.bytes_in = s->req->total = s->req->i;
s->logs.bytes_out = s->rep->total = s->rep->i;
if (s->pend_pos)
pendconn_free(s->pend_pos);
@ -3821,7 +3821,7 @@ void http_end_txn_clean_session(struct session *s)
* because the request will wait for it to flush a little
* bit before proceeding.
*/
if (s->req->l > s->req->o) {
if (s->req->i) {
if (s->rep->o &&
!(s->rep->flags & BF_FULL) &&
s->rep->r <= s->rep->data + s->rep->size - global.tune.maxrewrite)
@ -4087,7 +4087,7 @@ int http_sync_res_state(struct session *s)
if (txn->rsp.msg_state == HTTP_MSG_CLOSED) {
http_msg_closed:
/* drop any pending data */
buffer_ignore(buf, buf->l - buf->o);
buffer_ignore(buf, buf->i);
buffer_auto_close(buf);
buffer_auto_read(buf);
goto wait_other_side;
@ -4153,7 +4153,7 @@ int http_resync_states(struct session *s)
buffer_abort(s->req);
buffer_auto_close(s->req);
buffer_auto_read(s->req);
buffer_ignore(s->req, s->req->l - s->req->o);
buffer_ignore(s->req, s->req->i);
}
else if (txn->req.msg_state == HTTP_MSG_CLOSED &&
txn->rsp.msg_state == HTTP_MSG_DONE &&
@ -4459,13 +4459,13 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
int cur_idx;
int n;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
rep,
rep->rex, rep->wex,
rep->flags,
rep->l,
rep->i,
rep->analysers);
/*
@ -4490,7 +4490,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
* protected area is affected, because we may have to move processed
* data later, which is much more complicated.
*/
if (rep->l && msg->msg_state < HTTP_MSG_ERROR) {
if (buffer_not_empty(rep) && msg->msg_state < HTTP_MSG_ERROR) {
if (unlikely((rep->flags & BF_FULL) ||
rep->r < rep->lr ||
rep->r > rep->data + rep->size - global.tune.maxrewrite)) {
@ -4502,7 +4502,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
return 0;
}
if (rep->l <= rep->size - global.tune.maxrewrite)
if (rep->i <= rep->size - global.tune.maxrewrite)
http_buffer_heavy_realign(rep, msg);
}
@ -4565,7 +4565,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0;
txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->o);
buffer_ignore(rep, rep->i);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK))
@ -4579,7 +4579,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
/* too large response does not fit in buffer. */
else if (rep->flags & BF_FULL) {
if (msg->err_pos < 0)
msg->err_pos = rep->l;
msg->err_pos = rep->i;
goto hdr_response_bad;
}
@ -4598,7 +4598,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0;
txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->o);
buffer_ignore(rep, rep->i);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK))
@ -4623,7 +4623,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0;
txn->status = 504;
rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->o);
buffer_ignore(rep, rep->i);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_504));
if (!(s->flags & SN_ERR_MASK))
@ -4648,7 +4648,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0;
txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->o);
buffer_ignore(rep, rep->i);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK))
@ -4889,13 +4889,13 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s
struct proxy *cur_proxy;
struct cond_wordlist *wl;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
t,
rep,
rep->rex, rep->wex,
rep->flags,
rep->l,
rep->i,
rep->analysers);
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
@ -4998,7 +4998,7 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s
rep->analysers = 0;
txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->o);
buffer_ignore(rep, rep->i);
stream_int_retnclose(rep->cons, error_message(t, HTTP_ERR_502));
if (!(t->flags & SN_ERR_MASK))
t->flags |= SN_ERR_PRXCOND;
@ -7456,9 +7456,9 @@ void http_reset_txn(struct session *s)
* a HEAD with some data, or sending more than the advertised
* content-length.
*/
if (unlikely(s->rep->l > s->rep->o)) {
s->rep->l = s->rep->o;
s->rep->r = s->rep->w + s->rep->l;
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;
}

View File

@ -669,13 +669,13 @@ int tcp_inspect_request(struct session *s, struct buffer *req, int an_bit)
struct stktable *t;
int partial;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
/* We don't know whether we have enough data, so must proceed
@ -787,13 +787,13 @@ int tcp_inspect_response(struct session *s, struct buffer *rep, int an_bit)
struct tcp_rule *rule;
int partial;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
rep,
rep->rex, rep->wex,
rep->flags,
rep->l,
rep->i,
rep->analysers);
/* We don't know whether we have enough data, so must proceed
@ -1477,10 +1477,10 @@ pattern_fetch_payloadlv(struct proxy *px, struct session *l4, void *l7, int dir,
b = (dir & PATTERN_FETCH_RTR) ? l4->rep : l4->req;
if (!b || !b->l)
if (!b || !b->i)
return 0;
if (len_offset + len_size > b->l)
if (len_offset + len_size > b->i)
return 0;
for (i = 0; i < len_size; i++) {
@ -1490,7 +1490,7 @@ pattern_fetch_payloadlv(struct proxy *px, struct session *l4, void *l7, int dir,
if (!buf_size)
return 0;
if (buf_offset + buf_size > b->l)
if (buf_offset + buf_size > b->i)
return 0;
/* init chunk as read only */
@ -1550,10 +1550,10 @@ pattern_fetch_payload(struct proxy *px, struct session *l4, void *l7, int dir,
b = (dir & PATTERN_FETCH_RTR) ? l4->rep : l4->req;
if (!b || !b->l)
if (!b || !b->i)
return 0;
if (buf_offset + buf_size > b->l)
if (buf_offset + buf_size > b->i)
return 0;
/* init chunk as read only */

View File

@ -725,13 +725,13 @@ static void sess_update_stream_int(struct session *s, struct stream_interface *s
{
struct server *srv = target_srv(&s->target);
DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rql=%d rpl=%d cs=%d ss=%d\n",
DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d\n",
now_ms, __FUNCTION__,
s,
s->req, s->rep,
s->req->rex, s->rep->wex,
s->req->flags, s->rep->flags,
s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state);
s->req->i, s->req->o, s->rep->i, s->rep->o, s->rep->cons->state, s->req->cons->state);
if (si->state == SI_ST_ASS) {
/* Server assigned to connection request, we have to try to connect now */
@ -911,14 +911,15 @@ static void sess_set_term_flags(struct session *s)
* indicating that a server has been assigned. It may also return SI_ST_QUE,
* or SI_ST_CLO upon error.
*/
static void sess_prepare_conn_req(struct session *s, struct stream_interface *si) {
DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rql=%d rpl=%d cs=%d ss=%d\n",
static void sess_prepare_conn_req(struct session *s, struct stream_interface *si)
{
DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d\n",
now_ms, __FUNCTION__,
s,
s->req, s->rep,
s->req->rex, s->rep->wex,
s->req->flags, s->rep->flags,
s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state);
s->req->i, s->req->o, s->rep->i, s->rep->o, s->rep->cons->state, s->req->cons->state);
if (si->state != SI_ST_REQ)
return;
@ -961,13 +962,13 @@ static int process_switching_rules(struct session *s, struct buffer *req, int an
req->analysers &= ~an_bit;
req->analyse_exp = TICK_ETERNITY;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
/* now check whether we have some switching rules for this request */
@ -1062,7 +1063,7 @@ static int process_server_rules(struct session *s, struct buffer *req, int an_bi
req,
req->rex, req->wex,
req->flags,
req->l,
req->i + req->o,
req->analysers);
if (!(s->flags & SN_ASSIGNED)) {
@ -1105,13 +1106,13 @@ static int process_sticking_rules(struct session *s, struct buffer *req, int an_
struct proxy *px = s->be;
struct sticking_rule *rule;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
req,
req->rex, req->wex,
req->flags,
req->l,
req->i,
req->analysers);
list_for_each_entry(rule, &px->sticking_rules, list) {
@ -1195,13 +1196,13 @@ static int process_store_rules(struct session *s, struct buffer *rep, int an_bit
struct sticking_rule *rule;
int i;
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__,
s,
rep,
rep->rex, rep->wex,
rep->flags,
rep->l,
rep->i,
rep->analysers);
list_for_each_entry(rule, &px->storersp_rules, list) {
@ -1435,14 +1436,14 @@ struct task *process_session(struct task *t)
/* Check for connection closure */
DPRINTF(stderr,
"[%u] %s:%d: task=%p s=%p, sfl=0x%08x, rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rql=%d rpl=%d cs=%d ss=%d, cet=0x%x set=0x%x retr=%d\n",
"[%u] %s:%d: task=%p s=%p, sfl=0x%08x, rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rqh=%d rqt=%d rph=%d rpt=%d cs=%d ss=%d, cet=0x%x set=0x%x retr=%d\n",
now_ms, __FUNCTION__, __LINE__,
t,
s, s->flags,
s->req, s->rep,
s->req->rex, s->rep->wex,
s->req->flags, s->rep->flags,
s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state,
s->req->i, s->req->o, s->rep->i, s->rep->o, s->rep->cons->state, s->req->cons->state,
s->rep->cons->err_type, s->req->cons->err_type,
s->req->cons->conn_retries);

View File

@ -85,7 +85,7 @@ static int stream_sock_splice_in(struct buffer *b, struct stream_interface *si)
if (!(b->flags & BF_KERN_SPLICING))
return -1;
if (b->l) {
if (buffer_not_empty(b)) {
/* We're embarrassed, there are already data pending in
* the buffer and we don't want to have them at two
* locations at a time. Let's indicate we need some
@ -269,7 +269,7 @@ int stream_sock_read(int fd) {
#endif
cur_read = 0;
while (1) {
max = buffer_max_len(b) - b->l;
max = buffer_max_len(b) - buffer_len(b);
if (max <= 0) {
b->flags |= BF_FULL;
@ -280,7 +280,7 @@ int stream_sock_read(int fd) {
/*
* 1. compute the maximum block size we can read at once.
*/
if (b->l == 0) {
if (buffer_empty(b)) {
/* let's realign the buffer to optimize I/O */
b->r = b->w = b->lr = b->data;
}
@ -298,7 +298,7 @@ int stream_sock_read(int fd) {
if (ret > 0) {
b->r += ret;
b->l += ret;
b->i += ret;
cur_read += ret;
/* if we're allowed to directly forward data, we must update ->o */
@ -310,6 +310,7 @@ int stream_sock_read(int fd) {
b->to_forward -= fwd;
}
b->o += fwd;
b->i -= fwd;
b->flags &= ~BF_OUT_EMPTY;
}
@ -324,11 +325,11 @@ int stream_sock_read(int fd) {
b->total += ret;
if (b->l >= buffer_max_len(b)) {
if (buffer_len(b) >= buffer_max_len(b)) {
/* The buffer is now full, there's no point in going through
* the loop again.
*/
if (!(b->flags & BF_STREAMER_FAST) && (cur_read == b->l)) {
if (!(b->flags & BF_STREAMER_FAST) && (cur_read == buffer_len(b))) {
b->xfer_small = 0;
b->xfer_large++;
if (b->xfer_large >= 3) {
@ -446,7 +447,7 @@ int stream_sock_read(int fd) {
* HTTP chunking).
*/
if (b->pipe || /* always try to send spliced data */
(b->o == b->l && (b->cons->flags & SI_FL_WAIT_DATA))) {
(b->i == 0 && (b->cons->flags & SI_FL_WAIT_DATA))) {
int last_len = b->pipe ? b->pipe->data : 0;
b->cons->chk_snd(b->cons);
@ -624,7 +625,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) ||
(b->flags & BF_EXPECT_MORE))) ||
((b->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK)) == BF_SHUTW_NOW && (max == b->o)) ||
(max != b->l && max != b->o)) {
(max != b->o)) {
send_flag |= MSG_MORE;
}
@ -654,15 +655,14 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
if (b->w == b->data + b->size)
b->w = b->data; /* wrap around the buffer */
b->l -= ret;
if (likely(b->l < buffer_max_len(b)))
b->flags &= ~BF_FULL;
if (likely(!b->l))
b->o -= ret;
if (likely(!buffer_len(b)))
/* optimize data alignment in the buffer */
b->r = b->w = b->lr = b->data;
b->o -= ret;
if (likely(buffer_len(b) < buffer_max_len(b)))
b->flags &= ~BF_FULL;
if (!b->o) {
/* Always clear both flags once everything has been sent, they're one-shot */
b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT);
@ -939,13 +939,13 @@ void stream_sock_data_finish(struct stream_interface *si)
struct buffer *ob = si->ob;
int fd = si->fd;
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibl=%d obl=%d si=%d\n",
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibh=%d ibt=%d obh=%d obd=%d si=%d\n",
now_ms, __FUNCTION__,
fd, fdtab[fd].owner,
ib, ob,
ib->rex, ob->wex,
ib->flags, ob->flags,
ib->l, ob->l, si->state);
ib->i, ib->o, ob->i, ob->o, si->state);
/* Check if we need to close the read side */
if (!(ib->flags & BF_SHUTR)) {
@ -1017,13 +1017,13 @@ void stream_sock_chk_rcv(struct stream_interface *si)
{
struct buffer *ib = si->ib;
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibl=%d obl=%d si=%d\n",
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibh=%d ibt=%d obh=%d obd=%d si=%d\n",
now_ms, __FUNCTION__,
si->fd, fdtab[si->fd].owner,
ib, si->ob,
ib->rex, si->ob->wex,
ib->flags, si->ob->flags,
ib->l, si->ob->l, si->state);
ib->i, ib->o, si->ob->i, si->ob->o, si->state);
if (unlikely(si->state != SI_ST_EST || (ib->flags & BF_SHUTR)))
return;
@ -1052,13 +1052,13 @@ void stream_sock_chk_snd(struct stream_interface *si)
struct buffer *ob = si->ob;
int retval;
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibl=%d obl=%d si=%d\n",
DPRINTF(stderr,"[%u] %s: fd=%d owner=%p ib=%p, ob=%p, exp(r,w)=%u,%u ibf=%08x obf=%08x ibh=%d ibt=%d obh=%d obd=%d si=%d\n",
now_ms, __FUNCTION__,
si->fd, fdtab[si->fd].owner,
si->ib, ob,
si->ib->rex, ob->wex,
si->ib->flags, ob->flags,
si->ib->l, ob->l, si->state);
si->ib->i, si->ib->o, ob->i, ob->o, si->state);
if (unlikely(si->state != SI_ST_EST || (ob->flags & BF_SHUTW)))
return;