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.
diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h
index 5d9b5ca..bc26f73 100644
--- a/include/haproxy/connection.h
+++ b/include/haproxy/connection.h
@@ -220,6 +220,7 @@
/* 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 @@
/* 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);
}
diff --git a/src/check.c b/src/check.c
index da2deab..7e6430f 100644
--- a/src/check.c
+++ b/src/check.c
@@ -744,6 +744,8 @@
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;
diff --git a/src/connection.c b/src/connection.c
index af453a6..b666d18 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -809,6 +809,8 @@
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 @@
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 @@
if (!conn_ctrl_ready(conn))
goto fail;
+ BUG_ON(conn->flags & CO_FL_FDLESS);
+
if (!fd_recv_ready(conn->handle.fd))
goto not_ready;
diff --git a/src/raw_sock.c b/src/raw_sock.c
index 7ee5f9b..553375b 100644
--- a/src/raw_sock.c
+++ b/src/raw_sock.c
@@ -59,6 +59,8 @@
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 @@
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 @@
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 @@
if (!conn_ctrl_ready(conn))
return 0;
+ BUG_ON(conn->flags & CO_FL_FDLESS);
+
if (!fd_send_ready(conn->handle.fd))
return 0;
diff --git a/src/sock.c b/src/sock.c
index ae825fc..5afa59f 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -702,6 +702,7 @@
*/
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_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 @@
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 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 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 @@
*/
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);
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 748ab13..00c35d8 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -5849,6 +5849,8 @@
* 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) ||