Subject: Re: [PATCH] Send internal packet priority

Re: [PATCH] Send internal packet priority

From: liuzl <>
Date: Fri, 9 Sep 2011 16:26:44 +0800

The next step is then to figure out why the receive window function fails in
> your tests - I keep trying but I can't repeat these problems which makes
> things a little difficult for me.

I think the initial receive-window-size is smaller, it will occur easily.

 Like this: download a file in non-block mode, offered a receive buffer 1MB.
 1), call libssh2_sftp_read()
      a), sftp_read() will package many READ packets.
      b), sftp_read() send READ packets until block.
      c), sftp_read() ask for ACK
 2), in _libssh2_channel_read():
      a), check read_state(receive-window-size), no need to expand in the
first time, skip.
      b), call _libssh2_transport_read() to process incoming packets.then
remote window will shrink in _libssh2_packet_add().
      c), fecth some data into the incoming
parameter buf: memcpy(&buf[bytes_read], &readpkt->data[readpkt->data_head],
      d), if (!bytes_read) {return *;} if there is no data for offerring,
will return anyhow.
      e), if receive-window is too narrow,
call _libssh2_channel_receive_window_adjust() to expand.since we have read
many data, we have
           to expand the receive
window. _libssh2_channel_receive_window_adjust()->_libssh2_transport_send()->send_existing()
           send_existing() will return LIBSSH2_ERROR_BAD_USE because we are
blocking and data != p->odata.
           _libssh2_channel_receive_window_adjust() will
return LIBSSH2_ERROR_SOCKET_SEND to _libssh2_channel_read(),
           _libssh2_channel_read() will ignore the error code and
set channel->read_state = libssh2_NB_state_created; then return bytes_read;
      then sftp_read() will ask for ACK for READ packets until no data
available. it will produce many LIBSSH2_ERROR_SOCKET_SEND errors.
     in the end will return EAGAIN since we are non-block.
 3), we call libssh2_sftp_read() again, because our receive buffer 1MB is
big, sftp_read() sending READ packet will result in blocking again.
      the receive window adjust packet can't be sent. and the receive window
will shrink again.
      if this recur several times, the receive window will reduce to zero.
and no data will arrive from server.
      then in the step [2,d]:if (!bytes_read) {return *;} if there is no
data for offerring, will return anyhow.
      then we have no chance to send window adjust packet in the step[2,e]
and no data will arrive forever.

> Second, if _libssh2_channel_receive_**window_adjust() return EAGAIN,
>> caller will get a big problem.
> When and how?

 if we return EAGAIN or other error code there in the step[2,e], we will
lose data we read in step[2, c].usually it's a 4 bytes packet head.
 then we will get a un-normal packet head in the next time, result

Received on 2011-09-09