2011-07-01 6 views
0

私はC#でサーバーを開発しています(* Asyncメソッドを使用しています)。片方がプロトコルに違反するまで(例えば、サーバーへの攻撃)、すべてうまく動作します。プロトコルエラー耐性ソケットサーバー

以下の構造のクライアントとサーバー交換メッセージ:

  1. 最初の4つのバイトは、次のNバイトはメッセージボディ
を定義
  • バイトのメッセージボディの長さ(N)を定義します

    誰かが間違った長さを送信した場合、このクライアントとサーバー間の通信はすべて予測不可能になります。

    したがって、アイデアは最も簡単な方法で自己同期プロトコルを作成することです。

    私はTCPプロトコルを使用しているので、メッセージをパケットに分割し、同じパケットを2つのメッセージで共有する必要はありません。このようにして、プロトコル違反を無視して通信を復元できます間違っている。

    私はそのためにTCPを使いたいので、パケットはTCPセグメントと同じになります。しかし、いくつかの漁獲があります

    • (MSSを定義する)MTUが異なる可能性があり、私が使用できるバッファサイズには事前に定義された値がありません(私が間違っているなら、私を修正)
    • 私は「couldn TCPセグメントを直接( "ストリーム"抽象化なしで)手動で管理する方法を見つけることができます。

    私はソケットサーバプログラミングには新しく、助けが必要です。おそらく、誰かがこの問題(耐故障性プロトコル)に対する共通の解決策を共有したり、一般的な落とし穴を記述したり、役に立つリンクを提供することができます。

    私は.NETで開発しており、避けることができればP/Invokesを使用したくありません。

  • 答えて

    2

    TCP抽象化はなし内蔵メッセージ境界で、ストリームのものである、とあなたはその抽象化に違反しようとするべきではありません。

    不正なクライアントを処理するための主な戦略は、クライアントが提供するすべての入力を厳密にチェックすることです(たとえば、プロトコルレベルのメッセージの許容サイズに上限を設定するなど)。サニティチェックでプロトコルに違反していることが示されると、誤ったメッセージの処理が停止します。エラーをログに記録したり、クライアントに報告したりすることもできます。

    プロトコルの違反が再同期できないようなものなら、クライアントを切断するしかありません。これは問題ありません。不正なクライアントは、あらゆるレベルのサービスを期待する権利がありません。

    再同期を可能にするプロトコルを設計することができます。最も簡単な例は、後続のプロトコルメッセージの境界でデリミタを使用することです(デリミタ自体はメッセージ内で発生することはできません)。 FTP、SMTP、IRCなどの古い "行ベースの"インターネットプロトコルの多くは、このように動作します(この場合の区切り文字は改行文字です)。

    0

    あなたが読みたいと思うかもしれませんについてthe protobuf-c RPC implementation

    • 方法インデックス(4バイトのリトルとしてエンコード:

      クライアントがいるProtobufエンコードされたメッセージのペイロードに続く12バイトのヘッダーを発行-endian number)

    • メッセージ長:protobufでエンコードされたペイロードの長さ(エンコードされた4バイトリトルエンディアン)
    • 要求ID:クライアントがそれを許可するために選択した値複数の未処理要求の場合にどのサーバ応答がどの要求に対応するかを知る)。 (4バイトリトルエンディアン番号など)

      • ステータスコード:(4バイトで符号化された)

      サーバは最終的に類似した16バイトの応答を発行します。次のいずれかの値:
      0:成功
      1:サービスは、(すなわち閉鎖へのメッセージのためにNULLに渡された)失敗した
      2:あまりにも多くの保留

    • 方法(クライアント接続は、あまりにも多くの保留中の要求を持っています)インデックス(要求と同じ)
    • メッセージ長(要求と同じ)
    • リクエストID(要求と同じ)

    tにもう一つあなたはこれをTCP/IP以外のプロトコル(すなわち、エラーのないチャネル)は、ヘッダーとペイロードにCRCチェックを追加することです。

    +0

    誰かが送信にいくつかの壊れたバイトを挿入した場合、どうすればよいでしょうか。たとえば、「メソッドインデックス」と「メッセージ長」の間にある場合 – dipyalov

    +0

    CRCチェックよりも見事なものにならない限り([エラー検出と修正のコーディング](http://en.wikipedia.org/wiki/) Error_detection_and_correction))、挿入されたバイトが意図したメッセージインデックスまたはメッセージ長ではないことをどのように検出するのか分かりません。 –

    1

    ここには2つの別の問題があります。

    1. 違反をどのように処理しますか?
    2. サーバーを保護するにはどうすればよいですか?

    プロトコルハンドラにエラー修正を組み込むことによってサーバーを保護することはできません。これを行うには、安全なコーディング方法が必要です。初心者のためのSSLを見てください - もしあなたが自分でサーバを安全にしようとするなら、それはそうではないでしょうし、そしてb)それは長い時間がかかります。

    サーバーが安全になったら、プロトコルエラーの問題を解決するのがずっと簡単になることがあります。これは、クライアント上のコーディングエラー、またはネットワークデータの整合性の問題を意味します。上記の悪意のある行為を排除することは、どちらの問題にも対処しやすくする。

    0

    切断誤動作クライアント

    +0

    問題は、正常な送信が始まる場所と不正行為を検出することです。 – dipyalov

    +0

    私はそれが-1と少し厳しいと思います。私は同じことを言うでしょう、どんなプロトコルエラーが検出されるとすぐに切断してください。試したり再同期したり、試したり修正したりしないでください。したがって、あなたが無効なデータを取得したときにそれを知ることができれば、問題のクライアントを切断するだけです。 –

    +0

    それは私ではありませんでした:)しかし、問題はまだ残っています - どのようにミスビビウオアとそれが発生する場所を検出するには?そして私はそれをまったくやりますか? – dipyalov

    関連する問題