const char *conn_err_code_name(struct connection *c);
const char *conn_err_code_str(struct connection *c);
int xprt_add_hs(struct connection *conn);
+int xprt_add_l6hs(struct connection *conn, int xprt);
void register_mux_proto(struct mux_proto_list *list);
static inline void conn_report_term_evt(struct connection *conn, enum term_event_loc loc, unsigned char type);
return 0;
}
+/* Activates an <xprt> layer on top of <conn> connection. This handshake layer
+ * should be designed to work on top of the layer 6. If SSL is active and its
+ * handshake still in progress, this function does nothing.
+ *
+ * Returns 0 on success else a negative error code.
+ */
+int xprt_add_l6hs(struct connection *conn, int xprt)
+{
+ const struct xprt_ops *ops = xprt_get(xprt);
+ void *ops_ctx = NULL;
+
+ /* Only QMux is supported as handshake on top of layer6 for now. */
+ BUG_ON(xprt != XPRT_QMUX);
+
+ if (conn->flags & CO_FL_ERROR)
+ return -1;
+
+ /* Do nothing if SSL is in used but handshake still in progress. In
+ * this case, xprt layer will be added on handshake completion.
+ */
+ if (conn->xprt == xprt_get(XPRT_SSL) &&
+ (conn->flags & CO_FL_WAIT_L6_CONN)) {
+ return 0;
+ }
+
+ if (ops->init(conn, &ops_ctx))
+ return -1;
+
+ ops->add_xprt(conn, ops_ctx, conn->xprt_ctx, conn->xprt, NULL, NULL);
+ conn->xprt = ops;
+ conn->xprt_ctx = ops_ctx;
+ /* Reset XPRT READY flag before the next conn_xprt_start(). */
+ conn->flags &= ~CO_FL_XPRT_READY;
+
+ return 0;
+}
+
/* returns a short name for an error, typically the same as the enum name
* without the "CO_ER_" prefix, or an empty string for no error (better eye
* catching in logs). This is more compact for some debug cases.
mux = !conn_is_back(conn) ?
conn_select_mux_fe(conn) : conn_select_mux_be(conn);
- if (mux->init_xprt == XPRT_QMUX) {
- const struct xprt_ops *ops = xprt_get(XPRT_QMUX);
- void *xprt_ctx_hs = NULL;
-
- ret = ops->init(conn, &xprt_ctx_hs);
+ if (mux->init_xprt) {
+ ret = xprt_add_l6hs(conn, mux->init_xprt);
/* Frontend conn must be freed in case of XPRT init failure. */
if (ret) {
if (!conn_is_back(conn)) {
goto leave;
}
- ret = ops->add_xprt(conn, xprt_ctx_hs,
- conn->xprt_ctx, conn->xprt, NULL, NULL);
- BUG_ON(ret); /* xprt_qmux add_xprt always succeeds */
-
- conn->xprt = ops;
- conn->xprt_ctx = xprt_ctx_hs;
-
- ret = conn->xprt->start(conn, xprt_ctx_hs);
- BUG_ON(ret);
+ ret = conn_xprt_start(conn);
}
else {
/* TODO MUX selection already performs by conn_select_mux_fe/be().