#undef _
}
+/* H1 connection state, in h1c->state */
+enum h1_cs {
+ H1_CS_IDLE, /* IDLE connection. A freashly open or a reusable connection (H1S is NULL) */
+ H1_CS_EMBRYONIC, /* Connection is waiting for the message headers (H1S is not NULL, not attached to a SC - Frontend connection only) */
+ H1_CS_UPGRADING, /* TCP>H1 upgrade in-progress (H1S is not NULL and attached to a SC - Frontend connection only) */
+ H1_CS_RUNNING, /* Connection fully established and the H1S is processing data (H1S is not NULL and attached to a SC) */
+ H1_CS_CLOSING, /* Send pending outgoing data and close the connection ASAP (H1S may be NULL) */
+ H1_CS_CLOSED, /* Connection must be closed now and H1C must be released (H1S is NULL) */
+ H1_CS_ENTRIES,
+} __attribute__((packed));
+
+
+/**** tiny state decoding functions for debug helpers ****/
+
+/* returns a h1c state as an abbreviated 3-letter string, or "???" if unknown */
+static inline const char *h1c_st_to_str(enum h1_cs st)
+{
+ switch (st) {
+ case H1_CS_IDLE: return "IDL";
+ case H1_CS_EMBRYONIC: return "EMB";
+ case H1_CS_UPGRADING: return "UPG";
+ case H1_CS_RUNNING: return "RUN";
+ case H1_CS_CLOSING: return "CLI";
+ case H1_CS_CLOSED: return "CLD";
+ default: return "???";
+ }
+}
+
#endif /* _HAPROXY_MUX_H1_T_H */
struct task *task; /* timeout management task */
uint32_t flags; /* Connection flags: H1C_F_* */
+ enum h1_cs state; /* Connection state */
+
struct buffer ibuf; /* Input buffer to store data before parsing */
struct buffer obuf; /* Output buffer to store data after reformatting */
return;
/* Display frontend/backend info by default */
- chunk_appendf(&trace_buf, " : [%c]", ((h1c->flags & H1C_F_IS_BACK) ? 'B' : 'F'));
+ chunk_appendf(&trace_buf, " : [%c,%s]", ((h1c->flags & H1C_F_IS_BACK) ? 'B' : 'F'), h1c_st_to_str(h1c->state));
/* Display request and response states if h1s is defined */
if (h1s) {
}
}
+/* Returns 1 if the H1 connection is alive (IDLE, EMBRYONIC, RUNNING or
+ * RUNNING). Ortherwise 0 is returned.
+ */
+static inline int h1_is_alive(const struct h1c *h1c)
+{
+ return (h1c->state <= H1_CS_RUNNING);
+}
+
+/* Switch the H1 connection to CLOSING or CLOSED mode, depending on the output
+ * buffer state and if there is still a H1 stream or not. If there are sill
+ * pending outgoing data or if there is still a H1 stream, it is set to CLOSING
+ * state. Otherwise it is set to CLOSED mode. */
+static inline void h1_close(struct h1c *h1c)
+{
+ h1c->state = ((h1c->h1s || b_data(&h1c->obuf)) ? H1_CS_CLOSING : H1_CS_CLOSED);
+}
+
/* returns the number of streams in use on a connection to figure if it's idle
* or not. We rely on H1C_F_ST_IDLE to know if the connection is in-use or
* not. This flag is only set when no H1S is attached and when the previous
h1c->conn = conn;
h1c->px = proxy;
+ h1c->state = H1_CS_IDLE;
h1c->flags = H1C_F_ST_IDLE;
h1c->errcode = 0;
h1c->ibuf = *input;