質問
TCP / IPは、同じパケットの複数のコピーが宛先に到達するのを防ぎますか?それとも、その上にi等性ロジックを階層化するエンドポイント次第ですか?
可能であれば、TCP / IP仕様の特定の段落を参照してください。
解決
重複パケットから回復するのはTCPスタックの仕事です:
TCPは次のデータから回復する必要があります 損傷、紛失、複製、または インターネット通信システムによって順不同で配信されます。この 各オクテットにシーケンス番号を割り当てることにより実現されます 送信され、からの肯定応答(ACK)が必要 TCPを受信します。タイムアウト内にACKが受信されない場合 間隔、データは再送信されます。受信機では、 シーケンス 番号は、受信される可能性のあるセグメントを正しく順序付けるために使用されます 故障し、重複を排除します。損傷はによって処理されます 送信された各セグメントにチェックサムを追加し、 破損したセグメントを破棄します。
- RFC 793 -伝送制御プロトコル、セクション1.5
ただし、それらが新しいシーケンス番号を持つ同じパケットである場合、いいえ。
他のヒント
TCPは、再送信の場合にシーケンス番号を使用して重複を検出します。これにより、些細なリプレイ攻撃も防止されます。
RFC 793、セクション3.3-シーケンス番号から:
設計の基本的な概念 送信されるデータのすべてのオクテットが TCP接続を介したシーケンス 数。すべてのオクテットは シーケンスされ、それらのそれぞれは 認めた。謝辞 使用されるメカニズムは累積的ですので シーケンスの確認 番号Xは、すべてのオクテットが上であることを示します Xを含むが、Xは含まない 受け取りました。このメカニズムにより、 簡単な重複検出 再送信が存在する場合。 セグメント内のオクテットの番号付け それは最初のデータオクテットです ヘッダーの直後は 最小の番号、および次の オクテットには連続した番号が付けられます。
重複検出により、同じパケットを簡単に再送信できないようになります。シーケンス番号により、データストリームへのデータの挿入(置換ではなく)が確実に通知されます。偽造パケットに続く追加の正当なパケットには重複したシーケンス番号が含まれ、データフローが中断されます。これにより、これらのパケットが重複としてドロップされる可能性が高く、使用されているプロトコルが破損する可能性があります。
元の(1981)TCP / IP仕様の詳細については、 RFC 793 をご覧ください。 a>、およびTCP / IPプロトコルの拡張または変更を含む他の多くのRFC。
はい、TCPレイヤーはパケットの重複を防ぎます。その下のIP層はそうではありません。
RFC 1122 の詳細。
次の2つのことを心配しているようです:
- TCPの信頼できる配信が提供する保証は何ですか
- リプレイ攻撃で攻撃者がサーバープロセスに影響を与えることはできますか
1への回答:
TCPは、バイトシーケンスの信頼性の高い順序どおりの配信を保証します。クライアントアプリケーションが write()
を介してTCPに送信するデータは、サーバーの read()
呼び出し中にまったく同じになります。
2への回答:
リプレイ攻撃はTCPではうまく機能しません。これは、すべての接続が、クライアントとサーバーによってそれぞれ生成される2つのランダムな32ビット数に依存するためです。リプレイ攻撃が機能するためには、攻撃者は、開始している偽の接続に対してサーバーによって生成されたシーケンス番号を推測する必要があります(理論的には、攻撃者は正しく推測するために1/2 ** 32のチャンスがあります)。攻撃者が誤って推測した場合、最悪の場合、OSのデータのバッファリングが発生します。
リプレイ攻撃が機能しないという理由だけで、攻撃者がサーバーとの正当な接続を確立し、必要なデータストリームをアプリケーションに送信することを妨げるものは何もないことに注意してください。これが、常に入力を検証することが重要な理由です。
TCP未満のレイヤーでは、複数のパケットまたはドロップされたパケットが発生する可能性があります。 TCPより上のレイヤーでは、パケットの繰り返しやドロップが発生しません。
パケットの再認識については知りませんが、TCP / IPを使用してこれに遭遇したことはなく、パケットがすべて正しい順序で到着することを保証していることを知っているので、なぜそうしないのか理解できません't。
実際には、データの受信方法に依存します-技術的にはプロトコルは重複(つまり、同じtcpチェックサムを持つパケット)を与えるべきではありませんが、他の要因により重複が発生する可能性があります-たとえば、ネットワークハードウェア使用して;また、アプリケーションで開いているソケットを読み取るのではなく、スニファーを使用してtcpストリームを見る場合、監視している実際のtcpストリームにdupパケットがなくても、スニファーからdupパケットを取得することができます。
実世界の例を挙げるために-現時点では、主要な証券取引所の内部ネットワークのtcp分析に取り組んでおり、私が見ているデータは複数のスニファーから入力され、一緒にスプライスされています。そのため、データを取り込む際に、重複の検出や削除など、多くの前処理手順を実行する必要があることがわかりました。たとえば、約60,000個のデータパケットを読み込んだばかりのストリームで、95個の重複パケットを見つけて削除しました。
ここでの戦略は、最新の10個のtcpチェックサムのローリングウィンドウを保持し、それらのチェックサムに一致するパケットを無視することです。これはPSHパケットではうまく機能しますが、ACKパケットではそれほどうまく機能しないことに注意してください-とにかくそれらについてはあまり気にしません。
このtcpチェックサムのローリングウィンドウを追跡するための特別なコレクションを作成しました。これは、他の人に役立つ可能性があります。
/// <summary>
/// Combination of a double-linked-list and a hashset with a max bound;
/// Works like a bounded queue where new incoming items force old items to be dequeued;
/// Re-uses item containers to avoid GC'ing;
/// Public Add() and Contains() methods are fully thread safe through a ReaderWriterLockSlim;
/// </summary>
public class BoundedHashQueue<T>
{
private readonly int _maxSize = 100;
private readonly HashSet<T> _hashSet = new HashSet<T>();
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private readonly Item _head;
private readonly Item _tail;
private int _currentCount = 0;
public BoundedHashQueue(int maxSize)
{
_maxSize = maxSize;
_head = _tail = new Item();
}
private class Item
{
internal T Value;
internal Item Next;
internal Item Previous;
}
public void Add(T value)
{
_lock.Write(() =>
{
if (_currentCount == 0)
{
Item item = new Item();
item.Value = value;
_head.Next = item;
item.Previous = _head;
item.Next = _tail;
_tail.Previous = item;
_currentCount++;
}
else
{
Item item;
if (_currentCount >= _maxSize)
{
item = _tail.Previous;
_tail.Previous = item.Previous;
_tail.Previous.Next = _tail;
_hashSet.Remove(item.Value);
}
else
{
item = new Item();
_currentCount++;
}
item.Value = value;
item.Next = _head.Next;
item.Next.Previous = item;
item.Previous = _head;
_head.Next = item;
_hashSet.Add(value);
}
});
}
public bool Contains(T value)
{
return _lock.Read(() => _hashSet.Contains(value));
}
}}
問題を完全に理解していない。 こちらのリンクをご覧ください: http://en.wikipedia.org/wiki/Transmission_Control_Protocol
このページには次のように書かれています:
RFC 1323で定義されている&quot; TCPタイムスタンプは、TCPが送信者と受信者の間の往復時間を計算するのに役立ちます。タイムスタンプオプションには、送信者がそのタイムスタンプクロックの現在の値を挿入する4バイトのタイムスタンプ値と、受信者が受信した最新のタイムスタンプ値を通常挿入する4バイトのエコー応答タイムスタンプ値が含まれます。送信者は、確認応答でエコー応答タイムスタンプを使用して、確認済みセグメントが送信されてからの合計経過時間を計算します。[2]
TCPタイムスタンプは、TCPシーケンス番号が2 ^ 32バウンドおよび「ラップアラウンド」に遭遇した場合に役立ちます。シーケンス番号スペース。このスキームは、ラップシーケンス番号に対する保護、またはPAWSとして知られています(詳細についてはRFC 1323を参照してください)。
よろしく、 ジョイント(ポーランド)