Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Net::SSH::Perl ConnectTimeout (ssh -o option)

by codejerk (Initiate)
on Aug 09, 2006 at 18:25 UTC ( #566455=perlquestion: print w/replies, xml ) Need Help??
codejerk has asked for the wisdom of the Perl Monks concerning the following question:


I noticed today that my script using Net::SSH::Perl was seemingly ignoring the ConnectTimeout option I specified. I tried defining it in ~/.ssh/config as well as within the script. After a few minutes of digging, it appears that Net::SSH::Perl simply does not implement this option. Can anyone verify this? If it is true, has anyone come up with a workaround? I was considering modifying a few pieces of btrott's code to use IO::Socket::INET's socket creation mechanism instead of just Socket... but I didn't want to undertake some unnecessary heavy lifting if it has already been done.

Any input here would be great. btrott, if you read this... you da man. I love the module, I just want to patch up this little "feature hole" :). I did notice that btrott hasn't logged in for 10 weeks, so my hopes of an author response are all but faded. If not from the horse's mouth... is there an answer to be had somewhere? Does anyone know how to get Net::SSH::Perl to properly timeout a connection?


  • Comment on Net::SSH::Perl ConnectTimeout (ssh -o option)

Replies are listed 'Best First'.
Re: Net::SSH::Perl ConnectTimeout (ssh -o option)
by neilwatson (Priest) on Aug 10, 2006 at 13:49 UTC
    Looking at the source code, the ToDo file, reveals that this is not yet finished:
    $Id: ToDo,v 1.22 2003/12/03 15:35:21 autarch Exp $ Add more tests to the test suite; add SSH2 tests. Fixes to SSH2 implementation: * get rid of dummy shell channel (if possible) * more documentation * anything currently marked XXX in the code Compatibility with NetScreen? Switch over to using Crypt::RSA for SSH1 RSA implementation? SSH2 RSA keys now use Crypt::RSA; at this point it might just be too much extra baggage to try to force people to use Crypt::RSA, because it has so many prereqs. Switch completely to Math::Pari? Worthwhile? Again, don't want existing SSH1 users to have to switch. Use non-blocking connect, like IO::Socket, to implement a connect Timeout. A proper scp client. Port forwarding.

    Neil Watson

      very true. Because this module is unfinished, has anyone managed to use a workaround or modification to (at least temporarily... I'm sure btrott will get back to this module soon) implement a connect timeout?
      to summarize:
      • Net::SSH::Perl is unfinished.
      • Net::SSH::Perl does not yet have an implementation of the SSH ConnectTimeout option.
      • I am searching for a quick, temporary solution to this "feature hole"

      If anyone can assist, I will greatly appreciate the input :)
        This is a very late reply, but this has still not been implemented. I added the following to, right after the socket creation to give me a send/receive timeout of 10 seconds:

        setsockopt($sock, SOL_SOCKET, SO_SNDTIMEO, pack('LL', 10, 0) ) or die $!;
        setsockopt($sock, SOL_SOCKET, SO_RCVTIMEO, pack('LL', 10, 0) ) or die $!;

        Hope that helps.
        Hi folks, I would like to know if there is a way to get time taken for each step in debug mode to be displayed to find out which step is taking the longer time. Net::SSH::Perl Version 1.35, protocol version 2.0, running in debug mode I have the following timeout issue at times and would like to get UNIX time displayed besides the sourceserver like following for each debug line. Thanks.
        sourceserver unixtime: Reading configuration data /usr/local/apps/.ssh +/config sourceserver unixtime: Reading configuration data /etc/ssh_config sourceserver unixtime: Connecting to targetserver, port 22. sourceserver etc: Remote protocol version 2.0, remote software version + OpenSSH_4.3 sourceserver: Net::SSH::Perl Version 1.35, protocol version 2.0. sourceserver: No compat match: OpenSSH_4.3. sourceserver: Connection established. sourceserver: Sent key-exchange init (KEXINIT), wait response. sourceserver: Algorithms, c->s: 3des-cbc hmac-sha1 none sourceserver: Algorithms, s->c: 3des-cbc hmac-sha1 none sourceserver: Entering Diffie-Hellman Group 1 key exchange. sourceserver: Sent DH public key, waiting for reply. sourceserver: Received host key, type 'ssh-dss'. sourceserver: Host 'targetserver' is known and matches the host key. sourceserver: Computing shared secret key. sourceserver: Verifying server signature. sourceserver: Waiting for NEWKEYS message. sourceserver: Send NEWKEYS. sourceserver: Enabling encryption/MAC/compression. sourceserver: Sending request for user-authentication service. sourceserver: Service accepted: ssh-userauth. sourceserver: Trying empty user-authentication request. sourceserver: Authentication methods that can continue: publickey,gssa +pi-w ith-mic,password,keyboard-interactive. sourceserver: Next method to try is publickey. sourceserver: Next method to try is password. sourceserver: Trying password authentication. Taking too long to complete. Timed out after 60 seconds.
