]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: stop connect timeout when connect succeeds
authorWilly Tarreau <w@1wt.eu>
Sun, 20 May 2012 08:38:46 +0000 (10:38 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 20 May 2012 08:38:46 +0000 (10:38 +0200)
If the connect succeeds exactly at the same millisecond as the connect
timeout is supposed to strike, the timeout is still considered while
data may have already be sent. This results in a new connection attempt
with no data and with the response being lost.

Note that in practice the only real-world situation where this is observed
is when connect timeouts are extremely low, too low for safe operations.
This bug was encountered with a 1ms connect timeout.

It is also present on 1.4 and needs to be fixed there too.

src/proto_tcp.c
src/sock_raw.c

index 3b6f9864240a4639a085df27a8ff855cc90633a1..533e9e6c040c48a1a753a371b477643a471c620f 100644 (file)
@@ -564,6 +564,7 @@ static int tcp_connect_write(int fd)
        fdtab[fd].cb[DIR_RD].f = si->sock.read;
        fdtab[fd].cb[DIR_WR].f = si->sock.write;
        fdtab[fd].state = FD_STREADY;
+       si->exp = TICK_ETERNITY;
 
  out_wakeup:
        task_wakeup(si->owner, TASK_WOKEN_IO);
index 351195c5f062b7f8f26bb83d43e21fb89c400e6b..37524be6d777c9463eac20a452dd4b5aa70b6269 100644 (file)
@@ -323,8 +323,10 @@ static int sock_raw_read(int fd)
                                b_adv(b, fwd);
                        }
 
-                       if (fdtab[fd].state == FD_STCONN)
+                       if (fdtab[fd].state == FD_STCONN) {
                                fdtab[fd].state = FD_STREADY;
+                               si->exp = TICK_ETERNITY;
+                       }
 
                        b->flags |= BF_READ_PARTIAL;
                        b->total += ret;
@@ -541,8 +543,10 @@ static int sock_raw_write_loop(struct stream_interface *si, struct buffer *b)
                ret = send(si->fd, trash + ret + si->send_proxy_ofs, -si->send_proxy_ofs,
                           (b->flags & BF_OUT_EMPTY) ? 0 : MSG_MORE);
                if (ret > 0) {
-                       if (fdtab[si->fd].state == FD_STCONN)
+                       if (fdtab[si->fd].state == FD_STCONN) {
                                fdtab[si->fd].state = FD_STREADY;
+                               si->exp = TICK_ETERNITY;
+                       }
 
                        si->send_proxy_ofs += ret; /* becomes zero once complete */
                        b->flags |= BF_WRITE_NULL; /* connect() succeeded */
@@ -647,8 +651,10 @@ static int sock_raw_write_loop(struct stream_interface *si, struct buffer *b)
                }
 
                if (ret > 0) {
-                       if (fdtab[si->fd].state == FD_STCONN)
+                       if (fdtab[si->fd].state == FD_STCONN) {
                                fdtab[si->fd].state = FD_STREADY;
+                               si->exp = TICK_ETERNITY;
+                       }
 
                        b->flags |= BF_WRITE_PARTIAL;