[Haskell-cafe] Re: sendfile leaking descriptors on Linux?
spam at scientician.net
Sun Feb 14 15:04:30 EST 2010
> Jeremy Shaw wrote:
>> import Control.Concurrent
>> import Control.Concurrent.MVar
>> import System.Posix.Types
>> data RW = Read | Write
>> threadWaitReadWrite :: Fd -> IO RW
>> threadWaitReadWrite fd =
>> do m <- newEmptyMVar
>> rid <- forkIO $ threadWaitRead fd >> putMVar m Read
>> wid <- forkIO $ threadWaitWrite fd >> putMVar m Write
>> r <- takeMVar m
>> killThread rid
>> killThread wid
>> return r
I've tested this extensively during this weekend and not a single
"leaked" FD so far.
I think we can safely say that polling an FD for read readiness is
sufficient to properly detect a disconnected client regardless of
why/how the client disconnected.
The only issue I can see with just dropping the above code directly into
the sendfile library is that it may lead to busy-waiting on EAGAIN *if*
the client is actually trying to send data to the server while it's
receiving the file via sendfile(). If the client sends even a single
byte and the server isn't reading it from the socket, then
threadWaitRead will keep returning immediately since it's
level-triggered rather than edge triggered.
In the worst case this could be exploited by evil clients as a trivial
way to DoS a server -- simply send data while the server is sending you
a file. Bam, instant 100% CPU utilization on the server.
Not sure what the best solution for this would be, API-wise... Maybe
actually have sendfile read the data and supply it to a user-defined
function which could react to the data in some way? (Could supply two
standard functions: "disconnect immediately" and "accumulate all
received data into a bytestring".)
More information about the Haskell-Cafe