少し蒸留すると、次のように見えるperlスクリプトがあります。
my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time
my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &"); # create the tunnel in the background
sleep 10; # Give the tunnel some time to come up
# Create the telnet object
my $telnet = new Net::Telnet(
Timeout => 10,
Host => 'localhost',
Port => $randport,
Telnetmode => 0,
Errmode => \&fail,
);
# SNIPPED... a bunch of parsing data from $telnet
問題は、ターゲット $ip が非常に予測不可能な帯域幅を持つリンク上にあるため、トンネルがすぐにアップする可能性があることです。しばらく時間がかかる可能性があり、まったくアップしない可能性があります。そのため、トンネルを起動して実行するための時間を確保するために、スリープが必要です。
問題は、トンネルが稼働しているかどうかをテストするにはどうすればよいかということです。トンネルがすぐにアップする場合、10 秒は本当に望ましくない遅延です。理想的には、それが稼働しているかどうかを確認し、telnet オブジェクトの作成を最大 30 秒まで続けたいと考えています。
編集:トンネルのリモートエンドは一般的にアップしていますが、パケットロスが非常に多いため、Pingは私が口を開くのに役立ちません
解決済み: mikebabcock によって提案されたヒントからの外挿はsleep 10
、魅力のように機能する次のブロックに置き換えられました。
my $starttime = time();
while (1)
{
# Check for success
if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last }
# Check for timeout
if (time() > $starttime + 30) { &fail() }
# 250ms delay before recheck
select (undef, undef, undef, 0.25);
}