You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Joe Orton <jo...@manyfish.co.uk> on 2004/05/07 02:29:29 UTC

blocking bucket reads on non-blocking sockets

The mod_perl test suite started failing on platforms where the
c->client_socket is now left with O_NONBLOCK set.

As I read it, the reason is that the socket bucket ->read function does
not attempt to handle being called with APR_BLOCK_READ on a non-blocking
socket (and can fail with EAGAIN etc in that case); whereas it does
handle being called with APR_NONBLOCK_READ on a blocking socket. 

This seems a little counter-intuitive; is it by design, or is it a bug?

Regards,

joe

Re: blocking bucket reads on non-blocking sockets

Posted by Joe Orton <jo...@manyfish.co.uk>.
On Mon, May 17, 2004 at 01:45:03PM +0100, Joe Orton wrote:
> On Fri, May 14, 2004 at 05:36:01PM -0700, Stas Bekman wrote:
> > So what's the solution here?
> 
> I'd hoped some friendly buckets guru would step in here :) I guess if
> it's correct to solve this at bucket-level, the solution is to make
> socket_bucket_read() check whether the socket is non-blocking on each
> call, and temporarily set the timeout to -1 if it is...

Hmmm.  http://thread.gmane.org/gmane.comp.apache.apr.devel/4554 says
that the only timeout setting which works consistently on both Win32 and
Unix for sockets with APR_SO_NONBLOCK set is timeout = 0, so maybe that
doesn't work so well.



Re: blocking bucket reads on non-blocking sockets

Posted by Stas Bekman <st...@stason.org>.
Cliff Woolley wrote:
> On Mon, 17 May 2004, Stas Bekman wrote:
> 
> 
>>You mean, you dare to leave, without finding a proxy first? :)
> 
> 
> I'll be here for the member's meeting.  I'm not leaving until Wednesday.
> I just have a lot to do between now and then.  :)

I meant a buckets guru proxy :)

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: blocking bucket reads on non-blocking sockets

Posted by Cliff Woolley <jw...@virginia.edu>.
On Mon, 17 May 2004, Stas Bekman wrote:

> You mean, you dare to leave, without finding a proxy first? :)

I'll be here for the member's meeting.  I'm not leaving until Wednesday.
I just have a lot to do between now and then.  :)

Re: blocking bucket reads on non-blocking sockets

Posted by Stas Bekman <st...@stason.org>.
Cliff Woolley wrote:
> On Mon, 17 May 2004, Joe Orton wrote:
> 
> 
>>I'd hoped some friendly buckets guru would step in here :) I guess if
>>it's correct to solve this at bucket-level, the solution is to make
>>socket_bucket_read() check whether the socket is non-blocking on each
>>call, and temporarily set the timeout to -1 if it is...
> 
> 
> How is it that you guys always come up with work for /me/ to do when I'm
> on my way out of town?  heheheh  Anyway this particular bucket guru is
> about to get on the road to head to Santa Clara, CA for the summer... and
> it'll be about a week and a half voyage.  So either some other bucket guru
> needs to step in, or somebody else needs to do it, or it has to wait until
> I'm on the left coast.  :)

You mean, you dare to leave, without finding a proxy first? :)


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: blocking bucket reads on non-blocking sockets

Posted by Stas Bekman <st...@stason.org>.
Cliff Woolley wrote:
> On Mon, 17 May 2004, Joe Orton wrote:
> 
> 
>>I'd hoped some friendly buckets guru would step in here :) I guess if
>>it's correct to solve this at bucket-level, the solution is to make
>>socket_bucket_read() check whether the socket is non-blocking on each
>>call, and temporarily set the timeout to -1 if it is...
> 
> 
> How is it that you guys always come up with work for /me/ to do when I'm
> on my way out of town?  heheheh  Anyway this particular bucket guru is
> about to get on the road to head to Santa Clara, CA for the summer... and
> it'll be about a week and a half voyage.  So either some other bucket guru
> needs to step in, or somebody else needs to do it, or it has to wait until
> I'm on the left coast.  :)

This bug is still unresolved. It was last discussed 2.5 months ago.
Cliff or someone else, could you please take a look at it?

