#define H2_CF_DEM_DALLOC 0x00000004 // demux blocked on lack of connection's demux buffer
#define H2_CF_DEM_DFULL 0x00000008 // demux blocked on connection's demux buffer full
-#define H2_CF_DEM_MBUSY 0x00000010 // demux blocked on connection's mux side busy
+/* 0x00000010 unused */
#define H2_CF_DEM_MROOM 0x00000020 // demux blocked on lack of room in mux buffer
#define H2_CF_DEM_SALLOC 0x00000040 // demux blocked on lack of stream's request buffer
#define H2_CF_DEM_SFULL 0x00000080 // demux blocked on stream request buffer full
#define H2_CF_DEM_TOOMANY 0x00000100 // demux blocked waiting for some stream connectors to leave
-#define H2_CF_DEM_BLOCK_ANY 0x000001F0 // aggregate of the demux flags above except DALLOC/DFULL
+#define H2_CF_DEM_BLOCK_ANY 0x000001E0 // aggregate of the demux flags above except DALLOC/DFULL
// (SHORT_READ is also excluded)
#define H2_CF_DEM_SHORT_READ 0x00000200 // demux blocked on incomplete frame
_(0);
/* flags */
_(H2_CF_MUX_MALLOC, _(H2_CF_MUX_MFULL, _(H2_CF_DEM_DALLOC,
- _(H2_CF_DEM_DFULL, _(H2_CF_DEM_MBUSY, _(H2_CF_DEM_MROOM,
+ _(H2_CF_DEM_DFULL, _(H2_CF_DEM_MROOM,
_(H2_CF_DEM_SALLOC, _(H2_CF_DEM_SFULL, _(H2_CF_DEM_TOOMANY,
_(H2_CF_DEM_SHORT_READ, _(H2_CF_DEM_IN_PROGRESS, _(H2_CF_GOAWAY_SENT,
_(H2_CF_GOAWAY_FAILED, _(H2_CF_WAIT_FOR_HS, _(H2_CF_IS_BACK,
_(H2_CF_WINDOW_OPENED, _(H2_CF_RCVD_SHUT, _(H2_CF_END_REACHED,
_(H2_CF_RCVD_RFC8441, _(H2_CF_SHTS_UPDATED, _(H2_CF_DTSU_EMITTED,
- _(H2_CF_ERR_PENDING, _(H2_CF_ERROR)))))))))))))))))))))));
+ _(H2_CF_ERR_PENDING, _(H2_CF_ERROR))))))))))))))))))))));
/* epilogue */
_(~0U);
return buf;
/* states for the mux direction */
struct buffer mbuf[H2C_MBUF_CNT]; /* mux buffers (ring) */
- int32_t msi; /* mux stream ID (<0 = idle) */
- int32_t mfl; /* mux frame length (if dsi >= 0) */
- int8_t mft; /* mux frame type (if dsi >= 0) */
- int8_t mff; /* mux frame flags (if dsi >= 0) */
- /* 16 bit hole here */
int32_t miw; /* mux initial window size for all new streams */
int32_t mws; /* mux window size. Can be negative. */
int32_t mfs; /* mux's max frame size */
h2c->dbuf = *input;
h2c->dsi = -1;
- h2c->msi = -1;
h2c->last_sid = -1;
return h2s->sws + h2s->h2c->miw;
}
-/* returns true of the mux is currently busy as seen from stream <h2s> */
-static inline __maybe_unused int h2c_mux_busy(const struct h2c *h2c, const struct h2s *h2s)
-{
- if (h2c->msi < 0)
- return 0;
-
- if (h2c->msi == h2s_id(h2s))
- return 0;
-
- return 1;
-}
-
/* marks an error on the connection. Before settings are sent, we must not send
* a GOAWAY frame, and the error state will prevent h2c_send_goaway_error()
* from verifying this so we set H2_CF_GOAWAY_FAILED to make sure it will not
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_SETTINGS, h2c->conn);
- if (h2c_mux_busy(h2c, NULL)) {
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
chunk_init(&buf, buf_data, sizeof(buf_data));
chunk_memcpy(&buf,
"\x00\x00\x00" /* length : 0 for now */
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_PREFACE, h2c->conn);
- if (h2c_mux_busy(h2c, NULL)) {
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
res = br_tail(h2c->mbuf);
retry:
if (!h2_get_buf(h2c, res)) {
goto out;
}
- if (h2c_mux_busy(h2c, h2s)) {
- if (h2s)
- h2s->flags |= H2_SF_BLK_MBUSY;
- else
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
/* len: 8, type: 7, flags: none, sid: 0 */
memcpy(str, "\x00\x00\x08\x07\x00\x00\x00\x00\x00", 9);
goto ignore;
}
- if (h2c_mux_busy(h2c, h2s)) {
- h2s->flags |= H2_SF_BLK_MBUSY;
- goto out;
- }
-
/* len: 4, type: 3, flags: none */
memcpy(str, "\x00\x00\x04\x03\x00", 5);
write_n32(str + 5, h2s->id);
goto ignore;
}
- if (h2c_mux_busy(h2c, h2s)) {
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
/* len: 4, type: 3, flags: none */
memcpy(str, "\x00\x00\x04\x03\x00", 5);
goto out;
}
- if (h2c_mux_busy(h2c, h2s)) {
- h2s->flags |= H2_SF_BLK_MBUSY;
- goto out;
- }
-
/* len: 0x000000, type: 0(DATA), flags: ES=1 */
memcpy(str, "\x00\x00\x00\x00\x01", 5);
write_n32(str + 5, h2s->id);
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_SETTINGS, h2c->conn);
- if (h2c_mux_busy(h2c, NULL)) {
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
memcpy(str,
"\x00\x00\x00" /* length : 0 (no data) */
"\x04" "\x01" /* type : 4, flags : ACK */
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_WU, h2c->conn);
- if (h2c_mux_busy(h2c, NULL)) {
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
/* length: 4, type: 8, flags: none */
memcpy(str, "\x00\x00\x04\x08\x00", 5);
write_n32(str + 5, sid);
if (b_data(&h2c->dbuf) < 8)
goto out;
- if (h2c_mux_busy(h2c, NULL)) {
- h2c->flags |= H2_CF_DEM_MBUSY;
- goto out;
- }
-
memcpy(str,
"\x00\x00\x08" /* length : 8 (same payload) */
"\x06" "\x01" /* type : 6, flags : ACK */
}
if (h2c->rcvd_s > 0 &&
- !(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))) {
+ !(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM))) {
TRACE_PROTO("sending stream WINDOW_UPDATE frame", H2_EV_TX_FRAME|H2_EV_TX_WU, h2c->conn, h2s);
h2c_send_strm_wu(h2c);
}
if (h2c->rcvd_c > 0 &&
- !(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))) {
+ !(h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM))) {
TRACE_PROTO("sending H2 WINDOW_UPDATE frame", H2_EV_TX_FRAME|H2_EV_TX_WU, h2c->conn);
h2c_send_conn_wu(h2c);
}
(h2c->flags & H2_CF_GOAWAY_FAILED))
break;
- if (h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))
+ if (h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MROOM))
flags |= CO_SFL_MSG_MORE;
for (buf = br_head(h2c->mbuf); b_size(buf); buf = br_del_head(h2c->mbuf)) {
return;
}
- if ((h2c->flags & H2_CF_DEM_BLOCK_ANY && h2s->id == h2c->dsi) ||
- (h2c->flags & H2_CF_MUX_BLOCK_ANY && h2s->id == h2c->msi)) {
+ if ((h2c->flags & H2_CF_DEM_BLOCK_ANY && h2s->id == h2c->dsi)) {
/* unblock the connection if it was blocked on this
* stream.
*/
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- if (h2c_mux_busy(h2c, h2s)) {
- TRACE_STATE("mux output busy", H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- h2s->flags |= H2_SF_BLK_MBUSY;
- TRACE_LEAVE(H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- return 0;
- }
-
/* get the start line (we do have one) and the rest of the headers,
* that we dump starting at header 0 */
sl = NULL;
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- if (h2c_mux_busy(h2c, h2s)) {
- TRACE_STATE("mux output busy", H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- h2s->flags |= H2_SF_BLK_MBUSY;
- TRACE_LEAVE(H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- return 0;
- }
-
/* get the start line (we do have one) and the rest of the headers,
* that we dump starting at header 0 */
sl = NULL;
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
- if (h2c_mux_busy(h2c, h2s)) {
- TRACE_STATE("mux output busy", H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
- h2s->flags |= H2_SF_BLK_MBUSY;
- TRACE_LEAVE(H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
- goto end;
- }
-
htx = htx_from_buf(buf);
/* We only come here with HTX_BLK_DATA blocks */
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
- if (h2c_mux_busy(h2c, h2s)) {
- TRACE_STATE("mux output busy", H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
- h2s->flags |= H2_SF_BLK_MBUSY;
- TRACE_LEAVE(H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
- goto end;
- }
-
htx = htx_from_buf(buf);
next_data:
TRACE_ENTER(H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- if (h2c_mux_busy(h2c, h2s)) {
- TRACE_STATE("mux output busy", H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- h2s->flags |= H2_SF_BLK_MBUSY;
- TRACE_LEAVE(H2_EV_TX_FRAME|H2_EV_TX_HDR, h2c->conn, h2s);
- goto end;
- }
-
/* get trailers. */
hdr = 0;
for (blk = htx_get_head_blk(htx); blk; blk = htx_get_next_blk(htx, blk)) {
if (pfx)
chunk_appendf(msg, "\n%s", pfx);
- chunk_appendf(msg, " .msi=%d"
- " .mbuf=[%u..%u|%u],h=[%u@%p+%u/%u],t=[%u@%p+%u/%u]",
- h2c->msi,
+ chunk_appendf(msg, " .mbuf=[%u..%u|%u],h=[%u@%p+%u/%u],t=[%u@%p+%u/%u]",
br_head_idx(h2c->mbuf), br_tail_idx(h2c->mbuf), br_size(h2c->mbuf),
(unsigned int)b_data(hmbuf), b_orig(hmbuf),
(unsigned int)b_head_ofs(hmbuf), (unsigned int)b_size(hmbuf),