sparvu has asked for the wisdom of the Perl Monks concerning the following question:

Hi all

I have developed a small client based on libssh2 and Net::SSH2 which connects to a backend system to run one command. The client as well uses File::Tail::select to look over a number of files for changes.

These changes, will be detected using File::Tail module and pass over a ssh2 connection to a backend system via Net::SSH2. The client, will make a single session and will try to keep this as long as the backend system is up and available. In case of a network outage, power failure on the backend system the client must reconnect automatically.

The code works ok, exception being if the backend system (the ssh2 server) will unexpected die, or sufer a power outage. In this case, the client, my code, wont notice immediately this and will wait for a certain amount of time before seeing that the backend is gone.

Example of my ssh2 client:

if (defined($s2)) { $rcode = send2report($s2, $dbid, $delta); if ($rcode == 0) { addlog("error: no ssh2 connection, trying again..."); #sleep(5); $s2 = ssh2tunnel($dest, $port, $user, $pass); next if (! defined($s2)); addlog("info: ssh2 re-established"); $rcode = send2report($s2, $dbid, $delta); } } else { addlog("info: waiting for ssh2..."); #sleep(10); $s2 = ssh2tunnel($dest, $port, $user, $pass); addlog("info: ssh2 re-established") if (defined($s2)); } sub ssh2tunnel { my ($dest, $port, $user, $pass) = @_; my $ssh2 = Net::SSH2->new(); #$ssh2->poll(1000); #$ssh2->debug(1); if( $ssh2->connect($dest, $port) ) { if ($pass eq "") { # authentication using private key my $pubkey = "$pkey" . ".pub"; eval { $ssh2->auth_publickey($user, $pubkey, $pkey); 1 } or do { warn "error: ssh2 authkey failed $@ \n", $ssh2->error; }; } else { # authentication using private key eval { $ssh2->auth(username => "$user", password => "$pass"); 1 } or do { warn "error: ssh2 auth failed $@ \n", $ssh2->error; }; } } else { addlog("error: ssh2 connect failed $@"); return; } return $ssh2; } sub send2report { my ($s, $id, $payload) = @_; my $c = $s->channel(); if($c) { $c->exec("echo $payload | /opt/sdr/report/bin/hostadm -I $id:$host +\n"); #$c->shell(); } else { return 0; } # print $c "echo $payload | /opt/sdr/report/bin/hostadm -I $id:$host\n +"; my ( $code, $error_name, $error_string ) = $s->error(); if ( $code ) { addlog("error send2report($id): code:$code:$error_name: $error_str +ing"); $c->close; return 0; } $c->close; return 1; }

Questions:

1. How can I detect in my code if the ssh2 session is not valid anymore ? I tried using $c -> blocking(0) or blocking(1). Setting the blocking to 0 will make things worse, since Im getting a new session everytime.

2. Do I need to use poll() on the channel created in order to look and timeout in case the backend is gone ?

Many thanks!

Versions used: perl 5.16.1, openssl 1.0.0j, libssh2 1.4.2, Net-SSH2 0.45.

Replies are listed 'Best First'.
Re: Net::SSH2 connection timeout
by zentara (Cardinal) on Sep 12, 2012 at 17:31 UTC
    Do I need to use poll() on the channel

    From the documentation, it looks like that is what you need to do. I would try putting the poll in a separate thread, and passing in the ssh2 filehandle's fileno.

    The docs say:

    poll ( timeout, arrayref of hashes )
    Pass in a timeout in milliseconds and an arrayref of hashes with the following keys:

    handle
    May be a Net::SSH2::Channel or Net::SSH2::Listener object, integer file descriptor, or perl file handle.

    events
    Requested events. Combination of LIBSSH2_POLLFD_* constants (with the POLL prefix stripped if present), or an arrayref of the names ('in', 'hup' etc.).

    On linux, if the 'in' event fires, and there is no data to be read, then it can be interpreted that the connection is lost. See Net::SSH2 odd polling behavior for example. Also see Net::SSH2 Interactive command example for a similar problem.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      Cant use threads since my perl is built without thread support. Interesting about 'in', 'hup' . I need to try to test this part and read further.

      I sent some feedback to the author of Net::SSH2 that we could improve a bit the documentation and have more samples. That would be sweet.

      Very much appreciated your feedback. Later if Im successful the code will be available so anyone can reuse, change or take a look.