Re: Still confused about window adjust :-(

On Fri, 13 Jul 2007 09:08:10 +0100, Simon Tatham wrote:

H.K. Kingston-Smith <HKK-S@xxxxxxxxx> wrote:
If I read the standard correctly (RFC 4254, section 5.2) the only data
that counts for windowing purposes is the data string in


So imagine that we have an SSH_MSG_CHANNEL_DATA packet whose total
length is L, whereas the length of the data string that it carries is
D, with D < L. Let's assume that the current window size is W, with W <

If W < D, you should never have constructed a data packet in the first
place which contained more than W bytes of data.

What portion of this packet can be sent?

You can't send partial packets in an SSH data stream; how would the
other end work out where a partial packet stopped and some other packet
started? You must send either a whole packet or no packet at all.

Thanks for your answers, which are most informative. However, I
believe that you are not addressing my two core issues here. Forget about
partial packets for a moment. Assuming that we have just sent a complete
SSH_MSG_CHANNEL_DATA packet of total length L, containing a data string
of length S, S < L, how does the window size change after this? Does it
decrease by S bytes? By L bytes? Something else?

About partial packets now. How can the SSH layer be sure that it
will get at least one complete SSH packet when reading data from the
network? I still think it can't. First, the network layer might not be
able to deliver a whole SSH packet if, for instance, this is a very large
one; several consecutive reads might be necessary. Second, the network
layer does not know anything about the SSH protocol, and therefore cannot
accumulate incoming data on that basis. Actually, once the data stream is
encrypted, the networking layer can't tell what the heck the data

On the other hand, it is easy for the SSH layer to determine
whether or not data it has received contains a complete SSH packet,
taking into account the structure of an SSH-2 packet. According to the
standard (RFC 4253, section 6) SSH-2 packets are structured as follows:

uint32 packet_length
byte padding_length
byte[n1] payload; n1 = packet_length - padding_length - 1
byte[n2] random padding; n2 = padding_length
byte[m] mac (Message Authentication Code - MAC); m = mac_length

Thus, when receiving data the information contained in packet_length and
padding_length, together with the knowledge of mac_length, and the length
of the data received, are enough to find out whether or not the data
received in this read operation constitutes a complete SSH-2 packet.

Or is there anything wrong with this analysis?

Or do we have to wait until the other party adjusts the window so we
can send the whole packet?

If you're absolutely determined to send a single packet containing D
bytes of actual channel data, then you will indeed have to wait until
the window size has grown to at least D before sending it.

However, you shouldn't have such a packet in your possession at all. The
part of your code which takes a stream of incoming data and divides it
into SSH packets should have known the current window size when it
constructed that packet, and so it should have constructed one
containing at most W bytes, which it would then have been able to send
immediately. The remaining D-W bytes would stay in its buffer,
unpacketised as yet, until the window size expanded from zero and
permitted them to be sent.

I agree that that strategy works, and it probably is the best
one. However, I believe that the one I have outlined is also legal, as
far as the SSH-2 standards are concerned.