jnthn / p6-ssh-libssh

Asynchronous binding for libssh; client-only and limited functionality so far.
8 stars 8 forks source link

Closing Channel causes Supply of next Channel to be immediately closed. #21

Open bbkr opened 11 hours ago

bbkr commented 11 hours ago

I'm working on bigger tool using forwarding and I have to reuse local listener to open multiple channels on single session to different remote hosts/ports.

Unfortunately after channel is closed SSH connection is left in some bogus state:

react {
        whenever IO::Socket::Async.listen('127.0.0.1', $local-port) -> $connection {
            whenever $session.forward($remote-host, $remote-port,
                                      '127.0.0.1', $local-port) -> $channel {
                whenever $connection.Supply(:bin) {
                    $channel.write($_);
                    LAST $channel.close;                        <=== 1
                }
                whenever $channel.Supply(:bin) {       <==== 2
                    $connection.write($_);
                    LAST $connection.close;
                }
            }
        }

When 1 is called on first channel opened then every new channel opened after that immediately leaves block 2. I can reproduce it using provided forward.p6 file.

First request:

$ curl -v -H "Host: www.bash.org" http://127.0.0.1:8888/
*   Trying 127.0.0.1:8888...
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> Host: www.bash.org
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 14 Oct 2024 20:28:20 GMT
< Server: Apache/2.2.15 (CentOS)
< Last-Modified: Tue, 14 Dec 2010 19:47:34 GMT
< ETag: "28148c-0-497641785a180"
< Accept-Ranges: bytes
< Content-Length: 0
< Connection: close
< Content-Type: text/html; charset=UTF-8
<
* Closing connection 0

Second request:

$ curl -v -H "Host: www.bash.org" http://127.0.0.1:8888/
*   Trying 127.0.0.1:8888...
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> Host: www.bash.org
> User-Agent: curl/7.74.0
> Accept: */*
>
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server

When not closing channel next connections work fine (of course until session limit is reached).

bbkr commented 11 hours ago

Also there is some oddity here. Commenting out LAST $connection.close causes infinite wait on $session.forward. I completly do not see the correlation, but it is 100% reproducible.

bbkr commented 11 hours ago
$ raku -v
Welcome to Rakudo™ v2024.08.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2024.08.
$ apt list --installed | grep ssh
libssh-4/oldstable,oldstable-security,now 0.9.8-0+deb11u1 arm64 [installed]
libssh2-1/oldstable,now 1.9.0-2+deb11u1 arm64 [installed,automatic]
openssh-client/oldstable,oldstable-security,now 1:8.4p1-5+deb11u3 arm64 [installed]