mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-14 17:37:46 +00:00
BUG/MINOR: unix: fix connect's polling in case no data are scheduled
There's a test after a successful synchronous connect() consisting in waking the data layer up asap if there's no more handshake. Unfortunately this test is run before setting the CO_FL_SEND_PROXY flag and before the transport layer adds its own flags, so it can indicate a willingness to send data while it's not the case and it will have to be handled later. This has no visible effect except a useless call to a function in case of health checks making use of the proxy protocol for example. Additionally a corner case where EALREADY was returned and considered equivalent to EISCONN was fixed so that it's considered equivalent to EINPROGRESS given that the connection is not complete yet. But this code should never return on the first call anyway so it's mostly a cleanup. This fix should be backported to 1.7 and 1.6 at least to avoid headaches during some debugging.
This commit is contained in:
parent
819efbf4b5
commit
9484179f32
@ -495,12 +495,12 @@ int uxst_connect_server(struct connection *conn, int data, int delack)
|
||||
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) {
|
||||
if (errno == EALREADY || errno == EISCONN) {
|
||||
conn->flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
}
|
||||
else if (errno == EINPROGRESS) {
|
||||
if (errno == EINPROGRESS || errno == EALREADY) {
|
||||
conn->flags |= CO_FL_WAIT_L4_CONN;
|
||||
}
|
||||
else if (errno == EISCONN) {
|
||||
conn->flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
}
|
||||
else if (errno == EAGAIN || errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
|
||||
char *msg;
|
||||
if (errno == EAGAIN || errno == EADDRNOTAVAIL) {
|
||||
@ -533,13 +533,9 @@ int uxst_connect_server(struct connection *conn, int data, int delack)
|
||||
}
|
||||
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).
|
||||
* sockets. Let's avoid a second connect() probe to complete it.
|
||||
*/
|
||||
conn->flags &= ~CO_FL_WAIT_L4_CONN;
|
||||
if (!(conn->flags & CO_FL_HANDSHAKE))
|
||||
data = 1;
|
||||
}
|
||||
|
||||
conn->flags |= CO_FL_ADDR_TO_SET;
|
||||
@ -550,8 +546,6 @@ int uxst_connect_server(struct connection *conn, int data, int delack)
|
||||
|
||||
conn_ctrl_init(conn); /* registers the FD */
|
||||
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);
|
||||
@ -559,6 +553,17 @@ int uxst_connect_server(struct connection *conn, int data, int delack)
|
||||
return SF_ERR_RESOURCE;
|
||||
}
|
||||
|
||||
if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN)) {
|
||||
conn_sock_want_send(conn); /* for connect status, proxy protocol or SSL */
|
||||
}
|
||||
else {
|
||||
/* If there's no more handshake, we need to notify the data
|
||||
* layer when the connection is already OK otherwise we'll have
|
||||
* no other opportunity to do it later (eg: health checks).
|
||||
*/
|
||||
data = 1;
|
||||
}
|
||||
|
||||
if (data)
|
||||
conn_data_want_send(conn); /* prepare to send data if any */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user