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().
diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h
index 40b15a3..f0ad25c 100644
--- a/include/haproxy/connection.h
+++ b/include/haproxy/connection.h
@@ -62,7 +62,7 @@
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);
diff --git a/src/connection.c b/src/connection.c
index d44402e..7c70e66 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -194,66 +194,24 @@
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;
}
/*
diff --git a/src/mux_pt.c b/src/mux_pt.c
index 3e2d066..1530996 100644
--- a/src/mux_pt.c
+++ b/src/mux_pt.c
@@ -75,7 +75,7 @@
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 @@
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 @@
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);
}
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index e1de595..732f586 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -5276,7 +5276,7 @@
* 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 @@
* 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;
diff --git a/src/tcp_act.c b/src/tcp_act.c
index 182234f..9179a80 100644
--- a/src/tcp_act.c
+++ b/src/tcp_act.c
@@ -176,7 +176,7 @@
#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.