Help with openssh: ssh application writing data > 131071 to socket causing message too long error

Reji Thomas rejithomas.d at gmail.com
Tue Nov 13 17:20:39 EST 2007


Hi,

I am facing an issue with openssh-4.5p1. I am not sure whether its an
openssh issue or a tcp stack issue since I am using a simulated tcp/ip
stack.
While copying a file  of around 1GB using sftp/scp I am getting a
send:Message too long error.

I did a bit of debugging and found that ssh code was sending packet of
size greater than 131072 bytes from the application level to the
socket and hence
the issue.

On going through the code

In client_loop( in clientloop.c)

 if (packet_not_very_much_data_to_write())
                                channel_output_poll();

In packet.c

packet_not_very_much_data_to_write(void)
{
        if (interactive_mode)
          {
            fprintf(stderr,"interactive mode buffer len %d\n",
buffer_len(&output));
                return buffer_len(&output) < 16384;
          }
        else
          {
            fprintf(stderr,"non interactive mode buffer len %d\n",
buffer_len(&output));
                return buffer_len(&output) < 128 * 1024;
          }

}

which allows more data to be buffered if buffersize is less than
128*1024 ie 131072 bytes. ie data size can be greater (excluding
headers, mac,padding fields etc) than 131072 bytes. Now my issue is
my socket library will reject anything greater than 131071 bytes.
As to my understanding this is true with a linux networking stack also
(on my system the max system  value allowed is 131071).Please correct
me if I am wrong.

In channel_output_poll(void) in channels.c

 if (compat20) {
                                if (len > c->remote_window)
                                        len = c->remote_window;
                                if (len > c->remote_maxpacket)
                                        len = c->remote_maxpacket;
                        fprintf(stderr,"Remote window size %d Remote
max packet %d\n",c->remote_window,c->remote_maxpacket);
                        } else {
                                if (packet_is_interactive()) {
                                        if (len > 1024)
                                                len = 512;
                                } else {
                                        /* Keep the packets at
reasonable size. */
                                        if (len > packet_get_maxsize()/
2)
                                                len =
packet_get_maxsize()/2;
                                }
                        }

 if (len > 0) {
                                packet_start(compat20 ?
                                    SSH2_MSG_CHANNEL_DATA :
SSH_MSG_CHANNEL_DATA);
                                packet_put_int(c->remote_id);
                                packet_put_string(buffer_ptr(&c-
>input), len);

                                packet_send();
                                buffer_consume(&c->input, len);
                                c->remote_window -= len;

The issue starts happening when the server side sends a window size of
131072. As seen from the above code ,the length of data only (and
excludes padding,mac,headers etc)is reduced from the remote window and
hence the window size is effectively the data size and doesnt include
headers etc.

In packet_send() in packet.c

we add padding ,mac and other headers which increase the packet size
(another 48 bytes as I see )   and hence the buffer_len(&output)
increases by datalength+48.
and hence I feel the total packet size written to socket buffer can go
more than 131071

Please correct me if I am wrong.Also where my understanding is
wrong.Wheres the issue . Is it with the networking stack ??.




Debug data (I have inserted)

Remote window size 131072 Remote max packet 32768
send: len 16416 ( padding length 18)
non interactive mode buffer len 16432

Remote window size 114688 Remote max packet 32768
send: len 16416 (includes payload, padding and padding length 18)
non interactive mode buffer len 32864

Remote window size 98304 Remote max packet 32768
send: len 16416 (includes payload, padding and padding length 18)
non interactive mode buffer len 49296

Remote window size 81920 Remote max packet 32768
send: len 16416 (includes payload, padding and padding length 18)
non interactive mode buffer len 65728

Remote window size 65536 Remote max packet 32768
send: len 16416 (includes payload, padding and padding length 18)
non interactive mode buffer len 82160

Remote window size 49152 Remote max packet 32768
send: len 16416 (includes payload, padding and padding length 18)
non interactive mode buffer len 98592

Remote window size 32768 Remote max packet 32768
send: len 16304 (includes payload, padding and padding length 11)
non interactive mode buffer len 114912

Remote window size 16489 Remote max packet 32768
send: len 16416 (includes payload, padding and padding length 18)
non interactive mode buffer len 131344
Before packet_write_poll
length before calling systemcall write 131344
Write failed: Message too long
Couldn't send packet: Broken pipe

Thanks
Reji Thomas


More information about the openssh-unix-dev mailing list