]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: add check for readiness in I/O handlers
authorWilly Tarreau <w@1wt.eu>
Mon, 20 Jan 2014 14:13:07 +0000 (15:13 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 25 Jan 2014 23:42:30 +0000 (00:42 +0100)
The recv/send callbacks must check for readiness themselves instead of
having their callers do it. This will strengthen the test and will also
ensure we never refrain from calling a handshake handler because a
direction is being polled while the other one is ready.

src/connection.c
src/proto_tcp.c
src/raw_sock.c
src/stream_interface.c

index 2538cc52155677059f69529bb2f61f277abc373c..876d71a43ce5559d2fd45da9437ff6fb1b07d091 100644 (file)
@@ -120,7 +120,7 @@ int conn_fd_handler(int fd)
        if (unlikely(conn->flags & (CO_FL_HANDSHAKE | CO_FL_ERROR)))
                goto process_handshake;
 
-       if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && fd_send_ready(conn->t.sock.fd)) {
+       if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN)) {
                /* still waiting for a connection to establish and nothing was
                 * attempted yet to probe the connection. Then let's retry the
                 * connect().
@@ -255,6 +255,9 @@ int conn_recv_proxy(struct connection *conn, int flag)
        if (!(conn->flags & CO_FL_CTRL_READY))
                goto fail;
 
+       if (!fd_recv_ready(conn->t.sock.fd))
+               return 0;
+
        do {
                trash.len = recv(conn->t.sock.fd, trash.str, trash.size, MSG_PEEK);
                if (trash.len < 0) {
index cb10661409d9a27e56841bcda9cfe7b5000882c4..79c7baf845ede2c95495627db5290af0c939cf4c 100644 (file)
@@ -632,6 +632,9 @@ int tcp_connect_probe(struct connection *conn)
        if (!(conn->flags & CO_FL_WAIT_L4_CONN))
                return 1; /* strange we were called while ready */
 
+       if (!fd_send_ready(fd))
+               return 0;
+
        /* we might be the first witness of FD_POLL_ERR. Note that FD_POLL_HUP
         * without FD_POLL_IN also indicates a hangup without input data meaning
         * there was no connection.
index 3d4278146a82b9635dc41999cac8dfe45c48809e..a67a8d979186b02ec03e0f298a3384c923f74bf2 100644 (file)
@@ -75,7 +75,10 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co
        int retval = 0;
 
 
-       if (!(conn->flags & CO_FL_CTRL_READY))
+       if (!conn_ctrl_ready(conn))
+               return 0;
+
+       if (!fd_recv_ready(conn->t.sock.fd))
                return 0;
 
        errno = 0;
@@ -193,7 +196,10 @@ int raw_sock_from_pipe(struct connection *conn, struct pipe *pipe)
 {
        int ret, done;
 
-       if (!(conn->flags & CO_FL_CTRL_READY))
+       if (!conn_ctrl_ready(conn))
+               return 0;
+
+       if (!fd_send_ready(conn->t.sock.fd))
                return 0;
 
        done = 0;
@@ -240,7 +246,10 @@ static int raw_sock_to_buf(struct connection *conn, struct buffer *buf, int coun
        int ret, done = 0;
        int try;
 
-       if (!(conn->flags & CO_FL_CTRL_READY))
+       if (!conn_ctrl_ready(conn))
+               return 0;
+
+       if (!fd_recv_ready(conn->t.sock.fd))
                return 0;
 
        errno = 0;
@@ -342,7 +351,10 @@ static int raw_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
 {
        int ret, try, done, send_flag;
 
-       if (!(conn->flags & CO_FL_CTRL_READY))
+       if (!conn_ctrl_ready(conn))
+               return 0;
+
+       if (!fd_send_ready(conn->t.sock.fd))
                return 0;
 
        done = 0;
index 6096dd74987fe3f55efe0b118c2a988b85de0c53..abbbcb10ac698c3473fea82a8b29f86352010d2c 100644 (file)
@@ -400,6 +400,9 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
        if (!conn_ctrl_ready(conn))
                goto out_error;
 
+       if (!fd_send_ready(conn->t.sock.fd))
+               goto out_wait;
+
        /* If we have a PROXY line to send, we'll use this to validate the
         * connection, in which case the connection is validated only once
         * we've sent the whole proxy line. Otherwise we use connect().