Issue Details (XML | Word | Printable)

Key: NET-73
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Rob Hasselbaum
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Commons Net

[net][PATCH] TelnetInputStream.read hangs when socket data ends in a command sequence

Created: 21/Apr/06 09:15 PM   Updated: 05/Mar/08 01:20 AM
Return to search
Component/s: None
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments:
  Size
Text File cmd-seq-hang.patch 2006-04-25 02:41 AM Rob Hasselbaum 3 kB
Environment:
Operating System: other
Platform: All

Bugzilla Id: 39377
Resolution Date: 26/Aug/06 04:38 PM


 Description  « Hide
Background: If one calls TelnetInputStream.read() in single-threaded mode (no
reader thread) and there is no data immediately available, the call blocks on
a socket read. When data starts to arrive, the stream adds all the available
bytes to its internal queue before returning the first one to the caller. To
do this, it calls __read() in a loop for as long as there are bytes available.
The __read() method returns the first byte of "user data" from the socket. If
__read() encounters a Telnet command sequence (IAC, WILL, WONT, DO, DONT,
etc.), it handles the negotiation transparently and then returns the first
byte of user data.

In most cases, this works fine, but a problem arises if a chunk of data from
the remote host ends in a Telnet command sequence. When that happens, the
TelnetInputStream.read() method hangs, even though it may have already
acquired some user data. This is because it calls __read() in a loop as long
as super.available() returns true. But if the remaining data from the socket
consists entirely of Telnet commands, __read() will process those AND THEN
BLOCK waiting for user data.

Just checking super.available() is not sufficient. We should continue the loop
only if there are bytes of USER DATA still available from the socket. Not
doing this can cause the client to wait indefinitely.



 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Daniel Savarese added a comment - 22/Apr/06 12:37 AM
Can you submit a patch that corrects the error? All I can offer you in return
is our thanks and the addition of your name to the list of contributors.

Rob Hasselbaum added a comment - 22/Apr/06 12:40 AM
I am working on a patch now. If someone can commit my earlier patch for bug
38688, we can avoid a messy merge later, as this impacts some of the same code.

Daniel Savarese added a comment - 24/Apr/06 12:02 AM
Patch for COM-2776 applied. Thanks!

Rob Hasselbaum added a comment - 25/Apr/06 02:41 AM
Created an attachment (id=18174)
Fix read hang after command sequence

This patch prevents the read hang that occurs in single-threaded mode when a
remote host response ends in a Telnet command sequence.

I have added a boolean flag to TelnetInputStream.__read that tells it whether
or not to block on a socket read if there is no user data available in the
superclass buffer. It is set to true for the first iteration through the loop
in read(), which is the only time we need to wait. Subsequent iterations only
serve to eagerly fill the queue, so we don't need to wait, and the argument is
set to false.

If the argument is false and there is no data available, __read() returns a
value of -2 that prevents the caller from using the data. I didn't use an
exception because of overhead concern. (We could hit this condition often.)

If the reader thread is enabled, run() calls __read() with the argument set to
true, which is equivalent to the old behavior.


Rory Winston added a comment - 26/Aug/06 04:38 PM
This has been fixed.

Sebb added a comment - 05/Mar/08 01:15 AM
The fix has been applied to trunk - surely it should also be applied to the NET_2_0 branch before closing this bug?

Martin Oberhuber added a comment - 05/Mar/08 01:20 AM
Darn, it seems to be missing on the NET_2_0 branch indeed... and this has been detected before, see NET-179 : https://issues.apache.org/jira/browse/NET-179 Looks like that one needs to get re-opened?