*/
static inline const struct mux_proto_list *conn_get_best_mux_entry(
const struct ist mux_proto,
+ const struct ist alpn,
int proto_side, int proto_is_quic, int proto_mode)
{
struct mux_proto_list *item;
if (istlen(mux_proto) && isteq(mux_proto, item->mux_proto)) {
return item;
}
+ else if (istlen(alpn) && item->alpn &&
+ strlen(item->alpn) == istlen(alpn) + 1 &&
+ !memcmp(alpn.ptr, item->alpn + 1, istlen(alpn)))
+ return item;
else if (!istlen(item->mux_proto)) {
if (!fallback || (item->mode == proto_mode && fallback->mode != proto_mode))
fallback = item;
*/
static inline const struct mux_ops *conn_get_best_mux(struct connection *conn,
const struct ist mux_proto,
+ const struct ist alpn,
int proto_side, int proto_mode)
{
const struct mux_proto_list *item;
- item = conn_get_best_mux_entry(mux_proto, proto_side, proto_is_quic(conn->ctrl), proto_mode);
+ item = conn_get_best_mux_entry(mux_proto, alpn, proto_side, proto_is_quic(conn->ctrl), proto_mode);
return item ? item->mux : NULL;
}
struct ist mux_proto, int mode)
{
struct bind_conf *bind_conf = __objt_listener(conn->target)->bind_conf;
+ struct ist alpn = IST_NULL;
const struct mux_ops *old_mux, *new_mux;
void *old_mux_ctx;
const char *alpn_str = NULL;
if (!mux_proto.len) {
conn_get_alpn(conn, &alpn_str, &alpn_len);
- mux_proto = ist2(alpn_str, alpn_len);
+ alpn = ist2(alpn_str, alpn_len);
}
- new_mux = conn_get_best_mux(conn, mux_proto, PROTO_SIDE_FE, mode);
+ new_mux = conn_get_best_mux(conn, mux_proto, alpn, PROTO_SIDE_FE, mode);
old_mux = conn->mux;
/* No mux found */
if (bind_conf->mux_proto)
mux_ops = bind_conf->mux_proto->mux;
else {
- struct ist mux_proto;
+ struct ist alpn;
const char *alpn_str = NULL;
int alpn_len = 0;
int mode = conn_pr_mode_to_proto_mode(bind_conf->frontend->mode);
conn_get_alpn(conn, &alpn_str, &alpn_len);
- mux_proto = ist2(alpn_str, alpn_len);
- mux_ops = conn_get_best_mux(conn, mux_proto, PROTO_SIDE_FE, mode);
+ alpn = ist2(alpn_str, alpn_len);
+ mux_ops = conn_get_best_mux(conn, IST_NULL, alpn, PROTO_SIDE_FE, mode);
if (!mux_ops)
return -1;
}
mux_ops = force_mux_ops;
}
else {
- struct ist mux_proto;
+ struct ist alpn;
const char *alpn_str = NULL;
int alpn_len = 0;
int mode = conn_pr_mode_to_proto_mode(prx->mode);
alpn_len = strlen(alpn_str);
}
}
- mux_proto = ist2(alpn_str, alpn_len);
+ alpn = ist2(alpn_str, alpn_len);
- mux_ops = conn_get_best_mux(conn, mux_proto, PROTO_SIDE_BE, mode);
+ mux_ops = conn_get_best_mux(conn, IST_NULL, alpn, PROTO_SIDE_BE, mode);
if (!mux_ops)
return -1;
}
if (check->mux_proto)
mux_ops = check->mux_proto->mux;
else {
- struct ist mux_proto;
+ struct ist alpn;
const char *alpn_str = NULL;
int alpn_len = 0;
int mode = tcpchk_rules_type_to_proto_mode(check->tcpcheck->rs->flags);
conn_get_alpn(conn, &alpn_str, &alpn_len);
- mux_proto = ist2(alpn_str, alpn_len);
+ alpn = ist2(alpn_str, alpn_len);
- mux_ops = conn_get_best_mux(conn, mux_proto, PROTO_SIDE_BE, mode);
+ mux_ops = conn_get_best_mux(conn, IST_NULL, alpn, PROTO_SIDE_BE, mode);
if (!mux_ops)
return -1;
}
* due to the proxy's mode not being taken into account
* on first pass. Let's adjust it now.
*/
- mux_ent = conn_get_best_mux_entry(bind_conf->mux_proto->mux_proto, PROTO_SIDE_FE, is_quic, mode);
+ mux_ent = conn_get_best_mux_entry(bind_conf->mux_proto->mux_proto, IST_NULL, PROTO_SIDE_FE, is_quic, mode);
if (!mux_ent || !isteq(mux_ent->mux_proto, bind_conf->mux_proto->mux_proto)) {
ha_alert("%s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
* due to the proxy's mode not being taken into account
* on first pass. Let's adjust it now.
*/
- mux_ent = conn_get_best_mux_entry(newsrv->mux_proto->mux_proto, PROTO_SIDE_BE, srv_is_quic(newsrv), mode);
+ mux_ent = conn_get_best_mux_entry(newsrv->mux_proto->mux_proto, IST_NULL, PROTO_SIDE_BE, srv_is_quic(newsrv), mode);
if (!mux_ent || !isteq(mux_ent->mux_proto, newsrv->mux_proto->mux_proto)) {
ha_alert("%s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
int proto_mode = conn_pr_mode_to_proto_mode(be->mode);
const struct mux_proto_list *mux_ent;
- mux_ent = conn_get_best_mux_entry(srv->mux_proto->mux_proto, PROTO_SIDE_BE, srv_is_quic(srv), proto_mode);
+ mux_ent = conn_get_best_mux_entry(srv->mux_proto->mux_proto, IST_NULL, PROTO_SIDE_BE, srv_is_quic(srv), proto_mode);
if (!mux_ent || !isteq(mux_ent->mux_proto, srv->mux_proto->mux_proto)) {
ha_alert("MUX protocol is not usable for server.\n");
px->options |= PR_O_HTTP_UPG;
if (mux_proto) {
- mux_ent = conn_get_best_mux_entry(mux_proto->mux_proto, PROTO_SIDE_FE, 0, mode);
+ mux_ent = conn_get_best_mux_entry(mux_proto->mux_proto, IST_NULL, PROTO_SIDE_FE, 0, mode);
if (!mux_ent || !isteq(mux_ent->mux_proto, mux_proto->mux_proto)) {
memprintf(err, "MUX protocol '%.*s' is not compatible with the selected mode",
(int)mux_proto->mux_proto.len, mux_proto->mux_proto.ptr);
}
}
else {
- mux_ent = conn_get_best_mux_entry(IST_NULL, PROTO_SIDE_FE, 0, mode);
+ mux_ent = conn_get_best_mux_entry(IST_NULL, IST_NULL, PROTO_SIDE_FE, 0, mode);
if (!mux_ent) {
memprintf(err, "Unable to find compatible MUX protocol with the selected mode");
return 0;
else {
int mode = tcpchk_rules_type_to_proto_mode(check->tcpcheck->rs->flags);
- mux_ops = conn_get_best_mux(conn, IST_NULL, PROTO_SIDE_BE, mode);
+ mux_ops = conn_get_best_mux(conn, IST_NULL, IST_NULL, PROTO_SIDE_BE, mode);
}
if (mux_ops && conn_install_mux(conn, mux_ops, check->sc, proxy, check->sess) < 0) {
TRACE_ERROR("failed to install mux", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check);