When http connection sharing is enabled, a great care is taken to respect the
connection properties and compatibility. Indeed, some properties are specific
- and it is not possible to reuse it blindly. Those are the SSL SNI, source
- and destination address, proxy protocol block as well as tos and mark
- sockopts. A connection is reused only if it shares the same set of properties
- with the request.
+ and it is not possible to reuse it blindly. Those are the source and
+ destination address, proxy protocol block as well as tos and mark sockopts.
+ It is also possible to manually define an extra expression identifier using
+ "pool-conn-name" server keyword, or "sni" as a fallback. A connection is
+ reused only if it shares the same set of properties with the request.
Also note that connections with certain bogus authentication schemes (relying
on the connection) like NTLM are marked private if possible and never shared.
An extra parameter <expr> can be specified. Its value is interpreted as a
sample expression to name the connection inside the server idle pool. When
routing an outgoing request through this server, this name will be matched
- against the 'sni' parameter of the server line. Otherwise, the connection
- will have no name and will only match requests without SNI.
+ against the 'pool-conn-name' parameter of the server line, or 'sni' as a
+ fallback. Otherwise, the connection will have no extra identifier and will
+ only match requests without name.
This rule is only valid for frontend in HTTP mode. Also all listeners must
not require a protocol different from HTTP/2.
Actions are disabled by default
+pool-conn-name <expr>
+ May be used in the following contexts: http
+
+ Set an expression which will be interpreted to differentiate connections
+ inside the server idle pool. On reuse, only connection with identical name
+ will be eligible. If SNI expression is defined but not this parameter, it
+ will act as idle pool identifier to guarantee that SNI match on reuse.
+
pool-low-conn <max>
May be used in the following contexts: http
return 0;
}
+static int srv_parse_pool_conn_name(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
+{
+ char *arg;
+
+ arg = args[*cur_arg + 1];
+ if (!*arg) {
+ memprintf(err, "'%s' expects <value> as argument", args[*cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ ha_free(&newsrv->pool_conn_name);
+ newsrv->pool_conn_name = strdup(arg);
+ if (!newsrv->pool_conn_name) {
+ memprintf(err, "'%s' : out of memory", args[*cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ return 0;
+}
+
static int srv_parse_pool_low_conn(char **args, int *cur_arg, struct proxy *curproxy, struct server *newsrv, char **err)
{
char *arg;
{ "on-error", srv_parse_on_error, 1, 1, 1 }, /* Configure the action on check failure */
{ "on-marked-down", srv_parse_on_marked_down, 1, 1, 1 }, /* Configure the action when a server is marked down */
{ "on-marked-up", srv_parse_on_marked_up, 1, 1, 1 }, /* Configure the action when a server is marked up */
+ { "pool-conn-name", srv_parse_pool_conn_name, 1, 1, 1 }, /* Define expression to identify connections in idle pool */
{ "pool-low-conn", srv_parse_pool_low_conn, 1, 1, 1 }, /* Set the min number of orphan idle connecbefore being allowed to pick from other threads */
{ "pool-max-conn", srv_parse_pool_max_conn, 1, 1, 1 }, /* Set the max number of orphan idle connections, -1 means unlimited */
{ "pool-purge-delay", srv_parse_pool_purge_delay, 1, 1, 1 }, /* Set the time before we destroy orphan idle connections, defaults to 1s */
srv->tcp_ut = src->tcp_ut;
#endif
srv->mux_proto = src->mux_proto;
+ if (srv->pool_conn_name)
+ srv->pool_conn_name = strdup(srv->pool_conn_name);
srv->pool_purge_delay = src->pool_purge_delay;
srv->low_idle_conns = src->low_idle_conns;
srv->max_idle_conns = src->max_idle_conns;
free(srv->per_thr);
free(srv->per_tgrp);
free(srv->curr_idle_thr);
+ free(srv->pool_conn_name);
+ release_sample_expr(srv->pool_conn_name_expr);
free(srv->resolvers_id);
free(srv->addr_node.key);
free(srv->lb_nodes);
srv_settings_cpy(newsrv, srv, 1);
srv_prepare_for_resolution(newsrv, srv->hostname);
+ /* Use sni as fallback if pool_conn_name isn't set */
+ if (!newsrv->pool_conn_name && newsrv->sni_expr) {
+ newsrv->pool_conn_name = strdup(newsrv->sni_expr);
+ if (!newsrv->pool_conn_name)
+ goto err;
+ }
+
+ if (newsrv->pool_conn_name) {
+ newsrv->pool_conn_name_expr = _parse_srv_expr(srv->pool_conn_name, &px->conf.args, NULL, 0, NULL);
+ if (!newsrv->pool_conn_name_expr)
+ goto err;
+ }
+
if (newsrv->sni_expr) {
newsrv->ssl_ctx.sni = _parse_srv_expr(srv->sni_expr, &px->conf.args, NULL, 0, NULL);
if (!newsrv->ssl_ctx.sni)
return ret;
}
+ /* Use sni as fallback if pool_conn_name isn't set */
+ if (!srv->pool_conn_name && srv->sni_expr) {
+ srv->pool_conn_name = strdup(srv->sni_expr);
+ if (!srv->pool_conn_name) {
+ ha_alert("out of memory\n");
+ return ERR_ALERT | ERR_FATAL;
+ }
+ }
+
+ if ((ret = parse_srv_expr(srv->pool_conn_name, &srv->pool_conn_name_expr,
+ px, &errmsg))) {
+ if (errmsg) {
+ ha_alert("error detected while parsing pool-conn-name expression : %s.\n", errmsg);
+ free(errmsg);
+ }
+ return ret;
+ }
+
/* A dynamic server is disabled on startup. It must not be counted as
* an active backend entry.
*/
}
if (rule->arg.attach_srv.name) {
- if (!srv->sni_expr) {
- memprintf(err, "attach-srv rule has a name argument while server '%s/%s' does not have an sni argument; either add a sni argument to the server or remove the name argument from this attach-srv rule", ist0(be_name), ist0(sv_name));
+ if (!srv->pool_conn_name) {
+ memprintf(err, "attach-srv rule has a name argument while server '%s/%s' does not use pool-conn-name; either reconfigure the server or remove the name argument from this attach-srv rule", ist0(be_name), ist0(sv_name));
return 0;
}
} else {
- if (srv->sni_expr) {
- memprintf(err, "attach-srv rule has no name argument while server '%s/%s' has an sni argument; either add a name argument to the attach-srv rule or remove the sni argument from the server", ist0(be_name), ist0(sv_name));
+ if (srv->pool_conn_name) {
+ memprintf(err, "attach-srv rule has no name argument while server '%s/%s' uses pool-conn-name; either add a name argument to the attach-srv rule or reconfigure the server", ist0(be_name), ist0(sv_name));
return 0;
}
}