Knowledgebase
SSH channel not closing / SFTP connection dropped prematurely
Posted by Mohammad Jawwad on 03 November 2008 07:14 PM
When a client program connects to a SSH based server the client and server enter a negotiation phase where they both eventually 'settle' for a certain window size. This usually involves closing the existing channel and opening a new one in place of it. A typical debug log for this negotiation is shown below :

=========================================================================
INFO [SSH] message received: SSH_MSG_USERAUTH_SUCCESS
INFO [SSH] message sent: SSH_MSG_CHANNEL_OPEN, channel type: session, senderChannel channel: 0, initial window size: 32368, maximum packet size: 32368
INFO [SSH] message received: SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recipient channel: 0, sender channnel: 0, initial window size: 0, maximum packet size: 32768
INFO [SSH] message sent: SSH_MSG_CHANNEL_EOF, recipient channel: 0
INFO [SSH] message sent: SSH_MSG_CHANNEL_CLOSE, recipient channel: 0
INFO [SSH] message received: SSH_MSG_CHANNEL_CLOSE, recipient channel: 0
INFO [SSH] message sent: SSH_MSG_CHANNEL_OPEN, channel type: session, senderChannel channel: 1, initial window size: 32368, maximum packet size: 32768
INFO [SSH] message received: SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recipient channel: 1, sender channnel: 0, initial window size: 0, maximum packet size: 32768
INFO [SSH] message sent: SSH_MSG_CHANNEL_REQUEST, recipient channel: 0, request type: subsystem, want reply: false
INFO [SFTP] client started
INFO [SFTP] packet sent: SSH_FXP_INIT, version: 3
INFO [SSH] message received: SSH_MSG_CHANNEL_WINDOW_ADJUST, recipient channel: 1, bytes to add: 131072
INFO [SSH] message sent: SSH_MSG_CHANNEL_DATA, recipient channel: 0
INFO [SSH] message received: SSH_MSG_CHANNEL_DATA, recipient channel: 1
INFO [SSH] message sent: SSH_MSG_CHANNEL_WINDOW_ADJUST, recipient channel: 0, bytes to add: 97113
INFO [SFTP] packet received: SSH_FXP_VERSION, version: 3
=========================================================================

We can see here that channel 0 is open as evident by SSH_MSG_CHANNEL_OPEN_CONFIRMATION message on the 3rd line. Just before this message is received we can see that a window size of 32368 bytes is in use (line 2). This is often called the initial window size. Now if the server offers a larger window size the existing channel (channel 0) will close and a new one will be opened. We can see above that SSH_MSG_CHANNEL_CLOSE is both sent and received for
channel 0 - this means it has closed successfully.

A new channel (channel 1) is opened in place of channel 0. This will use a larger window size. The following line in the above debug output shows this actually takes place :
"message received: SSH_MSG_CHANNEL_WINDOW_ADJUST, recipient channel: 1, bytes to add: 131072"
The "bytes to add" part of the message shows that 131072 bytes were added to the window size.

Sometimes channel 0 will not close properly. The following log output shows where the channel 0 was not closed by the server during the window size negotiation phase:

==========================================================================
INFO [SSH] message sent: SSH_MSG_CHANNEL_EOF, recipient channel: 0
INFO [SSH] message sent: SSH_MSG_CHANNEL_CLOSE, recipient channel: 0
INFO [SSH] message sent: SSH_MSG_CHANNEL_OPEN, channel type: session, senderChannel channel: 1, initial window size: 32368, maximum packet size: 4096
INFO [SSH] message received: SSH_MSG_IGNORE
INFO [SSH] message received: SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recipient channel: 1, sender channnel: 1, initial window size: 65536, maximum packet size: 4096
INFO [SSH] message sent: SSH_MSG_CHANNEL_REQUEST, recipient channel: 1, request type: subsystem, want reply: false
INFO [SFTP] client started
INFO [SFTP] packet sent: SSH_FXP_INIT, version: 3
==========================================================================

We can see that SSH_MSG_CHANNEL_CLOSE, recipient channel: 0 was sent but never received. According to RFC specifications SSH_MSG_CHANNEL_CLOSE must be sent AND received to indicate the channel has closed. This channel in all probability will remain open. The server will eventually timeout and close the channel - however in the process the server will be taxed unnecessarily. It is safe to say we don't want this behavior.

Some servers do not handle the negotiation phase very well. In most cases you can't do anything about this except to wait for a newer version of the server and hope this will be fixed. However there is another way you can get around this until a newer fixed version of your server comes along. Use the following code to restrict the window size to the initial size (32K) and prevent further channels from opening/closing :

=========================================================================
import com.jscape.inet.sftp.SftpConfiguration;

SftpConfiguration config = new SftpConfiguration();
config.setUseAdaptiveConnection(false);
SshParameters params = new SshParameters(hostName, userName, password);
Sftp sftp = new Sftp(params, config);
sftp.connect();
=========================================================================

setUseAdaptiveConnection(false) prevents the negotiation to take place. During the connection a window size of 32K will be used.






(101 vote(s))
This article was helpful
This article was not helpful

Comments (0)
Post a new comment
 
 
Full Name:
Email:
Comments:
CAPTCHA Verification 
 
Please enter the text you see in the image into the textbox below. This is required to prevent automated registrations and form submissions.

Help Desk Software by Kayako fusion