On Sat, Oct 31, 2020 at 01:57:08AM +0100, Yann Ylavic wrote: > On Wed, Oct 28, 2020 at 6:40 PM Joe Orton <jor...@redhat.com> wrote: > > > > On Wed, Oct 21, 2020 at 05:17:01PM +0100, Adam Hill wrote: > > > On Linux at least, you can see how much unsent data remains by querying > > > the > > > SIOCOUTQ ioctl, so the mitigation would be to check to see that ANY data > > > was draining at all, and if so ( and there's some left ) extend the > > > lingering close time and repeat. However, this wouldn't be a cross > > > platform > > > solution, but it would at least be the "correct" thing to do in terms of > > > network function. Not sure if there's an equivalent on other systems. > > > > Nice writeup, thank you. > > +1 > > > So I kind of wish that > > something was missed here, but multiple people have come to exactly that > > conclusion independently. > > It may be due to r1802875 where I added RST (SO_LINGER.l_linger = 0) > after lingering close timeout.
Oh, happy to see I missed that! Thanks Yann. > Thinking of it now, it's probably not the right thing to do. Simply > calling apr_socket_close() in abort_socket_nonblocking() would allow > the system's lingering close after httpd's. +1 > Adam, can you still observe the same behaviour with the attached > mpm_event patch applied? > > > Regards; > Yann. > Index: server/mpm/event/event.c > =================================================================== > --- server/mpm/event/event.c (revision 1881339) > +++ server/mpm/event/event.c (working copy) > @@ -526,21 +526,6 @@ static void abort_socket_nonblocking(apr_socket_t > { > apr_status_t rv; > apr_socket_timeout_set(csd, 0); > -#if defined(SOL_SOCKET) && defined(SO_LINGER) > - /* This socket is over now, and we don't want to block nor linger > - * anymore, so reset it. A normal close could still linger in the > - * system, while RST is fast, nonblocking, and what the peer will > - * get if it sends us further data anyway. > - */ > - { > - apr_os_sock_t osd = -1; > - struct linger opt; > - opt.l_onoff = 1; > - opt.l_linger = 0; /* zero timeout is RST */ > - apr_os_sock_get(&osd, csd); > - setsockopt(osd, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof opt); > - } > -#endif > rv = apr_socket_close(csd); > if (rv != APR_SUCCESS) { > ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, > APLOGNO(00468)