summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2016-06-29 21:02:44 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2016-06-29 21:02:44 -0400
commit416b5729fbb0a10fb91da1e02481b1dc695b5141 (patch)
treedb4466e7c2d53747ce0eb556fea6ce20e84e2423
parenteefb94bb39b7e2abbf5615df742b5a20a04bc6a0 (diff)
downloadlighttpd-git-416b5729fbb0a10fb91da1e02481b1dc695b5141.tar.gz
[core] disable Nagle algorithm (TCP_NODELAY)
disable Nagle algorithm (TCP_NODELAY) on client sockets
-rw-r--r--src/connections.c3
-rw-r--r--src/network.c30
-rw-r--r--src/network.h2
-rw-r--r--src/server.c4
4 files changed, 39 insertions, 0 deletions
diff --git a/src/connections.c b/src/connections.c
index e8b42bc0..d2a6da18 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -909,6 +909,9 @@ connection *connection_accept(server *srv, server_socket *srv_socket) {
}
return NULL;
} else {
+ if (cnt_addr.plain.sa_family != AF_UNIX) {
+ network_accept_tcp_nagle_disable(cnt);
+ }
return connection_accepted(srv, srv_socket, &cnt_addr, cnt);
}
}
diff --git a/src/network.c b/src/network.c
index a0b43835..62c8e836 100644
--- a/src/network.c
+++ b/src/network.c
@@ -50,6 +50,28 @@ static void ssl_info_callback(const SSL *ssl, int where, int ret) {
}
#endif
+void
+network_accept_tcp_nagle_disable (const int fd)
+{
+ static int noinherit_tcpnodelay = -1;
+ int opt;
+
+ if (!noinherit_tcpnodelay) /* TCP_NODELAY inherited from listen socket */
+ return;
+
+ if (noinherit_tcpnodelay < 0) {
+ socklen_t optlen = sizeof(opt);
+ if (0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen)) {
+ noinherit_tcpnodelay = !opt;
+ if (opt) /* TCP_NODELAY inherited from listen socket */
+ return;
+ }
+ }
+
+ opt = 1;
+ (void)setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+}
+
static handler_t network_server_handle_fdevent(server *srv, void *context, int revents) {
server_socket *srv_socket = (server_socket *)context;
connection *con;
@@ -408,6 +430,14 @@ static int network_server_init(server *srv, buffer *host_token, specific_config
goto error_free_socket;
}
+ if (srv_socket->addr.plain.sa_family != AF_UNIX) {
+ val = 1;
+ if (setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) < 0) {
+ log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt(TCP_NODELAY) failed:", strerror(errno));
+ goto error_free_socket;
+ }
+ }
+
if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) {
switch(srv_socket->addr.plain.sa_family) {
case AF_UNIX:
diff --git a/src/network.h b/src/network.h
index c478c423..37f021de 100644
--- a/src/network.h
+++ b/src/network.h
@@ -4,6 +4,8 @@
#include "server.h"
+void network_accept_tcp_nagle_disable(int fd);
+
int network_write_chunkqueue(server *srv, connection *con, chunkqueue *c, off_t max_bytes);
int network_init(server *srv);
diff --git a/src/server.c b/src/server.c
index db020c09..a55c315c 100644
--- a/src/server.c
+++ b/src/server.c
@@ -530,6 +530,10 @@ static int server_oneshot_init(server *srv, int fd) {
return 0;
}
+ if (cnt_addr.plain.sa_family != AF_UNIX) {
+ network_accept_tcp_nagle_disable(fd);
+ }
+
con = connection_accepted(srv, srv_socket, &cnt_addr, fd);
if (NULL == con) return 0;