zoukankan      html  css  js  c++  java
  • zt TCP协议存在那些缺陷?

    https://www.zhihu.com/question/47560918

    作者:车小胖
    链接:https://www.zhihu.com/question/47560918/answer/234698413
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    TCP做为一种可靠传输协议,其核心目标是把应用层的数据正确、可靠、高效传输到对端,而TCP所依赖的IP网络是一个原始的丛林世界,丢包、乱序、延迟不固定。

    TCP有一个孪生兄弟叫UDP,UDP是一大老粗,但非常听话。UDP在IP网络丛林里,严格执行自己的主人(应用层)的旨意,主人让发1000个/秒UDP包,UDP就一定会发那么多,也许这1000个包最终到达目的地的只有200个,其它的800个消失在丛林世界里无影无踪。

    TCP是举止优雅的绅士,对丛林世界的潜规则很反感,但又有极强的适应能力,能够从容应对一切的挑战。TCP也接到老板的吩咐:把1000个数据包1秒之内发到目的地!

    TCP委婉地表达自己的想法,可以准确无误地发到目的地,但时间无法保证!

    TCP凡事喜欢预约,每当需要拜访对方时,总会提前打过招呼(建立连接),只有对方在、并且接受预约(连接建立),才会带着老板的数据包去拜访对方。

    TCP是这么做的:
    先发一个包,等一个包的确认收到,可以得到一个往返时间RTT
    发两个,收到确认,得到第二个RTT,与第一个相加算平均SRTT

    一直两倍的指数增长,一直计算SRTT。

    直到检测到丢包,或retransmission timer 超时、或收到至少三次duplicated ACK,

    1.TCP决定在SRTT时间内发送个数指数减半

    2.如果收到ACK,则持续计算SRTT,发送个数线性增长,一个SRTT多发一个包。

    3.如果依然没有收到ACK,重复步骤1、2

    这是TCP的自适应流量控制算法,决定TCP能发多快,由这个公式得到:

    Delivery Rate = CWND/SRTT,其中

    CWND = 可发送包的个数 * 包的大小

    SRTT 是平滑RTT,动态测量的结果

     

    如果SRTT不变,CWND越大,发送速率越快。

    如果CWND不变,SRTT越小,发送速率越快。

    但一旦网络拥堵,路由器缓存队列使得SRTT变大,所以rate 会变小。

    如果缓冲队列尾丢(溢出),意味着有丢包,发送方肯定能检测出,指数减小CWND,这样rate 也会突减1/2。

    TCP就是通过这种小速率探测网络拥堵、指数增加发送速度、检测到丢包、发送速率减半、直到不再检测到丢包、线性增长发送速率、检测到丢包、再指数减小发送速率…

     

    TCP流控算法的关键,是基于丢包,有否丢包是唯一的判断依据,是加油门还是踩刹车。

    但TCP由于对网络了解的很片面,无法分辨丢包是什么原因造成的

    1)网络真的拥堵而丢包

    2)线路质量差CRC校验失败丢、或信号干扰丢

    3)IP包乱序而引起的误判

    只有情况1是需要踩刹车的,而情况2、3并不需要。

    Google BBR算法则提出基于带宽实时测量的算法,对于每个有数据的TCP包都测量其RTT,动态计算SRTT,这个比传统TCP计算的SRTT更精准,因为传统的TCP是一个SRTT时间周期内测量一次,而不是每个有数据的TCP包都测量。

    根据实时带宽值的趋势,是增还是减,如果增,说明带宽还有空间,可以乐观,在当前的delivery rate 的基础上 * 大于1的系数,等于加小油门,发送速率攀升。

    如果是减,则需要谨慎,在当前的delivery rate 的基础上 * 小于1的系数,等于小踩刹车,发送速率放缓。

    BBR算法不依赖于丢包,可以克服传统TCP对丢包的过分敏感与过激反应,避免发送速率骤增与骤减,使得整体发送速率在一个小范围内波动,更平缓、更平滑。

    这是传统TCP流控算法的一个改进。

    至于TCP其他的需要改进的,已经通过TCP option做了补丁,比如

    Scaling window 应对长肥管道

    Selective ACK 应对高丢包率场景

    Timestamp 应对序列号回滚RTT测量的精度

    Authentication Option 应对数据完整性挑战

    TCP Cookie 应对SYN Flooding DOS攻击

    FAST TCP Open 应对TCP传输数据延时大

    ==============================================================

    总体而言,TCP在传统的网络上工作的非常好,只是因为一些新的网络状况导致TCP不能很好的适应,这些就是需要改进的方向。

    首先是流控算法不能很好的适应高带宽高延迟的场景,因为ack确认因为传输延迟不能及时送达导致传输速度远低于理论的传输带宽。


    还有拥塞控制算法也不能很好的适应网络不太稳定的场景(比如无线网络),TCP的拥塞控制认为丢包是因为网络传输饱和,所以一但出现丢包就采取指数级避让,而无线网络因为短暂的信号干扰导致的丢包并不是因为网络传输饱和,此时采取指数级避让是不合适的,会导致无线传输的速度骤降。

    关于这个已经有很多改进的算法了,比如BBR。


    ==========================================================

    和端上高带宽高延迟相反,云上的问题在于超高的带宽(10-100 Gbps)和超低的延迟(10-100 us)需求,传统 TCP 以丢包来检测可用带宽的思路会导致重传(1-10ms),这对许多面向用户的应用是灾难性的。传统 TCP 过于保守的启动阶段浪费了带宽,过于激进的增长又使得交换机缓冲队列无限制增长直至出现拥塞,再加上云中极易出现的多对一的场景,导致传统 TCP 不能适应许多数据中心级别应用的需求。

    详细的阐述可以去看 DCTCP 这个协议,具体部署到数据中心的协议栈虽然是高度定制化的,但一般也是在 DCTCP 之上做出的一些改进,想解决的问题基本是一致的。


    ===========================================================
    作者:知乎用户
    链接:https://www.zhihu.com/question/47560918/answer/122549221
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    安全性缺陷:
    TCP使用三次握手机制来建立一条连接,握手的第一个报文为SYN包;第二个报文为SYN/ACK包,表明它应答第一个SYN包同时继续握手的过程;第三个报文仅仅是一个应答,表示为ACK包。若A放为连接方,B为响应方,其间可能的威胁有:
    1. 攻击者监听B方发出的SYN/ACK报文。
    2. 攻击者向方发送RST包,接着发送SYN包,假冒A方发起新的连接。
    3. B方响应新连接,并发送连接响应报文SYN/ACK。
    4. 攻击者再假冒A方对B方发送ACK包。
    这样攻击者便达到了破坏连接的作用,若攻击者再趁机插入有害数据包,则后果更严重。TCP协议把通过连接而传输的数据看成是字节流,用一个32位整数对传送的字节编号。 初始序列号(ISN)在TCP握手时产生,产生机制与协议实现有关。攻击者只要向目标主机发送一个连接请求,即可获得上次连接的ISN,再通过多次测量来回传输路径,得到进攻主机到目标主机之间数据包传送的来回时间RTT。已知上次连接的ISN和RTT,很容易就能预测下一次连接的ISN。若攻击者假冒信任主机向目标主机发出TCP连接,并预测到目标主机的TCP序列号,攻击者就能伪造有害数据包,使之被目标主机接受。
    IP协议在互连网络之间提供无连接的数据包传输。IP协议根据IP头中的目的地址项来发送IP数据包。也就是说,IP路由IP包时,对IP头中提供的源地址不作任何检查,并且认为IP头中的源地址即为发送该包的机器的IP
    地址。这样,许多依靠IP源地址做确认的服务将产生问题并且会被非法入侵。其中最重要的就是利用IP欺骗引起的各种攻击。
    以防火墙为例,一些网络的防火墙只允许网络信任的IP数据包通过。但是由于IP地址不检测IP数据包中的IP源地址是否为放送该包的源主机的真实地址,攻击者可以采用IP源地址欺骗的方法来绕过这种防火墙。另外有一些以IP地址作为安全权限分配依据的网络应用,攻击者很容易使用IP源地址欺骗的方法获得特权,从而给被攻击者造成严重的损失。事实上,每一个攻击者都可以利用IP不检验IP头源地址的特点,自己填入伪造的IP地址来进行攻击,使自己不被发现。
     
    ===========================================================

    就我个人来看,感觉tcp最难受的就是原来假设的丢包是拥塞引起的,只是因为拥塞引起的。

    这个现象导致在现在高速链路下,反应太慢。

    所以觉得tcp支持多连接是必需的改进。另外,希望能够增加一些其他的信息指示来提高控制能力。例如,建立tcp时,通报一下双方所在的网络情况(带宽、介质、跳数)等等

    ===========================================================
     
    TCP存在的主要缺陷有:
    1)性能比UDP低,包括延迟时间等。
    2)TCP的crc校验位只有16位, 当出现错误时,有1/65535的概率不能够被检测出来,不够可靠。
    3)TCP存在粘包的情况,就是就是我们收到的数据流,并且有可能是多个数据包合并的内容,而不是数据块,在后续处理的过程中一定要单独处理。
    4)目前TCP层的设计过于陈旧,毕竟是60-70年代的东西, 很多地方不够理想。例如:单个连接只能承载一套数据流,这样导致象新浪这样的网站,打开网页要发很多TCP连接。如果在底层设计承载多套数据流就要好很多。
    5)TCP的内部参数默认很多不完全适应现在高速网络的需求,当时的网络和现在不一样,例如:现在我们为了加快ip包的传递往往设置了nodelay,关闭一些过于老化的模块。

    =================================================================

    说tcp的缺陷,要看你在什么场景下对其进行评价。有人说tcp的AIMD机制是缺陷,也有人说tcp的丢包驱动的降速(dup ack及超时)是缺陷。

    经典的tcp在中间交换机路由器能缓存一个bdp数据包的情况下,是能跑满带宽且是能保证流公平性的。但是,大家也会看到,在数据中心里面就没有人用tcp(别说为了兼容前段tcp的事),为什么?那是因为要求不一样。数据中心rtt较短,速率较高,但又对丢包容忍性比较差,这就给rdma提供了炮弹,成了rdma的靶子(内核旁路啥的技术按下不表)。

    因此,从做研究的角度来讲,想攻击tcp的缺点,太多了。不过,依然撼动不了tcp的地位。

    ==================================================================
     
    TCP是高可靠性的协议,为了提高可靠性,必然要牺牲一些其它方面的性能作为代价,这是必然的。这些牺牲的性能就是其所谓的缺陷了。
    1,确保高可靠性就需要知道通信对方的状态,那就必须要建立连接、维护连接、释放连接,这当然就要有对应的开销。以“握手”的方式建立和释放连接(有关TCP的三次握手就不赘言了,其它回答已经说了很多了),导致延时和数据收发双方的资源分配的开销。而对应的UDP协议由于是无连接的,自然无需延时和资源开销。因此,延时和资源开销算是第一种“缺陷”了。
    先写到这,航班要起飞了,到目的地后再继续。


  • 相关阅读:
    VUE 源码工具
    elasticsearch 根据主键_id更新部分字段
    Linux下解压文件到其他目录
    centos 7 安装docker
    英语阅读
    将Word文件上传到博客园
    kafka
    ubantu批量下载依赖包+apt命令list
    llvm.20.SwiftCompiler.Compiler-Driver
    Java获取resources文件夹下properties配置文件
  • 原文地址:https://www.cnblogs.com/e-shannon/p/14271264.html
Copyright © 2011-2022 走看看