If you're unsure what is this about: it's the socket_bucket_read() bug 
in protocol handlers, due to the httpd-level fix to have the socket 
unblocking by default. The whole thread is here:
http://marc.theaimsgroup.com/?t=108401828500002&r=1&w=2

Thank you!

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: blocking bucket reads on non-blocking sockets

Posted by Cliff Woolley <jw...@virginia.edu>.
On Mon, 17 May 2004, Joe Orton wrote:

> I'd hoped some friendly buckets guru would step in here :) I guess if
> it's correct to solve this at bucket-level, the solution is to make
> socket_bucket_read() check whether the socket is non-blocking on each
> call, and temporarily set the timeout to -1 if it is...

How is it that you guys always come up with work for /me/ to do when I'm
on my way out of town?  heheheh  Anyway this particular bucket guru is
about to get on the road to head to Santa Clara, CA for the summer... and
it'll be about a week and a half voyage.  So either some other bucket guru
needs to step in, or somebody else needs to do it, or it has to wait until
I'm on the left coast.  :)

--Cliff

Re: blocking bucket reads on non-blocking sockets

Posted by Joe Orton <jo...@manyfish.co.uk>.
On Fri, May 14, 2004 at 05:36:01PM -0700, Stas Bekman wrote:
> Joe Orton wrote:
> >Oh, the trigger for this is as we discussed before, simply the fact that
> >2.0.49 leaves sockets with O_NONBLOCK set (after the multi-listen DoS
> >security fix) on some platforms.
> 
> Was this fix needed specificaly for HTTP or for any protocols?

It was a bug in the accept/select handling at MPM leve, needed for any
protocols, yes.

> >This doesn't matter for httpd since any request-level filters will use
> >the apr_socket when it has a non-zero timeout set (by the net_time
> >filter), in which case it acts just like a blocking socket.
> >
> >The problem is as you say in protocol-level filters/handlers; there, the
> >apr_socket has no timeout set, so it really does act like a non-blocking
> >socket.
> 
> So what's the solution here?

I'd hoped some friendly buckets guru would step in here :) I guess if
it's correct to solve this at bucket-level, the solution is to make
socket_bucket_read() check whether the socket is non-blocking on each
call, and temporarily set the timeout to -1 if it is...

Or alternatively, for apr_socket_bucket_create() to check once whether 
the socket is non-blocking, and use a wrapper for socket_bucket_read 
which does that.

joe 

Re: blocking bucket reads on non-blocking sockets

Posted by Stas Bekman <st...@stason.org>.
Joe Orton wrote:
> On Fri, May 14, 2004 at 04:16:34PM -0700, Stas Bekman wrote:
> 
>>Cliff Woolley wrote:
>>
>>>On Fri, 14 May 2004, Stas Bekman wrote:
>>>
>>>
>>>
>>>>So, who changed that in 2.0.49? It worked just fine pre-2.0.48. The
>>>>guilty party please stand up and explain. This change causes a
>>>>serious breakage in the protocol handlers and filters on those
>>>>affected platforms. I suppose apr doesn't have tests for that, and
>>>>that's why the problem wasn't caught when it was introduced. Thanks.
> 
> 
> Oh, the trigger for this is as we discussed before, simply the fact that
> 2.0.49 leaves sockets with O_NONBLOCK set (after the multi-listen DoS
> security fix) on some platforms.

Was this fix needed specificaly for HTTP or for any protocols?

> This doesn't matter for httpd since any request-level filters will use
> the apr_socket when it has a non-zero timeout set (by the net_time
> filter), in which case it acts just like a blocking socket.
> 
> The problem is as you say in protocol-level filters/handlers; there, the
> apr_socket has no timeout set, so it really does act like a non-blocking
> socket.

So what's the solution here?

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: blocking bucket reads on non-blocking sockets

Posted by Joe Orton <jo...@manyfish.co.uk>.
On Fri, May 14, 2004 at 04:16:34PM -0700, Stas Bekman wrote:
> Cliff Woolley wrote:
> >On Fri, 14 May 2004, Stas Bekman wrote:
> >
> >
> >>So, who changed that in 2.0.49? It worked just fine pre-2.0.48. The
> >>guilty party please stand up and explain. This change causes a
> >>serious breakage in the protocol handlers and filters on those
> >>affected platforms. I suppose apr doesn't have tests for that, and
> >>that's why the problem wasn't caught when it was introduced. Thanks.

