MEDIUM: h2: update to the new buffer API

There is no more distinction between ->i and ->o for the mux's buffers,
we always use b_data() to know the buffer's length since only one side
is used for each direction.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 934c949..46d69bb 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -239,7 +239,7 @@
  */
 static inline int h2_recv_allowed(const struct h2c *h2c)
 {
-	if (h2c->dbuf->i == 0 &&
+	if (b_data(h2c->dbuf) == 0 &&
 	    (h2c->st0 >= H2_CS_ERROR ||
 	     h2c->conn->flags & CO_FL_ERROR ||
 	     conn_xprt_read0_pending(h2c->conn)))
@@ -556,11 +556,11 @@
 {
 	uint64_t w;
 
-	if (b->i < 9)
+	if (b_data(b) < 9)
 		return 0;
 
 	w = h2_get_n64(b, 1);
-	h->len = *b->p << 16;
+	h->len = *(uint8_t*)b_head(b) << 16;
 	h->sid = w & 0x7FFFFFFF; /* RFC7540#4.1: R bit must be ignored */
 	h->ff = w >> 32;
 	h->ft = w >> 40;
@@ -752,7 +752,7 @@
 	int ret1;
 	int ret2;
 
-	ret1 = b_isteq(h2c->dbuf, 0, h2c->dbuf->i, 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))
@@ -1109,7 +1109,7 @@
 	}
 
 	/* process full frame only */
-	if (h2c->dbuf->i < h2c->dfl)
+	if (b_data(h2c->dbuf) < h2c->dfl)
 		return 0;
 
 	/* parse the frame */
@@ -1302,7 +1302,7 @@
 	char str[17];
 	int ret = -1;
 
-	if (h2c->dbuf->i < 8)
+	if (b_data(h2c->dbuf) < 8)
 		return 0;
 
 	if (h2c_mux_busy(h2c, NULL)) {
@@ -1355,7 +1355,7 @@
 	}
 
 	/* process full frame only */
-	if (h2c->dbuf->i < h2c->dfl)
+	if (b_data(h2c->dbuf) < h2c->dfl)
 		return 0;
 
 	inc = h2_get_n32(h2c->dbuf, 0);
@@ -1441,7 +1441,7 @@
 	}
 
 	/* process full frame only */
-	if (h2c->dbuf->i < h2c->dfl)
+	if (b_data(h2c->dbuf) < h2c->dfl)
 		return 0;
 
 	last = h2_get_n32(h2c->dbuf, 0);
@@ -1475,7 +1475,7 @@
 	}
 
 	/* process full frame only */
-	if (h2c->dbuf->i < h2c->dfl)
+	if (b_data(h2c->dbuf) < h2c->dfl)
 		return 0;
 
 	if (h2_get_n32(h2c->dbuf, 0) == h2c->dsi) {
@@ -1509,7 +1509,7 @@
 	}
 
 	/* process full frame only */
-	if (h2c->dbuf->i < h2c->dfl)
+	if (b_data(h2c->dbuf) < h2c->dfl)
 		return 0;
 
 	/* late RST, already handled */
@@ -1550,10 +1550,10 @@
 		goto strm_err;
 	}
 
-	if (!h2c->dbuf->size)
+	if (!b_size(h2c->dbuf))
 		return 0; // empty buffer
 
-	if (h2c->dbuf->i < h2c->dfl && h2c->dbuf->i < h2c->dbuf->size)
+	if (b_data(h2c->dbuf) < h2c->dfl && !b_full(h2c->dbuf))
 		return 0; // incomplete frame
 
 	if (h2c->flags & H2_CF_DEM_TOOMANY)
@@ -1636,10 +1636,10 @@
 	 * to signal an end of stream (with the ES flag).
 	 */
 
-	if (!h2c->dbuf->size && h2c->dfl)
+	if (!b_size(h2c->dbuf) && h2c->dfl)
 		return 0; // empty buffer
 
-	if (h2c->dbuf->i < h2c->dfl && h2c->dbuf->i < h2c->dbuf->size)
+	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 */
@@ -1768,7 +1768,7 @@
 	}
 
 	/* process as many incoming frames as possible below */
