You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Bill Stoddard <bi...@wstoddard.com> on 2005/09/15 22:09:19 UTC

Re: Bandwidth Limit on Windows

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


Re: Bandwidth Limit on Windows

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Thu, Sep 15, 2005 at 03:26:49PM -0500, William A. Rowe, Jr. wrote:
> So how to figure out if we are making progress?  I'm unsure and this
> all deserves another look at the current state of the Win32 sockets API,
> I haven't fallen down that well in a good long time :)

I have, it's painful ;) 

This is truly evil, and I apologise in advance for making suggestion,
but what about GetTcpTable() ? It's how netstat and the likes of TCPview
work, and has more than enough information (it's a dump of the entire
TCP table), which means the useful part would have to be seperated out,
but this should not effect performance (of the socket itself) since
paralellism is implied.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net

Re: Bandwidth Limit on Windows

Posted by Bill Stoddard <bi...@wstoddard.com>.
William A. Rowe, Jr. wrote:
> Bill Stoddard wrote:
> 
>>> 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 forgot the punch line here but hopefully it's obvious where I'm 
>> heading...  apr_sendfile on windows performs badly because of a 
>> misguided attempt at mitigating a particular DoS attack against the 
>> server and the cure is worse than the disease.  We should change 
>> apr_sendfile to perform optimally on Windows w/o concern for httpd 
>> level DoS attacks.
> 
> 
> Yup.  It's definately worth considering your alternatives.  It's also
> worth looking at what socket-level timeouts exist, or if we can start
> plugging in some higher-level timeout within the MPM.  
But they all will be gated by the basic algorithm of timeout = Timeout * sizetosend/64KB unless we discover 
how to determine if a TransmitFile is making progress.

> When a process
> does nothing in certain phases of the request cycle after some timeout,
> simply close the socket from underneath APR.
> 
> So how to figure out if we are making progress?  

By all means keep looking. I took a look a few months back and found nothing new. I do know how to emulate 
event driven network i/o on windows now tho.

Bill





Re: Bandwidth Limit on Windows

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Thu, Sep 15, 2005 at 03:26:49PM -0500, William A. Rowe, Jr. wrote:
> So how to figure out if we are making progress?  I'm unsure and this
> all deserves another look at the current state of the Win32 sockets API,
> I haven't fallen down that well in a good long time :)

I have, it's painful ;) 

This is truly evil, and I apologise in advance for making suggestion,
but what about GetTcpTable() ? It's how netstat and the likes of TCPview
work, and has more than enough information (it's a dump of the entire
TCP table), which means the useful part would have to be seperated out,
but this should not effect performance (of the socket itself) since
paralellism is implied.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net

Re: Bandwidth Limit on Windows

Posted by Bill Stoddard <bi...@wstoddard.com>.
William A. Rowe, Jr. wrote:
> Bill Stoddard wrote:
> 
>>> 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 forgot the punch line here but hopefully it's obvious where I'm 
>> heading...  apr_sendfile on windows performs badly because of a 
>> misguided attempt at mitigating a particular DoS attack against the 
>> server and the cure is worse than the disease.  We should change 
>> apr_sendfile to perform optimally on Windows w/o concern for httpd 
>> level DoS attacks.
> 
> 
> Yup.  It's definately worth considering your alternatives.  It's also
> worth looking at what socket-level timeouts exist, or if we can start
> plugging in some higher-level timeout within the MPM.  
But they all will be gated by the basic algorithm of timeout = Timeout * sizetosend/64KB unless we discover 
how to determine if a TransmitFile is making progress.

> When a process
> does nothing in certain phases of the request cycle after some timeout,
> simply close the socket from underneath APR.
> 
> So how to figure out if we are making progress?  

By all means keep looking. I took a look a few months back and found nothing new. I do know how to emulate 
event driven network i/o on windows now tho.

Bill





Re: Bandwidth Limit on Windows

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
Bill Stoddard wrote:
>> 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 forgot the punch line here but hopefully it's obvious where I'm 
> heading...  apr_sendfile on windows performs badly because of a 
> misguided attempt at mitigating a particular DoS attack against the 
> server and the cure is worse than the disease.  We should change 
> apr_sendfile to perform optimally on Windows w/o concern for httpd level 
> DoS attacks.

Yup.  It's definately worth considering your alternatives.  It's also
worth looking at what socket-level timeouts exist, or if we can start
plugging in some higher-level timeout within the MPM.  When a process
does nothing in certain phases of the request cycle after some timeout,
simply close the socket from underneath APR.

So how to figure out if we are making progress?  I'm unsure and this
all deserves another look at the current state of the Win32 sockets API,
I haven't fallen down that well in a good long time :)

Of course async would be wonderful, at some point, as apache 3.0 starts
to draw interest.

Bill

Re: Bandwidth Limit on Windows

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
Bill Stoddard wrote:
>> 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 forgot the punch line here but hopefully it's obvious where I'm 
> heading...  apr_sendfile on windows performs badly because of a 
> misguided attempt at mitigating a particular DoS attack against the 
> server and the cure is worse than the disease.  We should change 
> apr_sendfile to perform optimally on Windows w/o concern for httpd level 
> DoS attacks.

Yup.  It's definately worth considering your alternatives.  It's also
worth looking at what socket-level timeouts exist, or if we can start
plugging in some higher-level timeout within the MPM.  When a process
does nothing in certain phases of the request cycle after some timeout,
simply close the socket from underneath APR.

So how to figure out if we are making progress?  I'm unsure and this
all deserves another look at the current state of the Win32 sockets API,
I haven't fallen down that well in a good long time :)

Of course async would be wonderful, at some point, as apache 3.0 starts
to draw interest.

Bill

Re: Bandwidth Limit on Windows

Posted by Bill Stoddard <bi...@wstoddard.com>.
> 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 forgot the punch line here but hopefully it's obvious where I'm heading...  apr_sendfile on windows performs 
badly because of a misguided attempt at mitigating a particular DoS attack against the server and the cure is 
worse than the disease.  We should change apr_sendfile to perform optimally on Windows w/o concern for httpd 
level DoS attacks.


Re: Bandwidth Limit on Windows

Posted by Bill Stoddard <bi...@wstoddard.com>.
> 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 forgot the punch line here but hopefully it's obvious where I'm heading...  apr_sendfile on windows performs 
badly because of a misguided attempt at mitigating a particular DoS attack against the server and the cure is 
worse than the disease.  We should change apr_sendfile to perform optimally on Windows w/o concern for httpd 
level DoS attacks.