Browse Source

[core] proxy,scgi omit shutdown() to backend (fixes #2743)

Due to the POLLHUP behavior triggered on *BSD/Darwin, the shutdown()
had previously been limited to local connections.  If interested in
squeezing the last bits of performance out of a machine, an admin
should configure local connections to be AF_UNIX instead of AF_INET
or AF_INET6 to localhost.  The reason the shutdown() was originally
added in mod_proxy and mod_scgi was to aggressively reduce the number
of potential sockets in TIME_WAIT held by lighttpd.
(See commit:923688d2 "drain backend socket/pipe bufs upon FDEVENT_HUP",
 done for reliability given the aforementioned *BSD/Darwin behavior.)
When using AF_UNIX, the TIME_WAIT issue does not exist, ergo, the
recommendation is to use AF_UNIX for local sockets, when available.
Using AF_UNIX sockets is a better solution to eliminate TIME_WAIT
than is TCP shutdown() half-close which, as we have seen, might not
be handled well by frameworks which are more complex than basic read
request, send response, and close.

x-ref:
  "1.4.40/41 mod_proxy, mod_scgi may trigger POLLHUP on *BSD,Darwin"
  https://redmine.lighttpd.net/issues/2743
personal/stbuehler/mod-csrf-old
Glenn Strauss 6 years ago
parent
commit
27f85dbdf4
  1. 14
      src/mod_proxy.c
  2. 14
      src/mod_scgi.c

14
src/mod_proxy.c

@ -854,20 +854,6 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
if (hctx->wb->bytes_out == hctx->wb_reqlen) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
#if (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__FreeBSD__) || defined(__NetBSD__) \
|| defined(__OpenBSD__) || defined(__DragonflyBSD__)
/*(*BSD stack on remote might signal POLLHUP and remote
* might treat as socket error instead of half-close)*/
#else
/*(remote could be different machine running affected OS,
* so only issue shutdown for known local sockets)*/
if ( '/' == host->host->ptr[0]
|| buffer_is_equal_string(host->host, CONST_STR_LEN("127.0.0.1"))
|| buffer_is_equal_string(host->host, CONST_STR_LEN("::1"))) {
shutdown(hctx->fd, SHUT_WR);/* future: remove if HTTP/1.1 request */
}
#endif
proxy_set_state(srv, hctx, PROXY_STATE_READ);
} else {
off_t wblen = hctx->wb->bytes_in - hctx->wb->bytes_out;

14
src/mod_scgi.c

@ -2438,20 +2438,6 @@ static handler_t scgi_write_request(server *srv, handler_ctx *hctx) {
if (hctx->wb->bytes_out == hctx->wb_reqlen) {
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
#if (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__FreeBSD__) || defined(__NetBSD__) \
|| defined(__OpenBSD__) || defined(__DragonflyBSD__)
/*(*BSD stack on remote might signal POLLHUP and remote
* might treat as socket error instead of half-close)*/
#else
/*(remote could be different machine running affected OS,
* so only issue shutdown for known local sockets)*/
if ( '/' == host->host->ptr[0]
|| buffer_is_equal_string(host->host, CONST_STR_LEN("127.0.0.1"))
|| buffer_is_equal_string(host->host, CONST_STR_LEN("::1"))) {
shutdown(hctx->fd, SHUT_WR);
}
#endif
scgi_set_state(srv, hctx, FCGI_STATE_READ);
} else {
off_t wblen = hctx->wb->bytes_in - hctx->wb->bytes_out;

Loading…
Cancel
Save