2012-03-02 26 views
0

私は現在、クライアントがログインできるようにするUDPアプリケーションをプログラミングしています。その後、エンドポイントはリストに格納されます。UDPとポートのランダム化

private void socket_Callback(IAsyncResult result_) 
{ 
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0); 
    socket.EndReceiveFrom(result_, ref remote); 

    if (!listOfEndPoints.Contains(remote)) 
    { 
     // registration process 

     // add it to list 
     listOfEndPoints.Add(remote) 
    } 
    else 
    { 
     // process packet 
    } 
} 

ただし、クライアントのNATによって、すべてのパケットに異なる外部エンドポイントが割り当てられることがあります。登録パケットのソースエンドポイントが12.34.56.78:1000の場合、そのエンドポイントはリストに追加されます。しかし、同じクライアントが別のパケットを送信した場合、NATはそれを別のポートに割り当てるため、そのソースエンドポイントは12.34.56.78:1001になります。 この結果、サーバーはクライアントが登録されていないと見なし、パケットを登録サーバーとして処理しようとします。言うまでもなく、これはうまくいきません。

これを修正する方法は、IDを送信することです(ただし、超暗号でない場合は簡単に偽造することができます)。ただし、クライアントはサーバーに送信する各パケットにそれを追加する必要があります。 そのようにするのはあまり効果的ではありません。

パケットが登録パケットと同じクライアントから送信されたことを伝える他の方法はありますか。

答えて

3

間違いなくにする必要があります。 UDPパケットの送信元IPアドレスとポートを使用して、論理接続に関連付けます。各パケットに接続のIDを含め、同じ論理接続の新しいIPとポートを受け取った場合に応答するIPとポートを更新する必要があります。接続ハイジャッキが問題になる場合は、データグラムに安全なチェックサムなどのセキュリティを実装する必要があります。

TCPは、パケットを接続に関連付ける処理を行います。 UDPでは、データグラムを自分で論理セッションに関連付ける必要があります。なぜそれをそうするのはあまり効果がないと思うのか分かりません。

UDPのトレードオフの1つは、TCPが提供するものが必要な場合は、自分でコード化する必要があるということです。

ところで、私はこのようにポートがシフトするのを見たことはありません。クライアントコードが壊れていないと確信していますか?送信した各データグラムに対して新しいソケットを開いている可能性があります。

+0

ありがとうございます!私のコードのバグだったら、なぜパケットのエンドポイントを使わないのですか?それはすべてのクライアントのためにユニークではないだろうか?そして、安全なチェックサムはどのように見えるでしょうか?私は登録時に乱数をクライアントに送ることを考えていました。クライアントはパケットにmd5(パケットデータXORチェックサム)を追加します。サーバーは、チェックサムの正しさをチェックします。あなたはそれが意味することでしたか? – haiyyu

+1

@haiyyu:エンドポイントデータを使用しない理由は、相手先のIPアドレスが変更される可能性があるためです。 TCPでは、ネットワークがパケットをセッションに関連付ける必要があり、NATデバイスはIPを保持することを知っている必要があります。 UDPでは、そうではありません。そして、はい、それは私が意味するもののようなものです。もちろん、最適なソリューションは要件によって異なります。 –

関連する問題