TCP 校验和能否检测到错误?如果是,如何处理?

Posted

技术标签:

【中文标题】TCP 校验和能否检测到错误?如果是,如何处理?【英文标题】:Can a TCP checksum fail to detect an error? If yes, how is this dealt with? 【发布时间】:2011-04-19 07:34:18 【问题描述】:

如果 TCP 有效负载在传输过程中损坏,则重新计算的校验和将与传输的校验和不匹配。太好了,到目前为止一切都很好。

如果 TCP 校验和在传输过程中损坏,则重新计算的校验和将与现在损坏的校验和不匹配。太好了,到目前为止一切都很好。

当有效负载和校验和都损坏并且重新计算的校验和虽然与应有的不同但恰好与现在损坏的校验和匹配时会发生什么?

我可以看到一个好的校验和算法(以及较低级别的附加校验和)这可能非常非常不可能,但 TCP 不是意味着 100% 可靠吗?它如何解决这些误报?

【问题讨论】:

【参考方案1】:

这里需要注意的一点是,大多数人完全忽略的事实是,TCP 校验和实际上是一个非常差的校验和。

TCP 校验和是数据的 16 位补码和。这笔款项 将捕获任何 15 位或更少的突发错误,以及所有 16 位突发 错误,除了那些用 1 的补码 0 替换的错误 另一个(即,16 个相邻的 1 位被 16 个零位替换,或 反之亦然)。在均匀分布的数据上,预计检测 其他类型的错误率与 2 ^ 16 中的 1 成比例。这 校验和还有一个很大的限制:一组 16 位的和 值是相同的,无论值的顺序如何 出现。

来源:ftp://ftp.cis.upenn.edu/pub/mbgreen/papers/ton98.pdf

因此,如果您在数据包的数据部分的任意位置随机翻转任意数字位,则即使您根本不触摸校验和,也有可能在 1 到 65536 之间未检测到此错误,作为新数据,即使完全损坏,实际上也具有与旧校验和相同的校验和。如果您只是在数据部分交换两个 16 位值,无论是哪个以及无论频率如何,甚至 100% 的机会都不会检测到此错误,因为 16 位值出现在数据部分的顺序数据包与计算的校验和的值完全无关。

我在这里想说的是,您不必太担心数据和校验和都损坏并且由于损坏的校验和与损坏的数据匹配而未检测到此错误的不太可能的情况,事实上,互联网上每天数以百万计的 TCP 数据包只有数据损坏,并且没有检测到此错误,因为未损坏的校验和仍然与损坏的数据匹配。

如果您需要传输数据并且希望确保数据没有损坏,那么仅 TCP 校验和肯定不足以完成这项任务。我什至敢说 CRC 校验和不足以完成这项任务,因为 CRC32 可能无法检测到连续超过 32 位受到影响的错误(这些错误可以相互“抵消”)。确保完美数据传输所需的最小校验和是数据的 MD5 值。当然,任何比这更好的东西(SHA-1、SHA-256、SHA-384、SHA-512、Whirlpool 等)都会更好,但 MD5 就足够了。 MD5 可能不再足够安全用于加密安全(因为它在过去被多次破坏),但作为数据校验和,MD5 仍然绝对足够。

【讨论】:

为什么 MD5 校验和就足够了? @fumoboy007 因为你不是在处理密码学。损坏的数据与正确数据具有相同的 MD5 校验和的可能性是 1 到 340,282,366,920,938,463,463,374,607,431,768,211,456(39 位!),宇宙的原子可能比这更少。您可以轻松地生成具有相同 MD5 校验和的两组数据(这就是为什么您不得不再使用 MD5 进行加密),但这两个数据集看起来完全不同(甚至不相似!) .被传输错误修改的数据看起来仍然与正确的数据非常相似。 引用的论文非常好读。这篇文章真正有趣的是他们对数据包错误来源的分析以及它们在现实世界中的处理方式。然而,他们忽略了 CRC 误报推导的来源。本文确实推导出 CRC 误报概率:ris.utwente.nl/ws/portalfiles/portal/5382287。参见等式 (2) 并参见图 2,它适用于 CCITT CRC-16,但对于 CRC-32 也可以计算出类似的结果。底线:错误的 CRC 阳性比 1/2^N 更有可能。【参考方案2】:

不,它不可能 100% 可靠:this paper 提到错误控制系统未捕获到的 1600 万到 100 亿个数据包中有 1 个。我会让你计算每天/每周的发生次数:)

【讨论】:

