web-dev-qa-db-ja.com

永続的な設定方法TCPジェンダーチェンジャープロキシ?

着信TCP接続を介してデータを送信したいプロバイダー(A)がいます。残念ながら、消費サービス(B)は受信TCP接続を受信できません。また、別の要件である静的IPもありません。

これを解決する1つの方法は、着信TCP Aポートを別のTCPポートBに接続し、コンシューマがB..

これは固有の問題ではありません [1][2] 、そしてsocatを使用して私が望むものに非常に近いものを作ることができます:

socat -d -d -d -u TCP4-LISTEN:PORT-A,reuseaddr TCP4-LISTEN:PORT-B,reuseaddr

ただし、これには次の問題があります。

  • Bが切断すると、再接続できません。 TCP4-LISTEN:PORT-B,reuseaddr,forkを使用すると、接続できますが、データを受信しません。
  • Aが接続を確立する前にBが接続できない(乗り越え可能)
  • PORT-Bへの接続は1つしか確立できません(乗り越え可能)

コマンドが「永続的」になり、障害に耐性を持つようにコマンドを調整する方法はありますか?

10
dtech

重要な質問は、Aが接続の喪失または接続の拒否にどのように反応するかです。単一のTCP接続が永遠に続くことを前提とするものはすべて、脆弱になるでしょう;それはインターネットの性質です。

socat[x]inetdサービスとして設定してみませんか?

PORT-Bでリッスンするようにxinetdを設定し、Bサイドが接続するとすぐにsocat -u TCP4-LISTEN:PORT-A,reuseaddr STDIOを開始します。

xinetdは、着信トラフィックをBサイドからsocatの標準入力に渡し、socatの標準出力をキャッチしてBサイドに渡します。

Bが切断した場合、socatプロセスを終了することができます。 xinetdは、Bが再び接続するとすぐに新しいものを開始します。 Bが切断されている間、Aは「接続拒否」エラーを受け取ります。

私はかつて、古いHP-UXシステムでまったく同じようなことをしなければなりませんでした。

10
telcoM

実世界は乱雑です。

現実の世界では、TCP接続が停止することがあります。これは、たとえば、ステートフルファイアウォールまたはNATが再起動され、接続がトラフィックなしで長すぎる場合に発生します。基礎となる接続が長時間ダウンしている場合。

さらに、接続が停止したときに、対称的に停止しない場合があります。大量のデータを伝送する接続が停止した場合、受信者が停止するずっと前に、送信者が接続が停止していることに気付く可能性があります。これにはいくつかの副作用があります。

  • 送信者から受信者への接続が開始された場合、古い接続がまだ存続している間に新しい接続が着信する可能性があります。
  • 受信者から送信者への接続が開始された場合、送信者が接続の切断を検出してから受信者がその事実を検出して再接続をトリガーするまでにかなりの遅延が生じる可能性があります。

さらにTCP接続はバイトのストリームであり、メッセージのストリームではないため、接続が失敗すると、部分的なメッセージを受信する可能性があります。

この最終的な結果から、ソリューションを理解できるようにするには、堅牢なソリューションにはアプリケーションプロトコルを理解する必要があると結論づけられます。

  1. 新しい接続が入ったときにストリームをスプライスする方法。
  2. データソースがデータ受信者によって接続されているときにメッセージを保存する必要があるかどうか。
  3. エンドツーエンドの確認応答メカニズムがメッセージの損失を防ぐのに適切かどうか。
  4. デッド接続の検出を高速化するために、ある種のアプリケーションレベルの「ping」メカニズムが必要かどうか。
3
Peter Green