From: Willy Tarreau Date: Sun, 20 May 2012 08:38:46 +0000 (+0200) Subject: BUG/MINOR: stop connect timeout when connect succeeds X-Git-Tag: v1.5-dev12~179 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ae52cb144f62de7700147c6e8da8454e8d5d288;p=thirdparty%2Fhaproxy.git BUG/MINOR: stop connect timeout when connect succeeds 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. --- diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 3b6f986424..533e9e6c04 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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); diff --git a/src/sock_raw.c b/src/sock_raw.c index 351195c5f0..37524be6d7 100644 --- a/src/sock_raw.c +++ b/src/sock_raw.c @@ -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;