世界流量大约是每天 10 到 15 个数据包:因此,它发生在其他人的一些数据包(尽管不是你的数据包)上的可能性非常高。 我认为衡量一个人体验它的可能性的唯一指标是与数据包相关的;您与使用相同数量数据包的其他人一样容易遇到此问题。 OTOH,要引人注目,您必须在关键数据包中遇到故障;如果您的 html 或 js 被破坏,您会皱眉并重新加载页面,您不会使用验尸工具 :) 顺便说一句,您在哪里找到您的统计数据?我环顾四周,但找不到有关数据包数量的数据... 我只是指出,如果错误率是 100 亿分之一,那么它可能不会发生在你身上(因为你没有发送那么多数据包):但它可能会发生其他人(因为他们确实发送了很多数据包)。我发现的第一个统计数据是World 7,500-12,000 PB (PetaByte = 10^15 bytes),我将其除以我对每个数据包 500 字节的估计。 @ChrisW 感谢您的链接 :) 不过,对于数据包大小,您比我更保守,但即使采用数据包的最大大小,每天都会发生错误 实际上,您的号码包括结合 TCP 的较低级别的检查(例如以太网 CRC)。仅 TCP 校验和就有 65536 个错误中有 1 个未被检测到的概率。这是非常高的。考虑到每天有万亿个数据包,仅 TCP 的错误率仍然会导致每天数百万个损坏的数据包未被检测到,因为损坏的数据仍然与原始数据具有相同的校验和。【参考方案3】:

TCP 校验和会产生误报吗?

是的。校验和比数据包小得多,因此许多不同的数据包可以匹配给定的校验和。

如果是,如何处理?

在 TCP 中,完全没有。但是,大多数数据损坏在更高级别上会很明显,例如您的 XML 格式不再正确;您的电子邮件不再是英文等。

【讨论】:

除了内容丰富之外,我还笑得很开心“你的电子邮件不再是英文” 数据中的一个翻转位是否会导致电子邮件翻转其语言? 翻转一位会导致校验和失败;需要更多位翻转来观察原始问题所涉及的问题。但我的意思是说,这些词会被完全弄乱,而不是从英语变成法语。发生这种情况并且仍然通过校验和的可能性非常非常低:-)【参考方案4】:

以及较低级别的附加校验和

其中一些比校验和更严格,例如以太网使用CRC 而不是校验和。

这可能非常非常不可能,但 TCP 不是 100% 可靠的吗?它如何解决这些误报?

我不认为它可以。即使它通过硬拷贝和信鸽发送复制品,宇宙射线或量子效应理论上也可能以完全相同的方式破坏复制品。这是非常非常不可能的。

您还可以在应用层(TCP 之上)实现任意强完整性检查,例如使用加密签名。

【讨论】:

虽然以太网具有良好的完整性检查,但其他形式的网络呢? 我希望您希望设计完整性检查以匹配您的数据链路的错误率。例如PPP 也使用 CRC。 这是有道理的。对于许多不同数据链路类型(以太网、ppp、atm)的长连接,我猜你会受制于更糟糕的组件链路(可能根本没有完整性检查)。 "以太网使用 CRC 而不是校验和。" 为什么 CRC 不是“校验和”? @curiousguy 对我来说,“checksum”这个词意味着(因为该术语包括)一个简单的异或,一个比特字节上的奇偶校验位,或者一个字节包上的奇偶校验字节——而 CRC 是一种更复杂的算法。【参考方案5】:

假设

数据包负载:1000 字节

数据包校验和:2 字节

数据包出现双重错误的概率,其中一个是校验和(假设 P 非常小,小于 1/10^5):

A = 8P*(1000*8P) = 6*10^4 * P^2

准确校验和的概率:

B = 1/2^16 = 6/10^4

误报概率:

A * B = 40 * P^2 

概率很低(P=1/10^6,则误报概率 A*B=4/10^11),但无论如何使用任何 crc 算法,它都不能为零。一个随机 1000 字节数据包出现为另一个随机 1000 字节数据包的概率为 P^8000,就好像所有字节都包含错误一样。

如果 P 很高,例如从 1/10^3 到 1,则上述计算不适用。在这种情况下,A=1(所有数据包都包含双重错误),误报的概率仅为 A*B = 6/10^4。这不是一个非常相关的案例,因为超过 99% 的接收数据包会在 crc 中包含错误。

【讨论】:

【参考方案6】:

我认为概率是十亿分之一,因为如果 TCP 数据(即传输层)损坏,也意味着其他层(数据链路和网络)也将损坏。我相信至少数据链路层有一个完整性校验和,所以你必须让两个校验和都失败。

以至少两个单独的校验和失败的方式进行损坏,在天文数字上是不可能的,甚至是不可能的。

【讨论】:

不是所有的数据链路层都有完整性检查吗? 不,他们没有。我上面链接的论文提到在某些情况下使用应用程序级检查 见academic.research.microsoft.com/Paper/22436.aspx,低级crc可能没有你想象的那么可靠。 RAM 也会引入错误。并非所有问题都发生在电线(或以太网)中。

以上是关于TCP 校验和能否检测到错误?如果是,如何处理?的主要内容,如果未能解决你的问题,请参考以下文章

ip报文发送时进行分片 在发送过程中丢失一个或是多个片时如何处理 以及如何分辨丢失与否?

我如何处理改造错误或获取 URL 请求以检测问题

Viola-Jones 人脸检测器如何处理多种尺寸的人脸?

找不到人脸时如何处理 deepFace.analyze() 中的错误?

如何处理错误“dial tcp 10.240.0.4:10250: i/o timeout”以查看 AKS 中的 pod 日志?

在iOS开发中,是如何处理好网络加密这块的?[个人详细分析]