zoukankan      html  css  js  c++  java
  • 俺的分布式架构系统之计算机网络4

    运输层

    从网络层来到运输层,整个人变的轻松许多,毕竟是写软件编码的,涉及到一些硬件设备方面的知识,总是需要多付出一些时间和精力去学习和理解。虽说状态放松了许多,仍然不敢轻视这部分内容,尽管编程语言和操作系统已经将传输层的两大协议UDP和TCP封装好,直接使用/调用即可,但该学习和理解的概念与原理是不能省略掉的。运输层以下属于数据通信,以上属于数据处理,也起到了桥梁和承上启下的作用,所以这部分内容的重要性也是不言而喻的。

    大多数时候我们一直在努力追求远方的美好,然而真正的美好就在自己身旁,我们总是喜欢做舍近求远的事情,也因此常常感到各方面的压力都很大。我一直都坚守量力而为的自觉,一个人能做什么事情,能有多么大的作为,其实早在你做某些事之前就已经确定了。从利己的角度说,大家能够共苦而不愿意同甘,在利益面前总是希望多收获一些好处,而在付出的时候可以少出一些力量,这就是人性的贪婪。踏踏实实做事的人往往并不能得到应有的尊重和报酬,这是社会普遍存在的问题,所以才会出现各种各样的矛盾和不公平,那些踏踏实实做事的人也开始浮躁了,组织机构变得零零散散,无法机动高效的协调起来,最终面临崩塌毁灭。因此组织机构的拥有者应该多多注重人的价值,不要忽略人的差异,特别是这个信息化时代,理当充分尊重人才,而不应该像对待机器人那样漠视、藐视处理,更不应把知识型人才当成体力型人才对待,不然组织机构存在的意义又是什么。

    对于我这么个奇葩中的奇葩来说,生活中的很多事情反而是困难的,当写程序时会觉得这才是生活的本质,因此生活中的朋友并不多,技术无国界使我活的很惬意。我的技术水平如何呢?首先我把技术分为了三个或四个层次,就当四个层次说好了,第一层属于应用程序层,就是为大家开发各种应用软件使用;第二层应用技术层,就是负责为应用程序层提供服务支持的;第三层系统技术层,即系统软件,比如操作系统、数据库、设备驱动、网络通信等等;第四层数学算法层,就是可以把数学算法应用于现实世界,比如华为的5G通信算法。第一层算是比较简单的,同时又可以划分为三个等级,第一级是项目级,乱七八糟的堆技术能把项目做出来就行;第二级是产品级,开始标准化不允许使用杂乱无章的技术;第三级自主级,即做出来的程序不仅标准化而且用到的核心技术为自主研发。第二层开始深入,同时也可以划分为三个等级,第一级是组装级,就是没有设计研发实力和能力,只能用这个软件、那个程序拼凑出来的一套东西;第二级是研发级,就是有设计能力、研发实力,有核心和重心了,虽然还会用到其他软件,但其他软件不再是必须的而是可选可以被替换的;第三级是实力级,就是系统可以支持高并发、高负载等突发场景。第三层,能达到这个层次的单位是可以数过来的,所需的资源、资本、实力都是巨大的。第四层属于奇迹层,出现的概率为亿万分之一,一旦出现了就是奇迹,改变人类的生活方式。自我感觉自己处于第二层的第二级,哈哈哈,是不是很不要脸啊!那就不吹牛逼了,抄写开始……

    协议概述

    当网络的边缘部分中的两台主机使用网络的核心部分的功能进行端到端的通信时,只有主机的协议栈才有运输层,运输层也常被称为传输层。生活中我们常常会说两台电脑连上网就能通信了,实际上用两台电脑或主机连上网通信不够准确,因为真正进行通信的实体是主机中的进程,即主机A中的应用进程1通过网络和主机B中的应用进程2进行数据的交换。IP协议虽然能把分组送到目的主机,但是这个分组还停留在主机的网络层,并没有交付给主机中的应用进程。

    一台主机中经常有多个应用进程和另一台主机中的多个应用进程通信,这个时候出现了两个重要的概念:复用分用。就像现实生活中的传达室一样,所有文件包裹的收发都要经过传达室完成,这个时候传达室就是运输层,而多个应用进程就是一个个要发送和接收的包裹。如果传达室接收来自各个快递员送来的包裹,那么传达室相当于复用,即所有包裹只有来到传达室才能最终达到每个人的手中;当传达室将包裹分发到每个人的手中时叫做分用。

    运输层提供应用进程间的逻辑通信,从应用层来看,只要是把应用层报文交给下面的运输层,运输层就可以把报文传送到对方的运输层,好像这种通信就是沿着水平方向直接传送数据,但实际上这两个运输层之间并没有一条水平方向的物理连接,数据在网络层需要经过非常复杂的传输过程。网络层为主机间提供逻辑通信,运输层为应用进程间提供端到端的逻辑通信。

    运输层向高层协议屏蔽了下面网络核心的细节,比如网络拓扑、路由选择协议等等,它使应用进程看着就好像在两个运输层实体之间有一条端到端的逻辑通信信道,在这条通信信道通信时,会因选择的运输层协议的不同对上层表现出很大的差异。当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的,但TCP协议却使这条通信信道变成了一条全双工的可靠信道;当运输层采用无连接的UDP协议时,这条信道依然是一条不可靠信道。

    TCP即传输控制协议(Transmission Control Protocol)UDP即用户数据报协议(User Datagram Protocol),在OSI的术语中,两个对等运输实体在通信时传送的数据单元叫运输协议数据单元TPDU(Transport Protocol Data Unit),但是在TCP/IP体系中,分别叫TCP报文段UDP用户数据报。UDP在传送数据之前不需要先建立连接,目的主机的运输层在收到UDP报文后,也不需要给出任何确认。TCP则提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接,因为它提供可靠的面向连接的运输服务,所以还有许多事情要做。下图是应用层常用的使用运输层协议的应用。

          

    经过上述分析,已经清楚的知晓主机的网络通信实质就是主机的应用进程在网络上的通信,现在新的问题来了,如何知道主机上的哪个应用进程和另一台主机上的哪个应用进程通信呢?在单台主机上,每一个应用进程都有一个用整数标识的应用进程标识符,可否使用它作为网络间主机进程通信的标识符,答案是否定的,第一应用进程标识符是随着进程的创建产生和销毁消失的,即它是动态的,通信一方是不可能使用的;第二网络上的计算机操作系统种类很多,不同的操作系统使用的进程标识符并不一样。要解决网络上主机的应用进程通信就要寻找其他解决方案了,也就是在运输层使用协议端口号,又简称为端口。虽然通信的终点是应用进程,但是只要把所传送的报文交到目的主机的某个合适的目的端口,剩下的工作就由TCP或UDP来完成。切记这种在协议栈层间的抽象的协议端口是软件端口,和路由器或交换机上的硬件端口是完全不同的概念,硬件端口是不同硬件设备进行交互的接口,软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。

    TCP/IP的运输层用一个16位端口号来标识一个端口,它允许由65535个不同的端口号。端口号只具有本地意义,它只是为了标识本计算机应用层中的各个进程在和运输层交互时的层间接口,在互联网不同计算机中,相同的端口号是没有关联的。综上可知,两台计算机中的进程要相互通信,不仅要知道对方的IP地址(找对方的计算机),而且还要知道对方的端口号(找对方计算机中的应用进程)。

    运输层的端口号分为两大类:服务器端使用的端口号和客户端使用的端口号,具体如下:

    1)   服务器端使用的端口号,它又被分为两类:熟知端口号和登记端口号

    a)   熟知端口号:又被称为系统端口号,数值范围:0到1023。IANA把这些端口号指派给了TCP/IP最重要的一些应用程序,让所有的用户都知道。常用的熟知端口号如下:

           

    b)   登记端口号:数值范围1024到49151,这类端口号是为没有熟知端口号的应用程序使用的,一定要避免重复。

    2)   客户端使用的端口号,数值范围:49152到65535,由于这类端口号仅在客户进程运行时才动态选择,又叫做短暂端口号。这类端口号是留给客户进程选择暂时使用的,当服务器进程收到客户进程的报文时,就知道了客户进程所使用的端口号,因而可以把数据发送给客户进程,通信结束后,刚才已使用的客户端口号就不复存在,这个端口号就可以供其他客户进程使用。

     

    用户数据报协议UDP

    1.   UDP概述

    用户数据报协议UDP只在IP的数据报服务之上增加了很少一点的功能,就是复用和分用以及差错检测。UDP主要有以下特点:

    1)   UDP是无连接的,即发送数据之前不需要建立连接(发送数据结束时也没有连接可释放),因此减少了开销和发送数据之前的时延。

    2)   UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。

    3)   UDP是面向报文的,发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层,既不合并也不拆分,而是保留这些报文的边界。所以为了传输效率一定要合理的控制应用程序报文的长度,即不能太长导致IP层分片传输,又不能太短使IP数据报的首部大于数据部分。

    4)   UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。某些实时应用,要求源主机以恒定的速率发送数据,允许在网络发生拥塞时丢失一些数据,但却不允许数据有太大的延时,UDP正好适合这种需求。

    5)   UDP支持一对一、一对多、多对一和多对多的交互通信

    6)   UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。

     2.   UDP的首部格式

             

    UDP用户数据报有两个字段:数据字段和首部字段,首部字段很简单,只有8个字节,由四个字段组成,每个字段的长度都是两个字节:

    1)   源端口,源端口号,在需要对应回信时选用,不需要时可用全0。

    2)   目的端口,目的端口号,这在终点交付报文时必须使用。

    3)   长度,UDP用户数据报的长度,其最小值是8(仅有首部)。

    4)   检验和,检测UDP用户数据报在传输中是否有错,有错就丢弃。

    UDP用户数据报首部中检验和的计算方法有些特殊,在计算检验和时,要在UDP用户数据报之前增加12个字节的伪首部,所谓“伪首部”因为它不是UDP用户数据报真正的首部,只是在计算检验和时,临时添加在UDP用户数据报前面,得到一个临时的UDP用户数据报,检验和就是按照这个临时的UDP用户数据报计算出来的。伪首部既不向下传送也不向上递交,仅仅为了计算检验和。伪首部各字段的解释如下:

    1)   源IP地址,发送方主机IP地址

    2)   目的IP地址,接收方主机IP地址

    3)   第3字段是全零

    4)   第4字段IP首部中的协议字段值,UDP协议是17

    5)   第5字段是UDP用户数据报的长度

    UDP采用伪首部的检验和,既检查了UDP用户数据报的源端口号和目的端口号以及UDP用户数据报的数据部分,又检查了IP数据报的源IP地址和目的IP地址。

     

    传输控制协议TCP

    1.   概述

    TCP是TCP/IP体系中非常复杂的一个协议,它主要有以下特点:

    1)   TCP是面向连接的运输层协议。应用程序在使用TCP协议之前,必须先建立TCP连接。在传输数据完毕后,必须释放已经建立的TCP连接。

    2)   每一条TCP连接只能有两个端点(endpoint),每一条TCP连接只能是点对点的(一对一)。

    3)   TCP提供可靠交付的服务,通过TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达。

    4)   TCP提供全双工通信,TCP允许通信双方的应用进程在任何时候都能发送数据,TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。
          在发送时,应用程序在把数据传送给TCP的缓存后,就可以做自己的事,TCP在合适的时候把数据发送出去。
          在接收时,TCP把收到的数据放入缓存,上层的应用进程在合适的时候读取缓存中的数据。

    5)   面向字节流。首先“流”是指流入到进程或从进程流出的字节序列。面向字节流的含义是:虽然应用程序和TCP的交互式一次一个数据块,但是TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流,TCP并不知道所传送的字节流的含义。
    TCP不保证接收方应用程序所接收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系,但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。且接收方的应用程序必须有能力识别收到的字节流,把它还原成有意义的应用层数据。

    TCP和UDP在发送报文时所采用的方式完全不同,TCP并不关心应用进程一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥塞程序决定一个报文段应该包含多少个字节。如果数据块太长,TCP就会把它划分短一些再发,如果数据块太短,TCP就会等待累积有足够多的字节后再构成报文段发送出去。

     2.   连接

    TCP把连接作为最基本的抽象,TCP的许多特性都是基于这个基本特性的。前面说过,每一条TCP连接都有两个端点,TCP连接的端点是什么?不是主机、不是主机的IP地址、不是应用进程、也不是运输层的协议端口,TCP连接的端点叫套接字(socket)或插口。根据RFC793定义:端口号拼接到IP地址即构成了套接字,因此套接字的表示方法是在点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开:

    套接字socket=(IP地址:端口号)或(IP地址,端口号)

    每一条TCP连接唯一地被通信两端的两个端点所确定,即:

    TCP连接::={socket1,socket2}={(IP1:Port1),(IP2:Port2)}

    TCP连接的端点是个很抽象的套接字,同一个IP地址可以有多个不同的TCP连接,而同一个端口号也可以出现多个不同的TCP连接中。

     

    TCP之可靠传输的原理

    当TCP发送报文段给IP层传送时,IP层只是提供尽最大努力交付,TCP下面的网络提供的是不可靠传输,因此TCP必须采用适当的措施才能使两个运输层之间的通信变得可靠。理想的传输条件有以下两个特点:

    1)   传输信道不产生差错。

    2)   不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据。

    在这样的理想传输条件下,不需要采取任何措施就能够实现可靠传输。然而实际的网络都不具备以上两个理想条件,但是可以使用一些可靠传输协议,当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速度,这样本来不可靠的传输信道就能够实现可靠传输了。

    停止等待协议

    TCP是全双工通信方式,即通信双方既是发送方也是接收方,但是为了讨论问题方便,仅考虑A发送数据,B接收数据并发送确认,因此A叫发送方,B叫接收方,传送的数据单元称为分组。停止等待就是每发送完一个分组就停止发送,等待对方的确认,在收到确认后再发送下一个分组。以下从四个方面分析停止等待协议的工作原理和优缺点。

    1.   无差错情况

        

    无差错情况如上图所示,表示A发送分组,在等待期限内必能收到B的确认,即不中不会发生差错。

     2.   出现差错

         

    出现差错如上图所示,B接收分组M1时检测出了差错,就丢弃M1,其他什么也不做;M1也有可能在传输过程中丢失,这时B什么也不知道,这两种情况下,B不会发送任何信息告知A。可靠传输协议规定:发送方只要超过一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组,即超时重传。要实现超时重传,就要在每发送完一个分组时设置一个超时计时器,如果在超时计时器到期之前收到接收方的确认,就撤销已设置的超时计时器。发送分组需要遵守以下三点:

    a)   在发送完一个分组后,必须暂时保留已发送的分组的副本(在发送超时重传时使用),只有在收到相应的确认后才能清除暂时保留的分组副本。

    b)   分组和确认分组都必须进行编号,这样才能明确是哪一个发送出去的分组收到了确认,而哪一个分组还没有收到确认。

    c)   超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。太长了通信效率就很低,太短了就会产生不必要的重传浪费网络资源。

    3.   确认丢失和确认迟到

     a)   确认丢失

          

      确认丢失如上图所示,B发送的确认丢失了,或者A在设定的超时重传时间内没有收到确认,A无法知道分组是出错了、丢失了、还是B发送的确认丢失了,因此A在超时计时器到期后就要重传分组。现在假定B又收到了重传的分组,需要执行的动作:

           i.     丢弃这个重复的分组M1,不向上层交付

          ii.     向A发送确认,不能认为已经发送过确认就不再发送确认,A之所以重传M1就表示A没有收到对M1的确认。

     b)   确认迟到

          

     确认迟到如上图所示,表示传输过程中没有出现差错,但B对分组M1的确认迟到了,A会收到重复的确认。这时A和B的处理方法很简单:A收下后就丢弃;B收到重传的M1同样丢弃,但是要发送重传确认。

    按照上述逻辑就出现了死循环逻辑,通常处理方法是:如果A不断重传分组,但总是收不到确认,就说明通信线路太差,不能进行通信。

    通过以上确认和重传机制,就可以在不可靠的传输网络上实现可靠的通信。这种可靠传输通信称为自动重传请求ARQ(Automatic Repeat Request),表示重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。

     4.   信道利用率

     停止等待协议简单的实现了可靠传输,但是它对信道的利用率太低。为了提高传输效率,发送方可以不使用低效率的停止等待协议,而采用流水线传输,流水线传输就是发送方可以连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认,这样可使信道上一直有数据不间断地在传送,显然可以提高对信道的利用率。也就是连续ARQ协议和滑动窗口协议。

     

    连续ARQ协议

    连续ARQ协议表示发送方维持了一个发送窗口,位于发送窗口内的分组可以连续发送出去,而不需要等待对方的确认。如下图:

         

    连续ARQ协议规定:发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。接收方一般都采用累计确认的方式,即接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认,表示到这个分组为止的所有分组都已正确收到了。

    累计确认的有点:容易实现,及时确认丢失也不必重传;缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。当通信线路质量不好的时候,连续ARQ协议会带来较大的负面影响。

     

    TCP报文段的首部格式

    TCP虽然是面向字节流的,但是TCP传送的数据单元却是报文段。而TCP的全部功能都体现在它首部中各字段的作用,因此只有弄清楚TCP首部各字段的作用才能掌握TCP的工作原理。

    TCP报文段首部的前20个字节是固定的,后面是4n字节可以根据需要而增加的选项,选项的最大值是40字节,所以TCP报文段首部最小值是20字节,最大值是60字节。

         

    1)   源端口和目的端口,各占2个字节,分别为源端口号和目的端口号。和UDP的分用相似,TCP的分用功能也是通过端口实现的。

    2)   序号,占4字节,序号范围:[0,232-1],供232(4 294 967 296)个序号。序号增加到最大值后,下一个序号就又回到0。
    TCP是面向字节流的,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置,首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号。
    例如:一个报文段的序号字段值是301,而携带的数据共有100字节。分析:本报文段的数据的第一个字节的序号是301,最后一个字节的序号是400,显然下一个报文段的数据序号应当从401开始。

    3)   确认号,占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。
    例如:B正确收到A发送过来的一个报文段,其序号字段值是301,而数据长度是100字节,这表明B正确收到了A发送的到序号400为止的数据。因此B期望收到A的下一个数据序号是401,于是B在发送给A的确认报文段中把确认号置为401。

    若确认号=N,则表明:到序号N-1为止的所有数据都已正确收到。

    4)   数据偏移,占4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,其实际指TCP报文段的首部长度。由于首部中存在长度不确定的选项字段,因此此字段是必须的。

    5)   保留,占6位,保留为今后使用,但目前应置为0。

    6)   紧急URG(URGent),当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送,而不要按原来的排队顺序来传送。过程:发送应用进程告诉发送方的TCP有紧急数据要传送,于是发送方TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍然是普通数据。

    7)   确认ACK(ACKnowledgment),仅当ACK=1时确认号字段才有效,当ACK=0时确认号无效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置1。

    8)   推送PSH(Push),当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。这种情况下,TCP就可以使用推送操作,这时,发送方TCP把PSH置1,并立即创建一个报文段发送出去;接收方TCP收到PSH=1的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满后再向上交付。
    虽然应用程序可以选择推送操作,但推送操作很少使用。

    9)   复位RST(Reset),当RST=1时,表明TCP连接中出现严重差错(如主机崩溃等原因),必须释放连接,然后再重新建立运输连接。RST置1还用来拒绝一个非法的报文段或拒绝打开一个连接。RST也可称为重建位或重置位。

    10)  同步SYN(Synchronization),在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使用SYN=1和ACK=1,因此SYN置为1就表示这是一个连接请求或连接接收报文。

    11)  终止FIN(Finish),用来释放一个连接,当FIN=1时,表示此报文段的发送方的数据已发送完毕,并要求释放运输连接。

    12)  窗口,占2字节,窗口值:[0,216-1]之间的整数。窗口指的是发送本报文段的一方的接收窗口,而不是自己的发送窗口。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。之所有要有这个限制,因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。
    例如:发送一个报文段,其确认号是701,窗口字段是1000。这就告诉对方:从701号算起,我(即发送此报文段的一方)的接收缓存空间还可以接收1000个字节数据,你在给我发送数据时,必须考虑到这一点。

    窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化着。

    13)  检验和,占2字节,检验和字段检验的范围包括首部和数据两部分。和UDP一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用IPv6,则相应的伪首部也要改变。

    14)  紧急指针,占2字节,紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。因此紧急指针指出了紧急数据的末尾在报文段中的位置,当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。即使窗口为零时也可发送紧急数据。

    15)  选项,长度可变,最长可达40字节。当没有使用选项时,TCP的首部长度是20字节。

    a)   最大报文段长度MSS(Maximum Segment Size)选项,表示每一个TCP报文段中的数据字段的最大长度。

    b)   窗口扩大选项,它是为了扩大窗口,TCP首部的窗口字段长度是16位,最大的窗口大小为64K字节,对于现代网络通信,如果要获得高吞吐率需要更大的窗口大小。
    它占3字节,其中有一个字节表示移位值S,新的窗口值等于TCP首部中的窗口位数从16增大到(16+S),移位值允许使用的最大值是14,相当于窗口最大值增大到2(16+14)-1=230-1
    它可以在双方初始建立TCP连接时进行协商。如果连接的某一端实现了窗口扩大,当它不再需要扩大其窗口时,可发送S=0的选项,使窗口大小回到16。

    c)   时间戳选项,占10字节,其中最主要的字段是时间戳值字段(4字节)时间戳回送回答字段(4字节),它有以下两个功能:

             i.      用来计算往返时间RTT。发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段值复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确地计算出RTT来。

     ii.      用于处理TCP序号超过232的情况,又称为防止序号绕回PAWS(Protect Against Wrapped Squence numbers)。TCP报文段的序号只有32位,而每增加232个序号就会重复使用原来用过的序号。当使用高速网络时,在一次TCP连接的数据传送中序号很可能会被重复使用。为了使接收方能够把新的报文段和迟到很久的报文段区分开,可以在报文段中加上这种时间戳。

    d)   选择确认(SACK)选项,后续解读。

     

    TCP之可靠传输的实现

    TCP的滑动窗口是以字节为单位,为了更好的表述实现过程,以下内容假定:数据传输只在一个方向进行。

    以字节为单位的滑动窗口

    本节内容以场景案例为主分析解读,然后再概括总结。

     1.  A收到B发来的确认报文段,A发送数据给B

       

    以图中的内容为例,解读图形:假定A收到B发来的确认报文段,其中窗口是20字节,确认号是31,A构造出了上图结构。发送窗口后沿的后面部分表示已发送且确认,不需要保留;发送窗口前沿的前面部分表示不允许发送,因为接收方还不知道有这部分数据。

    根据A的发送窗口解析,发送窗口表示在没有收到B的确认情况下,A可以连续把窗口内的数据都发送出去,并且凡是发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。

    发送窗口里的序号表示允许发送的序号,从图中可知,窗口越大,发送方在收到对方确认之前连续发送更多的数据,进而获得更高的传输效率。然而发送方的窗口值受接收方影响,接收方会发送自己的接收窗口数值在窗口字段中给对方,因此A的发送窗口一定不能超过B的接收窗口数值。此外发送方的发送窗口大小还要受到当时网络拥堵程度的制约。

    发送窗口的位置由窗口前沿和后沿的位置共同确定。发送窗口后沿有两种变化情况:不动 (没有收到新的确认)和 前移(收到新的确认),因为数据已经发送并确认,所以发送窗口不可能后移。发送窗口前沿是不断向前移动的,但也有可能不动,原因有二:一没有收到新的确认,对方通知的窗口大小也不变;二是收到新的确认但对方通知的窗口缩小了,使得发送窗口前沿正好不动。

    发送窗口前沿也有可能向后收缩,这发生在对方通知的窗口缩小了,但TCP的标准强烈不赞成这样做,这会产生一些错误。

     2.  A已发送B未确认,B接收的数据未按序到达

        

      发送方:A发送了序号31到41的数据,发送窗口位置未变化。此时使用三个指针描述A的发送窗口状态

    1)   小于P1:已发送并已收到确认的部分

    2)   P3-P1:A的发送窗口

    3)   P2-P1:已发送但尚未收到确认的字节数

    4)   P3-P2:允许发送但当前尚未发送的字节数(又称可用窗口或有效窗口)

    5)   大于P3:不允许发送的部分

    接收方:B的接收窗口大小是20,接收窗口外部:序号到30为止的数据已经发送确认,并已经交付主机,B不再保留这些数据。接收窗口内部:序号31到50允许接收,如图所示,B收到了序号为32和33的数据,但这些数据没有按序到达,因为序号为31的数据没有收到。此时,B只能对按序收到的数据中的最高序号给出确认,因此B发送的确认报文段中的确认号是31,而不是32或33。

     3.  A接收到B的确认,A可用窗口增大

        

    假定B收到了序号为31的数据,并把序号为31到33的数据交付主机,然后删除这些数据,接着把接收窗口向前移动3个序号,同时给A发送确认,其中窗口值仍为20,但是确认号变成34。

    这时候表明B已经收到了到序号33为止的数据,从图中可知B还收到了序号为37、38和40的数据,但这些都没有按序到达,只能先暂存在接收窗口中。

    A收到B的确认后,就可以把发送窗口向前滑动3个序号,但指针P2不动,那么现在A的可用窗口就增大了,可以发送序号范围是42到53。

     4.  A全部发送,B全部接收,确认在网络中滞留

        

     A继续发送完序号42到53的数据后,指针P2向前移动和P3重合,表示发送窗口内的序号都已用完,但是还没有收到确认。

    由于A的发送窗口已满,必须停止发送,但此时存在以下可能性,就是发送窗口内所有的数据都已正确到达B,B也早已发出了确认,但不幸的是所有这些确认都滞留在网络中。

    在没有收到B的确认之前,A为了保证可靠传输,A只能认为B还没有收到这些数据,于是当A的超时计时器到期时就要重传这部分数据,重新设置超时计时器,直到收到B的确认为止。

    如果A收到确认号落在发送窗口内,那么A就可以使发送窗口继续向前滑动,并发送新的数据。

    5.   A和B的缓存作用

    a)   发送缓存和发送窗口

    发送缓存用来暂时存放以下两种数据:一发送应用程序传送给发送方TCP准备发送的数据,二TCP已发送出去但尚未收到确认的数据。

    发送窗口通常只是发送缓存的一部分,已被确认的数据应当从发送缓存中删除,因此发送缓存和发送窗口的后沿是重合的。

    发送应用程序最后写入发送缓存的字节减去最后被确认的字节,就是还保留在发送缓存中的被写入的字节数。

    发送应用程序必须控制写入缓存的速率,不能太快,否则发送缓存就没有存放数据的空间。

    b)   接收缓存和接收窗口

    接收缓存用来暂时存在以下两种数据:一按序到达的、但尚未被接收应用程序读取的数据,二未按序到达的数据。

    如果收到的分组被检测出有差错,则要丢弃。如果接收应用程序来不及读取收到的数据,接收缓存最终会被填满,使接收窗口减小到零。

    如果接收应用程序能够及时从接收缓存中读取收到的数据,接收窗口就可以增大,但最大不能超过接收缓存的大小。

     6.   概述总结

    综合上述场景案例的分析过程,可以确定以下三点事项

    a)   虽然A的发送窗口是根据B的接收窗口设置的,但在同一时刻,A的发送窗口并不总是和B的接收窗口一样大。因为通过网络传送窗口值需要经历一定的时间滞后。

    b)   对于不按序到达的数据应如何处理,TCP标准并无明确规定。如果接收方把不按序到达的数据一律丢弃,那么接收窗口的管理将会比较简单,但这样做对网络资源的利用不利。因此TCP通常对不按序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,在按序交付上层的应用进程。

    c)   TCP要求接收方必须有累计确认的功能,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。但是需要注意两点:一是接收方不应过分推迟发送确认,否则会导致发送方不必要的重传,结果反而浪费了网络的资源。TCP标准规定,确认推迟的时间不应超过0.5秒,若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认。二是捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。

     

     超时重传时间的选择

    1.   问题

    TCP的发送方在规定的时间内没有收到确认就要重传已发送的报文段,重传的概念很简单,但是重传时间的计算却是非常复杂的问题。因为TCP的下层是互联网环境,发送的报文段可能只经过一个高速率的局域网,也可能经过多个低速率的网络,并且每个IP数据报所选择的路由还可能不同,这样一来重传时间的设定就是个大问题了。设置太长网络空间利用率不足,降低传输效率;设置太短势必造成许多报文段不必要的重传,网络符合增大。

     2.   方案

    TCP采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间,这两个时间之差就是报文段的往返时间RTT。TCP保留一个RTT的一个加权平均往返时间RTTs,因为进行了加权平均,所以得出的结果更加平滑。

    每当第一次测量到RTT样本时,RTTs值就取为所测量到的RTT样本值。但以后每测量到一个新的RTT样本,就按照公式重新计算一次RTTs:

    新的RTTs = (1-α)×(旧的RTTs)+α×(新的RTT样本)

    公式中,0≤α(阿尔法)<1。若α很接近于0,表示新的RTTs值和旧的RTTs值相比变化不大,对新的RTT样本影响不大(RTT值更新较慢)。若α接近于1,表示新的RTTs值受新的RTT样本影响较大(RTT值更新较快)。RFC6298推荐的α值为1/8,即0.125。

    显然超时计时器设置的超时重传时间RTO应略大于上面得出的加权平均往返时间RTTs,RTO的计算公式如下:

    RTO = RTTs + 4×RTTd

    RTTd是RTT的偏差的加权平均值,它与RTTs和新的RTT样本之差有关。当第一次测量时,RTTd值取为测量到的RTT样本值的一半,在以后的测量中,使用公式计算加权平均的RTTd:

    新的RTTd = (1-β)×(旧的RTTd)+β×|RTTs – 新的RTT样本|

    β是小于1的系数,推荐值是1/4,即0.25。

     3.   案例

        

    如图所示,发送出一个报文段,设定的重传时间到了,还没有收到确认,于是重传报文段。经过了一段时间后,收到了确认报文段。现在的问题是:如何判定此确定报文段是对先发送的报文段的确认,还是对后来重传的报文段的确认?由于重传的报文段和原来的报文段完全一样,源主机在收到确认后是无法做出正确判断的,而正确的判断对确定加权平均RTTs的值关系很大。

    分析1:若收到的确认是对重传报文段的确认,但却被源主机当成是对原来的报文段的确认,则这样计算出的RTTs和超时重传时间RTO就会偏大。若后面再发送的报文段又是经过重传后才收到确认报文段,那么按照此方法得出的超时重传时间RTO就越来越长。

    分析2:若收到的确认是对原来的报文段的确认,但被当成是对重传报文段的确认,则由此计算出的RTTs和RTO都会缩小,必然导致报文段过多的重传,这样就有可能使RTO越来越短。

    根据分析1和分析2,Karn提出了一个算法:在计算加权平均RTTs时,只要报文段重传了,就不采用其往返时间样本,这样得出的加权平均RTTs和RTO就较准确。不过如果采用这种算法就又引发新的问题,假设现实情况就是:报文段的时延突然增大了很多,在原来的重传时间内就是不会收到确认报文段。这样不考虑重传报文段的往返时间样本计算,超时重传时间就无法更新。

    因此要对Karn算法进行修正:报文段每重传一次,就把超时重传时间RTO增大一些,典型做法是取新的重传时间为旧的重传时间的2倍,当不再发生报文段的重传时,才根据上述公式计算超时重传时间,实践证明这种策略较为合理。

     

    选择确认SACK

    1.   问题

    若接收方收到的报文段无差错,只是未按序号到达,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达的数据?可以的,就是使用“选择确认(Selective ACK)”。

    2.   方案

    回过头来看看TCP的首部,没有哪一个字段能够提供SACK功能,如果要使用选择确认SACK,那么在建立TCP连接时,就要在TCP首部的选项中加上“允许SACK”的 选项,而双方必须都事先商定好。

    使用SACK选项,原来首部中的“确认号字段”的用法仍然不变,只是以后在TCP报文段的首部中都增加SACK选项,以便报告收到的不连续的字节块的边界。

    由于首部选项的长度最多只有40字节,而指明一个边界就要用掉4字节(序号有32位=4字节),因此在选项中最多只能指明4个字节块的边界信息,因为4个字节块共有8个边界,需要用32个字节来描述。

    另外还需要两个字节,一个字节用来指明是SACK选项,另一个字节是指明这个选项要占用多少字节。如果要报告5个字节块的边界信息,那么至少需要42个字节,这就超过了选项长度的40字节的上限。

    除上述内容所占字节之外,互联网建议标准RFC2018还对报告这些边界信息的格式做出了非常明确的规定。

    3.   结论

    由于SACK文档并没有指明发送方应当怎么响应SACK,因此大多数的实现还是重传所有未被确认的数据块。

     

    TCP之流量控制

    利用滑动窗口实现流量控制

    按常理说数据传输越快越好,但是如果发送方把数据发送的过快,接收方就可能来不及接收,这就会造成数据的丢失。所谓的流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。以下内容将结合图形分析滑动窗口机制如何进行流量控制:

        

    1)   A和B在连接建立时,B告诉A:我的接收窗口rwnd=400。

    因此,发送方的发送窗口不能超过接收方给出的接收窗口的数值(TCP的窗口单位是字节,不是报文段),TCP连接建立时窗口协商过程没有显示出来。
    假设每个报文段为100字节长,而数据报文段序号的初始值为1。Seq表示序号,ACK表示确认位,ack表示确认字段的值。

    2)   A发送序号从1到100的字节,此时发送窗口从400减小到300。

    3)   接着A发送序号从101到200的字节,此时发送窗口从300减小到200。

    4)   接着A发送序号从201到300的字节,此时发送窗口从200减小到100。

    5)   此刻,B发送的确认报文段到来,确认号ack=201,说明1到200的数据都已经接收到了,但是201到300的数据丢失了。接收窗口值rwnd=300,说明还可以接收300个字节,此时又能说明有100个字节已经交付B的应用进程了。

    6)   A继续发送序号从301到400的字节,上一步发送窗口从100增大到300,此时发送窗口从300减小到200。

    7)   A继续发送序号从401到500的字节,此时发送窗口从200减小到100。

    8)   接下来,A开始发送超时重传的数据,即201到300,此时发送窗口从100减小到0。由于A的发送窗口减小到0,所以不能发送任何数据。

    9)   此刻,B发送的确认报文段到来,确认号ack=501,说明从201到500的数据都已经接收到了。接收窗口值rwnd=100,说明还可以接收100个字节,此时又能说明有100个字节已经交付B的应用进程了。

    10)  A继续发送序号从501到600的字节,上一步发送窗口从0增大到100,此时发送窗口从100减小到0。由于A的发送窗口减小到0,所以不能发送任何数据。

    11)  此刻,B发送的确认报文段到来,确认号ack=601,说明从501到600的数据都已经接收到了。接收窗口值rwnd=0,说明A不允许再发送任何数据了。

    经过上述过程分析,已经发现了一个棘手的问题,就是第二次确认的时候,A没有接收到B发送的确认报文段。这就造成A一直等待B发送的非零窗口的通知,B也一直等待A发送的数据,如果没有处理措施,这种互相等待的死锁局面就会一直延续下去。

    为例解决这个问题,TCP为每一个连接设有一个持续计时器。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器,若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出现在的窗口值;若窗口仍然是零,那么收到这个报文段的一方就重新设置持续计时器;若窗口不是零,死锁的僵局就可以打破了。

     

    TCP的传输效率

    TCP是由首部和数据部分组成,而且首部的固定部分长度是20字节,IP层的首部固定长度也是20字节,加一起就是40字节。如果TCP发送报文段的数据部分的长度只有几个字节,那么相比起来传输效率就非常低下。

    应用进程把数据传送到TCP的发送缓存后,剩下的发送任务就由TCP来控制,可以用不同的机制来控制TCP报文段的发送时机。第一种机制是TCP维持一个变量,它等于最大报文段长度MSS,只要缓存中存放的数据达到MSS字节时,就组装成一个TCP报文段发送出去。第二种机制是由发送方的应用进程指明要求发送报文段,即TCP支持的推送操作。第三种机制是发送方的一个计时器期限到了,这是就把当前已有的缓存数据装入报文段(长度不能超过MSS)发送出去。那么又该如何控制TCP发送报文段的时机呢?

    在TCP的实现中广泛使用Nagle算法。算法如下:若发送应用进程把要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字节的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。Nagle算法还规定:当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段,这样做就可以有效地提高网络的吞吐量。

    另外一个问题叫做糊涂窗口综合征,有时也会使TCP的性能变坏。设想,TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1个字节,然后向发送方发送确认,并把窗口设置为1个字节。接着发送方又发来1个字节的数据,接收方发回确认,仍然将窗口设置为1个字节。这样进行下去,就会造成网络的传输效率很低。

    要解决这个问题,可以让接收方等待一段时间,使得接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,二是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。

    上述两种方法配合使用,可以提升TCP的传输效率,使得在发送方不发送很小的报文段,同时接收方也不要在缓存刚有一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。

     

    TCP之拥塞控制

    首先说明拥塞控制和流量控制的区别,经过上一节的内容分析,可以把流量控制当作端对端模式,即1:1;而拥塞控制就是太多请求都去请求一个资源,太拥挤了,即1:N,这样是不是就容易理解两者的差别了。

    拥塞控制的一般原理

    在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源,在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这就叫拥塞。公式:

    对资源的需求 > 可用资源

    有时候我们可以通过增加可用资源的方式应对需求,但是造成网络拥塞的因素很多,有时单凭增加可用资源也并不能解决拥塞问题。所以需要寻找和设计一套拥塞控制方案,不使提供服务的主机因负载过重造成拥塞,甚至造成死锁、宕机。

    实践证明,拥塞控制是很难设计的,因为它是一个动态的问题。当前网络正朝着高速化的方向发展,这很容易出现缓存不够大而造成分组的丢失,但分组的丢失是网络发生拥塞的征兆而不是原因。在许多情况下,甚至正是拥塞控制机制本身为引起网络性能恶化甚至发生死锁的原因。

    由于计算机网络是一个很复杂的系统,因此可以从控制理论的角度来看拥塞控制这个问题。从大的方面分为开环控制和闭环控制两种方法:

    1)   开环控制就是在设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞,但一旦整个系统运行起来,就不在中途进行改正了。

    2)   闭环控制是基于反馈环路的概念,主要有以下几种措施:

    a)   监测网络系统以便检测到拥塞在何时、何处发生。

    b)   把拥塞发生的信息传送到可采取行动的地方。

    c)   调整网络系统的运行以解决出现的问题。

    TCP的拥塞控制方法

    TCP进行拥塞控制的算法有四种,即慢开始(slow-start)拥塞避免(Congestion avoidance)快重传(fast retransmit)快恢复(fast recovery)。为了集中精力说明这些算法和拥塞控制,现在假定:一数据是单方向传送的,对方只传送确认报文;二接收方总是有足够的的缓存空间,因而发送窗口的大小由网络的拥塞程度决定。

     1.   过程分析

     a)   拥塞分析

    拥塞控制也叫做基于窗口的拥塞控制,为此发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化,发送方让自己的发送窗口等于拥塞窗口。

    发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。

    发送方如何知道网络发生拥塞呢?当网络发生拥塞时,路由器就要丢弃分组,因此只要发送方没有按时收到应当到达的确认报文,也就是说只要出现了超时,就可以认为网络可能出现了拥塞。现在通信线路的传输质量一般都很好,因传输出差错而丢弃分组的概率很小,因此,判断网络拥塞的依据就是出现了超时。

    b)   算法分解

           i.     慢开始

    慢开始算法思路:当主机开始发送数据时,由于并不清楚网络的负荷情况,所以如果立刻把大量数据字节注入到网络,那么就有可能引起网络发生拥塞。经过证明,较好的方式是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。按照规定:初始拥塞窗口cwnd设置为不超过2至4个最大报文段SMSS(Sender Maximum Segment Size)的数据值,具体规定如下:

    1)   若SMSS > 2190字节,则设置初始拥塞窗口cwnd=2×SMSS字节,且不得超过2个报文段。

    2)   若SMSS > 1095字节且SMSS≤2190字节,则设置初始拥塞窗口cwnd=3×SMSS字节,且不得超过3个报文段。

    3)   若SMSS ≤ 1095字节,则设置初始拥塞窗口cwnd=4×SMSS字节,且不得超过4个报文段。

    慢开始规定,在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个SMSS的数值,公式如下:

    拥塞窗口cwnd每次的增加量 = min(N,SMSS)

    其中N是原先未被确认的,但现在被刚收到的确认报文段所确认的字节数,当N < SMSS时,拥塞窗口每次的增加量要小于SMSS。用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。

    之所以叫慢开始,是因为TCP开始发送报文段时,先设置cwnd=1(为方便叙述用报文段的个数作为窗口大小的单位,实际窗口大小的单位还是字节),使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大cwnd。这样操作比一下子设置个大的cwnd值,把许多报文段注入网络中要慢的多。

    为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量,慢开始门限ssthresh的用法如下:

    1)   当cwnd < ssthresh时,使用慢开始算法。

    2)   当cwnd > ssthresh时,停止使用慢开始算法,而改用拥塞避免算法。

    3)   当cwnd = ssthresh时,既可使用慢开始算法,也可使用拥塞避免算法。

          ii.     拥塞避免

    拥塞避免算法思路:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是像慢开始算法那样加倍增长。因此拥塞避免算法就有“加法增大”特点,拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增加速率缓慢很多。

         iii.     快重传

    快重传算法思路:让发送方尽早知道发生了个别报文段的丢失信息,它要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。它要求发送方只要一连收到3个重复确认,就知道接收方确实没有收到报文段M,应当立即进行重传。这样就不会出现超时,发送方也就不会误认为出现了网络拥塞,使用快重传可以使整个网络的吞吐量提高约20%。

          iv.     快恢复

    快恢复算法思路:它是相对于慢开始来说的,即发送方知道了只是丢失了个别的报文段,不启动慢开始,而执行快恢复算法逻辑:发送方同时设置

    新的拥塞窗口cwnd = 门限值 = 拥塞窗口cwnd/2

            然后执行拥塞避免算法。

             

                 通过对上述四种拥塞算法的解读,以下将会结合上图案例将四种算法演绎一遍。在上图中,已标明:ssthresh=16,当TCP连接进行初始化时,把拥塞窗口cwnd设置为1。

    首先执行慢开始算法,发送方每收到一个对新报文段的确认ACK,就把拥塞窗口值叠加,然后开始下一轮的传输,因此拥塞窗口cwnd随着传输轮次按指数规律增长

    当拥塞窗口cwnd增长到慢开始门限值ssthread时(图中的点1),就改为执行拥塞避免算法,拥塞窗口按线性规律增长

    当拥塞窗口cwnd=24时,网络出现超时(图中的点2),发送方判断为网络拥塞。于是调整门限值ssthresh=cwnd/2=12,同时设置拥塞窗口cwnd=1,进入慢开始阶段。

    当拥塞窗口按照慢开始算法cwnd = ssthresh = 12时(图中的点3),改为执行拥塞避免算法。

    当拥塞窗口cwnd=16时(图中的点4),发送方一连收到3个对同一个报文段的重复确认(图中记为3-ACK),这时候就执行快重传算法。

    同时发送方执行快恢复算法,发送方调整门限值和拥塞窗口=原拥塞窗口cwnd/2=8,并执行拥塞避免算法。

    2.   结论概述

     采用上述拥塞控制方法使得TCP的性能有明显的改进。在上述内容中假定了接收方总是有足够大的缓存空间,因而发送窗口的大小由网络的拥塞程度来决定。但实际上接收方的缓存空间总是有限的,接收方根据自己的接收能力设定接收方窗口rwnd,并把这个窗口值写入TCP首部中的窗口字段,传送给发送方,因此接收方窗口又称为通知窗口。现在从接收方对发送方的流量控制的角度考虑,发送方的发送窗口一定不能超过对方给出的接收方窗口值rwnd。

    如果综合考虑拥塞控制和接收方对发送方的流量控制,那么发送方的窗口的上限值应当取为接收方窗口rwnd和拥塞窗口cwnd两者较小的一个,即:

    发送方窗口的上限值 = Min[rwnd,cwnd]

     

     主动队列管理AQM

    以上内容并没有和网络层采取的策略联系起来,其实它们之间有着密切的关系。网络层策略对TCP拥塞控制影响最大的就是路由器的分组丢弃策略,路由器的队列通常都是按照“先进先出”的规则处理到来的分组,由于队列长度总是有限的,因此当队列已满时,以后再到达的所有分组将都被丢弃,这叫尾部丢弃策略

    路由器的尾部丢弃往往会导致一连串分组的丢失,这就是发送方出现超时重传,使TCP进入拥塞控制的慢开始状态,实际上网络并没有发生拥塞。在网络中很多TCP连接中的报文段通常是复用在网络层的IP数据报中传送,若在这种情况下发生路由器的尾部丢弃,就会同时影响很多条TCP连接,使它们同时进入慢开始状态,这种情况称为全局同步

    全局同步使得全网的通信量突然下降很多,网络恢复正常后,通信量又突然增大很多。为了避免发生网络中的全局同步现象,在1998年提出主动队列管理AQM(Active Queue Management)。所谓“主动”就是不要等到路由器的队列长度已经达到最大值时才不得不丢弃后面到达的分组,这样就太被动了;应当在队列长度达到某个值的警惕数值时就主动丢弃到达的分组,这样就提醒发送方放慢发送的速率,因而有可能使网络拥塞的程度减轻,甚至不出现网络拥塞。

    AQM的实现方式有多种方法,其中曾流行多年的就是随机早期检测RED(Random Early Detection),实现RED时需要使路由器维持两个参数,即队列长度最小门限最大门限,当每一个分组到达时,RED就按照规定的算法先计算当前的平均队列长度。

    1)   若平均队列长度小于最小门限,则把新到达的分组放入队列进行排队。

    2)   若平均队列长度超过最大门限,则把新达到的分组丢弃。

    3)   若平均队列长度在最小门限和最大门限之间,则按照某一丢弃概率p把新达到的分组丢弃,即随机丢弃。

    由此可见,RED不是等到已经发生网络拥塞后才把所有在队列尾部的分组全部丢弃,而是在检测到网络拥塞的早期征兆时,按照概率p随机丢弃,避免了发生全局性的拥塞控制。

    不过在RED的操作中,最难处理的就是丢弃概率p,因为它不是一个常数。而今经过多年的实践证明,RED的使用效果并不太理想,因此IETF就不再推荐使用RED。虽然如此,但是对路由器进行主动队列管理AQM仍是必要的。

     

    TCP之连接管理

    TCP是面向连接的协议,连接是用来传送TCP报文的,连接管理分为三阶段:连接建立、数据传送和连接释放。在TCP连接建立过程中要解决三个问题:

      1. 要使每一方能够确知对方的存在。
      2. 要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)。
      3. 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。

    TCP连接的建立采用客户-服务器方式,主动发起连接建立的应用进程叫客户Client,而被动等待连接建立的应用进程叫服务器Server

    TCP的连接建立

    TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段,具体过程将结合下图分解:

        

    假定主机A运行TCP客户程序,主机B运行TCP服务器程序。最初两端TCP进程都处于CLOSED(关闭)状态,图片中A主动打开连接,B被动打开连接。

    1)   创建TCB传输控制块

    a)   A的TCP客户进程创建传输控制模块TCB。

    b)   B的TCP服务器进程创建传输控制模块TCB。准备接收客户进程的连接请求,然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。

    2)   A主动建立TCP连接,向B发出连接请求报文段,然后TCP客户进程进入SYN-SENT(同步已发送)状态。TCP首部主要参数:

    a)   同步位SYN=1。TCP规定SYN=1不能携带数据,但要消耗掉一个序号

    b)   初始序号seq=x

    3)   B收到连接请求报文段后,如同意建立连接,向A发送确认,然后TCP服务器进程进入SYN-RCVD(同步收到)状态。TCP首部主要参数:

    a)   同步位SYN=1。这个报文段也不能携带数据,同样消耗掉一个序号。

    b)   确认位ACK=1

    c)   确认号ack=x+1

    d)   初始序号seq=y

    4)   A收到B的确认后,还要向B给出确认,TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。TCP首部主要参数:

    a)   确认位ACK=1。TCP规定ACK报文段可以携带数据,但如果不携带数据则不消耗序号。

    b)   确认号ack=y+1

    c)   序号seq=x+1

    5)   B接收到A的确认后,也进入ESTABLISHED(已建立连接)状态

    为什么A最后还要发送一次确认呢?主要防止“已失效的连接请求报文段突然传送到B,而产生错误”。

    已失效的连接请求报文段产生过程如下:A发出连接请求,但因连接请求报文丢失而未收到确认。于是A再重传一次连接请求,后来收到确认建立了连接,数据传输完毕后就释放连接。期间A共发送两个连接请求报文段,其中第一个丢失,第二个到达,没有产生已失效的连接请求报文段。

    现在假定出现一种异常情况,A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段,但是B收到此失效的连接请求报文段后,就误认为是A又发出一次新的连接请求,于是就向A发出确认报文段,同意建立连接,假定不采用报文握手,那么只要B发出确认,新的连接就建立了。

    由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据,但B却以为新的运输连接已经建立,并一直等待A发来的数据,结果B的许多资源就白白浪费了。所以要采用三次报文握手的办法,防止上述现象的发送,比如A不会向B的确认发出确认,B收不到确认,就知道A并没有要求建立连接。

    TCP的连接释放

        

    TCP连接释放的过程比连接建立要复杂,所以还是要结合图片中状态变化分解:

    1)   首先通信双方的TCP进程都处于ESTABLISHED状态

    2)   A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接,A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。TCP首部主要参数:

    a)   终止位FIN=1。TCP规定:FIN报文段即使不携带数据,也消耗一个序号。

    b)   序号seq=u。它等于前面已传送过的数据的最后一个字节的序号加1。

    3)   B的应用进程收到连接释放报文段后即发出确认,然后B进入CLOSE-WAIT(关闭等待)状态。TCP首部主要参数:

    a)   确认位ACK=1

    b)   确认号ack=u+1

    c)   序号seq=v。它等于B前面已传送过的数据的最后一个字节的序号加1。

    4)   TCP服务器进程通知高层应用进程:从A到B这个方向的连接释放了。这时TCP连接仅处于半关闭(half-close)状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收。也就是说从B到A这个方向的连接并未关闭。

    5)   A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。

    6)   若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。B进入LAST-ACK(最后确认)状态,等待A的确认。TCP首部主要参数:

    a)   终止位FIN=1

    b)   确认位ACK=1

    c)   确认号ack=u+1。B还必须重复上次已发送过的确认号

    d)   序号seq=w。在半关闭状态B可能又发送了一些数据。

    7)   A在收到B的连接释放报文段后,必须对此发出确认,然后A进入到TIME-WAIT(时间等待)状态。

    a)   确认位ACK=1

    b)   确认号ack=w+1

    c)   序号seq=u+1。TCP规定:前面发送过的FIN报文段要消耗一个序号。

    8)   B只要收到A发出的确认,就进入CLOSED状态。B在撤销相应的传输控制块TCB后,就结束了这次的TCP,B结束TCP连接的时间要早于A。

    9)   上述过程尚未结束。A的TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态。时间MSL叫做最长报文段寿命(Maximum Segment Lifetime),RFC793建议设为2分钟,但对于现在的网络2分钟可能太长了,因此TCP允许不同的实现可根据具体情况使用更小的MSL值。
    因此,当A进入到TIME-WAIT状态后,要经过4分钟才能进入到COLSED状态,才能开始建立下一个新的连接。
    当A撤销相应的传输控制块TCB后,就结束了这次的TCP连接。

    为什么A在TIME-WAIT状态必须等待2MSL的时间呢?

    a)   第一,为了保证A发送的最后一个ACK报文段能够到达B。
    这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都正常进入到CLOSED状态。
    如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段,这样B就无法按照正常步骤进入CLOSED状态。

    b)   第二,防止“已失效的连接请求报文段”出现。A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网格中消失。

    上述TCP连接释放过程是四次报文握手。除时间等待计时器外,TCP还设有一个保活计时器(keepalive timer)。假设有以下场景:

    客户已主动与服务器建立TCP连接,但是后来客户主机突然出现故障,显然服务器以后就不能再收到客户发来的数据,应当由措施使服务器不要再白白等待下去,这就要使用保活计时器。

    服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两小时,若两小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发送10个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭这个连接。

     

    TCP的有限状态机

    上述两节描述的不够直观,下图给出了TCP连接的各种状态间的关系,以及状态变迁过程,这样就更加清楚了:

         

      

    安全防控

    网络与通信的重点是了解计算机网络通信的过程,没有计划去解读网络安全防控方面的知识,所以就将安全防控的知识附加在本节中以示简要说明。

    攻击分析

    计算机网络通信面临两大类威胁:一被动攻击,二主动攻击。被动攻击是指攻击者从网络上窃听他人的通信内容,这类攻击通常被称为截获,攻击者只是观察和分析某一个协议数据单元PDU而不干扰信息流。即使这些数据对攻击者来说不易理解,他也可通过观察PDU的协议控制信息部分,了解正在通信的协议实体的地址和身份,研究PDU的长度和传输的频度,从而了解所交换的数据的某种性质。被动攻击还被称为流量分析(traffic analysis),战争年代,通过分析某处出现大量异常的通信量,往往可以发现敌方的指挥所的位置。

    主动攻击有以下几种最常见的方式:

      1. 篡改:攻击者故意篡改网络上传送的报文,也包括彻底中断传送的报文,甚至是把完全伪造的报文传送给接收方,所以有时也叫更改报文流。
      2. 恶意程序:它种类繁多,对网络安全威胁较大的主要有以下几种

    a)   计算机病毒(computer virus):一种会“传染”其他程序的程序,“传染”是通过修改其他程序来把自身或自己的变种复制进去而完成的。

    b)   计算机蠕虫(computer worm):一种通过网络的通信功能将自身从一个结点发送到另一个结点并自动启动运行的程序。

    c)   特洛伊木马(Trojan horse):一种程序,它执行的功能并非所声称的功能而是某种恶意功能。如一个编译程序除了执行编译任务以外,还把用户的源程序偷偷地复制下来,那么这种编译程序就是一种特洛伊木马。

    d)   逻辑炸弹(logic bomb):一种当运行环境满足某种特定条件时执行其他特殊功能的程序。如一个编辑程序,平时运行的很好,当系统时间为某一特定时间,它会删除系统中所有的文件。

    e)   后门入侵(backdoor knocking):是指利用系统实现中的漏洞通过网络入侵系统。就像一个盗贼在夜晚试图闯入民宅,如果房门有缺陷,盗贼就能乘虚而入。

    f)   流氓软件:一种未经用户允许就在用户计算机上安装运行并损害用户利益的软件,其典型特征是:强制安装、难以卸载、浏览器劫持、广告弹出、恶意收集用户信息、恶意卸载、恶意捆绑等等。现在流氓软件的泛滥程度已超过各种计算机病毒,称为互联网上最大的公害,它们的名字一半都很吸引人,因此要特别小心。

    3. 拒绝服务DoS(Denial of Service):指攻击者向互联网上的某个服务器不停地发送大量分组,使该服务器无法提供正常服务,甚至完全瘫痪。
    如果从互联网上的成百上千个网站集中攻击一个网站,则称为分布式拒绝服务DDos(Distributed Denial of Service),有时也称为网络带宽攻击连通性攻击

    4. 其他

    a)   交换机中毒:在使用以太网交换机的网络中,攻击者向某个以太网交换机发送大量的伪造源MAC地址的帧,以太网交换机收到这样的帧,就把这个假的源MAC地址写入交换表中。由于这种伪造的地址数量太大,很快就把交换表填满了,导致以太网交换机无法正常工作。

    对付被动攻击采用各种数据加密技术,而对付主动攻击,则需要加密技术与鉴别技术相结合。

    攻击方式

    1. SYN攻击:它属于DOS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。SYN攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上SYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。

    TCP在建立连接的时候要经过三次握手,SYN攻击就是在服务器确认要与客户端建立连接的时候,使其等不到客户端发送的确认引发的。

    2. DDos攻击:它是一种基于DoS的特殊形式的拒绝服务攻击,是一种分布的、协同的大规模攻击方式。单一的DoS攻击一般是采用一对一方式的,它利用网络协议和操作系统的一些缺陷,采用欺骗和伪装的策略来进行网络攻击,使网站服务器充斥大量要求回复的信息,消耗网络带宽或系统资源,导致网络或系统不胜负荷以至于瘫痪而停止提供正常的网络服务。与DoS攻击由单台主机发起攻击相比较,分布式拒绝服务攻击DDoS是借助数百、甚至数千台被入侵后安装了攻击进程的主机同时发起的集团行为。

    Dos攻击容易被抓到,而DDos攻击通过对源IP地址进行伪造,使得它的隐蔽性非常好,同时对攻击进行检测也非常困难,因此它成了非常难以防范的攻击。

    3. 中间人攻击:是一种由来已久的网络入侵手段,并且当今仍然有着广泛的发展空间,如SMB会话劫持、DNS欺骗等攻击都是典型的MITM攻击。简而言之,所谓的MITM攻击就是通过拦截正常的网络通信数据,并进行数据篡改和嗅探,而通信的双方却毫不知情。

    比如常见的中间人攻击,就是访问某个网站的网页时有各种广告,而这些广告并不是网站的拥有者投放的,而是数据在网络传输的中间有一台中间服务器干的,它将广告脚本添加到了原始的网页里。

    安全协议

      网络层的安全协议

    这部分内容主要包含几个对象:IPsec协议族、IP安全数据报、安全关联SA和安全关联SA管理涉及到的对象,按照这几个对象及其关系就比较容易理解了。网络层的安全协议的主要应用场景是VPN,即虚拟专用网,在网络层有意忽略掉了这部分内容,现在只从安全的角度简单了解一下。

    a)   IPsec协议族概述

    IPsec就是“IP安全(security)”的缩写,它不是一个单一协议,而是能够在IP层提供互联网通信安全的协议族。它不限定用户必须使用何种特定的加密和鉴别算法,实际上它是个框架,允许通信双方选择合适的算法和参数。为了保证互操作性,IPsec还包含了一套加密算法,所有IPsec的实现都必须使用。

    IP协议族中的协议可划分为三部分:

           i.     IP安全数据报格式的两个协议:鉴别首部AH(Authentication Header)协议和封装安全有效载荷ESP(Encapsulation Security Payload)协议

    1.   AH协议:提供源点鉴别和数据完整性,但不能保密。

    2.   ESP协议:提供源点鉴别、数据完整性和保密。

    3.   IPsec支持IPv4和IPv6:在IPv6中,AH和ESP都是扩展首部的一部分,ESP协议包含了AH协议的功能。

          ii.     有关加密算法的三个协议。

         iii.     互联网密钥交换IKE(Internet Key Exchange)协议

     使用ESP协议或AH协议的IP数据报称为IP安全数据报(或IPsec数据报),它有两种不同的工作方式:

            i.      运输方式(transport mode):它是在整个运输层报文段的前后分别添加若干控制信息,再加上IP首部,构成IP安全数据报。

           ii.      隧道方式(tunnel mode):它是在原始的IP数据报的前后分别添加若干控制信息,再加上新的IP首部,构成一个IP安全数据报。

    无论使用哪种方式,最后得出的IP安全数据报的IP首部都是不加密的。只有使用不加密的IP首部,互联网中的各个路由器才能识别IP首部中的有关信息,把IP安全数据报在不安全的互联网中进行转发,从源点安全地转发到终点。所谓“安全数据报”是指数据报的数据部分是经过加密的,并能够被鉴别的,目前使用最多的是隧道方式。

     b)   安全关联SA

    在发送IP安全数据报之前,在源实体和目的实体之间必须创建一条网络层的逻辑连接,即安全关联SA(Security Association),这样传统的互联网中无连接的网络层就变为了具有逻辑连接的一个层。安全关联是从源点到终点的单向连接,它能够提供安全服务,如果要进行双向安全通信,则两个方向都需要建立安全关联。

           i.     案例1:本地总部H1与外地分公司H2安全通信(路由器对路由器模式)

               

     过程分析如下:

        1. 总部主机H1发送给分公司主机H2的IP数据报,必须先经过总部的路由器R1
        2. 路由器R1安装有IPsec软件,经过IPsec的加密处理后,成为IP安全数据报。
        3. IP安全数据报经过互联网的转发,最后达到分公司的路由器R2。此处注意路由器R1和路由器R2已经构建了安全关联SA。
        4. 路由器R2对IP安全数据报解密,路由器R2安装有IPsec软件,还原出原始的IP数据报,传送给终点主机H2。

    从逻辑上看,IP安全数据报在安全关联SA上传送,就好像通过一个安全的隧道。如果总部主机H1和总部内的主机H3或互联网中其他服务器通信,会不会也将IP数据报变成IP安全数据报?答案:不需要。

           ii.     案例2:本地总部H1与出差员工主机H2安全通信(路由器对主机模式)

               

    过程分析如下:

    第一,  总部的路由器R1必须先与员工主机H2建立安全关联SA。当然员工主机H2必须事先安装IPsec软件。

    第二,  总部主机H1发送IP数据报给路由器R1。

    第三,  路由器R1使用IPsec软件加密后封装成IP安全数据报。

    第四,  IP安全数据报经过互联网转发,最后达到员工主机H2。

    第五,  主机H2使用IPsec软件解密还原成原始的IP数据报。

    建立安全关联SA的路由器或主机,必须维护这条SA的状态信息,其状态信息包括:

    1)   一个32为的连接标识符,称为安全参数索引SPI(Security Parameter Index)

    2)   安全关联SA的源点和终点的IP地址(即路由器R1和R2的IP地址)

    3)   所使用的加密类型(如DES或AES)

    4)   加密的密钥

    5)   完整性检查的类型

    6)   鉴别使用的密钥

    当路由器R1要通过SA发送IP安全数据报时,必须读取SA的这些状态信息,以便知道如何把IP数据报进行加密和鉴别。

    c)   IP安全数据报的格式

           

    上图是使用ESP协议构成的IP安全数据报,接下来逐步分析IP安全数据报的构成,以及ESP协议的构成。

    1)   ESP尾部:在原始的IP数据报(ESP的有效载荷)后面添加ESP尾部。ESP尾部有三个字段:

    a)   填充字段:用全0填充

    b)   填充长度(8位):填充字段的字节数,最大值255。

    c)   下一个首部(8位):现在的值为4,指明在接收端,ESP的有效载荷应交给什么样的协议来处理。
    如图中所示,IP安全数据报有三个首部,现在ESP尾部中的“下一个首部”就是指ESP的有效载荷中的“原始的IP首部”。如果不是隧道方式而是运输方式,则“ESP的有效载荷”就应当是TCP或UDP报文段,“下一个首部”的值也要改为另外的数值。

    2)   加密的部分:按照安全关联SA指明的加密算法和密钥,对“ESP的有效载荷+ESP尾部”进行加密。

    3)   ESP首部:ESP首部有两个32位字段。

    a)   安全参数索引SPI:通过同一个SA的所有IP安全数据报都使用同样的SPI值。

    b)   序号:鉴别的时候使用,它用来防止重放攻击,当分组重传时序号并不重复。

    4)   鉴别的部分:按照SA指明的算法和密钥,对“ESP首部+加密的部分”生成报文鉴别码MAC。

    5)   构成IP安全数据报的有效载荷:把所生成的报文鉴别码MAC添加在ESP尾部的后面,和ESP首部、ESP的有效载荷、ESP尾部一起,构成IP安全数据报的有效载荷。

    6)   新的IP首部:生成新的IP首部,通常位20字节长,和普通的IP数据报的首部的格式一样,只是首部中的协议字段的值是50,表明在接收端,首部后面的有效载荷应交给ESP协议来处理。

    注意事项:在“原始的IP首部”中的源地址和目的地址是主机H1和H2的IP地址,但是在路由器和路由器模式下,IP安全数据报的“新的IP首部”中,是使用路由器R1和路由器R2的IP地址分别作为源地址和目的地址。而在路由器和主机模式下,则是路由器R1和主机H2的IP地址作为源地址和目的地址。

    假设在通信时,有人截获了IP安全数据报,如果截获者不知道此安全数据报的密码,那么他只能知道这是一个从路由器R1发往路由器R2的IP数据报,不可能知道有效载荷的数据含义。如果截获者删改安全数据报中的一些字节,由于接收端能够进行完整性验证,就不会接收这种含有差错的信息。如果截获者试图进行重放攻击,由于安全数据报使用了有效的序号,使得重放攻击也无法得逞。

    d)   IPsec的其他构件

     i.     安全关联数据库SAD(Security Association Database):当主机要发送IP安全数据报时,就要在SAD中查找相应的SA,以便获得必要的信息,来对该IP安全数据报实施安全保护。同样,当主机要接收IP安全数据报时,也要在SAD中查找相应的SA,以便获得信息来检查该分组的安全性。

     ii.     安全策略数据库SPD(Security Plicy Database):并不是主机所发送的数据报都必须加密,很多信息使用普通的数据报明文发送即可。SPD指明什么样的数据报需要进行IPsec处理,这取决于源地址、源端口、目的地址、目的端口,以及协议的类型等。
    当一个IP数据报到达时,SPD指出应当做什么(是否使用IP安全数据报),而SAD指出使用IP安全数据报应当怎样做(使用哪一个SA)。

     iii.     互联网密钥交换IKE(Internet Key Exchange)协议:它就是负责创建SAD数据库中的安全关联SA,它是个非常复杂的协议,最新版本是V2,它以另外三个协议为基础:

    1.   Oakley是个密钥生成协议。

    2.   安全密钥交换机制SKEME(Secure Key Exchange Mechanism):用于密钥交换的协议。它利用公钥加密来事先密钥交换协议中的实体鉴别。

    3.   互联网安全关联和密钥管理协议ISAKMP(Internet Secure Association and Key Management Protocol):用于事先IKE中定义的密钥交换,使IKE的交换能够以标准化、格式化的报文创建安全关联SA。

     

       运输层的安全协议

    运输层的安全协议主要是指安全套接字层SSL(Secure Socket Layer)运输层安全TLS(Transport Layer Security),主要应用在应用层和运输层之间,它之所以被广泛应用,和网上购物、金融支付等场景有直接关系。在网上购物时,用户和销售商双方都需要鉴定彼此不是冒充者,而且双方传输的数据不会被拦截窃听,这个时候不仅需要鉴别双方的身份,还要加密双方传输的数据,所以SSL和TLS就肩负起了这个重任。

    SSL协议是Netscape(网景)公司在1994年开发的安全协议,广泛应用基于万维网(不限于万维网)的各种网络应用,SSL作用在端系统应用层的HTTP和运输层之间,在TCP之上建立起一个安全通道,为通过TCP传输的应用层数据提供安全保障。1995年Netscape公司把SSL转交给IETF,希望能够把SSL进行标准化,于是IETF在SSL3.0的基础上设计了TLS协议,为所有基于TCP的网络应用提供安全数据传输服务。以下内容如无特殊说明SSL=SSL/TLS。

    在没有使用SSL时,应用层的应用程序的数据是通过TCP套接字与运输层进行直接交互的。使用SSL后就有些特殊了,因为SSL增强了TCP的服务,SSL应该是运输层协议,然而需要使用安全运输的应用程序却把SSL驻留在应用层,结果应用层扩大了,在应用程序下面多了一个SSL子层,应用程序和SSL子层之间,还有一个SSL套接字,它和TCP套接字相似。

     

    应用层使用SSL最多的就是HTTP,当使用普通不加密的浏览器查看网页时,HTTP就直接使用TCP连接,SSL不起作用。当进行网上支付时,就需要使用安全的浏览器,应用程序HTTP就调用SSL对整个网页进行加密。

    网址栏原来显示http,现在变成了https,表示现在使用的是提供安全服务的HTTP协议(https端口号443,http端口号80)。在发送方:SSL从SSL套接字接收应用层的数据,对数据进行加密,然后把加密的数据送往TCP套接字。在接收方,SSL从TCP套接字读取数据,解密后,通过SSL套接字把数据交给应用层。

    SSL提供的安全服务可归纳为以下三种:

    1)   SSL服务器鉴别,允许用户证实服务器的身份。支持SSL的客户端通过验证来自服务器的证书,来鉴别服务器的真实身份并获取服务器的公钥。

    2)   SSL客户鉴别,SSL的可选安全服务,允许服务器证实客户的身份。

    3)   加密的SSL会话,对客户和服务器间发送的所有报文进行加密,并检测报文是否被篡改。

    下面以万维网应用为例简要说明SSL的工作过程。当浏览器点击网站链接建立TCP连接后,先进行浏览器和服务器之间的握手协议,完成加密算法的协商和会话密钥的传递,然后进行安全数据传输,过程如下:

             

    1)   协商加密算法:浏览器A向服务器B发送浏览器的SSL版本号和一些可选的加密算法。服务器B从中选定自己所支持的算法,并告知A。

    2)   服务器鉴别:服务器B向浏览器A发送包含其RSA公钥的数字证书。A使用该证书认证机构CA公开发布的RSA公钥对该证书进行验证。

    3)   会话密钥计算:浏览器A随机产生一个秘密数,然后用服务器B的RSA公钥进行加密后发送给服务器B。双方根据协商的算法和秘密数产生共享的对称会话密钥。

    4)   安全数据传输:双方用会话密钥加密和解码它们之间传送的数据并验证其完整性。

     

    小节

    抄写到这里,我算是真的松了一口压抑已久的老气,主要是没有时间,好不容易拼凑着一边阅读、一边思考、一边抄写弄完了。最近发骚写了一篇文章,贴出来陶冶(污染)一下你的眼睛,哈哈哈……:

  • 相关阅读:
    深入理解JavaScript系列(4):立即调用的函数表达式
    深入理解JavaScript系列(3):全面解析Module模式
    深入理解JavaScript系列(2):揭秘命名函数表达式
    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
    深入理解JavaScript系列
    大白话讲解Promise(一)
    《你不知道的JavaScript》整理(二)——this
    Mysql日期时间大全
    Mysql的时间和日期
    mysql命令大全用户管理相关命令
  • 原文地址:https://www.cnblogs.com/Jkinbor/p/15089713.html
Copyright © 2011-2022 走看看