MINOR: backend: only allow reuse for reverse server

A reverse server relies solely on its pool of idle connection to
transfer requests which will be populated through a new tcp-request rule
'attach-srv'.

Several changes are required on connect_server() to implement this.
First, reuse mode is forced to always for this type of server. Then, if
no idle connection is found, the request will be aborted. This results
with a 503 HTTP error code, similarly to when no server is available.
This commit is contained in:
Amaury Denoyelle 2023-08-18 16:02:35 +02:00
parent e6223a3188
commit 6e428dfaf2
2 changed files with 23 additions and 2 deletions

View File

@ -33,6 +33,7 @@
#include <haproxy/task.h>
#include <haproxy/thread-t.h>
#include <haproxy/time.h>
#include <haproxy/tools.h>
__decl_thread(extern HA_SPINLOCK_T idle_conn_srv_lock);
@ -305,6 +306,16 @@ static inline void srv_minmax_conn_apply(struct server *srv)
}
}
/* Returns true if server is used as transparent mode. */
static inline int srv_is_transparent(const struct server *srv)
{
/* A reverse server does not have any address but it is not used as a
* transparent one.
*/
return (!is_addr(&srv->addr) && !(srv->flags & SRV_F_REVERSE)) ||
(srv->flags & SRV_F_MAPPORTS);
}
#endif /* _HAPROXY_SERVER_H */
/*

View File

@ -1326,7 +1326,7 @@ static int connect_server(struct stream *s)
struct connection *cli_conn = objt_conn(strm_orig(s));
struct connection *srv_conn = NULL;
struct server *srv;
const int reuse_mode = s->be->options & PR_O_REUSE_MASK;
int reuse_mode = s->be->options & PR_O_REUSE_MASK;
int reuse = 0;
int init_mux = 0;
int err;
@ -1342,6 +1342,10 @@ static int connect_server(struct stream *s)
* it can be NULL for dispatch mode or transparent backend */
srv = objt_server(s->target);
/* Override reuse-mode if reverse-connect is used. */
if (srv && srv->flags & SRV_F_REVERSE)
reuse_mode = PR_O_REUSE_ALWS;
err = alloc_dst_address(&s->scb->dst, srv, s);
if (err != SRV_STATUS_OK)
return SF_ERR_INTERNAL;
@ -1393,7 +1397,7 @@ static int connect_server(struct stream *s)
#endif /* USE_OPENSSL */
/* 3. destination address */
if (srv && (!is_addr(&srv->addr) || srv->flags & SRV_F_MAPPORTS))
if (srv && srv_is_transparent(srv))
hash_params.dst_addr = s->scb->dst;
/* 4. source address */
@ -1587,6 +1591,12 @@ static int connect_server(struct stream *s)
skip_reuse:
/* no reuse or failed to reuse the connection above, pick a new one */
if (!srv_conn) {
if (srv && (srv->flags & SRV_F_REVERSE)) {
DBG_TRACE_USER("cannot open a new connection for reverse server", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
s->conn_err_type = STRM_ET_CONN_ERR;
return SF_ERR_INTERNAL;
}
srv_conn = conn_new(s->target);
if (srv_conn) {
DBG_TRACE_STATE("alloc new be connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);