httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bill Stoddard <>
Subject Re: Bandwidth Limit on Windows
Date Thu, 15 Sep 2005 20:09:19 GMT
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 dev@apr).

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,
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 

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



View raw message