チケット #29792

DropbearでSCPが動作しない

登録: 2012-10-09 11:07 最終更新: 2012-10-15 09:18

報告者:
(del#24082)
担当者:
(del#24082)
チケットの種類:
状況:
完了
コンポーネント:
マイルストーン:
優先度:
5 - 中
重要度:
5 - 中
解決法:
なし
ファイル:
なし
投票
点数: 0
No votes
0.0% (0/0)
0.0% (0/0)

詳細

Dropbear 2012.55(SSHサーバ)に対して、32KBを超えるファイルがSCP送信できない。

チケットの履歴 (16 件中 3 件表示)

2012-10-09 11:07 更新者: (del#24082)
  • 新しいチケット "DropbearでSCPが動作しない" が作成されました
2012-10-09 11:09 更新者: (del#24082)
コメント

ssh_scp_thread スレッドで、バッファサイズ(32KB)よりリモートウィンドウサイズ(c->remote_window)が いつまでも小さいままなので、ファイル送信できていなかった。

buflen = 8192*4;       ↓ buflen = min(c->remote_window, 8192*4);

という修正でOKそう。

2012-10-09 12:05 更新者: (del#1144)
コメント

こちらでも確認しました。大丈夫そうですね。

2012-10-09 12:11 更新者: (del#1144)
コメント

送信が開始されないことはなくなったようですが、送信途中で

} while (ret > c->remote_window);

のループが終わらないことがあるようです。

2012-10-09 19:35 更新者: (del#24082)
コメント

maya への返信

送信が開始されないことはなくなったようですが、送信途中で {{{ } while (ret > c->remote_window); }}} のループが終わらないことがあるようです。

そのときの c->remote_window の値はいくつでしたでしょうか? 最初の 32KMB が大きすぎるのかもしれません。

2012-10-09 21:41 更新者: (del#1144)
コメント
c->remote_window = 24514

で始まって、止まったところでは

ret = 24514
c->remote_window = 16430
となっています。

ちなみに、6,920,986 バイトのファイルの 6,520,724 バイトで止まっています。

2012-10-10 12:49 更新者: (del#24082)
コメント
	buflen = 8192*4;
       ↓
	buflen = 8192*2;

上記のように、ssh_scp_thread()において、初期バッファサイズを半分にしたら、 9MB程度のファイル転送に成功しました。 この処置ではいかがでしょうか?

2012-10-10 14:12 更新者: (del#1144)
コメント

いまはbuflenの調整が最初の1回だけですが、c->remote_windowにあわせてbufのほうを増減するのは難しいでしょうか。

今回は16KB前後がしきい値になっているようですが、16KBより小さいところから上に回復しない場合には同様の現象が起こりそうです。また、余裕があるときにbufが増えれば転送レートが改善されるような気がするのですが、どうでしょう。

2012-10-10 19:53 更新者: (del#24082)
コメント

送信しようとしているデータが、リモートウィンドウサイズ(c->remote_window)よりはみ出している場合、 はみ出した分は遅延送信するしくみにしていることを思い出しました。 下記のdoループ自体、削除してしまってもよいような気がしますが、その結果どうなるでしょうか?

		do {
			// socket or channelがクローズされたらスレッドを終わる
			if (pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0)
				goto abort;

			if (ret > c->remote_window) {
				Sleep(100);
			}

		} while (ret > c->remote_window);

2012-10-11 21:33 更新者: (del#1144)
コメント
  • SCP のプログレスバーがすごい速さで進む
  • 100% まで行って SCP ダイアログが閉じる
  • ls してみると、ファイルサイズがどんどん増える(転送が終わってない)
  • 最後まで転送が終わらず、ファイルサイズが増えるのが止まる

という動きになりました。

2012-10-11 23:55 更新者: (del#24082)
コメント

それではダメですね。 doループは残しつつ、無限ループに陥らなければよいので、doループの中でカウンタを 設け、上限を超えたらループを抜けるようなしくみにするのはどうでしょうか?

        count = 0;
	do {
			// socket or channelがクローズされたらスレッドを終わる
			if (pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0)
				goto abort;

			if (ret > c->remote_window) {
				Sleep(100);
			}
                        count++;
                        if (count > 100)
                            break;
		} while (ret > c->remote_window);
2012-10-12 12:33 更新者: (del#1144)
コメント

こんなふうにするのはどうでしょうか。

		// ファイルから読み込んだデータはかならずサーバへ送信する。
		readlen = max(4096, min(buflen, c->remote_window));
		ret = fread(buf, 1, readlen, c->scp.localfp);
		if (ret == 0)
			break;

		// remote_window が回復するまで待つ
		do {
			// socket or channelがクローズされたらスレッドを終わる
			if (pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0)
				goto abort;

			if (ret > c->remote_window) {
				Sleep(100);
			}

			// 10秒抜けられなかったら抜けてしまう
			count++;
			if (count > 100) {
				break;
			}

		} while (ret > c->remote_window);

2012-10-13 00:11 更新者: (del#24082)
コメント

なるほど、それはよさそうですね。 SCPのスループットは下がってないでしょうか?

2012-10-13 22:35 更新者: (del#1144)
コメント

手元での計測では、openssh では 10% くらい、dropdear では 100% くらいスループットが上がりました。

2012-10-13 22:48 更新者: (del#24082)
コメント

maya への返信

手元での計測では、openssh では 10% くらい、dropdear では 100% くらいスループットが上がりました。

了解しました。 お手数ですが、修正のコミットをお願いできますでしょうか?

2012-10-15 09:18 更新者: (del#24082)
  • 状況オープン から 完了 に更新されました
  • チケット完了時刻2012-10-15 09:18 に更新されました
コメント

最先端で修正確認が取れましたので、本件はクローズとします。 ご協力どうもありがとうございました。>mayaさん

添付ファイルリスト

添付ファイルはありません

編集

ログインしていません。ログインしていない状態では、コメントに記載者の記録が残りません。 » ログインする