mirror of
https://github.com/haproxy/haproxy.git
synced 2026-02-18 18:19:39 -05:00
[MEDIUM] implement option tcp-smart-accept at the frontend
This option disables TCP quick ack upon accept. It is also automatically enabled in HTTP mode, unless the option is explicitly disabled with "no option tcp-smart-accept". This saves one packet per connection which can bring reasonable amounts of bandwidth for servers processing small requests.
This commit is contained in:
parent
3842f00a19
commit
9ea05a790f
5 changed files with 51 additions and 0 deletions
|
|
@ -706,6 +706,8 @@ option smtpchk X - X X
|
|||
[no] option splice-response X X X X
|
||||
[no] option srvtcpka X - X X
|
||||
option ssl-hello-chk X - X X
|
||||
[no] option tcp-smart-
|
||||
accept X X X -
|
||||
option tcpka X X X X
|
||||
option tcplog X X X X
|
||||
[no] option tcpsplice X X X X
|
||||
|
|
@ -2755,6 +2757,39 @@ option ssl-hello-chk
|
|||
See also: "option httpchk"
|
||||
|
||||
|
||||
option tcp-smart-accept
|
||||
no option tcp-smart-accept
|
||||
Enable or disable the saving of one ACK packet during the accept sequence
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
yes | yes | yes | no
|
||||
Arguments : none
|
||||
|
||||
When an HTTP connection request comes in, the system acknowledges it on
|
||||
behalf of HAProxy, then the client immediately sends its request, and the
|
||||
system acknowledges it too while it is notifying HAProxy about the new
|
||||
connection. HAProxy then reads the request and responds. This means that we
|
||||
have one TCP ACK sent by the system for nothing, because the request could
|
||||
very well be acknowledged by HAProxy when it sends its response.
|
||||
|
||||
For this reason, in HTTP mode, HAProxy automatically asks the system to avoid
|
||||
sending this useless ACK on platforms which support it (currently at least
|
||||
Linux). It must not cause any problem, because the system will send it anyway
|
||||
after 40 ms if the response takes more time than expected to come.
|
||||
|
||||
During complex network debugging sessions, it may be desirable to disable
|
||||
this optimization because delayed ACKs can make troubleshooting more complex
|
||||
when trying to identify where packets are delayed. It is then possible to
|
||||
fall back to normal behaviour by specifying "no option tcp-smart-accept".
|
||||
|
||||
It is also possible to force it for non-HTTP proxies by simply specifying
|
||||
"option tcp-smart-accept". For instance, it can make sense with some services
|
||||
such as SMTP where the server speaks first.
|
||||
|
||||
It is recommended to avoid forcing this option in a defaults section. In case
|
||||
of doubt, consider setting it back to automatic values by prepending the
|
||||
"default" keyword before it, or disabling it using the "no" keyword.
|
||||
|
||||
|
||||
option tcpka
|
||||
Enable or disable the sending of TCP keepalive packets on both sides
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
#define LI_O_NONE 0x0000
|
||||
#define LI_O_NOLINGER 0x0001 /* disable linger on this socket */
|
||||
#define LI_O_FOREIGN 0x0002 /* permit listening on foreing addresses */
|
||||
#define LI_O_NOQUICKACK 0x0004 /* disable quick ack of immediate data (linux) */
|
||||
|
||||
/* The listener will be directly referenced by the fdtab[] which holds its
|
||||
* socket. The listener provides the protocol-specific accept() function to
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@
|
|||
#define PR_O2_RSPBUG_OK 0x00000010 /* let buggy responses pass through */
|
||||
#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 */
|
||||
|
||||
/* This structure is used to apply fast weighted round robin on a server group */
|
||||
struct fwrr_group {
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ static const struct cfg_opt cfg_opts2[] =
|
|||
{ "accept-invalid-http-response", PR_O2_RSPBUG_OK, PR_CAP_BE, 0 },
|
||||
{ "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 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -3741,6 +3742,12 @@ int readcfgfile(const char *file)
|
|||
if (curproxy->mode == PR_MODE_HTTP)
|
||||
listener->analysers |= AN_REQ_HTTP_HDR;
|
||||
|
||||
/* smart accept mode is automatic in HTTP mode */
|
||||
if ((curproxy->options2 & PR_O2_SMARTACC) ||
|
||||
(curproxy->mode == PR_MODE_HTTP &&
|
||||
!(curproxy->no_options2 & PR_O2_SMARTACC)))
|
||||
listener->options |= LI_O_NOQUICKACK;
|
||||
|
||||
if (curproxy->tcp_req.inspect_delay ||
|
||||
!LIST_ISEMPTY(&curproxy->tcp_req.inspect_rules))
|
||||
listener->analysers |= AN_REQ_INSPECT;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
@ -263,6 +265,11 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
|||
goto tcp_close_return;
|
||||
}
|
||||
|
||||
#ifdef TCP_QUICKACK
|
||||
if (listener->options & LI_O_NOQUICKACK)
|
||||
setsockopt(fd, SOL_TCP, TCP_QUICKACK, (char *) &zero, sizeof(zero));
|
||||
#endif
|
||||
|
||||
/* the socket is ready */
|
||||
listener->fd = fd;
|
||||
listener->state = LI_LISTEN;
|
||||
|
|
|
|||
Loading…
Reference in a new issue