diff --git a/doc/configuration.txt b/doc/configuration.txt index 3266a4448..ce2a02b52 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2789,6 +2789,35 @@ no option tcp-smart-accept of doubt, consider setting it back to automatic values by prepending the "default" keyword before it, or disabling it using the "no" keyword. + See also : "option tcp-smart-connect" + + +option tcp-smart-connect +no option tcp-smart-connect + Enable or disable the saving of one ACK packet during the connect sequence + May be used in sections : defaults | frontend | listen | backend + yes | no | yes | yes + Arguments : none + + On certain systems (at least Linux), HAProxy can ask the kernel not to + immediately send an empty ACK upon a connection request, but to directly + send the buffer request instead. This saves one packet on the network and + thus boosts performance. It can also be useful for some servers, because they + immediately get the request along with the incoming connection. + + This feature is enabled when "option tcp-smart-connect" is set in a backend. + It is not enabled by default because it makes network troubleshooting more + complex. + + It only makes sense to enable it with protocols where the client speaks first + such as HTTP. In other situations, if there is no data to send in place of + the ACK, a normal ACK is sent. + + If this option has been enabled in a "defaults" section, it can be disabled + in a specific instance by prepending the "no" keyword before it. + + See also : "option tcp-smart-accept" + option tcpka Enable or disable the sending of TCP keepalive packets on both sides diff --git a/include/types/proxy.h b/include/types/proxy.h index 7664618f0..715f21d15 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -118,6 +118,7 @@ #define PR_O2_NOLOGNORM 0x00000020 /* don't log normal traffic, only errors and retries */ #define PR_O2_LOGERRORS 0x00000040 /* log errors and retries at level LOG_ERR */ #define PR_O2_SMARTACC 0x00000080 /* don't immediately ACK request after accept */ +#define PR_O2_SMARTCON 0x00000100 /* don't immediately send empty ACK after connect */ /* This structure is used to apply fast weighted round robin on a server group */ struct fwrr_group { diff --git a/src/backend.c b/src/backend.c index 5e78fd8df..58de35e54 100644 --- a/src/backend.c +++ b/src/backend.c @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -1912,6 +1914,15 @@ int connect_server(struct session *s) } } +#ifdef 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. + */ + if ((s->be->options2 & PR_O2_SMARTCON) && s->req->send_max) + setsockopt(fd, SOL_TCP, TCP_QUICKACK, (char *) &zero, sizeof(zero)); +#endif + if ((connect(fd, (struct sockaddr *)&s->srv_addr, sizeof(s->srv_addr)) == -1) && (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EISCONN)) { diff --git a/src/cfgparse.c b/src/cfgparse.c index 03a5303f5..9ec869e11 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -136,6 +136,7 @@ static const struct cfg_opt cfg_opts2[] = { "dontlog-normal", PR_O2_NOLOGNORM, PR_CAP_FE, 0 }, { "log-separate-errors", PR_O2_LOGERRORS, PR_CAP_FE, 0 }, { "tcp-smart-accept", PR_O2_SMARTACC, PR_CAP_FE, 0 }, + { "tcp-smart-connect", PR_O2_SMARTCON, PR_CAP_BE, 0 }, { NULL, 0, 0, 0 } };