mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MINOR: connection: make conn_sock_drain() use the control layer's ->drain()
Now we don't touch the fd anymore there, instead we rely on the ->drain() provided by the control layer. As such the function was renamed to conn_ctrl_drain().
This commit is contained in:
parent
427c846cc9
commit
2ded48dd27
@ -62,7 +62,7 @@ int conn_recv_netscaler_cip(struct connection *conn, int flag);
|
||||
int conn_ctrl_send(struct connection *conn, const void *buf, int len, int flags);
|
||||
|
||||
/* drains any pending bytes from the socket */
|
||||
int conn_sock_drain(struct connection *conn);
|
||||
int conn_ctrl_drain(struct connection *conn);
|
||||
|
||||
/* scoks4 proxy handshake */
|
||||
int conn_send_socks4_proxy_request(struct connection *conn);
|
||||
|
@ -194,66 +194,24 @@ int conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Drains possibly pending incoming data on the file descriptor attached to the
|
||||
* connection and update the connection's flags accordingly. This is used to
|
||||
* know whether we need to disable lingering on close. Returns non-zero if it
|
||||
* is safe to close without disabling lingering, otherwise zero. The SOCK_RD_SH
|
||||
* flag may also be updated if the incoming shutdown was reported by the drain()
|
||||
* function.
|
||||
/* Drains possibly pending incoming data on the connection and update the flags
|
||||
* accordingly. This is used to know whether we need to disable lingering on
|
||||
* close. Returns non-zero if it is safe to close without disabling lingering,
|
||||
* otherwise zero. The CO_FL_SOCK_RD_SH flag may also be updated if the incoming
|
||||
* shutdown was reported by the ->drain() function.
|
||||
*/
|
||||
int conn_sock_drain(struct connection *conn)
|
||||
int conn_ctrl_drain(struct connection *conn)
|
||||
{
|
||||
int turns = 2;
|
||||
int len;
|
||||
int ret = 0;
|
||||
|
||||
if (!conn_ctrl_ready(conn))
|
||||
return 1;
|
||||
|
||||
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH))
|
||||
return 1;
|
||||
|
||||
if (fdtab[conn->handle.fd].ev & (FD_POLL_ERR|FD_POLL_HUP))
|
||||
goto shut;
|
||||
|
||||
if (!fd_recv_ready(conn->handle.fd))
|
||||
return 0;
|
||||
|
||||
/* no drain function defined, use the generic one */
|
||||
|
||||
while (turns) {
|
||||
#ifdef MSG_TRUNC_CLEARS_INPUT
|
||||
len = recv(conn->handle.fd, NULL, INT_MAX, MSG_DONTWAIT | MSG_NOSIGNAL | MSG_TRUNC);
|
||||
if (len == -1 && errno == EFAULT)
|
||||
#endif
|
||||
len = recv(conn->handle.fd, trash.area, trash.size,
|
||||
MSG_DONTWAIT | MSG_NOSIGNAL);
|
||||
|
||||
if (len == 0)
|
||||
goto shut;
|
||||
|
||||
if (len < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
/* connection not closed yet */
|
||||
fd_cant_recv(conn->handle.fd);
|
||||
break;
|
||||
}
|
||||
if (errno == EINTR) /* oops, try again */
|
||||
continue;
|
||||
/* other errors indicate a dead connection, fine. */
|
||||
goto shut;
|
||||
}
|
||||
/* OK we read some data, let's try again once */
|
||||
turns--;
|
||||
if (!conn_ctrl_ready(conn) || conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH))
|
||||
ret = 1;
|
||||
else if (conn->ctrl->drain) {
|
||||
ret = conn->ctrl->drain(conn);
|
||||
if (ret)
|
||||
conn->flags |= CO_FL_SOCK_RD_SH;
|
||||
}
|
||||
|
||||
/* some data are still present, give up */
|
||||
return 0;
|
||||
|
||||
shut:
|
||||
/* we're certain the connection was shut down */
|
||||
fdtab[conn->handle.fd].linger_risk = 0;
|
||||
conn->flags |= CO_FL_SOCK_RD_SH;
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -75,7 +75,7 @@ static struct task *mux_pt_io_cb(struct task *t, void *tctx, unsigned short stat
|
||||
ctx->cs->data_cb->wake(ctx->cs);
|
||||
return NULL;
|
||||
}
|
||||
conn_sock_drain(ctx->conn);
|
||||
conn_ctrl_drain(ctx->conn);
|
||||
if (ctx->conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))
|
||||
mux_pt_destroy(ctx);
|
||||
else
|
||||
@ -148,7 +148,7 @@ static int mux_pt_wake(struct connection *conn)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
conn_sock_drain(conn);
|
||||
conn_ctrl_drain(conn);
|
||||
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
|
||||
mux_pt_destroy(ctx);
|
||||
return -1;
|
||||
@ -248,7 +248,7 @@ static void mux_pt_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
|
||||
cs->conn->xprt->shutr(cs->conn, cs->conn->xprt_ctx,
|
||||
(mode == CS_SHR_DRAIN));
|
||||
else if (mode == CS_SHR_DRAIN)
|
||||
conn_sock_drain(cs->conn);
|
||||
conn_ctrl_drain(cs->conn);
|
||||
if (cs->flags & CS_FL_SHW)
|
||||
conn_full_close(cs->conn);
|
||||
}
|
||||
|
@ -5276,7 +5276,7 @@ static int ssl_sock_handshake(struct connection *conn, unsigned int flag)
|
||||
* TCP sockets. We first try to drain possibly pending
|
||||
* data to avoid this as much as possible.
|
||||
*/
|
||||
conn_sock_drain(conn);
|
||||
conn_ctrl_drain(conn);
|
||||
if (!conn->err_code)
|
||||
conn->err_code = (ctx->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
|
||||
CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
|
||||
@ -5360,7 +5360,7 @@ static int ssl_sock_handshake(struct connection *conn, unsigned int flag)
|
||||
* TCP sockets. We first try to drain possibly pending
|
||||
* data to avoid this as much as possible.
|
||||
*/
|
||||
conn_sock_drain(conn);
|
||||
conn_ctrl_drain(conn);
|
||||
if (!conn->err_code)
|
||||
conn->err_code = (ctx->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
|
||||
CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
|
||||
|
@ -176,7 +176,7 @@ static enum act_return tcp_exec_action_silent_drop(struct act_rule *rule, struct
|
||||
|
||||
#ifdef TCP_QUICKACK
|
||||
/* drain is needed only to send the quick ACK */
|
||||
conn_sock_drain(conn);
|
||||
conn_ctrl_drain(conn);
|
||||
|
||||
/* re-enable quickack if it was disabled to ack all data and avoid
|
||||
* retransmits from the client that might trigger a real reset.
|
||||
|
Loading…
Reference in New Issue
Block a user