William A. Rowe, Jr. wrote:
Phillip Susi wrote:

When I asked about this a month or two ago, someone explained that Apache uses TransmitFile() to implement sendfile but in a weird way that makes it really, really slow. Disabling sendfile in the apache config, and just using the mmap module gives the best throughput on windows.


We, the apr developers, would be very interested in their observations
if you can find a pointer.

Right here is your pointer.. and the poor performance of apr_sendfile on windows has been discussed before (here and on [EMAIL PROTECTED]).

Windows does not provide a way to see if a call to TransmitFile is 'making progress' and it does not provide a way to set an 'activity timeout' on a sync call to transmitfile. IIS supports async network i/o, so IIS does not require the thread that makes the call to TransmitFile to hang around waiting for the send to complete. Apache httpd otoh, requires the thread to not unwind the stack until the call to TransmitFile completes. So you make a call to TransmitFile to send an entire 100MB file... if you make the call syncronously, your exposed to a DoS attack if the client does not read the data. If you make the call non-blocking, how long do you wait for the 100MB send to complete? Certainly not 'timeout' seconds; you'll not send 100M bytes over a reasonably fast link in the default timeout period, so your transfer would timeout prematurely.

My thinking on how to solve this has changed over the past year or so... there are numerous ways to DoS an httpd server and you can't protect against the more effective attacks at the httpd layer. I would be infavor or changing apr_sendfile on Windows in one of the following ways (both will dramatically boost the file transfer speed):

1. Make a synchronous call to TransmitFile to send -all- the requested content (rather than breaking up the sends in 64 KB chunks). This is a trivially easy change to make.

2. Make a non-blocking call to TransmitFile to send -all- the request content (rather than breaking up the sends into 64 KB chunks) and adjusting the timeout according to a simple algorithm:

timeout = Timeout (the config directive) * sizeofsend/64KB

option 2 would at least provide a method to eventually timeout a DoS call. This is a trivially easy change to make as well.

I would be in favor of making either change as compared to what is in apr_sendfile now (whcih causes so much grief).

There are other options involving watchdog threads and such, but they are limited by the inability to detect if a TransmitFile is 'making progress'.

votes?

Bill

Reply via email to