On Fri, Aug 10, 2012 at 1:31 PM, Jeff Trawick <[email protected]> wrote:
> On Fri, Aug 10, 2012 at 12:41 PM, Jeff Trawick <[email protected]> wrote:
>> On Thu, Aug 9, 2012 at 7:35 PM, William A. Rowe Jr. <[email protected]>
>> wrote:
>>> On 8/9/2012 11:26 AM, Claudio Caldato (MS OPEN TECH) wrote:
>>>> Better patch, fixed minor issue after another code review.
>>>
>>> Sadly, it won't fix the defect.
>>>
>>> Yes, you are successfullly performing a blocking initial read.
>>>
>>> And the pipe remains unblocked for the rest of the connection, so any
>>> further blocking reads will be ignored (just like the initial read by
>>> mod_ssl failed to block). Any module expecting blocking behavior on
>>> subsequent reads will be disappointed.
>>
>> The SSL case with the chitchat to set up the connection is a bit
>> different than the simple case where as soon as you read you have
>> everything needed, so it does seem moderately interesting that the
>> read|peek makes the simple SSL testcase work.
>>
>> Also in the FWLIW department:
>>
>> a. once we get to the process_connection hook, APR's limited knowledge
>> of the socket state (timeout, non-blocking) is the same on Linux and
>> Windows
>>
>> (That was expected all along.)
>>
>> I had hoped to query state directly from the OS socket too, but
>> apparently the Microsoft folks don't think you need to be able to do
>> that, and I don't see any external sysinternals|other tools to tell
>> you anything interesting about the socket other than the normal
>> netstat stuff.
>>
>> b. Using WSAEnumNetworkEvents to clear any existing events didn't seem to
>> help
>>
>> /* start new */
>> rv = WSAEnumNetworkEvents(context->accept_socket, 0,
>> &lpNetworkEvents);
>> if (rv == SOCKET_ERROR) {
>> ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf,
>> "failed to clear network events on connected
>> socket");
>> }
>> /* end new */
>> apr_os_sock_make(&context->sock, &sockinfo, context->ptrans);
>>
>> c. switching out the WSAEvent stuff for a straight
>> select(is-listener-readable) doesn't work around the problem either
>
> The APR socket gets set to non-blocking prior to the first call to
> apr_socket_recv():
>
> #0 apr_socket_opt_set (sock=0x2933890, opt=8, on=1)
> at network_io/win32/sockopt.c:104
> #1 0x00423daa in ap_core_output_filter (f=0xc2bb310, new_bb=0x2933d20)
> at core_filters.c:394
> #2 0x0042197c in ap_pass_brigade (next=0xc2bb310, bb=0x2933d20)
> at util_filter.c:533
> #3 0x0045be1e in bio_filter_out_pass (bio=<value optimized out>)
> at ssl_engine_io.c:134
> #4 bio_filter_out_flush (bio=<value optimized out>) at ssl_engine_io.c:155
> #5 0x0045bff9 in bio_filter_in_read (bio=0x28aa9a8,
> in=0x2899348 "0╪ \f\003\001", inlen=11) at ssl_engine_io.c:458
> #6 0x004b30f7 in BIO_read ()
> #7 0x00c1b798 in ?? ()
>
> We picked up that apr_socket_opt_set() from the async-dev branch with
> r327872, though the timeout calls in there were changed subsequently.
> I wonder if that call is stray and it doesn't get along with the
> timeout handling on Windows because of the SO_RCVTIMEO/SO_SENDTIMEO
> use on Windows, in lieu of non-blocking socket + poll like on Unix.
>
> At the time it was added, the new code was
>
> apr_socket_timeout_set(client_socket, 0)
> apr_socket_opt_set(client_socket, APR_SO_NONBLOCK, 1)
>
> (redundant unless there was some APR glitch at the time)
>
> The apr_socket_timeout_set() was subsequently removed.
>
> I'll proceed with the obvious test. (I'm pretending that someone is
> out there reading this and will chime in with any hints or other
> comments based on my stream of observations :) )
This patch is testing great so far with the AcceptFilter-none+SSL
scenario on Windows.
Index: server/core_filters.c
===================================================================
--- server/core_filters.c (revision 1371377)
+++ server/core_filters.c (working copy)
@@ -391,10 +391,6 @@
if (ctx == NULL) {
ctx = apr_pcalloc(c->pool, sizeof(*ctx));
net->out_ctx = (core_output_filter_ctx_t *)ctx;
- rv = apr_socket_opt_set(net->client_socket, APR_SO_NONBLOCK, 1);
- if (rv != APR_SUCCESS) {
- return rv;
- }
/*
* Need to create tmp brigade with correct lifetime. Passing
* NULL to apr_brigade_split_ex would result in a brigade
I'll run it through the test framework on Linux before committing.
--
Born in Roswell... married an alien...
http://emptyhammock.com/