-	while (h2c->dbuf->i) {
+	while (b_data(h2c->dbuf)) {
 		int ret = 0;
 
 		if (h2c->st0 >= H2_CS_ERROR)
@@ -1900,7 +1900,7 @@
 		 * the one advertised in GOAWAY. RFC7540#6.8.
 		 */
 		if (unlikely(h2c->last_sid >= 0) && h2c->dsi > h2c->last_sid) {
-			ret = MIN(h2c->dbuf->i, h2c->dfl);
+			ret = MIN(b_data(h2c->dbuf), h2c->dfl);
 			b_del(h2c->dbuf, ret);
 			h2c->dfl -= ret;
 			ret = h2c->dfl == 0;
@@ -1980,7 +1980,7 @@
 			 * the buffer so we drain all of their contents until
 			 * we reach the end.
 			 */
-			ret = MIN(h2c->dbuf->i, h2c->dfl);
+			ret = MIN(b_data(h2c->dbuf), h2c->dfl);
 			b_del(h2c->dbuf, ret);
 			h2c->dfl -= ret;
 			ret = h2c->dfl == 0;
@@ -2151,17 +2151,16 @@
 		return;
 	}
 
-	/* note: buf->o == 0 */
-	max = buf->size - buf->i;
+	max = buf->size - b_data(buf);
 	if (max)
 		conn->xprt->rcv_buf(conn, buf, max, 0);
 
-	if (!buf->i) {
+	if (!b_data(buf)) {
 		h2_release_buf(h2c, &h2c->dbuf);
 		return;
 	}
 
-	if (buf->i == buf->size)
+	if (b_data(buf) == buf->size)
 		h2c->flags |= H2_CF_DEM_DFULL;
 	return;
 }
@@ -2213,8 +2212,8 @@
 		if (h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))
 			flags |= CO_SFL_MSG_MORE;
 
-		if (h2c->mbuf->o) {
-			int ret = conn->xprt->snd_buf(conn, h2c->mbuf, h2c->mbuf->o, 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);
@@ -2227,7 +2226,7 @@
 
 	if (conn->flags & CO_FL_SOCK_WR_SH) {
 		/* output closed, nothing to send, clear the buffer to release it */
-		h2c->mbuf->o = 0;
+		b_reset(h2c->mbuf);
 	}
 }
 
@@ -2240,13 +2239,13 @@
 	struct h2c *h2c = conn->mux_ctx;
 	struct session *sess = conn->owner;
 
-	if (h2c->dbuf->i && !(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)
-			h2c->dbuf->i = 0;
+			b_reset(h2c->dbuf);
 
-		if (h2c->dbuf->i != h2c->dbuf->size)
+		if (!b_full(h2c->dbuf))
 			h2c->flags &= ~H2_CF_DEM_DFULL;
 	}
 
@@ -2303,7 +2302,7 @@
 		}
 	}
 
-	if (!h2c->dbuf->i)
+	if (!b_data(h2c->dbuf))
 		h2_release_buf(h2c, &h2c->dbuf);
 
 	/* stop being notified of incoming data if we can't process them */
@@ -2317,7 +2316,7 @@
 	/* adjust output polling */
 	if (!(conn->flags & CO_FL_SOCK_WR_SH) &&
 	    (h2c->st0 == H2_CS_ERROR ||
-	     h2c->mbuf->o ||
+	     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);
@@ -2328,7 +2327,7 @@
 	}
 
 	if (h2c->task) {
-		if (eb_is_empty(&h2c->streams_by_id) || h2c->mbuf->o) {
+		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);
 		}
@@ -2364,7 +2363,7 @@
 	h2c_error(h2c, H2_ERR_NO_ERROR);
 	h2_wake_some_streams(h2c, 0, 0);
 
