]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: connection: don't store recv() result into trash.data
authorWilly Tarreau <w@1wt.eu>
Wed, 22 Aug 2018 03:20:32 +0000 (05:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 22 Aug 2018 03:28:32 +0000 (05:28 +0200)
Cyril Bonté discovered that the proxy protocol randomly fails since
commit 843b7cb ("MEDIUM: chunks: make the chunk struct's fields match
the buffer struct"). This is because we used to store recv()'s return
code into trash.data which is now unsigned, so it never compares as
negative against 0. Let's clean this up and test the result itself
without storing it first.

No backport is needed.

src/connection.c

index ee80e616ff2b4ed0f1670d84ec3a6ccc2553da5e..b3ef56eba650807dafcd185d1361cd64360d9aee 100644 (file)
@@ -424,6 +424,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
        const char v2sig[] = PP2_SIGNATURE;
        int tlv_length = 0;
        int tlv_offset = 0;
+       int ret;
 
        /* we might have been called just after an asynchronous shutr */
        if (conn->flags & CO_FL_SOCK_RD_SH)
@@ -436,9 +437,8 @@ int conn_recv_proxy(struct connection *conn, int flag)
                return 0;
 
        do {
-               trash.data = recv(conn->handle.fd, trash.area, trash.size,
-                                MSG_PEEK);
-               if (trash.data < 0) {
+               ret = recv(conn->handle.fd, trash.area, trash.size, MSG_PEEK);
+               if (ret < 0) {
                        if (errno == EINTR)
                                continue;
                        if (errno == EAGAIN) {
@@ -447,6 +447,7 @@ int conn_recv_proxy(struct connection *conn, int flag)
                        }
                        goto recv_abort;
                }
+               trash.data = ret;
        } while (0);
 
        if (!trash.data) {
@@ -738,6 +739,7 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
        char *line;
        uint32_t hdr_len;
        uint8_t ip_v;
+       int ret;
 
        /* we might have been called just after an asynchronous shutr */
        if (conn->flags & CO_FL_SOCK_RD_SH)
@@ -750,9 +752,8 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
                return 0;
 
        do {
-               trash.data = recv(conn->handle.fd, trash.area, trash.size,
-                                MSG_PEEK);
-               if (trash.data < 0) {
+               ret = recv(conn->handle.fd, trash.area, trash.size, MSG_PEEK);
+               if (ret < 0) {
                        if (errno == EINTR)
                                continue;
                        if (errno == EAGAIN) {
@@ -761,6 +762,7 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag)
                        }
                        goto recv_abort;
                }
+               trash.data = ret;
        } while (0);
 
        if (!trash.data) {