Re: Net::SSH::Perl ConnectTimeout (ssh -o option)
by neilwatson (Priest) on Aug 09, 2006 at 19:49 UTC
    Perhaps you could show us your code. The fault may lie there and not in the module.

    Neil Watson

      To the best of my knowledge, the fault is not in my code. If you dig into Net::SSH::Perl's, you can easily find the routine for parsing the -o style options. ConnectTimeout is not parsed at all, and if you dig a bit more, you'll see that the socket is not created with any sort of timeout other than the default.

      My question is less about how to make Net::SSH::Perl work for me, and more about how to implement a socket timeout given the current form of Net::SSH::Perl's socket implementation. I'm curious if anyone else has ever had a need for it and attempted a modification or workaround to incorporate a timeout.

      All of that said... if a code snippet is what you want, here ya go :) :

      from Net::SSH::Perl::Config -

      %DIRECTIVES = ( BindAddress => [ \&_set_str, 'bind_address' ], Host => [ \&_host ], BatchMode => [ \&_batch_mode ], ChallengeResponseAuthentication => [ \&_set_yesno, 'auth_ch_res' ] +, Cipher => [ \&_cipher ], Ciphers => [ \&_set_str, 'ciphers' ], Compression => [ \&_set_yesno, 'compression' ], CompressionLevel => [ \&_set_str, 'compression_level' ], DSAAuthentication => [ \&_set_yesno, 'auth_dsa' ], GlobalKnownHostsFile => [ \&_set_str, 'global_known_hosts' ], HostKeyAlgorithms => [ \&_set_str, 'host_key_algorithms' ], HostName => [ \&_set_str, 'hostname' ], IdentityFile => [ \&_identity_file ], NumberOfPasswordPrompts => [ \&_set_str, 'number_of_password_promp +ts' ], PasswordAuthentication => [ \&_set_yesno, 'auth_password' ], PasswordPromptHost => [ \&_set_yesno, 'password_prompt_host' +], PasswordPromptLogin => [ \&_set_yesno, 'password_prompt_login' + ], Port => [ \&_set_str, 'port' ], Protocol => [ \&_protocol ], RhostsAuthentication => [ \&_set_yesno, 'auth_rhosts' ], RhostsRSAAuthentication => [ \&_set_yesno, 'auth_rhosts_rsa' ], RSAAuthentication => [ \&_set_yesno, 'auth_rsa' ], UsePrivilegedPort => [ \&_set_yesno, 'privileged' ], User => [ \&_set_str, 'user' ], UserKnownHostsFile => [ \&_set_str, 'user_known_hosts' ], );
      as you can see, the option "ConnectTimeout" is not provided for.
      sub _create_socket { my $ssh = shift; my $sock = gensym; my ($p,$end,$delta) = (0,1,1); # normally we use whatever por +t we can get ($p,$end,$delta) = (1023,512,-1) if $ssh->{config}->get('pr +ivileged'); # allow an explicit bind address my $addr = $ssh->{config}->get('bind_address'); $addr = inet_aton($addr) if $addr; ($p,$end,$delta) = (10000,65535,1) if $addr and not $p; $addr ||= INADDR_ANY; for(; $p != $end; $p += $delta) { socket($sock, AF_INET, SOCK_STREAM, getprotobyname('tcp') || 0 +) || croak "Net::SSH: Can't create socket: $!"; last if not $p or bind($sock, sockaddr_in($p,$addr)); if ($! =~ /(Address|The socket name is) already in use/i) { close($sock); next; } croak "Net::SSH: Can't bind socket to port $p: $!"; } if($p) { $ssh->debug("Allocated local port $p."); $ssh->{config}->set('localport', $p); } $sock; }
      here we see that the socket is created with the Simple method, with no configurable timeout.

      and for fun, my usage:

      use Net::SSH::Perl; my %ssh_params = ( protocol => "2,1", identity_files => ["/home/codejerk/.ssh/test_id_dsa"], options => [ "BatchMode yes", "ConnectTimeout 3", "StrictHostKeyChecking no"], debug => 'true' );
        Thanks for pointing this out. My script has the need to use the ControlMaster=auto option, but can't because it's not supported by the module. Say, any ideas when the next release is coming? And if it'll have expanded support for options? :) -dox

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://566455]
Approved by friedo
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2018-11-17 13:56 GMT
Find Nodes?
    Voting Booth?
    My code is most likely broken because:

    Results (203 votes). Check out past polls.