Skip to content

The write stucks at the transport layer. #1672

@cyberslav-games

Description

@cyberslav-games

I'm using channel, created with libssh2_channel_direct_tcpip2(). Sometimes when the program writes a lot of data, writing process stops and all calls of libssh2_channel_write() returns LIBSSH2_ERROR_EAGAIN.

After some debug I found the reason and fix the problem:
There is key exchange procedure, that starts by _libssh2_transport_send().
Also the _libssh2_transport_send tryes to continue sending existing packet if any by calling send_existing().
send_existing() checks that we are trying to send the same packet that allready exists (if any). If packets are not the same, send_existing() exits with LIBSSH2_ERROR_EAGAIN.
But what happens if we need key exchange and send existing at the same time?

  1. _libssh2_transport_send() calls _libssh2_kex_exchange()
  2. _libssh2_kex_exchange() makes it's own packet and tryies to send it with _libssh2_transport_send()
  3. _libssh2_transport_send() calls send_existing()
  4. send_existing() compares new packet address and existing packet address. Test fails and we get LIBSSH2_ERROR_EAGAIN
  5. All subsequent write calls exits with LIBSSH2_ERROR_EAGAIN by this scheme

My suggestion is simply call send_existing() before _libssh2_kex_exchange() in _libssh2_transport_send(). That solves the problem.

To Reproduce
The bug is rather random. It's hard to reproduce. You need to create channel with libssh2_channel_direct_tcpip2() and write data as many as possible.

Expected behavior
Succesful write attempts sooner or latter.

Version:

  • OS: Ubuntu 22.04 jammy
  • Kernel: x86_64 Linux 6.8.0-83-generic
  • libssh2 version: 1.11.1
  • crypto backend and version: OpenSSL from repository

Additional context
Also I'm using read/write callbacks to run SSH session through custom IO layer, but it doesnt matter I gues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions