diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2016-06-29 21:02:44 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2016-06-29 21:02:44 -0400 |
commit | 416b5729fbb0a10fb91da1e02481b1dc695b5141 (patch) | |
tree | db4466e7c2d53747ce0eb556fea6ce20e84e2423 | |
parent | eefb94bb39b7e2abbf5615df742b5a20a04bc6a0 (diff) | |
download | lighttpd-git-416b5729fbb0a10fb91da1e02481b1dc695b5141.tar.gz |
[core] disable Nagle algorithm (TCP_NODELAY)
disable Nagle algorithm (TCP_NODELAY) on client sockets
-rw-r--r-- | src/connections.c | 3 | ||||
-rw-r--r-- | src/network.c | 30 | ||||
-rw-r--r-- | src/network.h | 2 | ||||
-rw-r--r-- | src/server.c | 4 |
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; |