TCP / IP是否阻止数据包重播?
TCP / IP是否会阻止同一数据包的多个副本到达目的地?还是由端点决定其上的幂等逻辑?
如果可能,请参考TCP / IP规范中的特定段落。
解决方案
我不了解数据包重新分配,但是我从未使用TCP / IP遇到过它,我知道它确实可以保证所有数据包都以正确的顺序到达,所以我不明白为什么它不会。
TCP之下的层可能会遇到多个数据包或者丢弃的数据包。 TCP之上的层不会经历重复或者丢包。
TCP堆栈的工作是从重复的数据包中恢复:
The TCP must recover from data that is damaged, lost, duplicated, or delivered out of order by the internet communication system. This is achieved by assigning a sequence number to each octet transmitted, and requiring a positive acknowledgment (ACK) from the receiving TCP. If the ACK is not received within a timeout interval, the data is retransmitted. At the receiver, the sequence numbers are used to correctly order segments that may be received out of order and to eliminate duplicates. Damage is handled by adding a checksum to each segment transmitted, checking it at the receiver, and discarding damaged segments.
-RFC 793传输控制协议,第1.5节
但是,如果它们是具有新序列号的相同数据包,则否。
在重传的情况下,TCP使用序列号来检测重复,这也将防止琐碎的重放攻击。
从RFC 793,第3.3节序列号:
A fundamental notion in the design is that every octet of data sent over a TCP connection has a sequence number. Since every octet is sequenced, each of them can be acknowledged. The acknowledgment mechanism employed is cumulative so that an acknowledgment of sequence number X indicates that all octets up to but not including X have been received. This mechanism allows for straight-forward duplicate detection in the presence of retransmission. Numbering of octets within a segment is that the first data octet immediately following the header is the lowest numbered, and the following octets are numbered consecutively.
重复检测将确保相同的数据包不会被轻易重传。序列号还将确保在数据流中插入(而不是替换)数据,因为在伪造数据包之后的其他合法数据包将具有重复的序列号,这将破坏数据流。这可能会导致这些数据包被丢弃为重复数据,这很可能破坏正在使用的协议。
有关原始(1981年)TCP / IP规范的更多信息,请参见RFC 793,以及许多其他涉及对TCP / IP协议进行扩展或者修改的RFC。
是的,TCP层可以防止重复数据包。它下面的IP层则没有。
RFC 1122中的详细信息。
这实际上取决于我们如何接收数据,尽管从技术上讲该协议不应为我们提供重复项(即,具有相同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中定义的TCP时间戳可帮助TCP计算发送方和接收方之间的往返时间。时间戳选项包括4字节的时间戳值,其中发送方插入其时间戳时钟的当前值和4字节回声答复时间戳记值,接收方通常在其中插入接收到的最新时间戳记值,发送方在回执中使用回声答复时间戳记来计算自发送确认段以来的总经过时间。[2]
如果TCP序列号遇到其2 ^ 32界限并"环绕"序列号空间,则还可以使用TCP时间戳来提供帮助。这种方案称为"防止包装序列号"或者" PAWS"(有关详细信息,请参阅RFC 1323)。
问候,
联合(波兰)
- TCP可靠交付提供什么保证
- 攻击者能否通过重播攻击影响我的服务器进程
我们似乎担心两个不同的问题:
答案1:
TCP保证字节序列的可靠,有序传递。客户端应用程序通过write()发送到TCP的所有数据在服务器的read()调用期间将完全相同。
答案2:
对于TCP,重播攻击不能很好地起作用,因为每个连接都依赖于客户端和服务器分别生成的两个随机的32位数字。为了使重播攻击起作用,攻击者必须猜测服务器为其发起的虚假连接生成的序列号(理论上,攻击者有1/2 ** 32的机会可以正确猜测)。如果攻击者猜错了,最坏的情况是它将导致操作系统中的某些数据缓冲。
段落数量不匹配