On Fri, Aug 10, 2012 at 1:31 PM, Jeff Trawick <traw...@gmail.com> wrote:
> On Fri, Aug 10, 2012 at 12:41 PM, Jeff Trawick <traw...@gmail.com> wrote:
>> On Thu, Aug 9, 2012 at 7:35 PM, William A. Rowe Jr. <wr...@rowe-clan.net> 
>> 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/

Reply via email to