diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 83969da06..dba52fa32 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -306,7 +306,8 @@ enum proto_proxy_mode { PROTO_MODE_NONE = 0, PROTO_MODE_TCP = 1 << 0, // must not be changed! PROTO_MODE_HTTP = 1 << 1, // must not be changed! - PROTO_MODE_ANY = PROTO_MODE_TCP | PROTO_MODE_HTTP, + PROTO_MODE_SPOP = 1 << 2, // must not be changed! + PROTO_MODE_ANY = PROTO_MODE_TCP | PROTO_MODE_HTTP | PROTO_MODE_SPOP, }; enum proto_proxy_side { diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index aa61cc71a..dc187eb91 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -722,10 +722,9 @@ static inline int conn_pr_mode_to_proto_mode(int proxy_mode) { int mode; - /* for now we only support TCP and HTTP proto_modes, so we - * consider that if it's not HTTP, then it's TCP - */ - mode = 1 << (proxy_mode == PR_MODE_HTTP); + mode = ((proxy_mode == PR_MODE_HTTP) ? PROTO_MODE_HTTP : + (proxy_mode == PR_MODE_SPOP) ? PROTO_MODE_SPOP : + PROTO_MODE_TCP); return mode; } diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index 262dc11d5..9bafb22e5 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -52,6 +52,7 @@ enum pr_mode { PR_MODE_CLI, PR_MODE_SYSLOG, PR_MODE_PEERS, + PR_MODE_SPOP, PR_MODES } __attribute__((packed)); diff --git a/include/haproxy/tcpcheck.h b/include/haproxy/tcpcheck.h index 55c564a20..95244a521 100644 --- a/include/haproxy/tcpcheck.h +++ b/include/haproxy/tcpcheck.h @@ -119,6 +119,20 @@ static inline void action_kw_tcp_check_build_list(struct buffer *chk) action_build_list(&tcp_check_keywords.list, chk); } +/* + * Map tcpcheck rules type (TCPCHK_RULES_*) to equivalent proto_proxy_mode (PROTO_MODE_*) + */ +static inline int tcpchk_rules_type_to_proto_mode(int tcpchk_rules_type) +{ + int mode; + + mode = (((tcpchk_rules_type & TCPCHK_RULES_PROTO_CHK) == TCPCHK_RULES_HTTP_CHK) ? PROTO_MODE_HTTP : + (((tcpchk_rules_type & TCPCHK_RULES_PROTO_CHK) == TCPCHK_RULES_SPOP_CHK) ? PROTO_MODE_SPOP : + PROTO_MODE_TCP)); + + return mode; +} + #endif /* _HAPROXY_TCPCHECK_H */ /* diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 1f6ddc2ad..2beb9377b 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -545,6 +545,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) if (strcmp(args[1], "http") == 0) curproxy->mode = PR_MODE_HTTP; else if (strcmp(args[1], "tcp") == 0) curproxy->mode = PR_MODE_TCP; else if (strcmp(args[1], "log") == 0 && (curproxy->cap & PR_CAP_BE)) curproxy->mode = PR_MODE_SYSLOG; + else if (strcmp(args[1], "spop") == 0 && (curproxy->cap & PR_CAP_BE)) curproxy->mode = PR_MODE_SPOP; else if (strcmp(args[1], "health") == 0) { ha_alert("parsing [%s:%d] : 'mode health' doesn't exist anymore. Please use 'http-request return status 200' instead.\n", file, linenum); err_code |= ERR_ALERT | ERR_FATAL; diff --git a/src/cfgparse.c b/src/cfgparse.c index 2434de2cb..990d2a488 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2977,6 +2977,11 @@ int check_config_validity() cfgerr += proxy_cfg_ensure_no_http(curproxy); break; + case PR_MODE_SPOP: + cfgerr += proxy_cfg_ensure_no_http(curproxy); + cfgerr += proxy_cfg_ensure_no_log(curproxy); + break; + case PR_MODE_PEERS: case PR_MODES: /* should not happen, bug gcc warn missing switch statement */ diff --git a/src/check.c b/src/check.c index 64464c4f4..40d403b27 100644 --- a/src/check.c +++ b/src/check.c @@ -1826,12 +1826,14 @@ int init_srv_check(struct server *srv) */ if (srv->mux_proto && !srv->check.mux_proto && ((srv->mux_proto->mode == PROTO_MODE_HTTP && check_type == TCPCHK_RULES_HTTP_CHK) || + (srv->mux_proto->mode == PROTO_MODE_SPOP && check_type == TCPCHK_RULES_SPOP_CHK) || (srv->mux_proto->mode == PROTO_MODE_TCP && check_type != TCPCHK_RULES_HTTP_CHK))) { srv->check.mux_proto = srv->mux_proto; } /* test that check proto is valid if explicitly defined */ else if (srv->check.mux_proto && ((srv->check.mux_proto->mode == PROTO_MODE_HTTP && check_type != TCPCHK_RULES_HTTP_CHK) || + (srv->check.mux_proto->mode == PROTO_MODE_SPOP && check_type != TCPCHK_RULES_SPOP_CHK) || (srv->check.mux_proto->mode == PROTO_MODE_TCP && check_type == TCPCHK_RULES_HTTP_CHK))) { ha_alert("config: %s '%s': server '%s' uses an incompatible MUX protocol for the selected check type\n", proxy_type_str(srv->proxy), srv->proxy->id, srv->id); diff --git a/src/connection.c b/src/connection.c index 3fedad9a5..668e626f5 100644 --- a/src/connection.c +++ b/src/connection.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -271,12 +272,7 @@ int conn_install_mux_fe(struct connection *conn, void *ctx) struct ist mux_proto; const char *alpn_str = NULL; int alpn_len = 0; - int mode; - - if (bind_conf->frontend->mode == PR_MODE_HTTP) - mode = PROTO_MODE_HTTP; - else - mode = PROTO_MODE_TCP; + 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); @@ -326,12 +322,7 @@ int conn_install_mux_be(struct connection *conn, void *ctx, struct session *sess struct ist mux_proto; const char *alpn_str = NULL; int alpn_len = 0; - int mode; - - if (prx->mode == PR_MODE_HTTP) - mode = PROTO_MODE_HTTP; - else - mode = PROTO_MODE_TCP; + int mode = conn_pr_mode_to_proto_mode(prx->mode); conn_get_alpn(conn, &alpn_str, &alpn_len); mux_proto = ist2(alpn_str, alpn_len); @@ -369,12 +360,7 @@ int conn_install_mux_chk(struct connection *conn, void *ctx, struct session *ses struct ist mux_proto; const char *alpn_str = NULL; int alpn_len = 0; - int mode; - - if ((check->tcpcheck_rules->flags & TCPCHK_RULES_PROTO_CHK) == TCPCHK_RULES_HTTP_CHK) - mode = PROTO_MODE_HTTP; - else - mode = PROTO_MODE_TCP; + int mode = tcpchk_rules_type_to_proto_mode(check->tcpcheck_rules->flags); conn_get_alpn(conn, &alpn_str, &alpn_len); mux_proto = ist2(alpn_str, alpn_len); @@ -1811,6 +1797,8 @@ void list_mux_proto(FILE *out) mode = "TCP"; else if (item->mode == PROTO_MODE_HTTP) mode = "HTTP"; + else if (item->mode == PROTO_MODE_SPOP) + mode = "SPOP"; else mode = "NONE"; diff --git a/src/extcheck.c b/src/extcheck.c index 05c53ff9f..f01931b9d 100644 --- a/src/extcheck.c +++ b/src/extcheck.c @@ -348,6 +348,7 @@ int prepare_external_check(struct check *check) case PR_MODE_PEERS: svmode = "peers"; break; case PR_MODE_HTTP: svmode = (s->mux_proto) ? s->mux_proto->token.ptr : "h1"; break; case PR_MODE_TCP: svmode = "tcp"; break; + case PR_MODE_SPOP: svmode = "spop"; break; /* all valid cases must be enumerated above, below is to avoid a warning */ case PR_MODES: svmode = "?"; break; } diff --git a/src/fcgi-app.c b/src/fcgi-app.c index 5790cebcf..b3a9b7c59 100644 --- a/src/fcgi-app.c +++ b/src/fcgi-app.c @@ -642,7 +642,7 @@ static int cfg_fcgi_apps_postparser() struct fcgi_flt_conf *fcgi_conf = find_px_fcgi_conf(px); int nb_fcgi_srv = 0; - if (px->mode == PR_MODE_TCP && fcgi_conf) { + if (px->mode != PR_MODE_HTTP && fcgi_conf) { ha_alert("proxy '%s': FCGI application cannot be used in non-HTTP mode.\n", px->id); err_code |= ERR_ALERT | ERR_FATAL; diff --git a/src/proxy.c b/src/proxy.c index 10cb78025..da589a28e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -431,6 +431,8 @@ const char *proxy_mode_str(int mode) { return "syslog"; else if (mode == PR_MODE_PEERS) return "peers"; + else if (mode == PR_MODE_SPOP) + return "spop"; else return "unknown"; } @@ -1881,11 +1883,11 @@ void proxy_cond_disable(struct proxy *p) * peers, etc) we must not report them at all as they're not really on * the data plane but on the control plane. */ - if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP || p->mode == PR_MODE_SYSLOG) && !(p->cap & PR_CAP_INT)) + if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP || p->mode == PR_MODE_SYSLOG || p->mode == PR_MODE_SPOP) && !(p->cap & PR_CAP_INT)) ha_warning("Proxy %s stopped (cumulated conns: FE: %lld, BE: %lld).\n", p->id, p->fe_counters.cum_conn, p->be_counters.cum_sess); - if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP) && !(p->cap & PR_CAP_INT)) + if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP || p->mode == PR_MODE_SPOP) && !(p->cap & PR_CAP_INT)) send_log(p, LOG_WARNING, "Proxy %s stopped (cumulated conns: FE: %lld, BE: %lld).\n", p->id, p->fe_counters.cum_conn, p->be_counters.cum_sess);