diff --git a/src/proto_uxst.c b/src/proto_uxst.c index f2621facf..f83d34e11 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -381,7 +381,7 @@ int uxst_connect_server(struct connection *conn, int data, int delack) struct server *srv; struct proxy *be; - conn->flags = CO_FL_WAIT_L4_CONN; /* connection in progress */ + conn->flags = 0; switch (obj_type(conn->target)) { case OBJ_TYPE_PROXY: @@ -457,9 +457,14 @@ int uxst_connect_server(struct connection *conn, int data, int delack) if (global.tune.server_rcvbuf) setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &global.tune.server_rcvbuf, sizeof(global.tune.server_rcvbuf)); - if ((connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) && - (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) { - if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) { + if (connect(fd, (struct sockaddr *)&conn->addr.to, get_addr_len(&conn->addr.to)) == -1) { + if (errno == EALREADY || errno == EISCONN) { + conn->flags &= ~CO_FL_WAIT_L4_CONN; + } + else if (errno == EINPROGRESS) { + conn->flags |= CO_FL_WAIT_L4_CONN; + } + else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) { char *msg; if (errno == EAGAIN || errno == EADDRNOTAVAIL) { msg = "no free ports"; @@ -489,6 +494,16 @@ int uxst_connect_server(struct connection *conn, int data, int delack) return SN_ERR_SRVCL; } } + else { + /* connect() already succeeded, which is quite usual for unix + * sockets. Let's avoid a second connect() probe to complete it, + * but we need to ensure we'll wake up if there's no more handshake + * pending (eg: for health checks). + */ + conn->flags &= ~CO_FL_WAIT_L4_CONN; + if (!(conn->flags & CO_FL_HANDSHAKE)) + data = 1; + } conn->flags |= CO_FL_ADDR_TO_SET; @@ -497,8 +512,9 @@ int uxst_connect_server(struct connection *conn, int data, int delack) conn->flags |= CO_FL_SEND_PROXY; conn_ctrl_init(conn); /* registers the FD */ - fdtab[fd].linger_risk = 1; /* close hard if needed */ - conn_sock_want_send(conn); /* for connect status */ + fdtab[fd].linger_risk = 0; /* no need to disable lingering */ + if (conn->flags & CO_FL_HANDSHAKE) + conn_sock_want_send(conn); /* for connect status or proxy protocol */ if (conn_xprt_init(conn) < 0) { conn_force_close(conn);