/* Calculate hash to select a matching connection for reuse. Here is the list
* of input parameters :
* - <srv> is the server instance. Can be NULL on dispatch/transparent proxy.
- * - <strm> is the stream instance.
+ * - <strm> is the stream instance. Can be NULL if no stream is used.
* - <src> is the bind address if an explicit source address is used.
* - <dst> is the destination address. Must be set in every cases, except on
* reverse HTTP.
*
+ * Note that all input parameters can be NULL. The only requirement is that
+ * it's not possible to have both <srv> and <strm> NULL at the same time.
+ *
* Returns the calculated hash.
*/
int64_t be_calculate_conn_hash(struct server *srv, struct stream *strm,
hash_params.src_addr = src;
/* 5. proxy protocol */
- if (srv && srv->pp_opts & SRV_PP_ENABLED) {
+ if (strm && srv && srv->pp_opts & SRV_PP_ENABLED) {
struct connection *cli_conn = objt_conn(strm_orig(strm));
int proxy_line_ret = make_proxy_line(trash.area, trash.size,
srv, cli_conn, strm, sess);
}
/* 6. Custom mark, tos? */
- if (strm->flags & (SF_BC_MARK | SF_BC_TOS)) {
+ if (strm && (strm->flags & (SF_BC_MARK | SF_BC_TOS))) {
/* mark: 32bits, tos: 8bits = 40bits
* last 2 bits are there to indicate if mark and/or tos are set
* total: 42bits:
#include <haproxy/action.h>
#include <haproxy/api.h>
+#include <haproxy/backend.h>
#include <haproxy/cfgparse.h>
#include <haproxy/check.h>
#include <haproxy/chunk.h>
goto out;
}
+/* Returns true if <check> or <connect> rule uses any specific connect options
+ * which may differ from their underlying server counterparts.
+ */
+static inline int tcpcheck_use_nondefault_connect(const struct check *check,
+ const struct tcpcheck_connect *connect)
+{
+ return check->mux_proto || connect->mux_proto ||
+ is_addr(&check->addr) || is_addr(&connect->addr) ||
+ check->port || connect->port || connect->port_expr ||
+ check->use_ssl || check->sni || connect->sni || check->alpn_len || connect->alpn_len ||
+ check->send_proxy || check->via_socks4 ||
+ (connect->options & TCPCHK_MASK_OPTS_CONNECT);
+}
+
/* Evaluates a TCPCHK_ACT_CONNECT rule. Returns TCPCHK_EVAL_WAIT to wait the
* connection establishment, TCPCHK_EVAL_CONTINUE to evaluate the next rule or
* TCPCHK_EVAL_STOP if an error occurred.
check_release_buf(check, &check->bi);
check_release_buf(check, &check->bo);
+ if (!(check->state & CHK_ST_AGENT) && check->reuse_pool &&
+ !tcpcheck_use_nondefault_connect(check, connect)) {
+ int64_t hash;
+ int conn_err;
+
+ TRACE_DEVEL("trying connection reuse for check", CHK_EV_TCPCHK_CONN, check);
+
+ hash = be_calculate_conn_hash(s, NULL, check->sess, NULL, NULL);
+ conn_err = be_reuse_connection(hash, check->sess, s->proxy, s,
+ check->sc, &s->obj_type, 0);
+ if (conn_err == SF_ERR_INTERNAL) {
+ TRACE_ERROR("error during connection reuse", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check);
+ set_server_check_status(check, HCHK_STATUS_SOCKERR, trash.area);
+ ret = TCPCHK_EVAL_STOP;
+ goto out;
+ }
+ else if (conn_err == SF_ERR_NONE) {
+ TRACE_STATE("check performed with connection reuse", CHK_EV_TCPCHK_CONN, check);
+ conn = __sc_conn(check->sc);
+ conn_set_owner(conn, check->sess, NULL);
+ /* connection will be reinsert in idle conn pool due to missing conn_set_private(). */
+ status = SF_ERR_NONE;
+ goto skip_connect;
+ }
+ }
+
/* No connection, prepare a new one */
conn = conn_new((s ? &s->obj_type : &proxy->obj_type));
if (!conn) {
}
fail_check:
+ skip_connect:
/* It can return one of :
* - SF_ERR_NONE if everything's OK
* - SF_ERR_SRVTO if there are no more servers