2011-12-20 5 views
4

PortFusionと呼ばれる分散リバースプロキシを開発しました。その最初の目標は、特にRDPのためのファイアウォールを介して、長期間、最小オーバーヘッド、高スループットのTCPトンネルを確立することでした。2xリバースプロキシネットワークでクローズしていないソケットによるポートの枯渇を回避するにはどうすればよいですか?

しかし、セキュリティに対するユーザーの要求に応え、活動家を助けるために、私は暗号化をサポートし、短命の接続をたくさんサポートするように拡張しています。

ネットワーク:

  Hu 1000 <============ Cx 1000 Au 
      [ 1001     1001=Ax:1000 
      ^       | 
       |        | 
       |        | 
       |        v 
      Cu 1001 Au     Hx 1000 
Squid <----- 1001=Au:3128    [ 1001 <----- Firefox 

Legend: 

    u you 
    x person x 

    A address 
    H PortFusionHost 
    [ hosted service 
    C PortFusionClient 

    < establish    bidirectional link 
    = encrypted, secure,  bidirectional link 
    - localhost-only, normal, bidirectional link 

Notes: 

    - Squid as a forward HTTP proxy 
    - Connection between two parties (===) are secure and encrypted 
    - Cu is in complete control of what services are shared with Hx 
    - A single Hu and a single Cu can handle multiple persons x y z 

質問:セットアップ上記のネットワークで

、私はソケットのConnectedプロパティをチェックし、例えば1 Hxは、Ax:1001 @ Firefoxのから受け付けSquidと通信するために、Cuによって使用される対応するミラーリングソケットにクロージャを伝播させる。

しかし、は常に接続されたままです!

  • Firefoxのソケットは常に接続されたままですか?
  • レスポンスを受け取ったHTTPリクエストに対して開くソケットをFirefoxが閉じるのは責任を負いませんか?
  • 他の外部トリガーがありますが、私は閉鎖ソケットに感知して使用することができませんか?

ソケットのConnectedプロパティを使用して受け入れ答え

に関する情報が間違っていました。受け入れられた答えの先端に続いて、私はthis postとこれをMSDN articleと読みます。

以下に変更を加えたら、要求が完全に応答され、クロージャ伝播が期待どおりに機能するとすぐに両端がとなります。が通知されます。 (過去に存在し、最終的に非アクティブなソケットをクリアするに蹴る異なるメカニズムがいたが、それは十分に速くはなかった。)

コード(F#)と前:

  try 
       request serverPort cl [||] 
       while transmitting && socket.Connected do 
        if socket.Available = 0 
        then Thread.Sleep Wait 
        else let length = read() 
         LogFlow "<:>" "Read" serverPort "<-" client length 
         request serverPort cl <| Array.sub buffer 0 length 
      with 

コードの後:

  try 
       request serverPort cl [||] 
       while transmitting && read() > 0 do 
        let length = !lengthR 
        LogFlow "<:>" "Read" serverPort "<-" client length 
        request serverPort cl <| Array.sub buffer 0 length 
      with 

readにはSocket.Receiveを呼び出し、lengthRを呼び出します。

答えて

1

'connected'プロパティは接続ではなくソケットを参照します。接続の接続状態はありません。彼らは読書のときにEOSを得るまで、または読書や書くときにエラーが出るまで接続されます。伝播すべきものは、EOS条件です。プロキシでは、ダウンストリームソケットの出力をシャットダウンします。あなたが使用しているプロキシベース製品は、すでにそれをすべて実行しているはずです。

+0

「Connected」の性質に関するあなたのヒントは、私が問題を解決するのを助けました!!私は関連する記事へのリンクと私が間違っていたことを質問で更新しています。 –

1

多くのHTTP要求は、Keep-Aliveをオンにして実行されます。これは、TCP接続を確立するのにかなりの時間がかかります。 Firefoxだけでなく、どんなブラウザでもこれを行うことができます。

私は、ソケットが長い間開かれているのを見ても驚かないでしょう。なぜなら、Firefoxが閉じている限り、彼らはそうしていますね。

+0

ですか?うーん、私にチェックさせてください。 Btw、Keep-Aliveに直面してポート疲労にどう対処することができますか? –

+0

1台のPC /マシンの場合、各サーバー/サイトに接続されている接続数は2または3(デフォルト)です。そのような限界に近づくのは非常に難しいですが、100人のユーザーがいる場合は明らかにずっと簡単です。 HTTPプロキシはそれを制御する方法の1つです。応答が送信された後、単に接続を終了することができます。 Keep-Aliveをサポートしていない場合もあります。それはブラウザの手を強制するでしょう。 –

+0

PortFusionはまた、巧妙にプロトコルを認識しないように設計されています。私は、異なるコードがあらゆる種類のプロトコルの異なる振る舞いを扱うことによってそれが汚れることを望んでいませんでした。興味深いプラグイン開発者にとって、最悪の場合でもフックを利用できるようにすることができます。しかし、その前に、私は最初に、単一のプロトコルに特有ではないソリューションを学び、見つけて、試してみたいと思います。 –

関連する問題