mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MEDIUM: proxy/spoe: Add a SPOP mode
The SPOE was significantly lightened. It is now possible to refactor it to use a dedicated multiplexer. The first step is to add a SPOP mode for proxies. The corresponding multiplexer mode is also added. For now, there is no SPOP multiplexer, so it is only declarative. But at the end, the SPOP multiplexer will be automatically selected for servers inside a SPOP backend. The related issue is #2502.
This commit is contained in:
parent
b986952a75
commit
1538c4aa82
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ enum pr_mode {
|
||||
PR_MODE_CLI,
|
||||
PR_MODE_SYSLOG,
|
||||
PR_MODE_PEERS,
|
||||
PR_MODE_SPOP,
|
||||
PR_MODES
|
||||
} __attribute__((packed));
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <haproxy/session.h>
|
||||
#include <haproxy/ssl_sock.h>
|
||||
#include <haproxy/stconn.h>
|
||||
#include <haproxy/tcpcheck.h>
|
||||
#include <haproxy/tools.h>
|
||||
#include <haproxy/xxhash.h>
|
||||
|
||||
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user