MEDIUM: connection: panic when calling FD-specific functions on FD-less conns

Certain functions cannot be called on an FD-less conn because they are
normally called as part of the protocol-specific setup/teardown sequence.
Better place a few BUG_ON() to make sure none of them is called in other
situations. If any of them would trigger in ambiguous conditions, it would
always be possible to replace it with an error.
This commit is contained in:
Willy Tarreau 2022-04-11 18:07:03 +02:00
parent e22267971b
commit 07ecfc5e88
6 changed files with 30 additions and 0 deletions

View File

@ -220,6 +220,7 @@ static inline void conn_sock_read0(struct connection *c)
/* we don't risk keeping ports unusable if we found the
* zero from the other side.
*/
BUG_ON(c->flags & CO_FL_FDLESS);
HA_ATOMIC_AND(&fdtab[c->handle.fd].state, ~FD_LINGER_RISK);
}
}
@ -236,6 +237,7 @@ static inline void conn_sock_shutw(struct connection *c, int clean)
/* don't perform a clean shutdown if we're going to reset or
* if the shutr was already received.
*/
BUG_ON(c->flags & CO_FL_FDLESS);
if (!(c->flags & CO_FL_SOCK_RD_SH) && clean)
shutdown(c->handle.fd, SHUT_WR);
}

View File

@ -744,6 +744,8 @@ static int retrieve_errno_from_socket(struct connection *conn)
if (!conn_ctrl_ready(conn))
return 0;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (getsockopt(conn->handle.fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr) == 0)
errno = skerr;

View File

@ -809,6 +809,8 @@ int conn_recv_proxy(struct connection *conn, int flag)
if (!conn_ctrl_ready(conn))
goto fail;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_recv_ready(conn->handle.fd))
goto not_ready;
@ -1188,6 +1190,8 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
if (!conn_ctrl_ready(conn))
goto fail;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_recv_ready(conn->handle.fd))
goto not_ready;
@ -1454,6 +1458,8 @@ int conn_recv_socks4_proxy_response(struct connection *conn)
if (!conn_ctrl_ready(conn))
goto fail;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_recv_ready(conn->handle.fd))
goto not_ready;

View File

@ -59,6 +59,8 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe,
if (!conn_ctrl_ready(conn))
return 0;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_recv_ready(conn->handle.fd))
return 0;
@ -172,6 +174,8 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip
if (!conn_ctrl_ready(conn))
return 0;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_send_ready(conn->handle.fd))
return 0;
@ -231,6 +235,8 @@ static size_t raw_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu
if (!conn_ctrl_ready(conn))
return 0;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_recv_ready(conn->handle.fd))
return 0;
@ -350,6 +356,8 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s
if (!conn_ctrl_ready(conn))
return 0;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_send_ready(conn->handle.fd))
return 0;

View File

@ -702,6 +702,7 @@ void sock_accept_iocb(int fd)
*/
void sock_conn_ctrl_init(struct connection *conn)
{
BUG_ON(conn->flags & CO_FL_FDLESS);
fd_insert(conn->handle.fd, conn, sock_conn_iocb, tid_bit);
}
@ -711,6 +712,7 @@ void sock_conn_ctrl_init(struct connection *conn)
*/
void sock_conn_ctrl_close(struct connection *conn)
{
BUG_ON(conn->flags & CO_FL_FDLESS);
fd_delete(conn->handle.fd);
conn->handle.fd = DEAD_FD_MAGIC;
}
@ -736,6 +738,8 @@ int sock_conn_check(struct connection *conn)
if (!(conn->flags & CO_FL_WAIT_L4_CONN))
return 1; /* strange we were called while ready */
BUG_ON(conn->flags & CO_FL_FDLESS);
if (!fd_send_ready(fd) && !(fdtab[fd].state & (FD_POLL_ERR|FD_POLL_HUP)))
return 0;
@ -901,6 +905,8 @@ int sock_drain(struct connection *conn)
int fd = conn->handle.fd;
int len;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (fdtab[fd].state & (FD_POLL_ERR|FD_POLL_HUP))
goto shut;
@ -953,6 +959,8 @@ int sock_check_events(struct connection *conn, int event_type)
{
int ret = 0;
BUG_ON(conn->flags & CO_FL_FDLESS);
if (event_type & SUB_RETRY_RECV) {
if (fd_recv_ready(conn->handle.fd))
ret |= SUB_RETRY_RECV;
@ -975,6 +983,8 @@ int sock_check_events(struct connection *conn, int event_type)
*/
void sock_ignore_events(struct connection *conn, int event_type)
{
BUG_ON(conn->flags & CO_FL_FDLESS);
if (event_type & SUB_RETRY_RECV)
fd_stop_recv(conn->handle.fd);

View File

@ -5849,6 +5849,8 @@ static int ssl_sock_handshake(struct connection *conn, unsigned int flag)
* the xprt layers should provide some status indicating their knowledge
* of shutdowns or error.
*/
BUG_ON(conn->flags & CO_FL_FDLESS);
skerr = 0;
lskerr = sizeof(skerr);
if ((getsockopt(conn->handle.fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr) < 0) ||