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 | |
by sparvu (Initiate) on Sep 12, 2012 at 17:53 UTC |