diff --git a/src/connection.c b/src/connection.c index 912285034..7a2ab2499 100644 --- a/src/connection.c +++ b/src/connection.c @@ -86,6 +86,15 @@ void conn_fd_handler(int fd) __conn_xprt_stop_send(conn); } + 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(). + */ + if (!tcp_connect_probe(conn)) + goto leave; + } + /* The data transfer starts here and stops on error and handshakes. Note * that we must absolutely test conn->xprt at each step in case it suddenly * changes due to a quick unexpected close(). @@ -105,14 +114,6 @@ void conn_fd_handler(int fd) __conn_xprt_stop_recv(conn); } - 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(). - */ - if (!tcp_connect_probe(conn)) - goto leave; - } leave: /* Verify if the connection just established. */ if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED)))) @@ -227,8 +228,14 @@ int conn_sock_send(struct connection *conn, const void *buf, int len, int flags) } while (ret < 0 && errno == EINTR); - if (ret > 0) + if (ret > 0) { + if (conn->flags & CO_FL_WAIT_L4_CONN) { + conn->flags &= ~CO_FL_WAIT_L4_CONN; + fd_may_send(conn->handle.fd); + fd_cond_recv(conn->handle.fd); + } return ret; + } if (ret == 0 || errno == EAGAIN || errno == ENOTCONN) { wait: diff --git a/src/proto_tcp.c b/src/proto_tcp.c index ff252e891..25e01bd57 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -576,6 +576,9 @@ int tcp_connect_server(struct connection *conn, int flags) conn_ctrl_init(conn); /* registers the FD */ fdtab[fd].linger_risk = 1; /* close hard if needed */ + if (conn->flags & CO_FL_WAIT_L4_CONN) + fd_cant_recv(fd); // we'll change this once the connection is validated + if (conn_xprt_init(conn) < 0) { conn_full_close(conn); conn->flags |= CO_FL_ERROR; @@ -711,6 +714,8 @@ int tcp_connect_probe(struct connection *conn) * data layer. */ conn->flags &= ~CO_FL_WAIT_L4_CONN; + fd_may_send(fd); + fd_cond_recv(fd); return 1; out_error: diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 6074daa46..c5acfcec7 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -575,6 +575,9 @@ static int uxst_connect_server(struct connection *conn, int flags) conn_ctrl_init(conn); /* registers the FD */ fdtab[fd].linger_risk = 0; /* no need to disable lingering */ + if (conn->flags & CO_FL_WAIT_L4_CONN) + fd_cant_recv(fd); // we'll change this once the connection is validated + if (conn_xprt_init(conn) < 0) { conn_full_close(conn); conn->flags |= CO_FL_ERROR; diff --git a/src/raw_sock.c b/src/raw_sock.c index cc9966925..64f7a05d1 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -207,8 +207,10 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip done += ret; pipe->data -= ret; } - if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done) + if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done) { conn->flags &= ~CO_FL_WAIT_L4_CONN; + fd_cond_recv(conn->handle.fd); + } return done; } @@ -387,8 +389,10 @@ static size_t raw_sock_from_buf(struct connection *conn, void *xprt_ctx, const s break; } } - if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done) + if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done) { conn->flags &= ~CO_FL_WAIT_L4_CONN; + fd_cond_recv(conn->handle.fd); + } if (done > 0) { /* we count the total bytes sent, and the send rate for 32-byte