-	if (h2c->mbuf->o) {
+	if (b_data(h2c->mbuf)) {
 		/* don't even try to send a GOAWAY, the buffer is stuck */
 		h2c->flags |= H2_CF_GOAWAY_FAILED;
 	}
@@ -2374,8 +2373,8 @@
 	if (h2c_send_goaway_error(h2c, NULL) <= 0)
 		h2c->flags |= H2_CF_GOAWAY_FAILED;
 
-	if (h2c->mbuf->o && !(h2c->flags & H2_CF_GOAWAY_FAILED) && conn_xprt_ready(h2c->conn)) {
-		int ret = h2c->conn->xprt->snd_buf(h2c->conn, h2c->mbuf, h2c->mbuf->o, 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);
@@ -2437,7 +2436,7 @@
 	if (cs->flags & CS_FL_DATA_WR_ENA) {
 		if (LIST_ISEMPTY(&h2s->list)) {
 			if (LIST_ISEMPTY(&h2s->h2c->send_list) &&
-			    !h2s->h2c->mbuf->o && // 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);
@@ -2450,7 +2449,7 @@
 	}
 
 	/* this can happen from within si_chk_snd() */
-	if (h2s->h2c->mbuf->o && !(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);
 }
 
@@ -2507,14 +2506,14 @@
 	    ((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) ||
-	     (!h2c->mbuf->o &&  /* 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) || h2c->mbuf->o) {
+		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);
 		}
@@ -2547,7 +2546,7 @@
 	    h2c_send_goaway_error(h2s->h2c, h2s) <= 0)
 		goto add_to_list;
 
-	if (h2s->h2c->mbuf->o && !(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);
@@ -2597,7 +2596,7 @@
 		h2s_close(h2s);
 	}
 
-	if (h2s->h2c->mbuf->o && !(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:
@@ -2617,7 +2616,7 @@
 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 *)h2c->dbuf->p;
+	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;
@@ -2633,19 +2632,19 @@
 		return 0;
 	}
 
-	if (h2c->dbuf->i < h2c->dfl && h2c->dbuf->i < h2c->dbuf->size)
+	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 = h2c->dbuf->data + h2c->dbuf->size - h2c->dbuf->p;
+	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, h2c->dbuf->p, wrap);
-		memcpy(copy->str + wrap, h2c->dbuf->data, 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;
 	}
 
@@ -2703,15 +2702,10 @@
 		b_slow_realign(buf, trash.str, 0);
 	}
 
-	/* first check if we have some room after p+i */
-	try = buf->data + buf->size - (buf->p + buf->i);
+	try = b_contig_space(buf);
+	if (!try)
+		goto fail;
 
-	/* otherwise continue between data and p-o */
-	if (try <= 0) {
-		try = buf->p - (buf->data + buf->o);
-		if (try <= 0)
-			goto fail;
-	}
 	if (try > count)
 		try = count;
 
@@ -2789,7 +2783,7 @@
 	 * after data. padlen+data+padding are included in flen.
 	 */
 	if (h2c->dff & H2_F_DATA_PADDED) {
-		if (h2c->dbuf->i < 1)
+		if (b_data(h2c->dbuf) < 1)
 			return 0;
 
 		h2c->dpl = *(uint8_t *)b_head(h2c->dbuf);
@@ -2810,8 +2804,8 @@
 	if (!flen)
 		goto end_transfer;
 
-	if (flen > h2c->dbuf->i) {
-		flen = h2c->dbuf->i;
+	if (flen > b_data(h2c->dbuf)) {
+		flen = b_data(h2c->dbuf);
 		if (!flen)
 			return 0;
 	}
@@ -2932,7 +2926,7 @@
 	if (h2c->dsi != h2s->id)
 		return 0; // not for us
 
-	if (!h2c->dbuf->size)
+	if (!b_size(h2c->dbuf))
 		return 0; // empty buffer
 
 	switch (h2c->dft) {
@@ -3007,7 +3001,7 @@
 		if (outbuf.size >= 9 || !b_space_wraps(h2c->mbuf))
 			break;
 	realign_again:
-		b_slow_realign(h2c->mbuf, trash.str, h2c->mbuf->o);
+		b_slow_realign(h2c->mbuf, trash.str, b_data(h2c->mbuf));
 	}
 
 	if (outbuf.size < 9) {
@@ -3090,8 +3084,7 @@
 	max -= ret;
 
 	/* commit the H2 response */
-	h2c->mbuf->p = b_peek(h2c->mbuf, h2c->mbuf->o + outbuf.len);
-	bo_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
@@ -3165,7 +3158,7 @@
 		if (outbuf.size >= 9 || !b_space_wraps(h2c->mbuf))
 			break;
 	realign_again:
-		b_slow_realign(h2c->mbuf, trash.str, h2c->mbuf->o);
+		b_slow_realign(h2c->mbuf, trash.str, b_data(h2c->mbuf));
 	}
 
 	if (outbuf.size < 9) {
@@ -3336,8 +3329,7 @@
 		outbuf.str[4] |= H2_F_DATA_END_STREAM;
 
 	/* commit the H2 response */
-	h2c->mbuf->p = b_peek(h2c->mbuf, h2c->mbuf->o + size + 9);
-	bo_add(h2c->mbuf, size + 9);
+	b_add(h2c->mbuf, size + 9);
 
 	/* consume incoming H1 response */
 	if (size > 0) {
@@ -3373,7 +3365,7 @@
 	}
 
  end:
-	trace("[%d] sent simple H2 DATA response (sid=%d) = %d bytes out (%u in, st=%s, ep=%u, es=%s, h2cws=%d h2sws=%d) buf->o=%u", h2c->st0, h2s->id, size+9, (unsigned int)total, h1_msg_state_str(h1m->state), h1m->err_pos, h1_msg_state_str(h1m->err_state), h2c->mws, h2s->mws, (unsigned int)buf->o);
+	trace("[%d] sent simple H2 DATA response (sid=%d) = %d bytes out (%u in, st=%s, ep=%u, es=%s, h2cws=%d h2sws=%d) data=%u", h2c->st0, h2s->id, size+9, (unsigned int)total, h1_msg_state_str(h1m->state), h1m->err_pos, h1_msg_state_str(h1m->err_state), h2c->mws, h2s->mws, (unsigned int)b_data(buf));
 	return total;
 }
 
@@ -3484,7 +3476,7 @@
 	}
 
 	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)h2c->dbuf->i, (unsigned int)h2c->dbuf->size, (unsigned int)h2c->mbuf->o, (unsigned int)h2c->mbuf->size);
+		      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));
 }
 
 /*******************************************************/