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.
diff --git a/src/acl.c b/src/acl.c
index 4630743..430f985 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -102,7 +102,7 @@
 	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 @@
 
 	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 @@
 		return 0;
 
 	msg_len = 0;
-	bleft = l4->req->l;
+	bleft = l4->req->i;
 	if (!bleft)
 		goto too_short;
 
@@ -324,7 +324,7 @@
 
 	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 @@
 
 	test->flags = 0;
 
-	bleft = l4->req->l;
+	bleft = l4->req->i;
 	if (bleft <= 11)
 		goto too_short;
 
diff --git a/src/backend.c b/src/backend.c
index 57acbe7..f04e26b 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -257,8 +257,8 @@
 	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 @@
 	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)
diff --git a/src/buffers.c b/src/buffers.c
index 0697d61..74e3a10 100644
--- a/src/buffers.c
+++ b/src/buffers.c
@@ -40,40 +40,43 @@
  */
 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 @@
 		return max;
 
 	memcpy(buf->r, msg, len);
-	buf->l += len;
 	buf->o += len;
 	buf->r += len;
 	buf->total += len;
@@ -122,7 +124,7 @@
 		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 @@
 
 	*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 @@
 		if (buf->to_forward != BUF_INFINITE_FORWARD)
 			buf->to_forward--;
 		buf->o++;
+		buf->i--;
 		buf->flags &= ~BF_OUT_EMPTY;
 	}
 
@@ -181,7 +184,7 @@
 		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 @@
 	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 @@
 			buf->to_forward -= fwd;
 		}
 		buf->o += fwd;
+		buf->i -= fwd;
 		buf->flags &= ~BF_OUT_EMPTY;
 	}
 
@@ -219,7 +223,7 @@
 		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 @@
 	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 @@
 	/* 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 @@
 	/* 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 @@
 		return;
 
 	from = buf->w;
-	to_move = buf->l;
+	to_move = buffer_len(buf);
 	while (to_move) {
 		char last, save;
 
@@ -572,11 +576,11 @@
 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++) {
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 907e2fe..26cbdd6 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -1540,9 +1540,9 @@
 	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 @@
 
 
 		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 @@
 			     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 @@
 				     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 @@
 						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),
diff --git a/src/frontend.c b/src/frontend.c
index e5d847b..c18cc66 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -253,22 +253,22 @@
 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 @@
 		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) {
diff --git a/src/proto_http.c b/src/proto_http.c
index 0b62078..f1167c1 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1944,7 +1944,7 @@
 			ptr = buf->data;
 	}
 
-	if (bytes > buf->l - buf->o)
+	if (bytes > buf->i)
 		return 0;
 
 	if (*ptr != '\n') {
@@ -1972,8 +1972,8 @@
 	 *   - 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 @@
 	}
 
 	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 @@
 	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 @@
 	 * 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 @@
 			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 @@
 		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 @@
 	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 @@
 		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 @@
 		 */
 		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 @@
 	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 @@
 	}
 
 	/* 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 @@
 	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 @@
 	 * 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 @@
 	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 @@
 		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 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 @@
 	 * 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 @@
 				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 @@
 			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 @@
 		/* 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 @@
 			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 @@
 			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 @@
 			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 @@
 	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 @@
 					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 @@
 	 * 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;
 	}
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 2a25420..7a3d714 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -669,13 +669,13 @@
 	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 @@
 	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 @@
 
 	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 @@
 	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 @@
 
 	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 */
diff --git a/src/session.c b/src/session.c
index 66ab81b..86aa28c 100644
--- a/src/session.c
+++ b/src/session.c
@@ -725,13 +725,13 @@
 {
 	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 @@
  * 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 @@
 	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 @@
 		req,
 		req->rex, req->wex,
 		req->flags,
-		req->l,
+		req->i + req->o,
 		req->analysers);
 
 	if (!(s->flags & SN_ASSIGNED)) {
@@ -1105,13 +1106,13 @@
 	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 @@
 	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 @@
 	/* 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);
 
diff --git a/src/stream_sock.c b/src/stream_sock.c
index 36120a1..74fe0b2 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -85,7 +85,7 @@
 	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 @@
 #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 @@
 		/*
 		 * 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 @@
 
 		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 @@
 					b->to_forward -= fwd;
 				}
 				b->o += fwd;
+				b->i -= fwd;
 				b->flags &= ~BF_OUT_EMPTY;
 			}
 
@@ -324,11 +325,11 @@
 
 			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 @@
 	 * 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 @@
 			    ((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 @@
 			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 @@
 	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 @@
 {
 	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 @@
 	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;