]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: connection: check EINTR when sending a PROXY header
authorWilly Tarreau <w@1wt.eu>
Wed, 4 Dec 2013 22:37:56 +0000 (23:37 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 4 Dec 2013 22:50:26 +0000 (23:50 +0100)
PROXY protocol header was not tolerant to signals, so it might cause a
connection to report an error if a signal comes in at the exact same
moment the send is done.

This is 1.5-specific and does not need any backport.

src/connection.c
src/stream_interface.c

index b477b463106bf6e628adb61abcb06b94c395afb9..78d28ed331d66af9131c892cba0c87e6a6ecf62b 100644 (file)
@@ -563,16 +563,20 @@ int conn_local_send_proxy(struct connection *conn, unsigned int flag)
        /* we have to send the whole trash. If the data layer has a
         * pending write, we'll also set MSG_MORE.
         */
-       ret = send(conn->t.sock.fd, trash.str, trash.len, (conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0);
-
-       if (ret == 0)
-               goto out_wait;
+       do {
+               ret = send(conn->t.sock.fd, trash.str, trash.len, (conn->flags & CO_FL_DATA_WR_ENA) ? MSG_MORE : 0);
 
-       if (ret < 0) {
-               if (errno == EAGAIN || errno == ENOTCONN)
+               if (ret == 0)
                        goto out_wait;
-               goto out_error;
-       }
+
+               if (ret < 0) {
+                       if (errno == EAGAIN || errno == ENOTCONN)
+                               goto out_wait;
+                       if (errno == EINTR)
+                               continue;
+                       goto out_error;
+               }
+       } while (0);
 
        if (ret != trash.len)
                goto out_error;
index 6fdaff394cd0fe91a92c57b23bb9c31b7aa743c5..702e7b38bcea47a62edb0eb8fe4481c217c1cce2 100644 (file)
@@ -442,7 +442,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
         * connection, in which case the connection is validated only once
         * we've sent the whole proxy line. Otherwise we use connect().
         */
-       if (si->send_proxy_ofs) {
+       while (si->send_proxy_ofs) {
                int ret;
 
                /* The target server expects a PROXY line to be sent first.
@@ -470,6 +470,8 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
                if (ret < 0) {
                        if (errno == EAGAIN || errno == ENOTCONN)
                                goto out_wait;
+                       if (errno == EINTR)
+                               continue;
                        goto out_error;
                }
 
@@ -478,6 +480,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag)
                        goto out_wait;
 
                /* OK we've sent the whole line, we're connected */
+               break;
        }
 
        /* The connection is ready now, simply return and let the connection