MEDIUM: checks: avoid waking the application up for pure TCP checks

Pure TCP checks only use the SYN/ACK in return to a SYN. By forcing
the system to use delayed ACKs, it is possible to send an RST instead
of the ACK and thus ensure that the application will never be needlessly
woken up. This avoids error logs or counters on checked components since
the application is never made aware of this connection which dies in the
network stack.
This commit is contained in:
Willy Tarreau 2012-11-23 14:16:39 +01:00
parent acbdc7a760
commit 24db47e0cc
2 changed files with 11 additions and 6 deletions

View File

@ -1312,8 +1312,10 @@ static struct task *process_chk(struct task *t)
* - SN_ERR_RESOURCE if a system resource is lacking (eg: fd limits, ports, ...)
* - SN_ERR_INTERNAL for any other purely internal errors
* Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
* Note that we try to prevent the network stack from sending the ACK during the
* connect() when a pure TCP check is used.
*/
ret = s->check.proto->connect(conn, 1);
ret = s->check.proto->connect(conn, (s->proxy->options2 & PR_O2_CHK_ANY) ? 1 : 2);
__conn_data_want_recv(conn); /* prepare for reading a possible reply */
conn->flags |= CO_FL_WAKE_DATA;
if (s->check.send_proxy)

View File

@ -221,9 +221,12 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
* bind addresses are still determined locally (due to the possible need of a
* source port). conn->target may point either to a valid server or to a backend,
* depending on conn->target. Only OBJ_TYPE_PROXY and OBJ_TYPE_SERVER are
* supported. The <data> parameter is a boolean indicating whether there are data
* waiting for being sent or not, in order to adjust data write polling and on
* some platforms, the ability to avoid an empty initial ACK.
* supported. The <data> parameter indicates when non-zero that data will
* immediately follow the connection and will tune the ACK behaviour after
* the connect :
* - 0 = always send it
* - 1 = send it unless the backends has the tcp-smart-connect option
* - 2 = never send it
*
* It can return one of :
* - SN_ERR_NONE if everything's OK
@ -418,9 +421,9 @@ int tcp_connect_server(struct connection *conn, int data)
#if defined(TCP_QUICKACK)
/* disabling tcp quick ack now allows the first request to leave the
* machine with the first ACK. We only do this if there are pending
* data in the buffer.
* data in the buffer or if we plan to close after SYN/ACK (TCP checks).
*/
if ((be->options2 & PR_O2_SMARTCON) && data)
if (data == 2 || (data && (be->options2 & PR_O2_SMARTCON)))
setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero));
#endif