Oh, the trigger for this is as we discussed before, simply the fact that
2.0.49 leaves sockets with O_NONBLOCK set (after the multi-listen DoS
security fix) on some platforms.

This doesn't matter for httpd since any request-level filters will use
the apr_socket when it has a non-zero timeout set (by the net_time
filter), in which case it acts just like a blocking socket.

The problem is as you say in protocol-level filters/handlers; there, the
apr_socket has no timeout set, so it really does act like a non-blocking
socket.

joe

Re: blocking bucket reads on non-blocking sockets

Posted by Stas Bekman <st...@stason.org>.
Cliff Woolley wrote:
> On Fri, 14 May 2004, Stas Bekman wrote:
> 
> 
>>So, who changed that in 2.0.49? It worked just fine pre-2.0.48. The guilty
>>party please stand up and explain. This change causes a serious breakage in
>>the protocol handlers and filters on those affected platforms. I suppose apr
>>doesn't have tests for that, and that's why the problem wasn't caught when it
>>was introduced. Thanks.
> 
> 
> The socket buckets (or any buckets that I know of) did not change between
> 2.0.48 and 2.0.49.  If they're broken now and weren't before, it's either
> something else changed, or it really WAS broken before and we just didn't
> notice.

The problem is that the bug doesn't appear to happen on Linux. So I can't tell 
when exactly this problem emerged. All I know that 3 tests that were written 
about 2-3 years ago worked fine all this time. The moment users upgraded to 
2.0.49 they started to report failures on Solaris, MacOSX and *BSD. Does it 
information provide any hints?

> It's certainly true that if apr_socket_recv() returns APR_EAGAIN, so will
> socket_bucket_read().  But the block of code that does that has been that
> way for as long as I can remember.  That doesn't necessarily make it
> right.  :)

I suppose it could be something in Apache. e.g. before 2.0.48 Apache was 
explicitly setting the socket to a blocking mode before handing it to the 
callbacks. And it probably stopped doing that in 2.0.49? Why linux and windows 
are then different from other platforms?

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Re: blocking bucket reads on non-blocking sockets

Posted by Cliff Woolley <jw...@virginia.edu>.
On Fri, 14 May 2004, Stas Bekman wrote:

> So, who changed that in 2.0.49? It worked just fine pre-2.0.48. The guilty
> party please stand up and explain. This change causes a serious breakage in
> the protocol handlers and filters on those affected platforms. I suppose apr
> doesn't have tests for that, and that's why the problem wasn't caught when it
> was introduced. Thanks.

The socket buckets (or any buckets that I know of) did not change between
2.0.48 and 2.0.49.  If they're broken now and weren't before, it's either
something else changed, or it really WAS broken before and we just didn't
notice.

It's certainly true that if apr_socket_recv() returns APR_EAGAIN, so will
socket_bucket_read().  But the block of code that does that has been that
way for as long as I can remember.  That doesn't necessarily make it
right.  :)

--Cliff


Re: blocking bucket reads on non-blocking sockets

Posted by Stas Bekman <st...@stason.org>.
Joe Orton wrote:
> The mod_perl test suite started failing on platforms where the
> c->client_socket is now left with O_NONBLOCK set.
> 
> As I read it, the reason is that the socket bucket ->read function does
> not attempt to handle being called with APR_BLOCK_READ on a non-blocking
> socket (and can fail with EAGAIN etc in that case); whereas it does
> handle being called with APR_NONBLOCK_READ on a blocking socket. 
> 
> This seems a little counter-intuitive; is it by design, or is it a bug?

So, who changed that in 2.0.49? It worked just fine pre-2.0.48. The guilty 
party please stand up and explain. This change causes a serious breakage in 
the protocol handlers and filters on those affected platforms. I suppose apr 
doesn't have tests for that, and that's why the problem wasn't caught when it 
was introduced. Thanks.

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com