MINOR: quic: handle perm error on bind during runtime
Improve EACCES permission errors encounterd when using QUIC connection socket at runtime : * First occurence of the error on the process will generate a log warning. This should prevent users from using a privileged port without mandatory access rights. * Socket mode will automatically fallback to listener socket for the receiver instance. This requires to duplicate the settings from the bind_conf to the receiver instance to support configurations with multiple addresses on the same bind line.
This commit is contained in:
parent
3ef6df7387
commit
2ac5d9a657
|
@ -28,6 +28,7 @@
|
|||
#include <haproxy/api-t.h>
|
||||
#include <haproxy/namespace-t.h>
|
||||
#include <haproxy/proto_reverse_connect-t.h>
|
||||
#include <haproxy/quic_sock-t.h>
|
||||
#include <haproxy/thread.h>
|
||||
|
||||
/* Bit values for receiver->flags */
|
||||
|
@ -79,6 +80,7 @@ struct receiver {
|
|||
struct list proto_list; /* list in the protocol header */
|
||||
#ifdef USE_QUIC
|
||||
struct mt_list rxbuf_list; /* list of buffers to receive and dispatch QUIC datagrams. */
|
||||
enum quic_sock_mode quic_mode; /* QUIC socket allocation strategy */
|
||||
#endif
|
||||
struct {
|
||||
struct task *task; /* Task used to open connection for reverse. */
|
||||
|
|
|
@ -645,6 +645,11 @@ static int quic_bind_listener(struct listener *listener, char *errmsg, int errle
|
|||
goto udp_return;
|
||||
}
|
||||
|
||||
/* Duplicate quic_mode setting from bind_conf. Useful to overwrite it
|
||||
* at runtime per receiver instance.
|
||||
*/
|
||||
listener->rx.quic_mode = listener->bind_conf->quic_mode;
|
||||
|
||||
/* Set IP_PKTINFO to retrieve destination address on recv. */
|
||||
fd = listener->rx.fd;
|
||||
switch (addr.ss_family) {
|
||||
|
|
|
@ -1264,7 +1264,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
|||
|
||||
conn_id->qc = qc;
|
||||
|
||||
if (l->bind_conf->quic_mode == QUIC_SOCK_MODE_CONN &&
|
||||
if (HA_ATOMIC_LOAD(&l->rx.quic_mode) == QUIC_SOCK_MODE_CONN &&
|
||||
(global.tune.options & GTUNE_QUIC_SOCK_PER_CONN) &&
|
||||
is_addr(local_addr)) {
|
||||
TRACE_USER("Allocate a socket for QUIC connection", QUIC_EV_CONN_INIT, qc);
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
|
||||
#define TRACE_SOURCE &trace_quic
|
||||
|
||||
/* Log only first EACCES bind() error runtime occurence. */
|
||||
static volatile char quic_bind_eacces_warn = 0;
|
||||
|
||||
/* Retrieve a connection's source address. Returns -1 on failure. */
|
||||
int quic_sock_get_src(struct connection *conn, struct sockaddr *addr, socklen_t len)
|
||||
{
|
||||
|
@ -812,7 +815,8 @@ int qc_rcv_buf(struct quic_conn *qc)
|
|||
void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
||||
const struct sockaddr_storage *dst)
|
||||
{
|
||||
struct proxy *p = qc->li->bind_conf->frontend;
|
||||
struct bind_conf *bc = qc->li->bind_conf;
|
||||
struct proxy *p = bc->frontend;
|
||||
int fd = -1;
|
||||
int ret;
|
||||
|
||||
|
@ -854,8 +858,20 @@ void qc_alloc_fd(struct quic_conn *qc, const struct sockaddr_storage *src,
|
|||
goto err;
|
||||
|
||||
ret = bind(fd, (struct sockaddr *)src, get_addr_len(src));
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
if (errno == EACCES) {
|
||||
if (!quic_bind_eacces_warn) {
|
||||
send_log(p, LOG_WARNING,
|
||||
"Permission error on QUIC socket binding for proxy %s. Consider using setcap cap_net_bind_service (Linux only) or running as root.\n",
|
||||
p->id);
|
||||
quic_bind_eacces_warn = 1;
|
||||
}
|
||||
|
||||
/* Fallback to listener socket for this receiver instance. */
|
||||
HA_ATOMIC_STORE(&qc->li->rx.quic_mode, QUIC_SOCK_MODE_LSTNR);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = connect(fd, (struct sockaddr *)dst, get_addr_len(dst));
|
||||
if (ret < 0)
|
||||
|
|
Loading…
Reference in New Issue