Subject: Packet drop on full socket problem

Packet drop on full socket problem

From: Thomas Rauscher <>
Date: Fri, 17 Sep 2010 16:09:23 +0200

I think I've found a problem that occurs when writing to the send socket returns -1 (EGAIN).
Additional preconditions to trigger the problem are writing in larger chunks than the
advertized window size, e.g. 128k writes vs. 12k window size.

The remote side is a dropbear SSH server which seems use 12k window size increments.
This means that packets need to be split very often. If additionally the socket buffer
gets full, the saved packet is never sent.

A workaround is to use smaller writes (1k), but this only hides the problem.

1) The application calls _libssh2_channel_write(..., 128*1024);

  * In _libssh2_transport_write()

    _libssh2_send returns -1 (EAGAIN) and the current packet is saved to p->odata, p->olen ...

  * _libssh2_transport_write() returns LIBSSH2_ERROR_EAGAIN to _libssh2_channel_write() which executes
    if(wrote) {
      goto _channel_write_done;
    _libssh2_transport_drain() frees p->outbuf and sets it to NULL.
  * _libssh2_transport_write then returns "wrote" (12k) to the application.
2) Application calls _libssh2_channel_write(..., 128*1024) again.
  _libssh2_transport_write() now calls send_existing() first which immediately returns because p->outbuf is NULL.

  if (!p->outbuf) {
    *ret = 0;
    return LIBSSH2_ERROR_NONE;

  * This results in not sending the saved packet, but sending the next packet. The SSH server then
    bails out and terminates the connection (saying "bad packet size").

Many thanks for any ideas.
Thomas Rauscher
Received on 2010-09-17