In a servlet-based app I’m currently writing we have separate thread classes for readers and writers. Data is transmitted from a writer to multiple readers by using LinkedBlockingQueue<byte[]>, so a reader safely blocks if there is no new data to get from the writer. The problem is that if remote clients served by these reader threads terminate connection, Tomcat won’t throw a broken pipe unless the writer sends in new data and attempts to transmit this new chunk to the remote clients. In other words, the following attack can be performed against our service:
- Start a streaming write request and don’t write any data to it at all.
- Keep creating and dropping read connections. Since the writer doesn’t produce any data, reading threads attached to it remain blocked and consume memory and other resources.
- Observe the server run out of RAM quickly.
Should I create a single maintenance thread that would monitor sockets belonging to blocked reader threads and send interrupt() to those that appear to have lost connection to their respective clients? Are there any major flaws in the architecture described above? Thank you.
Sounds to me that the vulnerability lies in the fact that your readers wait forever, regardless of the state of the incoming connection (which, of course, you can’t know about).
Thus a straightforward way to address this, if appropriate, would be to use the poll method on
BlockingQueue, rather than take.Callingpollallows you to specify a timeout, after which the reader will returnnullif no data has been added to the queue.In this way the readers won’t stay blocked forever, and should relatively quickly fall back into the normal processing loop, allowing their resources to be freed as appropriate.
(This isn’t a panacea of course; while the timeout is still running, the readers will consume resources. But ultimately a server with finite resources will have some vulnerability to a DDOS attack – and this reduces its impact to a customisably small window, instead of leaving your server permanently crippled, at least.)