int (*add_xprt)(struct connection *conn, void *xprt_ctx, void *toadd_ctx, const struct xprt_ops *toadd_ops, void **oldxprt_ctx, const struct xprt_ops **oldxprt_ops); /* Add a new XPRT as the new xprt, and return the old one */
};
+enum mux_ctl_type {
+ MUX_STATUS, /* Expects an int as output, sets it to a combinaison of MUX_STATUS flags */
+};
+
+#define MUX_STATUS_READY (1 << 0)
+
/* mux_ops describes the mux operations, which are to be performed at the
* connection level after data are exchanged with the transport layer in order
* to propagate them to streams. The <init> function will automatically be
void (*destroy)(void *ctx); /* Let the mux know one of its users left, so it may have to disappear */
void (*reset)(struct connection *conn); /* Reset the mux, because we're re-trying to connect */
const struct cs_info *(*get_cs_info)(struct conn_stream *cs); /* Return info on the specified conn_stream or NULL if not defined */
+ int (*ctl)(struct connection *conn, enum mux_ctl_type mux_ctl, void *arg); /* Provides informations about the mux */
unsigned int flags; /* some flags characterizing the mux's capabilities (MX_FL_*) */
char name[8]; /* mux layer name, zero-terminated */
};
return (fcgi_process(fconn));
}
+
+static int fcgi_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *output)
+{
+ int ret = 0;
+ switch (mux_ctl) {
+ case MUX_STATUS:
+ if (conn->flags & CO_FL_CONNECTED)
+ ret |= MUX_STATUS_READY;
+ return ret;
+ default:
+ return -1;
+ }
+}
+
/* Connection timeout management. The principle is that if there's no receipt
* nor sending for a certain amount of time, the connection is closed. If the
* MUX buffer still has lying data or is not allocatable, the connection is
.unsubscribe = fcgi_unsubscribe,
.shutr = fcgi_shutr,
.shutw = fcgi_shutw,
+ .ctl = fcgi_ctl,
.show_fd = fcgi_show_fd,
.flags = MX_FL_HTX,
.name = "FCGI",
}
#endif
+static int h1_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *output)
+{
+ int ret = 0;
+ switch (mux_ctl) {
+ case MUX_STATUS:
+ if (conn->flags & CO_FL_CONNECTED)
+ ret |= MUX_STATUS_READY;
+ return ret;
+ default:
+ return -1;
+ }
+}
+
/* for debugging with CLI's "show fd" command */
static void h1_show_fd(struct buffer *msg, struct connection *conn)
{
.shutw = h1_shutw,
.show_fd = h1_show_fd,
.reset = h1_reset,
+ .ctl = h1_ctl,
.flags = MX_FL_HTX,
.name = "H1",
};
return NULL;
}
+static int h2_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *output)
+{
+ int ret = 0;
+ struct h2c *h2c = conn->ctx;
+
+ switch (mux_ctl) {
+ case MUX_STATUS:
+ /* Only consider the mux to be ready if we're done with
+ * the preface and settings, and we had no error.
+ */
+ if (h2c->st0 >= H2_CS_FRAME_H && h2c->st0 < H2_CS_ERROR)
+ ret |= MUX_STATUS_READY;
+ return ret;
+ default:
+ return -1;
+ }
+}
+
/*
* Destroy the mux and the associated connection, if it is no longer used
*/
.used_streams = h2_used_streams,
.shutr = h2_shutr,
.shutw = h2_shutw,
+ .ctl = h2_ctl,
.show_fd = h2_show_fd,
.flags = MX_FL_CLEAN_ABRT|MX_FL_HTX,
.name = "H2",
}
#endif
+static int mux_pt_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *output)
+{
+ int ret = 0;
+ switch (mux_ctl) {
+ case MUX_STATUS:
+ if (conn->flags & CO_FL_CONNECTED)
+ ret |= MUX_STATUS_READY;
+ return ret;
+ default:
+ return -1;
+ }
+}
+
/* The mux operations */
const struct mux_ops mux_pt_ops = {
.init = mux_pt_init,
.avail_streams = mux_pt_avail_streams,
.used_streams = mux_pt_used_streams,
.destroy = mux_pt_destroy_meth,
+ .ctl = mux_pt_ctl,
.shutr = mux_pt_shutr,
.shutw = mux_pt_shutw,
.flags = MX_FL_NONE,