int ret;
res_htx = htx_from_buf(&res->buf);
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
goto out;
/* Check if the input buffer is available. */
*/
static inline int channel_may_send(const struct channel *chn)
{
- return chn_cons(chn)->si->state == SI_ST_EST;
+ return chn_cons(chn)->state == CS_ST_EST;
}
/* HTX version of channel_may_recv(). Returns non-zero if the channel can still
CS_SHW_SILENT = 1, /* imminent close, don't notify peer */
};
+/* A conn stream must have its own errors independently of the buffer's, so that
+ * applications can rely on what the buffer reports while the conn stream is
+ * performing some retries (eg: connection error). Some states are transient and
+ * do not last beyond process_session().
+ */
+enum cs_state {
+ CS_ST_INI = 0, /* CS not sollicitated yet */
+ CS_ST_REQ, /* [transient] connection initiation desired and not started yet */
+ CS_ST_QUE, /* CS waiting in queue */
+ CS_ST_TAR, /* CS in turn-around state after failed connect attempt */
+ CS_ST_ASS, /* server just assigned to this CS */
+ CS_ST_CON, /* initiated connection request (resource exists) */
+ CS_ST_CER, /* [transient] previous connection attempt failed (resource released) */
+ CS_ST_RDY, /* [transient] ready proven after I/O success during CS_ST_CON */
+ CS_ST_EST, /* connection established (resource exists) */
+ CS_ST_DIS, /* [transient] disconnected from other side, but cleanup not done yet */
+ CS_ST_CLO, /* CS closed, might not existing anymore. Buffers shut. */
+} __attribute__((packed));
+
+/* state bits for use with lists of states */
+enum cs_state_bit {
+ CS_SB_NONE = 0,
+ CS_SB_INI = 1U << CS_ST_INI,
+ CS_SB_REQ = 1U << CS_ST_REQ,
+ CS_SB_QUE = 1U << CS_ST_QUE,
+ CS_SB_TAR = 1U << CS_ST_TAR,
+ CS_SB_ASS = 1U << CS_ST_ASS,
+ CS_SB_CON = 1U << CS_ST_CON,
+ CS_SB_CER = 1U << CS_ST_CER,
+ CS_SB_RDY = 1U << CS_ST_RDY,
+ CS_SB_EST = 1U << CS_ST_EST,
+ CS_SB_DIS = 1U << CS_ST_DIS,
+ CS_SB_CLO = 1U << CS_ST_CLO,
+ CS_SB_ALL = CS_SB_INI|CS_SB_REQ|CS_SB_QUE|CS_SB_TAR|CS_SB_ASS|CS_SB_CON|CS_SB_CER|CS_SB_RDY|CS_SB_EST|CS_SB_DIS|CS_SB_CLO,
+};
+
struct conn_stream;
/* data_cb describes the data layer's recv and send callbacks which are called
*/
struct conn_stream {
enum obj_type obj_type; /* differentiates connection from applet context */
- /* 3 bytes hole here */
+ enum cs_state state; /* CS_ST* */
+ /* 2 bytes hole here */
+
unsigned int flags; /* CS_FL_* */
unsigned int hcto; /* half-closed timeout (0 = unset) */
struct cs_endpoint *endp; /* points to the end point (MUX stream or appctx) */
}
-/* to be called only when in SI_ST_DIS with SI_FL_ERR */
+/* to be called only when in CS_ST_DIS with CS_FL_ERR */
static inline void cs_report_error(struct conn_stream *cs)
{
if (!__cs_strm(cs)->conn_err_type)
cs_ic(cs)->flags |= CF_READ_ERROR;
}
+/* sets the current and previous state of a conn-stream to <state>. This is
+ * mainly used to create one in the established state on incoming conncetions.
+ */
+static inline void cs_set_state(struct conn_stream *cs, int state)
+{
+ cs->state = __cs_strm(cs)->prev_conn_state = state;
+}
+
+/* returns a bit for a conn-stream state, to match against CS_SB_* */
+static inline enum cs_state_bit cs_state_bit(enum cs_state state)
+{
+ BUG_ON(state > CS_ST_CLO);
+ return 1U << state;
+}
+
+/* returns true if <state> matches one of the CS_SB_* bits in <mask> */
+static inline int cs_state_in(enum cs_state state, enum cs_state_bit mask)
+{
+ BUG_ON(mask & ~CS_SB_ALL);
+ return !!(cs_state_bit(state) & mask);
+}
+
/* Returns the source address of the conn-stream and, if not set, fallbacks on
* the session for frontend CS and the server connection for the backend CS. It
* returns a const address on success or NULL on failure.
cs->endp->flags |= CS_EP_KILL_CONN;
}
+/* for debugging, reports the stream interface state name */
+static inline const char *cs_state_str(int state)
+{
+ switch (state) {
+ case CS_ST_INI: return "INI";
+ case CS_ST_REQ: return "REQ";
+ case CS_ST_QUE: return "QUE";
+ case CS_ST_TAR: return "TAR";
+ case CS_ST_ASS: return "ASS";
+ case CS_ST_CON: return "CON";
+ case CS_ST_CER: return "CER";
+ case CS_ST_RDY: return "RDY";
+ case CS_ST_EST: return "EST";
+ case CS_ST_DIS: return "DIS";
+ case CS_ST_CLO: return "CLO";
+ default: return "???";
+ }
+}
+
#endif /* _HAPROXY_CS_UTILS_H */
int conn_retries; /* number of connect retries performed */
unsigned int conn_exp; /* wake up time for connect, queue, turn-around, ... */
unsigned int conn_err_type; /* first error detected, one of STRM_ET_* */
- enum si_state prev_conn_state; /* SI_ST*, copy of previous state of the server conn-stream */
+ enum cs_state prev_conn_state; /* CS_ST*, copy of previous state of the server conn-stream */
struct list list; /* position in the thread's streams list */
struct mt_list by_srv; /* position in server stream list */
#define STRM_EV_STRM_ERR (1ULL << 2)
#define STRM_EV_STRM_ANA (1ULL << 3)
#define STRM_EV_STRM_PROC (1ULL << 4)
-#define STRM_EV_SI_ST (1ULL << 5)
+#define STRM_EV_CS_ST (1ULL << 5)
#define STRM_EV_HTTP_ANA (1ULL << 6)
#define STRM_EV_HTTP_ERR (1ULL << 7)
#define STRM_EV_TCP_ANA (1ULL << 8)
static inline void stream_choose_redispatch(struct stream *s)
{
- struct stream_interface *si = cs_si(s->csb);
-
/* If the "redispatch" option is set on the backend, we are allowed to
* retry on another server. By default this redispatch occurs on the
* last retry, but if configured we allow redispatches to occur on
sockaddr_free(&s->csb->dst);
s->flags &= ~(SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET);
- si->state = SI_ST_REQ;
+ s->csb->state = CS_ST_REQ;
} else {
if (objt_server(s->target))
_HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
_HA_ATOMIC_INC(&s->be->be_counters.retries);
- si->state = SI_ST_ASS;
+ s->csb->state = CS_ST_ASS;
}
}
struct conn_stream;
-/* A stream interface must have its own errors independently of the buffer's,
- * so that applications can rely on what the buffer reports while the stream
- * interface is performing some retries (eg: connection error). Some states are
- * transient and do not last beyond process_session().
- */
-enum si_state {
- SI_ST_INI = 0, /* interface not sollicitated yet */
- SI_ST_REQ, /* [transient] connection initiation desired and not started yet */
- SI_ST_QUE, /* interface waiting in queue */
- SI_ST_TAR, /* interface in turn-around state after failed connect attempt */
- SI_ST_ASS, /* server just assigned to this interface */
- SI_ST_CON, /* initiated connection request (resource exists) */
- SI_ST_CER, /* [transient] previous connection attempt failed (resource released) */
- SI_ST_RDY, /* [transient] ready proven after I/O success during SI_ST_CON */
- SI_ST_EST, /* connection established (resource exists) */
- SI_ST_DIS, /* [transient] disconnected from other side, but cleanup not done yet */
- SI_ST_CLO, /* stream intf closed, might not existing anymore. Buffers shut. */
-} __attribute__((packed));
-
-/* state bits for use with lists of states */
-enum si_state_bit {
- SI_SB_NONE = 0,
- SI_SB_INI = 1U << SI_ST_INI,
- SI_SB_REQ = 1U << SI_ST_REQ,
- SI_SB_QUE = 1U << SI_ST_QUE,
- SI_SB_TAR = 1U << SI_ST_TAR,
- SI_SB_ASS = 1U << SI_ST_ASS,
- SI_SB_CON = 1U << SI_ST_CON,
- SI_SB_CER = 1U << SI_ST_CER,
- SI_SB_RDY = 1U << SI_ST_RDY,
- SI_SB_EST = 1U << SI_ST_EST,
- SI_SB_DIS = 1U << SI_ST_DIS,
- SI_SB_CLO = 1U << SI_ST_CLO,
- SI_SB_ALL = SI_SB_INI|SI_SB_REQ|SI_SB_QUE|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY|SI_SB_EST|SI_SB_DIS|SI_SB_CLO,
-};
-
/* flags set after I/O (32 bit) */
enum {
SI_FL_NONE = 0x00000000, /* nothing */
*/
struct stream_interface {
/* struct members used by the "buffer" side */
- enum si_state state; /* SI_ST* */
/* 16-bit hole here */
unsigned int flags; /* SI_FL_* */
struct conn_stream *cs; /* points to the conn-streams that owns the endpoint (connection or applet) */
#include <haproxy/channel.h>
#include <haproxy/connection.h>
#include <haproxy/conn_stream.h>
+#include <haproxy/cs_utils.h>
#include <haproxy/obj_type.h>
extern struct si_ops si_embedded_ops;
return ((si->flags & SI_FL_ISBACK) ? strm->csf->si : strm->csb->si);
}
-/* initializes a stream interface in the SI_ST_INI state and create the event
+/* initializes a stream interface and create the event
* tasklet.
*/
static inline int si_init(struct stream_interface *si)
{
si->flags &= SI_FL_ISBACK;
si->cs = NULL;
- si->state = SI_ST_INI;
si->ops = &si_embedded_ops;
si->wait_event.tasklet = tasklet_new();
if (!si->wait_event.tasklet)
return 0;
}
-/* sets the current and previous state of a stream interface to <state>. This
- * is mainly used to create one in the established state on incoming
- * conncetions.
- */
-static inline void si_set_state(struct stream_interface *si, int state)
-{
- si->state = si_strm(si)->prev_conn_state = state;
-}
-
-/* returns a bit for a stream-int state, to match against SI_SB_* */
-static inline enum si_state_bit si_state_bit(enum si_state state)
-{
- BUG_ON(state > SI_ST_CLO);
- return 1U << state;
-}
-
-/* returns true if <state> matches one of the SI_SB_* bits in <mask> */
-static inline int si_state_in(enum si_state state, enum si_state_bit mask)
-{
- BUG_ON(mask & ~SI_SB_ALL);
- return !!(si_state_bit(state) & mask);
-}
-
/* call the applet's release function if any. Needs to be called upon close() */
static inline void si_applet_release(struct stream_interface *si)
{
struct appctx *appctx;
appctx = __cs_appctx(si->cs);
- if (appctx->applet->release && !si_state_in(si->state, SI_SB_DIS|SI_SB_CLO))
+ if (appctx->applet->release && !cs_state_in(si->cs->state, CS_SB_DIS|CS_SB_CLO))
appctx->applet->release(appctx);
}
*/
static inline void si_chk_rcv(struct stream_interface *si)
{
- if (si->flags & SI_FL_RXBLK_CONN && si_state_in(si_opposite(si)->state, SI_SB_RDY|SI_SB_EST|SI_SB_DIS|SI_SB_CLO))
+ if (si->flags & SI_FL_RXBLK_CONN && cs_state_in(si_opposite(si)->cs->state, CS_SB_RDY|CS_SB_EST|CS_SB_DIS|CS_SB_CLO))
si_rx_conn_rdy(si);
if (si_rx_blocked(si) || !si_rx_endp_ready(si))
return;
- if (!si_state_in(si->state, SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(si->cs->state, CS_SB_RDY|CS_SB_EST))
return;
si->flags |= SI_FL_RX_WAIT_EP;
return ret;
/* we're in the process of establishing a connection */
- si->state = SI_ST_CON;
+ si->cs->state = CS_ST_CON;
}
else {
/* try to reuse the existing connection, it will be
*/
/* Is the connection really ready ? */
if (conn->mux->ctl(conn, MUX_STATUS, NULL) & MUX_STATUS_READY)
- si->state = SI_ST_RDY;
+ si->cs->state = CS_ST_RDY;
else
- si->state = SI_ST_CON;
+ si->cs->state = CS_ST_CON;
}
/* needs src ip/port for logging */
si_update_tx(si);
}
-/* for debugging, reports the stream interface state name */
-static inline const char *si_state_str(int state)
-{
- switch (state) {
- case SI_ST_INI: return "INI";
- case SI_ST_REQ: return "REQ";
- case SI_ST_QUE: return "QUE";
- case SI_ST_TAR: return "TAR";
- case SI_ST_ASS: return "ASS";
- case SI_ST_CON: return "CON";
- case SI_ST_CER: return "CER";
- case SI_ST_RDY: return "RDY";
- case SI_ST_EST: return "EST";
- case SI_ST_DIS: return "DIS";
- case SI_ST_CLO: return "CLO";
- default: return "???";
- }
-}
-
#endif /* _HAPROXY_STREAM_INTERFACE_H */
/*
/* do not reuse if mode is not http */
if (!IS_HTX_STRM(s)) {
- DBG_TRACE_STATE("skip idle connections reuse: no htx", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("skip idle connections reuse: no htx", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
goto skip_reuse;
}
*/
if (unlikely(s->flags & SF_WEBSOCKET) && srv) {
if (!srv_check_reuse_ws(srv)) {
- DBG_TRACE_STATE("skip idle connections reuse: websocket stream", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("skip idle connections reuse: websocket stream", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
goto skip_reuse;
}
}
/* first, search for a matching connection in the session's idle conns */
srv_conn = session_get_conn(s->sess, s->target, hash);
if (srv_conn) {
- DBG_TRACE_STATE("reuse connection from session", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("reuse connection from session", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
reuse = 1;
}
if (!eb_is_empty(&srv->per_thr[tid].avail_conns)) {
srv_conn = srv_lookup_conn(&srv->per_thr[tid].avail_conns, hash);
if (srv_conn) {
- DBG_TRACE_STATE("reuse connection from avail", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("reuse connection from avail", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
reuse = 1;
}
}
}
if (srv_conn) {
- DBG_TRACE_STATE("reuse connection from idle/safe", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("reuse connection from idle/safe", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
reuse = 1;
}
}
if (!srv_conn) {
srv_conn = conn_new(s->target);
if (srv_conn) {
- DBG_TRACE_STATE("alloc new be connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("alloc new be connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
srv_conn->owner = s->sess;
/* connection will be attached to the session if
}
if (!conn_update_alpn(srv_conn, ist(alpn), force))
- DBG_TRACE_STATE("update alpn for websocket", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("update alpn for websocket", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
#endif
}
}
/* Now handle synchronously connected sockets. We know the stream-int
- * is at least in state SI_ST_CON. These ones typically are UNIX
+ * is at least in state CS_ST_CON. These ones typically are UNIX
* sockets, socket pairs, andoccasionally TCP connections on the
* loopback on a heavily loaded system.
*/
if (!(srv_conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)))
s->csb->endp->flags &= ~CS_EP_WAIT_FOR_HS;
- if (!si_state_in(cs_si(s->csb)->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
+ if (!cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO) &&
(srv_conn->flags & CO_FL_WAIT_XPRT) == 0) {
s->conn_exp = TICK_ETERNITY;
cs_oc(s->csb)->flags |= CF_WRITE_NULL;
- if (cs_si(s->csb)->state == SI_ST_CON)
- cs_si(s->csb)->state = SI_ST_RDY;
+ if (s->csb->state == CS_ST_CON)
+ s->csb->state = CS_ST_RDY;
}
/* Report EOI on the channel if it was reached from the mux point of
case SRV_STATUS_QUEUED:
s->conn_exp = tick_add_ifset(now_ms, s->be->timeout.queue);
- cs_si(s->csb)->state = SI_ST_QUE;
+ s->csb->state = CS_ST_QUE;
/* do nothing else and do not wake any other stream up */
return 1;
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE))));
}
-/* Update back stream interface status for input states SI_ST_ASS, SI_ST_QUE,
- * SI_ST_TAR. Other input states are simply ignored.
- * Possible output states are SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ, SI_ST_CON
- * and SI_ST_EST. Flags must have previously been updated for timeouts and other
+/* Update back stream interface status for input states CS_ST_ASS, CS_ST_QUE,
+ * CS_ST_TAR. Other input states are simply ignored.
+ * Possible output states are CS_ST_CLO, CS_ST_TAR, CS_ST_ASS, CS_ST_REQ, CS_ST_CON
+ * and CS_ST_EST. Flags must have previously been updated for timeouts and other
* conditions.
*/
void back_try_conn_req(struct stream *s)
struct conn_stream *cs = s->csb;
struct channel *req = &s->req;
- DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
- if (cs->si->state == SI_ST_ASS) {
+ if (cs->state == CS_ST_ASS) {
/* Server assigned to connection request, we have to try to connect now */
int conn_err;
*/
if (back_may_abort_req(req, s)) {
s->conn_err_type |= STRM_ET_CONN_ABRT;
- DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto abort_connection;
}
srv = objt_server(s->target);
if (conn_err == SF_ERR_NONE) {
- /* state = SI_ST_CON or SI_ST_EST now */
+ /* state = CS_ST_CON or CS_ST_EST now */
if (srv)
srv_inc_sess_ctr(srv);
if (srv)
srv_set_sess_last(srv);
- DBG_TRACE_STATE("connection attempt", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("connection attempt", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
goto end;
}
pendconn_cond_unlink(s->pend_pos);
/* no stream was ever accounted for this server */
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("internal error during connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("internal error during connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
* turn-around now, as the problem is likely a source port
* allocation problem, so we want to retry now.
*/
- cs->si->state = SI_ST_CER;
+ cs->state = CS_ST_CER;
cs->endp->flags &= ~CS_EP_ERROR;
back_handle_st_cer(s);
- DBG_TRACE_STATE("connection error, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
- /* now si->state is one of SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ */
+ DBG_TRACE_STATE("connection error, retry", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
+ /* now cs->state is one of CS_ST_CLO, CS_ST_TAR, CS_ST_ASS, CS_ST_REQ */
}
- else if (cs->si->state == SI_ST_QUE) {
+ else if (cs->state == CS_ST_QUE) {
/* connection request was queued, check for any update */
if (!pendconn_dequeue(s)) {
/* The connection is not in the queue anymore. Either
*/
s->conn_exp = TICK_ETERNITY;
if (unlikely(!(s->flags & SF_ASSIGNED)))
- cs->si->state = SI_ST_REQ;
+ cs->state = CS_ST_REQ;
else {
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
- cs->si->state = SI_ST_ASS;
+ cs->state = CS_ST_ASS;
}
- DBG_TRACE_STATE("dequeue connection request", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("dequeue connection request", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
goto end;
}
req->flags |= CF_WRITE_TIMEOUT;
if (!s->conn_err_type)
s->conn_err_type = STRM_ET_QUEUE_TO;
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("connection request still queued", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("connection request still queued", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
goto end;
}
pendconn_cond_unlink(s->pend_pos);
s->conn_err_type |= STRM_ET_QUEUE_ABRT;
- DBG_TRACE_STATE("abort queued connection request", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("abort queued connection request", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto abort_connection;
}
/* Nothing changed */
}
- else if (cs->si->state == SI_ST_TAR) {
+ else if (cs->state == CS_ST_TAR) {
/* Connection request might be aborted */
if (back_may_abort_req(req, s)) {
s->conn_err_type |= STRM_ET_CONN_ABRT;
- DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto abort_connection;
}
* FIXME: Should we force a redispatch attempt when the server is down ?
*/
if (s->flags & SF_ASSIGNED)
- cs->si->state = SI_ST_ASS;
+ cs->state = CS_ST_ASS;
else
- cs->si->state = SI_ST_REQ;
+ cs->state = CS_ST_REQ;
- DBG_TRACE_STATE("retry connection now", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("retry connection now", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
end:
- DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
return;
abort_connection:
s->flags &= ~SF_CONN_EXP;
si_shutr(cs->si);
si_shutw(cs->si);
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
return;
}
/* This function initiates a server connection request on a stream interface
- * already in SI_ST_REQ state. Upon success, the state goes to SI_ST_ASS for
+ * already in CS_ST_REQ state. Upon success, the state goes to CS_ST_ASS for
* a real connection to a server, indicating that a server has been assigned,
- * or SI_ST_EST for a successful connection to an applet. It may also return
- * SI_ST_QUE, or SI_ST_CLO upon error.
+ * or CS_ST_EST for a successful connection to an applet. It may also return
+ * CS_ST_QUE, or CS_ST_CLO upon error.
*/
void back_handle_st_req(struct stream *s)
{
struct conn_stream *cs = s->csb;
- if (cs->si->state != SI_ST_REQ)
+ if (cs->state != CS_ST_REQ)
return;
- DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
if (unlikely(obj_type(s->target) == OBJ_TYPE_APPLET)) {
/* the applet directly goes to the EST state */
si_shutw(cs->si);
s->req.flags |= CF_WRITE_ERROR;
s->conn_err_type = STRM_ET_CONN_RES;
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("failed to register applet", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("failed to register applet", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
if (tv_iszero(&s->logs.tv_request))
s->logs.tv_request = now;
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
- cs->si->state = SI_ST_EST;
+ cs->state = CS_ST_EST;
s->conn_err_type = STRM_ET_NONE;
be_set_sess_last(s->be);
- DBG_TRACE_STATE("applet registered", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("applet registered", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
/* let back_establish() finish the job */
goto end;
}
/* We did not get a server. Either we queued the
* connection request, or we encountered an error.
*/
- if (cs->si->state == SI_ST_QUE) {
- DBG_TRACE_STATE("connection request queued", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ if (cs->state == CS_ST_QUE) {
+ DBG_TRACE_STATE("connection request queued", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
goto end;
}
s->req.flags |= CF_WRITE_ERROR;
if (!s->conn_err_type)
s->conn_err_type = STRM_ET_CONN_OTHER;
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("connection request failed", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("connection request failed", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
/* The server is assigned */
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
- cs->si->state = SI_ST_ASS;
+ cs->state = CS_ST_ASS;
be_set_sess_last(s->be);
- DBG_TRACE_STATE("connection request assigned to a server", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("connection request assigned to a server", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
end:
- DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
-/* This function is called with (si->state == SI_ST_CON) meaning that a
+/* This function is called with (cs->state == CS_ST_CON) meaning that a
* connection was attempted and that the file descriptor is already allocated.
* We must check for timeout, error and abort. Possible output states are
- * SI_ST_CER (error), SI_ST_DIS (abort), and SI_ST_CON (no change). This only
+ * CS_ST_CER (error), CS_ST_DIS (abort), and CS_ST_CON (no change). This only
* works with connection-based streams. We know that there were no I/O event
* when reaching this function. Timeouts and errors are *not* cleared.
*/
struct channel *req = &s->req;
struct channel *rep = &s->res;
- DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
/* the client might want to abort */
if ((rep->flags & CF_SHUTW) ||
s->conn_err_type |= STRM_ET_CONN_ABRT;
if (s->srv_error)
s->srv_error(s, cs->si);
- /* Note: state = SI_ST_DIS now */
- DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ /* Note: state = CS_ST_DIS now */
+ DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
s->conn_err_type = STRM_ET_CONN_TO;
}
- cs->si->state = SI_ST_CER;
- DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ cs->state = CS_ST_CER;
+ DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
}
end:
- DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
-/* This function is called with (si->state == SI_ST_CER) meaning that a
+/* This function is called with (cs->state == CS_ST_CER) meaning that a
* previous connection attempt has failed and that the file descriptor
* has already been released. Possible causes include asynchronous error
- * notification and time out. Possible output states are SI_ST_CLO when
- * retries are exhausted, SI_ST_TAR when a delay is wanted before a new
- * connection attempt, SI_ST_ASS when it's wise to retry on the same server,
- * and SI_ST_REQ when an immediate redispatch is wanted. The buffers are
+ * notification and time out. Possible output states are CS_ST_CLO when
+ * retries are exhausted, CS_ST_TAR when a delay is wanted before a new
+ * connection attempt, CS_ST_ASS when it's wise to retry on the same server,
+ * and CS_ST_REQ when an immediate redispatch is wanted. The buffers are
* marked as in error state. Timeouts and errors are cleared before retrying.
*/
void back_handle_st_cer(struct stream *s)
struct conn_stream *cs = s->csb;
int must_tar = (cs->endp->flags & CS_EP_ERROR);
- DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
s->conn_exp = TICK_ETERNITY;
s->flags &= ~SF_CONN_EXP;
* client provoke retries.
*/
s->conn_retries = s->be->conn_retries;
- DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
}
}
s->req.flags |= CF_WRITE_ERROR;
s->res.flags |= CF_READ_ERROR;
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("connection failed", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("connection failed", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
s->req.flags |= CF_WRITE_ERROR;
s->res.flags |= CF_READ_ERROR;
- cs->si->state = SI_ST_CLO;
+ cs->state = CS_ST_CLO;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("error resetting endpoint", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("error resetting endpoint", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
s->conn_err_type = STRM_ET_CONN_ERR;
/* only wait when we're retrying on the same server */
- if ((cs->si->state == SI_ST_ASS ||
+ if ((cs->state == CS_ST_ASS ||
(s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_RR ||
(s->be->srv_act <= 1)) && !reused) {
- cs->si->state = SI_ST_TAR;
+ cs->state = CS_ST_TAR;
s->conn_exp = tick_add(now_ms, MS_TO_TICKS(delay));
}
- DBG_TRACE_STATE("retry a new connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("retry a new connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
end:
- DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
-/* This function is called with (si->state == SI_ST_RDY) meaning that a
+/* This function is called with (cs->state == CS_ST_RDY) meaning that a
* connection was attempted, that the file descriptor is already allocated,
* and that it has succeeded. We must still check for errors and aborts.
- * Possible output states are SI_ST_EST (established), SI_ST_CER (error),
- * and SI_ST_DIS (abort). This only works with connection-based streams.
+ * Possible output states are CS_ST_EST (established), CS_ST_CER (error),
+ * and CS_ST_DIS (abort). This only works with connection-based streams.
* Timeouts and errors are *not* cleared.
*/
void back_handle_st_rdy(struct stream *s)
struct channel *req = &s->req;
struct channel *rep = &s->res;
- DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
/* We know the connection at least succeeded, though it could have
* since met an error for any other reason. At least it didn't time out
* even though the timeout might have been reported right after success.
* - an I/O error might have been reported after a successful transfer,
* which is not retryable and needs to be logged correctly, and needs
* established as well
- * - SI_ST_CON implies !CF_WROTE_DATA but not conversely as we could
+ * - CS_ST_CON implies !CF_WROTE_DATA but not conversely as we could
* have validated a connection with incoming data (e.g. TCP with a
* banner protocol), or just a successful connect() probe.
* - the client might have requested a connection abort, this needs to
s->conn_err_type |= STRM_ET_CONN_ABRT;
if (s->srv_error)
s->srv_error(s, cs->si);
- DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
if (cs->endp->flags & CS_EP_ERROR) {
if (!s->conn_err_type)
s->conn_err_type = STRM_ET_CONN_ERR;
- cs->si->state = SI_ST_CER;
- DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ cs->state = CS_ST_CER;
+ DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
goto end;
}
}
/* data were sent and/or we had no error, back_establish() will
* now take over.
*/
- DBG_TRACE_STATE("connection established", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_STATE("connection established", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
s->conn_err_type = STRM_ET_NONE;
- cs->si->state = SI_ST_EST;
+ cs->state = CS_ST_EST;
end:
- DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
/* sends a log message when a backend goes down, and also sets last
res_htx = htx_from_buf(&res->buf);
total = res_htx->data;
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
goto out;
/* Check if the input buffer is available. */
int reql;
int len;
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
goto out;
/* Check if the input buffer is available. */
}
}
- if ((res->flags & CF_SHUTR) && (cs->si->state == SI_ST_EST)) {
+ if ((res->flags & CF_SHUTR) && (cs->state == CS_ST_EST)) {
DPRINTF(stderr, "%s@%d: si to buf closed. req=%08x, res=%08x, st=%d\n",
- __FUNCTION__, __LINE__, req->flags, res->flags, cs->si->state);
+ __FUNCTION__, __LINE__, req->flags, res->flags, cs->state);
/* Other side has closed, let's abort if we have no more processing to do
* and nothing more to consume. This is comparable to a broken pipe, so
* we forward the close to the request side so that it flows upstream to
si_shutw(cs->si);
}
- if ((req->flags & CF_SHUTW) && (cs->si->state == SI_ST_EST) && (appctx->st0 < CLI_ST_OUTPUT)) {
+ if ((req->flags & CF_SHUTW) && (cs->state == CS_ST_EST) && (appctx->st0 < CLI_ST_OUTPUT)) {
DPRINTF(stderr, "%s@%d: buf to si closed. req=%08x, res=%08x, st=%d\n",
- __FUNCTION__, __LINE__, req->flags, res->flags, cs->si->state);
+ __FUNCTION__, __LINE__, req->flags, res->flags, cs->state);
/* We have no more processing to do, and nothing more to send, and
* the client side has closed. So we'll forward this state downstream
* on the response buffer.
out:
DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%lu, rqs=%lu, rh=%lu, rs=%lu\n",
__FUNCTION__, __LINE__,
- cs->si->state, req->flags, res->flags, ci_data(req), co_data(req), ci_data(res), co_data(res));
+ cs->state, req->flags, res->flags, ci_data(req), co_data(req), ci_data(res), co_data(res));
}
/* This is called when the stream interface is closed. For instance, upon an
sockaddr_free(&s->csb->dst);
- si_set_state(cs_si(s->csb), SI_ST_INI);
+ cs_set_state(s->csb, CS_ST_INI);
cs_si(s->csb)->flags &= SI_FL_ISBACK; /* we're in the context of process_stream */
s->csb->flags &= CS_FL_ISBACK | CS_FL_DONT_WAKE; /* we're in the context of process_stream */
s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WROTE_DATA);
cs->obj_type = OBJ_TYPE_CS;
cs->flags = CS_FL_NONE;
+ cs->state = CS_ST_INI;
cs->hcto = TICK_ETERNITY;
cs->app = NULL;
cs->si = NULL;
if (!*args[3]) {
return cli_err(appctx,
"Usage: debug dev stream { <obj> <op> <value> | wake }*\n"
- " <obj> = {strm | strm.f | strm.x | sif.f | sif.s | sib.f | sib.s |\n"
+ " <obj> = {strm | strm.f | strm.x | sif.f | csf.s | sib.f | csb.s |\n"
" txn.f | req.f | req.r | req.w | res.f | res.r | res.w}\n"
" <op> = {'' (show) | '=' (assign) | '^' (xor) | '+' (or) | '-' (andnot)}\n"
" <value> = 'now' | 64-bit dec/hex integer (0x prefix supported)\n"
ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csf)->flags; size = sizeof(cs_si(s->csf)->flags);
} else if (isteq(name, ist("sib.f"))) {
ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csb)->flags; size = sizeof(cs_si(s->csb)->flags);
- } else if (isteq(name, ist("sif.s"))) {
- ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csf)->state; size = sizeof(cs_si(s->csf)->state);
- } else if (isteq(name, ist("sib.s"))) {
- ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csf)->state; size = sizeof(cs_si(s->csb)->state);
+ } else if (isteq(name, ist("csf.s"))) {
+ ptr = (!s || !may_access(s)) ? NULL : &s->csf->state; size = sizeof(s->csf->state);
+ } else if (isteq(name, ist("csb.s"))) {
+ ptr = (!s || !may_access(s)) ? NULL : &s->csf->state; size = sizeof(s->csb->state);
} else if (isteq(name, ist("wake"))) {
if (s && may_access(s) && may_access((void *)s + sizeof(*s) - 1))
task_wakeup(s->task, TASK_WOKEN_TIMER|TASK_WOKEN_IO|TASK_WOKEN_MSG);
/* if the connection is not established, inform the stream that we want
* to be notified whenever the connection completes.
*/
- if (cs_opposite(cs)->si->state < SI_ST_EST) {
+ if (cs_opposite(cs)->state < CS_ST_EST) {
si_cant_get(cs->si);
si_rx_conn_blk(cs->si);
si_rx_endp_more(cs->si);
* the message so that we can take our reference there if we have to
* stop before the end (ret=0).
*/
- if (cs_opposite(cs)->si->state == SI_ST_EST) {
+ if (cs_opposite(cs)->state == CS_ST_EST) {
/* we were already there, adjust the offset to be relative to
* the buffer's head and remove us from the counter.
*/
char *frame, *buf;
int ret;
- if (si_state_in(cs->si->state, SI_SB_CER|SI_SB_DIS|SI_SB_CLO)) {
+ if (cs_state_in(cs->state, CS_SB_CER|CS_SB_DIS|CS_SB_CLO)) {
/* closed */
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
goto exit;
}
- if (!si_state_in(cs->si->state, SI_SB_RDY|SI_SB_EST)) {
+ if (!cs_state_in(cs->state, CS_SB_RDY|CS_SB_EST)) {
/* not connected yet */
si_rx_endp_more(cs->si);
task_wakeup(__cs_strm(cs)->task, TASK_WOKEN_MSG);
int ret;
- if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO) {
+ if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO) {
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
goto exit;
}
struct spoe_agent *agent = SPOE_APPCTX(appctx)->agent;
int ret, skip_sending = 0, skip_receiving = 0, active_s = 0, active_r = 0, close_asap = 0;
- if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO) {
+ if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO) {
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
goto exit;
}
char *frame, *buf;
int ret;
- if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO)
+ if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO)
goto exit;
if (appctx->st1 == SPOE_APPCTX_ERR_TOUT)
char *frame;
int ret;
- if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO) {
+ if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO) {
SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
goto exit;
}
/* if the connection is not established, inform the stream that we want
* to be notified whenever the connection completes.
*/
- if (cs_opposite(cs)->si->state < SI_ST_EST) {
+ if (cs_opposite(cs)->state < CS_ST_EST) {
si_cant_get(cs->si);
si_rx_conn_blk(cs->si);
si_rx_endp_more(cs->si);
* and retrieve data from the server. The connection is initialized
* with the "struct server".
*/
- si_set_state(cs_si(s->csb), SI_ST_ASS);
+ cs_set_state(s->csb, CS_ST_ASS);
/* Force destination server. */
s->flags |= SF_DIRECT | SF_ASSIGNED | SF_BE_ASSIGNED;
}
/* If the stream is disconnect or closed, ldo nothing. */
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
return;
/* Execute the function. */
res_htx = htx_from_buf(&res->buf);
/* If the stream is disconnect or closed, ldo nothing. */
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
goto out;
/* Check if the input buffer is available. */
fcn = appctx->ctx.hlua_cli.fcn;
/* If the stream is disconnect or closed, ldo nothing. */
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
return 1;
/* Execute the function. */
si_shutr(si);
si_shutw(si);
s->conn_err_type = STRM_ET_NONE;
- si->state = SI_ST_CLO;
+ si->cs->state = CS_ST_CLO;
if (!(s->flags & SF_ERR_MASK))
s->flags |= SF_ERR_LOCAL;
peer_cs = peer->appctx->owner;
peer_s = __cs_strm(peer_cs);
- chunk_appendf(&trash, " state=%s", si_state_str(cs_opposite(peer_cs)->si->state));
+ chunk_appendf(&trash, " state=%s", cs_state_str(cs_opposite(peer_cs)->state));
conn = objt_conn(strm_orig(peer_s));
if (conn)
/* if the connection is not established, inform the stream that we want
* to be notified whenever the connection completes.
*/
- if (cs_opposite(cs)->si->state < SI_ST_EST) {
+ if (cs_opposite(cs)->state < CS_ST_EST) {
si_cant_get(cs->si);
si_rx_conn_blk(cs->si);
si_rx_endp_more(cs->si);
* the message so that we can take our reference there if we have to
* stop before the end (ret=0).
*/
- if (cs_opposite(cs)->si->state == SI_ST_EST) {
+ if (cs_opposite(cs)->state == CS_ST_EST) {
/* we were already there, adjust the offset to be relative to
* the buffer's head and remove us from the counter.
*/
/* if the connection is not established, inform the stream that we want
* to be notified whenever the connection completes.
*/
- if (cs_opposite(cs)->si->state < SI_ST_EST) {
+ if (cs_opposite(cs)->state < CS_ST_EST) {
si_cant_get(cs->si);
si_rx_conn_blk(cs->si);
si_rx_endp_more(cs->si);
* the message so that we can take our reference there if we have to
* stop before the end (ret=0).
*/
- if (cs_opposite(cs)->si->state == SI_ST_EST) {
+ if (cs_opposite(cs)->state == CS_ST_EST) {
/* we were already there, adjust the offset to be relative to
* the buffer's head and remove us from the counter.
*/
res_htx = htx_from_buf(&res->buf);
- if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+ if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
goto out;
/* Check if the input buffer is available. */
{ .mask = STRM_EV_STRM_ANA, .name = "strm_ana", .desc = "stream analyzers" },
{ .mask = STRM_EV_STRM_PROC, .name = "strm_proc", .desc = "stream processing" },
- { .mask = STRM_EV_SI_ST, .name = "si_state", .desc = "processing stream-interface states" },
+ { .mask = STRM_EV_CS_ST, .name = "cs_state", .desc = "processing conn-stream states" },
{ .mask = STRM_EV_HTTP_ANA, .name = "http_ana", .desc = "HTTP analyzers" },
{ .mask = STRM_EV_HTTP_ERR, .name = "http_err", .desc = "error during HTTP analyzis" },
}
/* Front and back stream-int state */
- chunk_appendf(&trace_buf, " SI=(%s,%s)",
- si_state_str(si_f->state), si_state_str(si_b->state));
+ chunk_appendf(&trace_buf, " CS=(%s,%s)",
+ cs_state_str(s->csf->state), cs_state_str(s->csb->state));
/* If txn is defined, HTTP req/rep states */
if (txn)
s->conn_retries = 0;
s->conn_exp = TICK_ETERNITY;
s->conn_err_type = STRM_ET_NONE;
- s->prev_conn_state = SI_ST_INI;
+ s->prev_conn_state = CS_ST_INI;
t->process = process_stream;
t->context = s;
t->expire = TICK_ETERNITY;
if (!s->csb)
goto out_fail_alloc_csb;
- si_set_state(cs_si(s->csf), SI_ST_EST);
+ cs_set_state(s->csf, CS_ST_EST);
s->csf->hcto = sess->fe->timeout.clientfin;
if (likely(sess->fe->options2 & PR_O2_INDEPSTR))
}
/*
- * This function handles the transition between the SI_ST_CON state and the
- * SI_ST_EST state. It must only be called after switching from SI_ST_CON (or
- * SI_ST_INI or SI_ST_RDY) to SI_ST_EST, but only when a ->proto is defined.
- * Note that it will switch the interface to SI_ST_DIS if we already have
+ * This function handles the transition between the CS_ST_CON state and the
+ * CS_ST_EST state. It must only be called after switching from CS_ST_CON (or
+ * CS_ST_INI or CS_ST_RDY) to CS_ST_EST, but only when a ->proto is defined.
+ * Note that it will switch the interface to CS_ST_DIS if we already have
* the CF_SHUTR flag, it means we were able to forward the request, and
* receive the response, before process_stream() had the opportunity to
- * make the switch from SI_ST_CON to SI_ST_EST. When that happens, we want
+ * make the switch from CS_ST_CON to CS_ST_EST. When that happens, we want
* to go through back_establish() anyway, to make sure the analysers run.
* Timeouts are cleared. Error are reported on the channel so that analysers
* can handle them.
struct channel *req = &s->req;
struct channel *rep = &s->res;
- DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
/* First, centralize the timers information, and clear any irrelevant
* timeout.
*/
req->flags |= CF_WRITE_ERROR;
rep->flags |= CF_READ_ERROR;
s->conn_err_type = STRM_ET_DATA_ERR;
- DBG_TRACE_STATE("read/write error", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ DBG_TRACE_STATE("read/write error", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
}
if (objt_server(s->target))
}
req->wex = TICK_ETERNITY;
/* If we managed to get the whole response, and we don't have anything
- * left to send, or can't, switch to SI_ST_DIS now. */
+ * left to send, or can't, switch to CS_ST_DIS now. */
if (rep->flags & (CF_SHUTR | CF_SHUTW)) {
- si->state = SI_ST_DIS;
- DBG_TRACE_STATE("response channel shutdwn for read/write", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+ s->csb->state = CS_ST_DIS;
+ DBG_TRACE_STATE("response channel shutdwn for read/write", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
}
- DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+ DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
}
/* Set correct stream termination flags in case no analyser has done it. It
static void sess_set_term_flags(struct stream *s)
{
if (!(s->flags & SF_FINST_MASK)) {
- if (cs_si(s->csb)->state == SI_ST_INI) {
+ if (s->csb->state == CS_ST_INI) {
/* anything before REQ in fact */
_HA_ATOMIC_INC(&strm_fe(s)->fe_counters.failed_req);
if (strm_li(s) && strm_li(s)->counters)
s->flags |= SF_FINST_R;
}
- else if (cs_si(s->csb)->state == SI_ST_QUE)
+ else if (s->csb->state == CS_ST_QUE)
s->flags |= SF_FINST_Q;
- else if (si_state_in(cs_si(s->csb)->state, SI_SB_REQ|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY))
+ else if (cs_state_in(s->csb->state, CS_SB_REQ|CS_SB_TAR|CS_SB_ASS|CS_SB_CON|CS_SB_CER|CS_SB_RDY))
s->flags |= SF_FINST_C;
- else if (cs_si(s->csb)->state == SI_ST_EST || s->prev_conn_state == SI_ST_EST)
+ else if (s->csb->state == CS_ST_EST || s->prev_conn_state == CS_ST_EST)
s->flags |= SF_FINST_D;
else
s->flags |= SF_FINST_L;
*/
srv = objt_server(s->target);
if (unlikely(s->csf->endp->flags & CS_EP_ERROR)) {
- if (si_state_in(si_f->state, SI_SB_EST|SI_SB_DIS)) {
+ if (cs_state_in(s->csf->state, CS_SB_EST|CS_SB_DIS)) {
si_shutr(si_f);
si_shutw(si_f);
cs_report_error(si_f->cs);
}
if (unlikely(s->csb->endp->flags & CS_EP_ERROR)) {
- if (si_state_in(si_b->state, SI_SB_EST|SI_SB_DIS)) {
+ if (cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS)) {
si_shutr(si_b);
si_shutw(si_b);
cs_report_error(si_b->cs);
/* note: maybe we should process connection errors here ? */
}
- if (si_state_in(si_b->state, SI_SB_CON|SI_SB_RDY)) {
+ if (cs_state_in(s->csb->state, CS_SB_CON|CS_SB_RDY)) {
/* we were trying to establish a connection on the server side,
* maybe it succeeded, maybe it failed, maybe we timed out, ...
*/
- if (si_b->state == SI_ST_RDY)
+ if (s->csb->state == CS_ST_RDY)
back_handle_st_rdy(s);
- else if (si_b->state == SI_ST_CON)
+ else if (s->csb->state == CS_ST_CON)
back_handle_st_con(s);
- if (si_b->state == SI_ST_CER)
+ if (s->csb->state == CS_ST_CER)
back_handle_st_cer(s);
- else if (si_b->state == SI_ST_EST)
+ else if (s->csb->state == CS_ST_EST)
back_establish(s);
- /* state is now one of SI_ST_CON (still in progress), SI_ST_EST
- * (established), SI_ST_DIS (abort), SI_ST_CLO (last error),
- * SI_ST_ASS/SI_ST_TAR/SI_ST_REQ for retryable errors.
+ /* state is now one of CS_ST_CON (still in progress), CS_ST_EST
+ * (established), CS_ST_DIS (abort), CS_ST_CLO (last error),
+ * CS_ST_ASS/CS_ST_TAR/CS_ST_REQ for retryable errors.
*/
}
- rq_prod_last = si_f->state;
- rq_cons_last = si_b->state;
- rp_cons_last = si_f->state;
- rp_prod_last = si_b->state;
+ rq_prod_last = s->csf->state;
+ rq_cons_last = s->csb->state;
+ rp_cons_last = s->csf->state;
+ rp_prod_last = s->csb->state;
/* Check for connection closure */
DBG_TRACE_POINT(STRM_EV_STRM_PROC, s);
/* nothing special to be done on client side */
- if (unlikely(si_f->state == SI_ST_DIS)) {
- si_f->state = SI_ST_CLO;
+ if (unlikely(s->csf->state == CS_ST_DIS)) {
+ s->csf->state = CS_ST_CLO;
/* This is needed only when debugging is enabled, to indicate
* client-side close.
/* When a server-side connection is released, we have to count it and
* check for pending connections on this server.
*/
- if (unlikely(si_b->state == SI_ST_DIS)) {
- si_b->state = SI_ST_CLO;
+ if (unlikely(s->csb->state == CS_ST_DIS)) {
+ s->csb->state = CS_ST_CLO;
srv = objt_server(s->target);
if (srv) {
if (s->flags & SF_CURR_SESS) {
if (unlikely((global.mode & MODE_DEBUG) &&
(!(global.mode & MODE_QUIET) ||
(global.mode & MODE_VERBOSE)))) {
- if (s->prev_conn_state == SI_ST_EST) {
+ if (s->prev_conn_state == CS_ST_EST) {
chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
s->uniq_id, s->be->id,
(unsigned short)conn_fd(__cs_conn(si_f->cs)),
if (((req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
((req->flags ^ rqf_last) & CF_MASK_STATIC) ||
(req->analysers && (req->flags & CF_SHUTW)) ||
- si_f->state != rq_prod_last ||
- si_b->state != rq_cons_last ||
+ s->csf->state != rq_prod_last ||
+ s->csb->state != rq_cons_last ||
s->pending_events & TASK_WOKEN_MSG) {
unsigned int flags = req->flags;
- if (si_state_in(si_f->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO)) {
+ if (cs_state_in(s->csf->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO)) {
int max_loops = global.tune.maxpollevents;
unsigned int ana_list;
unsigned int ana_back;
}
}
- rq_prod_last = si_f->state;
- rq_cons_last = si_b->state;
+ rq_prod_last = s->csf->state;
+ rq_cons_last = s->csb->state;
req->flags &= ~CF_WAKE_ONCE;
rqf_last = req->flags;
if (((res->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
(res->flags ^ rpf_last) & CF_MASK_STATIC ||
(res->analysers && (res->flags & CF_SHUTW)) ||
- si_f->state != rp_cons_last ||
- si_b->state != rp_prod_last ||
+ s->csf->state != rp_cons_last ||
+ s->csb->state != rp_prod_last ||
s->pending_events & TASK_WOKEN_MSG) {
unsigned int flags = res->flags;
- if (si_state_in(si_b->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO)) {
+ if (cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO)) {
int max_loops = global.tune.maxpollevents;
unsigned int ana_list;
unsigned int ana_back;
}
}
- rp_cons_last = si_f->state;
- rp_prod_last = si_b->state;
+ rp_cons_last = s->csf->state;
+ rp_prod_last = s->csb->state;
res->flags &= ~CF_WAKE_ONCE;
rpf_last = res->flags;
sess_set_term_flags(s);
/* Abort the request if a client error occurred while
- * the backend stream-interface is in the SI_ST_INI
- * state. It is switched into the SI_ST_CLO state and
+ * the backend stream-interface is in the CS_ST_INI
+ * state. It is switched into the CS_ST_CLO state and
* the request channel is erased. */
- if (si_b->state == SI_ST_INI) {
- si_b->state = SI_ST_CLO;
+ if (s->csb->state == CS_ST_INI) {
+ s->csb->state = CS_ST_CLO;
channel_abort(req);
if (IS_HTX_STRM(s))
channel_htx_erase(req, htxbuf(&req->buf));
*/
if (unlikely((!req->analysers || (req->analysers == AN_REQ_FLT_END && !(req->flags & CF_FLT_ANALYZE))) &&
!(req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
- (si_state_in(si_f->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO)) &&
+ (cs_state_in(s->csf->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO)) &&
(req->to_forward != CHN_INFINITE_FORWARD))) {
/* This buffer is freewheeling, there's no analyser
* attached to it. If any data are left in, we'll permit them to
* - there are data scheduled for emission in the buffer
* - the CF_AUTO_CONNECT flag is set (active connection)
*/
- if (si_b->state == SI_ST_INI) {
+ if (s->csb->state == CS_ST_INI) {
if (!(req->flags & CF_SHUTW)) {
if ((req->flags & CF_AUTO_CONNECT) || !channel_is_empty(req)) {
/* If we have an appctx, there is no connect method, so we
* immediately switch to the connected state, otherwise we
* perform a connection request.
*/
- si_b->state = SI_ST_REQ; /* new connection requested */
+ s->csb->state = CS_ST_REQ; /* new connection requested */
s->conn_retries = 0;
if ((s->be->retry_type &~ PR_RE_CONN_FAILED) &&
(s->be->mode == PR_MODE_HTTP) &&
}
else {
cs_detach_endp(s->csb);
- si_b->state = SI_ST_CLO; /* shutw+ini = abort */
+ s->csb->state = CS_ST_CLO; /* shutw+ini = abort */
channel_shutw_now(req); /* fix buffer flags upon abort */
channel_shutr_now(res);
}
/* we may have a pending connection request, or a connection waiting
* for completion.
*/
- if (si_state_in(si_b->state, SI_SB_REQ|SI_SB_QUE|SI_SB_TAR|SI_SB_ASS)) {
+ if (cs_state_in(s->csb->state, CS_SB_REQ|CS_SB_QUE|CS_SB_TAR|CS_SB_ASS)) {
/* prune the request variables and swap to the response variables. */
if (s->vars_reqres.scope != SCOPE_RES) {
if (!LIST_ISEMPTY(&s->vars_reqres.head))
/* nb: step 1 might switch from QUE to ASS, but we first want
* to give a chance to step 2 to perform a redirect if needed.
*/
- if (si_b->state != SI_ST_REQ)
+ if (s->csb->state != CS_ST_REQ)
back_try_conn_req(s);
- if (si_b->state == SI_ST_REQ)
+ if (s->csb->state == CS_ST_REQ)
back_handle_st_req(s);
/* get a chance to complete an immediate connection setup */
- if (si_b->state == SI_ST_RDY)
+ if (s->csb->state == CS_ST_RDY)
goto resync_stream_interface;
/* applets directly go to the ESTABLISHED state. Similarly,
* servers experience the same fate when their connection
* is reused.
*/
- if (unlikely(si_b->state == SI_ST_EST))
+ if (unlikely(s->csb->state == CS_ST_EST))
back_establish(s);
srv = objt_server(s->target);
- if (si_b->state == SI_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE))
+ if (s->csb->state == CS_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE))
http_perform_server_redirect(s, si_b);
- } while (si_b->state == SI_ST_ASS);
+ } while (s->csb->state == CS_ST_ASS);
}
/* Let's see if we can send the pending request now */
}
/* Benchmarks have shown that it's optimal to do a full resync now */
- if (si_f->state == SI_ST_DIS ||
- si_state_in(si_b->state, SI_SB_RDY|SI_SB_DIS) ||
- (s->csf->endp->flags & CS_EP_ERROR && si_f->state != SI_ST_CLO) ||
- (s->csb->endp->flags & CS_EP_ERROR && si_b->state != SI_ST_CLO))
+ if (s->csf->state == CS_ST_DIS ||
+ cs_state_in(s->csb->state, CS_SB_RDY|CS_SB_DIS) ||
+ (s->csf->endp->flags & CS_EP_ERROR && s->csf->state != CS_ST_CLO) ||
+ (s->csb->endp->flags & CS_EP_ERROR && s->csb->state != CS_ST_CLO))
goto resync_stream_interface;
/* otherwise we want to check if we need to resync the req buffer or not */
*/
if (unlikely((!res->analysers || (res->analysers == AN_RES_FLT_END && !(res->flags & CF_FLT_ANALYZE))) &&
!(res->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
- si_state_in(si_b->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
+ cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO) &&
(res->to_forward != CHN_INFINITE_FORWARD))) {
/* This buffer is freewheeling, there's no analyser
* attached to it. If any data are left in, we'll permit them to
si_shutr(si_b);
}
- if (si_f->state == SI_ST_DIS ||
- si_state_in(si_b->state, SI_SB_RDY|SI_SB_DIS) ||
- (s->csf->endp->flags & CS_EP_ERROR && si_f->state != SI_ST_CLO) ||
- (s->csb->endp->flags & CS_EP_ERROR && si_b->state != SI_ST_CLO))
+ if (s->csf->state == CS_ST_DIS ||
+ cs_state_in(s->csb->state, CS_SB_RDY|CS_SB_DIS) ||
+ (s->csf->endp->flags & CS_EP_ERROR && s->csf->state != CS_ST_CLO) ||
+ (s->csb->endp->flags & CS_EP_ERROR && s->csb->state != CS_ST_CLO))
goto resync_stream_interface;
if ((req->flags & ~rqf_last) & CF_MASK_ANALYSER)
s->csf->flags &= ~CS_FL_DONT_WAKE;
s->csb->flags &= ~CS_FL_DONT_WAKE;
- if (likely((si_f->state != SI_ST_CLO) || !si_state_in(si_b->state, SI_SB_INI|SI_SB_CLO) ||
+ if (likely((s->csf->state != CS_ST_CLO) || !cs_state_in(s->csb->state, CS_SB_INI|CS_SB_CLO) ||
(req->analysers & AN_REQ_FLT_END) || (res->analysers & AN_RES_FLT_END))) {
if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED) && !(s->flags & SF_IGNORE))
stream_process_counters(s);
chunk_appendf(buf,
"%sstrm=%p,%x src=%s fe=%s be=%s dst=%s%c"
"%stxn=%p,%x txn.req=%s,%x txn.rsp=%s,%x%c"
- "%srqf=%x rqa=%x rpf=%x rpa=%x sif=%s,%x sib=%s,%x%c"
- "%scsf=%p,%x csb=%p,%x%c"
+ "%srqf=%x rqa=%x rpf=%x rpa=%x sif=%x sib=%x%c"
+ "%scsf=%p,%s,%x csb=%p,%s,%x%c"
"%saf=%p,%u sab=%p,%u%c"
"%scof=%p,%x:%s(%p)/%s(%p)/%s(%d)%c"
"%scob=%p,%x:%s(%p)/%s(%p)/%s(%d)%c"
pfx, s->txn, (s->txn ? s->txn->flags : 0),
(s->txn ? h1_msg_state_str(s->txn->req.msg_state): "-"), (s->txn ? s->txn->req.flags : 0),
(s->txn ? h1_msg_state_str(s->txn->rsp.msg_state): "-"), (s->txn ? s->txn->rsp.flags : 0), eol,
- pfx, req->flags, req->analysers, res->flags, res->analysers,
- si_state_str(si_f->state), si_f->flags,
- si_state_str(si_b->state), si_b->flags, eol,
- pfx, csf, csf->flags, csb, csb->flags, eol,
+ pfx, req->flags, req->analysers, res->flags, res->analysers, si_f->flags, si_b->flags, eol,
+ pfx, csf, cs_state_str(csf->state), csf->flags, csb, cs_state_str(csb->state), csb->flags, eol,
pfx, acf, acf ? acf->st0 : 0, acb, acb ? acb->st0 : 0, eol,
pfx, cof, cof ? cof->flags : 0, conn_get_mux_name(cof), cof?cof->ctx:0, conn_get_xprt_name(cof),
cof ? cof->xprt_ctx : 0, conn_get_ctrl_name(cof), conn_fd(cof), eol,
strm->txn->req.flags, strm->txn->rsp.flags);
chunk_appendf(&trash,
- " si[0]=%p (state=%s flags=0x%02x endp0=%s:%p sub=%d)\n",
+ " si[0]=%p (flags=0x%02x endp0=%s:%p sub=%d)\n",
strm->csf->si,
- si_state_str(strm->csf->si->state),
strm->csf->si->flags,
(strm->csf->endp->flags & CS_EP_T_MUX ? "CONN" : "APPCTX"),
__cs_endp_target(strm->csf), strm->csf->si->wait_event.events);
chunk_appendf(&trash,
- " si[1]=%p (state=%s flags=0x%02x endp1=%s:%p sub=%d)\n",
+ " si[1]=%p (flags=0x%02x endp1=%s:%p sub=%d)\n",
strm->csb->si,
- si_state_str(strm->csb->si->state),
strm->csb->si->flags,
(strm->csb->endp->flags & CS_EP_T_MUX ? "CONN" : "APPCTX"),
__cs_endp_target(strm->csb), strm->csb->si->wait_event.events);
csf = strm->csf;
- chunk_appendf(&trash, " cs=%p csf=0x%08x endp=%p,0x%08x\n", csf, csf->flags, csf->endp->target, csf->endp->flags);
+ chunk_appendf(&trash, " cs=%p csf=0x%08x state=%s endp=%p,0x%08x\n", csf, csf->flags,
+ cs_state_str(csf->state), csf->endp->target, csf->endp->flags);
if ((conn = cs_conn(csf)) != NULL) {
chunk_appendf(&trash,
}
csb = strm->csb;
- chunk_appendf(&trash, " cs=%p csb=0x%08x endp=%p,0x%08x\n", csb, csb->flags, csb->endp->target, csb->endp->flags);
+ chunk_appendf(&trash, " cs=%p csb=0x%08x state=%s endp=%p,0x%08x\n", csb, csb->flags,
+ cs_state_str(csb->state), csb->endp->target, csb->endp->flags);
if ((conn = cs_conn(csb)) != NULL) {
chunk_appendf(&trash,
" co1=%p ctrl=%s xprt=%s mux=%s data=%s target=%s:%p\n",
conn = cs_conn(curr_strm->csf);
chunk_appendf(&trash,
- " s0=[%d,%1xh,fd=%d]",
- curr_strm->csf->si->state,
+ " s0=[%1xh,fd=%d]",
+ //curr_strm->csf->si->state,
curr_strm->csf->si->flags,
conn_fd(conn));
conn = cs_conn(curr_strm->csb);
chunk_appendf(&trash,
- " s1=[%d,%1xh,fd=%d]",
- curr_strm->csb->si->state,
+ " s1=[%1xh,fd=%d]",
+ //curr_strm->csb->si->state,
curr_strm->csb->si->flags,
conn_fd(conn));
ic->flags |= CF_SHUTR;
ic->rex = TICK_ETERNITY;
- if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
return;
if (si_oc(si)->flags & CF_SHUTW) {
- si->state = SI_ST_DIS;
+ si->cs->state = CS_ST_DIS;
__cs_strm(si->cs)->conn_exp = TICK_ETERNITY;
}
else if (si->cs->flags & CS_FL_NOHALF) {
ic->rex = tick_add(now_ms, ic->rto);
}
- switch (si->state) {
- case SI_ST_RDY:
- case SI_ST_EST:
+ switch (si->cs->state) {
+ case CS_ST_RDY:
+ case CS_ST_EST:
/* we have to shut before closing, otherwise some short messages
* may never leave the system, especially when there are remaining
* unread data in the socket input buffer, or when nolinger is set.
return;
/* fall through */
- case SI_ST_CON:
- case SI_ST_CER:
- case SI_ST_QUE:
- case SI_ST_TAR:
+ case CS_ST_CON:
+ case CS_ST_CER:
+ case CS_ST_QUE:
+ case CS_ST_TAR:
/* Note that none of these states may happen with applets */
- si->state = SI_ST_DIS;
+ si->cs->state = CS_ST_DIS;
/* fall through */
default:
si->cs->flags &= ~CS_FL_NOLINGER;
{
struct channel *ic = si_ic(si);
- DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+ DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
__FUNCTION__,
- si, si->state, ic->flags, si_oc(si)->flags);
+ si, si->cs->state, ic->flags, si_oc(si)->flags);
if (ic->pipe) {
/* stop reading */
{
struct channel *oc = si_oc(si);
- DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+ DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
__FUNCTION__,
- si, si->state, si_ic(si)->flags, oc->flags);
+ si, si->cs->state, si_ic(si)->flags, oc->flags);
- if (unlikely(si->state != SI_ST_EST || (oc->flags & CF_SHUTW)))
+ if (unlikely(si->cs->state != CS_ST_EST || (oc->flags & CF_SHUTW)))
return;
if (!(si->flags & SI_FL_WAIT_DATA) || /* not waiting for data */
struct connection *conn = cs_conn(si->cs);
if (((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW) &&
- (si->state == SI_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
+ (si->cs->state == CS_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
si_shutw(si);
oc->wex = TICK_ETERNITY;
}
/* wake the task up only when needed */
if (/* changes on the production side */
(ic->flags & (CF_READ_NULL|CF_READ_ERROR)) ||
- !si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST) ||
+ !cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST) ||
(si->cs->endp->flags & CS_EP_ERROR) ||
((ic->flags & CF_READ_PARTIAL) &&
- ((ic->flags & CF_EOI) || !ic->to_forward || sio->state != SI_ST_EST)) ||
+ ((ic->flags & CF_EOI) || !ic->to_forward || sio->cs->state != CS_ST_EST)) ||
/* changes on the consumption side */
(oc->flags & (CF_WRITE_NULL|CF_WRITE_ERROR)) ||
((oc->flags & CF_SHUTW) ||
(((oc->flags & CF_WAKE_WRITE) ||
!(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
- (sio->state != SI_ST_EST ||
+ (sio->cs->state != CS_ST_EST ||
(channel_is_empty(oc) && !oc->to_forward)))))) {
task_wakeup(task, TASK_WOKEN_IO);
}
/* The stream interface is only responsible for the connection during the early
* states, before plugging a mux. Thus it should only care about CO_FL_ERROR
- * before SI_ST_EST, and after that it must absolutely ignore it since the mux
+ * before CS_ST_EST, and after that it must absolutely ignore it since the mux
* may hold pending data. This function returns true if such an error was
* reported. Both the CS and the CONN must be valid.
*/
{
struct connection *conn;
- if (si->state >= SI_ST_EST)
+ if (si->cs->state >= CS_ST_EST)
return 0;
conn = __cs_conn(si->cs);
* care of it.
*/
- if (si->state >= SI_ST_CON) {
+ if (si->cs->state >= CS_ST_CON) {
if (si_is_conn_error(si))
cs->endp->flags |= CS_EP_ERROR;
}
task_wakeup(si_task(si), TASK_WOKEN_MSG);
}
- if (!si_state_in(si->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
+ if (!cs_state_in(si->cs->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO) &&
(conn->flags & CO_FL_WAIT_XPRT) == 0) {
__cs_strm(cs)->conn_exp = TICK_ETERNITY;
oc->flags |= CF_WRITE_NULL;
- if (si->state == SI_ST_CON)
- si->state = SI_ST_RDY;
+ if (si->cs->state == CS_ST_CON)
+ si->cs->state = CS_ST_RDY;
}
/* Report EOS on the channel if it was reached from the mux point of
if (cs->endp->flags & (CS_EP_ERROR|CS_EP_ERR_PENDING) || si_is_conn_error(si)) {
/* We're probably there because the tasklet was woken up,
* but process_stream() ran before, detected there were an
- * error and put the si back to SI_ST_TAR. There's still
+ * error and put the si back to CS_ST_TAR. There's still
* CO_FL_ERROR on the connection but we don't want to add
* CS_EP_ERROR back, so give up
*/
- if (si->state < SI_ST_CON)
+ if (si->cs->state < CS_ST_CON)
return 0;
cs->endp->flags |= CS_EP_ERROR;
return 1;
end:
if (did_send) {
oc->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
- if (si->state == SI_ST_CON)
- si->state = SI_ST_RDY;
+ if (si->cs->state == CS_ST_CON)
+ si->cs->state = CS_ST_RDY;
si_rx_room_rdy(si_opposite(si));
}
*/
int si_sync_recv(struct stream_interface *si)
{
- if (!si_state_in(si->state, SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(si->cs->state, CS_SB_RDY|CS_SB_EST))
return 0;
if (!cs_conn_mux(si->cs))
if (channel_is_empty(oc))
return;
- if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
return;
if (!cs_conn_mux(si->cs))
req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
- si_strm(si_b)->prev_conn_state = si_b->state;
+ si_strm(si_b)->prev_conn_state = si_b->cs->state;
/* let's recompute both sides states */
- if (si_state_in(si_f->state, SI_SB_RDY|SI_SB_EST))
+ if (cs_state_in(si_f->cs->state, CS_SB_RDY|CS_SB_EST))
si_update(si_f);
- if (si_state_in(si_b->state, SI_SB_RDY|SI_SB_EST))
+ if (cs_state_in(si_b->cs->state, CS_SB_RDY|CS_SB_EST))
si_update(si_b);
/* stream ints are processed outside of process_stream() and must be
ic->flags |= CF_SHUTR;
ic->rex = TICK_ETERNITY;
- if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
return;
if (si_oc(si)->flags & CF_SHUTW) {
cs_close(cs);
- si->state = SI_ST_DIS;
+ cs->state = CS_ST_DIS;
__cs_strm(cs)->conn_exp = TICK_ETERNITY;
}
else if (si->cs->flags & CS_FL_NOHALF) {
ic->rex = tick_add(now_ms, ic->rto);
}
- switch (si->state) {
- case SI_ST_RDY:
- case SI_ST_EST:
+ switch (cs->state) {
+ case CS_ST_RDY:
+ case CS_ST_EST:
/* we have to shut before closing, otherwise some short messages
* may never leave the system, especially when there are remaining
* unread data in the socket input buffer, or when nolinger is set.
}
/* fall through */
- case SI_ST_CON:
+ case CS_ST_CON:
/* we may have to close a pending connection, and mark the
* response buffer as shutr
*/
cs_close(cs);
/* fall through */
- case SI_ST_CER:
- case SI_ST_QUE:
- case SI_ST_TAR:
- si->state = SI_ST_DIS;
+ case CS_ST_CER:
+ case CS_ST_QUE:
+ case CS_ST_TAR:
+ cs->state = CS_ST_DIS;
/* fall through */
default:
cs->flags &= ~CS_FL_NOLINGER;
static void stream_int_chk_rcv_conn(struct stream_interface *si)
{
/* (re)start reading */
- if (si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+ if (cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
tasklet_wakeup(si->wait_event.tasklet);
}
BUG_ON(!cs_conn(cs));
- if (unlikely(!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST) ||
+ if (unlikely(!cs_state_in(cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST) ||
(oc->flags & CF_SHUTW)))
return;
if (cs->endp->flags & (CS_EP_ERROR|CS_EP_ERR_PENDING) || si_is_conn_error(si)) {
/* Write error on the file descriptor */
- if (si->state >= SI_ST_CON)
+ if (cs->state >= CS_ST_CON)
cs->endp->flags |= CS_EP_ERROR;
goto out_wakeup;
}
*/
if (((oc->flags & (CF_SHUTW|CF_AUTO_CLOSE|CF_SHUTW_NOW)) ==
(CF_AUTO_CLOSE|CF_SHUTW_NOW)) &&
- si_state_in(si->state, SI_SB_RDY|SI_SB_EST)) {
+ cs_state_in(cs->state, CS_SB_RDY|CS_SB_EST)) {
si_shutw(si);
goto out_wakeup;
}
if (likely((oc->flags & (CF_WRITE_NULL|CF_WRITE_ERROR|CF_SHUTW)) ||
((oc->flags & CF_WAKE_WRITE) &&
((channel_is_empty(oc) && !oc->to_forward) ||
- !si_state_in(si->state, SI_SB_EST))))) {
+ !cs_state_in(cs->state, CS_SB_EST))))) {
out_wakeup:
if (!(si->cs->flags & CS_FL_DONT_WAKE))
task_wakeup(si_task(si), TASK_WOKEN_IO);
int flags = 0;
/* If not established yet, do nothing. */
- if (si->state != SI_ST_EST)
+ if (cs->state != CS_ST_EST)
return 0;
/* If another call to si_cs_recv() failed, and we subscribed to
ic->flags |= CF_SHUTR;
ic->rex = TICK_ETERNITY;
- if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
return;
if (oc->flags & CF_SHUTW)
si_done_get(si);
- si->state = SI_ST_DIS;
+ cs->state = CS_ST_DIS;
__cs_strm(cs)->conn_exp = TICK_ETERNITY;
return;
}
/* Note: on shutr, we don't call the applet */
- if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+ if (!cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
return;
if (si_oc(si)->flags & CF_SHUTW) {
si_applet_release(si);
- si->state = SI_ST_DIS;
+ si->cs->state = CS_ST_DIS;
__cs_strm(si->cs)->conn_exp = TICK_ETERNITY;
}
else if (si->cs->flags & CS_FL_NOHALF) {
/* on shutw we always wake the applet up */
appctx_wakeup(__cs_appctx(si->cs));
- switch (si->state) {
- case SI_ST_RDY:
- case SI_ST_EST:
+ switch (si->cs->state) {
+ case CS_ST_RDY:
+ case CS_ST_EST:
/* we have to shut before closing, otherwise some short messages
* may never leave the system, especially when there are remaining
* unread data in the socket input buffer, or when nolinger is set.
return;
/* fall through */
- case SI_ST_CON:
- case SI_ST_CER:
- case SI_ST_QUE:
- case SI_ST_TAR:
+ case CS_ST_CON:
+ case CS_ST_CER:
+ case CS_ST_QUE:
+ case CS_ST_TAR:
/* Note that none of these states may happen with applets */
si_applet_release(si);
- si->state = SI_ST_DIS;
+ si->cs->state = CS_ST_DIS;
/* fall through */
default:
si->cs->flags &= ~CS_FL_NOLINGER;
BUG_ON(!cs_appctx(si->cs));
- DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+ DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
__FUNCTION__,
- si, si->state, ic->flags, si_oc(si)->flags);
+ si, si->cs->state, ic->flags, si_oc(si)->flags);
if (!ic->pipe) {
/* (re)start reading */
BUG_ON(!cs_appctx(si->cs));
- DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+ DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
__FUNCTION__,
- si, si->state, si_ic(si)->flags, oc->flags);
+ si, si->cs->state, si_ic(si)->flags, oc->flags);
- if (unlikely(si->state != SI_ST_EST || (oc->flags & CF_SHUTW)))
+ if (unlikely(si->cs->state != CS_ST_EST || (oc->flags & CF_SHUTW)))
return;
/* we only wake the applet up if it was waiting for some data */