一、介绍

The Transmission Control Protocol (TCP) is intended for use as a highly reliable host-to-host protocol between hosts in packet-switched computer communication networks, and in interconnected systems of such networks.

这份文件描述了TCP执行的函数,实现TCP的程序以及它为程序和用户提供的接口。

1.1 动机

计算机交流系统在军事方面、政府方面以及民众生活方面都起着十分重要的作用。这份文件主要关注军事级电脑交流需求,特别是拥塞(congestion)情况所导致的不稳定性发生时的鲁棒性。虽然关注点主要在军事方面,但是很多问题对政府和群众来说是通用的。

As strategic and tactical computer communication networks are developed and deployed, it is essential to provide means of interconnecting them and to provide standard interprocess communication protocols which can support a broad range of applications. In anticipation of the need for such standards, the Deputy Undersecretary of Defense for Research and Engineering has declared the Transmission Control Protocol (TCP) described herein to be a basis for DoD-wide inter-process communication protocol standardization.

TCP is a connection-oriented, end-to-end reliable protocol designed to fit into a layered hierarchy of protocols which support multi-network applications. The TCP provides for reliable inter-process communication between pairs of processes in host computers attached to distinct but interconnected computer communication networks. Very few assumptions are made as to the reliability of the communication protocols below the TCP layer. TCP assumes it can obtain a simple, potentially unreliable datagram service from the lower level protocols. In principle, the TCP should be able to operate above a wide spectrum of communication systems ranging from hard-wired connections to packet-switched or circuit-switched networks.

TCP is based on concepts first described by Cerf and Kahn in [1]. The TCP fits into a layered protocol architecture just above a basic Internet Protocol [2] which provides a way for the TCP to send and receive variable-length segments of information enclosed in internet datagram “envelopes”. The internet datagram provides a means for addressing source and destination TCPs in different networks. The internet protocol also deals with any fragmentation or reassembly of the TCP segments required to achieve transport and delivery through multiple networks and interconnecting gateways. The internet protocol also carries information on the precedence, security classification and compartmentation of the TCP segments, so this information can be communicated end-to-end across multiple networks.

Much of this document is written in the context of TCP implementations which are co-resident with higher level protocols in the host computer. Some computer systems will be connected to networks via front-end computers which house the TCP and internet protocol layers, as well as network specific software. The TCP specification describes an interface to the higher level protocols which appears to be implementable even for the front-end case, as long as a suitable host-to-front end protocol is implemented.

2.2 操作模型

进程通过调用TCP并将数据缓存作为参数传递给TCP来传输数据。TCP从数据缓存中将这些数据打包成段,然后调用网络模块来将每个段传输到目的TCP中。接收方TCP将段中的数据存放到接收方缓存中并且告知发送方。TCP在段中包含了控制信息来实现可靠数据传输。

The model of internet communication is that there is an internet protocol module associated with each TCP which provides an interface to the local network. This internet module packages TCP segments inside internet datagrams and routes these datagrams to a destination internet module or intermediate gateway. To transmit the datagram through the local network, it is embedded in a local network packet.

The packet switches may perform further packaging, fragmentation, or other operations to achieve the delivery of the local packet to the destination internet module.

2.3 终端环境

TCP被设想为操作系统中的一个模块。用户访问TCP的方式和他们访问文件系统的方式十分类似。TCP也可以调用操作系统的其他函数,例如,管理数据结构。实际的网络接口被设想为由设备驱动模块控制。TCP并不直接调用网络设备驱动模块,而是调用网络层数据报协议模块,这个网络层模块可能作为回应调用设备驱动器。

The mechanisms of TCP do not preclude implementation of the TCP in a front-end processor. However, in such an implementation, a host-to-front-end protocol must provide the functionality to support the type of TCP-user interface described in this document.

2.4 接口(1)

TCP/user接口为用户提供了对于TCP的调用。这些调用包括OPEN或CLOSE一个连接,SEND或RECEIVE数据,以及获取一个连接的STATUS。这些调用和用户程序在操作系统的上的调用一样(例如打开文件,读取文件以及关闭文件)。

TCP/internet 接口提供调用来发送和接收寻址到 Internet 系统中任何地方主机中的 TCP 模块的数据报。这些调用需要传递参数,参数包括地址,type of service,precedence,security以及其他的一些控制信息。

2.5 和其他协议的关系

下列的图表阐述了TCP在协议层次中的位置:

       +------+ +-----+ +-----+       +-----+                    |Telnet| | FTP | |Voice|  ...  |     |  Application Level +------+ +-----+ +-----+       +-----+                    |   |         |             |                       +-----+     +-----+       +-----+                    | TCP |     | RTP |  ...  |     |  Host Level        +-----+     +-----+       +-----+                    |           |             |                       +-------------------------------+                    |    Internet Protocol & ICMP   |  Gateway Level     +-------------------------------+                    |                                     +---------------------------+                      |   Local Network Protocol  |    Network Level     +---------------------------+

TCP被期望能够有效支持更高层的协议。It should be easy to interface higher level protocols like the ARPANET Telnet or AUTODIN II THP to the TCP.

2.7 连接的建立与清除(1)

每个TCP都使用port identifier来分辨它处理的不同的数据流。但由于port identifier由各个TCP独立选取,它们可能不是独一无二的。将识别TCP的网络地址和port identifier结合起来,就可以为每个socket提供独一无二的地址。

一个连接由一对socket来指定。一个local socket可以参与到和许多foreign socket的连接中,同时一个连接可以用来双向传递数据,被称为"full duplex"。

TCP可以自由地将进程和端口组合在一起,但需要注意几点。我们默认将一些well-known socket和进程绑定在一起,此时我们可以认为这些进程“拥有”这些端口,并且它们仅能从这些端口上发起连接。(实现拥有权的过程是一个本地问题l)

一个连接由OPEN call中的local port和foreign socket变量指定。作为回应,TCP会提供一个局部连接名字,用户可以在随后的调用中使用这个名字来引用这个连接。对于一个连接有几件事需要记住。为了存储连接的信息,我们假设存在一个称为Transmission Control Block(TCB)的数据结构。一种实现方式是使用局部连接名作为指向这个连接的TCB的指针。OPEN call同样指定了这个连接的建立是作为actively pursued或者是作为passively waited for。

一个passive OPEN请求意味着这个进程想要接受到来的连接请求,而不是尝试建立一个连接。通常请求passive OPEN的进程会接受来自任意调用者的连接请求。在这种情况下一个全是0的foreign socket被用来表示未指明的socket。未指明foreign socket只有在passive OPEN时才被允许使用。

希望为其他未知进程提供服务的服务进程将使用未指定的foreign套接字发出passive OPEN 请求。此时这个进程可以与任何请求连接到该本地套接字的进程建立连接。

well-known 套接字是一种方便的机制,用于将套接字地址与标准服务预先关联起来。例如,“Telnet服务器”进程被永久地分配给一个特定的套接字,其他套接字被保留用于文件传输、远程作业输入、文本生成器、回音器和接收进程(最后三个用于测试目的)。well-known 套接字的概念是TCP规范的一部分,但是套接字到服务的分配不在这个规范的范围内(见[4]。)

进程可以发起passive OPEN,等待来自其他进程的匹配active OPEN。同时向彼此发起active OPEN的两个进程将正确连接。这种灵活性对于分布式计算的支持是至关重要的,在分布式计算中,各部分之间是异步的。

匹配本地passive OPEN套接字和外部active OPEN套接字时存在两种主要情况。在第一种情况下,本地passive OPEN已完全指定外部套接字。在这种情况下,匹配必须是精确的。在第二种情况下,本地passive OPEN使外部套接字未指定。在这种情况下,只要本地套接字匹配,任何外部套接字都是可以接受的。

如果存在多个具有相同本地套接字的挂起passive OPEN(记录在TCB中),则在选择具有未指定外部套接字的TCB之前,外部active OPEN将与TCB中指定了相同外部active OPEN的套接字相匹配(如果存在此类TCB)。

建立连接的过程被称为三次握手 [3].

一个连接通过带有SYN标志位的到达段以及由OPEN调用创建的等待TCB条目启动。本地和外部套接字的匹配决定了何时启动连接。当序列号已在两个方向上同步时,连接将变为“已建立”。

关闭连接的过程称为四次挥手。

2.9 Precedence和Security

TCP利用网络层协议的type of service域以及security选项来对TCP用户的每个连接提供precedence以及security。 并不是所有的TCP模块都需要在多层安全环境中发挥作用,一些模块可能被限制在未分类的使用中,其他的可能仅在一层安全层次及compartment中发挥作用。 因此,一些TCP的实现以及针对用户的服务可能仅仅被限制在多层安全情况下的一个子集中。

TCP modules which operate in a multilevel secure environment must properly mark outgoing segments with the security, compartment, and precedence. Such TCP modules must also provide to their users or higher level protocols such as Telnet or THP an interface to allow them to specify the desired security level, compartment, and precedence of connections.

三、特定功能

3.1 头部格式

TCP段被封装在网络数据报中进行发送,TCP协议头部遵循了网络数据报头部的格式,并针对TCP所需的一些特定的信息进行了改动。

其头部格式如下:

    0                   1                   2                   3   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|          Source Port          |       Destination Port        |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                        Sequence Number                        |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    Acknowledgment Number                      |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|  Data |           |U|A|P|R|S|F|                               || Offset| Reserved  |R|C|S|S|Y|I|            Window             ||       |           |G|K|H|T|N|N|                               |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|           Checksum            |         Urgent Pointer        |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                    Options                    |    Padding    |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                             data                              |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • source port(16位):源端口号
  • destination port(16位):目的端口号
  • sequence number:数据中第一个字节的sequence number(除去SYN已经置位的情况)。如果SYN置位,那么sequence number是initial sequence number (ISN)并且第一个数据字节是 ISN+1.
  • acknowledgment number:当ACK控制位置位时,这个域内包含发送这个段的发送方期望收到的下一个sequence number
  • data offset:指代TCP头部有多少个32位的字。这个值指示了数据段的开始位置。注意,TCP头部(包括包含可选项的情况下)大小都是32的整数
  • reserved:保存下来供未来使用,必须为0
  • control bits:6位
    URG:Urgent Pointer field significant
    ACK: Acknowledgment field significant
    PSH: Push Function
    RST: Reset the connection
    SYN: Synchronize sequence numbers
    FIN: No more data from sender
  • window: The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept.
  • checksum:校验和字段是首部和text中所有16位字的补码和的16位补码。如果一个段包含奇数个要校验和的首部八位字节和text八位字节,则最后一个八位字节在右侧用零填充,以形成一个16位字,用于校验和。pad不作为段的一部分传输。在计算校验和时,校验和字段本身被替换为零。
    校验和还包括一个96位伪报头作为TCP报头的前缀。此伪头包含源地址、目标地址、协议和TCP长度。这为TCP提供了对于错误路由段的保护。
    TCP长度是以字节大小为单位的TCP报头长度加上数据长度(这个值通过计算得到),它不计算伪报头的12个八位字节。
                     +--------+--------+--------+--------+|           Source Address          |+--------+--------+--------+--------+|         Destination Address       |+--------+--------+--------+--------+|  zero  |  PTCL  |    TCP Length   |+--------+--------+--------+--------+
  • Urgent Pointer
  • Options
  • Padding:TCP首部padding用于确保TCP报头结束时数据在32位边界上开始,填充由零组成。

3.2 术语

在详解介绍TCP前我们需要介绍一些术语,这些术语也是描述一个TCP连接的变量。它们存储在关于这个连接的一个记录中,称为Transmission Control Block(TCB)。TCB中存储了本地变量、remote socket numbers、关于这个连接的security以及precedence、指向用户发送和接收缓存的指针以及指向retransmit queue以及当前段的指针。此外,TCB中还存储了几个关于发送方和接收方sequence number的变量。

发送方sequence number变量:

  • SND.UNA - send unacknowledged
  • SND.NXT - send next
  • SND.WND - send window
  • SND.UP - send urgent pointer
  • SND.WL1 - segment sequence number used for last window update
  • SND.WL2 - segment acknowledgment number used for last window update
  • ISS - initial send sequence number

接收方sequence number变量:

  • RCV.NXT - receive next
  • RCV.WND - receive window
  • RCV.UP - receive urgent pointer
  • IRS - initial receive sequence number

下列图表可以帮助我们将这些变量联系到sequence number空间:

发送方sequence number空间:

                   1         2          3          4      ----------|----------|----------|---------- SND.UNA    SND.NXT    SND.UNA        +SND.WND        1 - 已经被acknowledged的旧sequence numbers 2 - 还未被acknowledged的数据的sequence numbers3 - 允许传输的新数据的sequence numbers4 - 还未被允许传输的sequence numbers

接收方sequence number空间:

                       1          2          3      ----------|----------|---------- RCV.NXT    RCV.NXT        +RCV.WND        1 - 已经被acknowledged的旧sequence numbers2 - 允许接收的sequence numbers         3 - 还未被允许接收的未来的sequence numbers

receive window是接收sequence number空间中的2

讨论中还经常使用一些关于段的变量,这些变量从当前段的域中获取它们的值。

Current Segment Variables:

  • SEG.SEQ - segment sequence number
  • SEG.ACK - segment acknowledgment number
  • SEG.LEN - segment length
  • SEG.WND - segment window
  • SEG.UP - segment urgent pointer
  • SEG.PRC - segment precedence value

一个连接在它的持续时间内会经历一系列状态。这些状态分别是:LISTEN,SYN-SENT,SYN-RECEIVED,ESTABLISTHED,FIN-WAIT-1,FIN-WAIT-2,CLOSED-WAIT,CLOSING,LAST-ACK,TIME-WAIT以及虚构的状态CLOSED。CLOSED状态是虚构的是因为它代表没有TCB的状态,因此这时不存在连接。先简要介绍下这些状态:

  • LISTEN:代表等待一个远程TCP端口发来的连接请求
  • SYN-SENT:代表发送一个连接请求后等待一个匹配的连接请求
  • SYN-RECEIVED:represents waiting for a confirming connection request acknowledgment after having both received and sent a connection request.
  • ESTABLISHED:represents an open connection, data received can be delivered to the user. The normal state for the data transfer phase of the connection.
  • FIN-WAIT-1:represents waiting for a connection termination request from the remote TCP, or an acknowledgment of the connection termination request previously sent.
  • FIN-WAIT-2:represents waiting for a connection termination request from the remote TCP.
  • CLOSE-WAIT:represents waiting for a connection termination request from the local user.
  • CLOSING:represents waiting for a connection termination request acknowledgment from the remote TCP.
  • LAST-ACK:represents waiting for an acknowledgment of the connection termination request previously sent to the remote TCP (which includes an acknowledgment of its connection termination request).
  • TIME-WAIT:represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request.
  • CLOSED:代表没有任何连接状态

当发生某个特定事件时,TCP连接会从一个状态过渡到另一个状态。这些事件可以是user calls,OPEN,SEND,RECEIVE,CLOSE,ABORT和STATUS;来临的段,尤其是包含SYN、ACK及FIN标志位的;以及超时。

The state diagram in figure 6 illustrates only state changes, together with the causing events and resulting actions, but addresses neither error conditions nor actions which are not connected with state changes. In a later section, more detail is offered with respect to the reaction of the TCP to events.

NOTE BENE: this diagram is only a summary and must not be taken as the total specification.

                              +---------+ ---------\      active OPEN  |  CLOSED |            \    -----------  +---------+<---------\   \   create TCB  |     ^              \   \  snd SYN    passive OPEN |     |   CLOSE        \   \           ------------ |     | ----------       \   \         create TCB  |     | delete TCB         \   \       V     |                      \   \     +---------+            CLOSE    |    \   |  LISTEN |          ---------- |     |  +---------+          delete TCB |     |  rcv SYN      |     |     SEND              |     |  -----------   |     |    -------            |     V  +---------+      snd SYN,ACK  /       \   snd SYN          +---------+|         |<-----------------           ------------------>|         ||   SYN   |                    rcv SYN                     |   SYN   ||   RCVD  |<-----------------------------------------------|   SENT  ||         |                    snd ACK                     |         ||         |------------------           -------------------|         |+---------+   rcv ACK of SYN  \       /  rcv SYN,ACK       +---------+|           --------------   |     |   -----------                  |                  x         |     |     snd ACK                    |                            V     V                                |  CLOSE                   +---------+                              | -------                  |  ESTAB  |                              | snd FIN                  +---------+                              |                   CLOSE    |     |    rcv FIN                     V                  -------   |     |    -------                     +---------+          snd FIN  /       \   snd ACK          +---------+|  FIN    |<-----------------           ------------------>|  CLOSE  || WAIT-1  |------------------                              |   WAIT  |+---------+          rcv FIN  \                            +---------+| rcv ACK of FIN   -------   |                            CLOSE  |  | --------------   snd ACK   |                           ------- |  V        x                   V                           snd FIN V  +---------+                  +---------+                   +---------+|FINWAIT-2|                  | CLOSING |                   | LAST-ACK|+---------+                  +---------+                   +---------+|                rcv ACK of FIN |                 rcv ACK of FIN |  |  rcv FIN       -------------- |    Timeout=2MSL -------------- |  |  -------              x       V    ------------        x       V  \ snd ACK                 +---------+delete TCB         +---------+------------------------>|TIME WAIT|------------------>| CLOSED  |+---------+                   +---------+

3.4 建立一个TCP连接

三次握手就是指建立一个连接的过程。这个过程通常由一个TCP发起并且由另一个TCP进行回应。这个过程在两个TCP同时启动连接建立时同样可以成功。当两个TCP同时建立连接时,each TCP receives a “SYN” segment which carries no acknowledgment after it has sent a “SYN”. Of course, the arrival of an old duplicate “SYN” segment can potentially make it appear, to the recipient, that a simultaneous connection initiation is in progress. Proper use of “reset” segments can disambiguate these cases.

下面展示了连接初始化的几个例子。尽管这些例子没有使用携带数据段的段来展示连接的同步性,但这是合法的,so long as the receiving TCP doesn’t deliver the data to the user until it is clear the data is valid (i.e., the data must be buffered at the receiver until the connection reaches the ESTABLISHED state). 三次握手减少了错误连接的可能性。It is the implementation of a trade-off between memory and messages to provide information for this checking.

最简单的三次握手过程如下所示,图中的各种编号通过如下方式进行理解。Each line is numbered for reference purposes. Right arrows (–>) indicate departure of a TCP segment from TCP A to TCP B, or arrival of a segment at B from A. Left arrows (<–), indicate the reverse. 省略号(…)表明一个段还在网络中(delayed)。 An “XXX” indicates a segment which is lost or rejected. Comments appear in parentheses. TCP states represent the state AFTER the departure or arrival of the segment (whose contents are shown in the center of each line). Segment contents are shown in abbreviated form, with sequence number, control flags, and ACK field. 其他类似windows、address、length以及text等信息没有进行展示。

      TCP A                                                TCP B1.  CLOSED                                               LISTEN2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHEDBasic 3-Way Handshake for Connection Synchronization

在第4行,TCP A用一个空段进行回应,其中包含回应TCP B的SYN的ACK。在第5行,TCP A发送一些数据。注意,第5行中的段的序列号与第4行中的相同,因为ACK不占用序列号空间。

Simultaneous initiation is only slightly more complex, as is shown in figure 8. Each TCP cycles from CLOSED to SYN-SENT to SYN-RECEIVED to ESTABLISHED.

      TCP A                                            TCP B1.  CLOSED                                           CLOSED2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> ESTABLISHEDSimultaneous Connection Synchronization

三次握手的主要原因是为了防止网络残留的连接启动报文造成混淆。为了解决这个问题,我们设计了一个特殊的控制信息reset。如果接收TCP处于非同步状态(即SYN-SENT、SYN-RECEIVED),则在接收到可接受的reset时返回LISTEN。如果TCP处于某个同步状态(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT),它将中止连接并通知用户。

观察下面的残留报文段的例子。在第三行,一个旧的重复SYN到达TCP B。TCP B无法分辨这是一个旧的重复SYN,因此它会正常进行回应(第四行)。TCP A检测出了这个ACK不正确,因此返回一个RST(reset)。TCP B在收到这个RST后,返回到LISTEN状态。当初始的SYN最终到达(第六行)后这个同步过程才正常启动。如果第六行的SYN在RST前到达,那么a more complex exchange might have occurred with RST’s sent in both directions.

      TCP A                                                TCP B1.  CLOSED                                               LISTEN2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               ...3.  (duplicate) ... <SEQ=90><CTL=SYN>               --> SYN-RECEIVED4.  SYN-SENT    <-- <SEQ=300><ACK=91><CTL=SYN,ACK>  <-- SYN-RECEIVED5.  SYN-SENT    --> <SEQ=91><CTL=RST>               --> LISTEN6.              ... <SEQ=100><CTL=SYN>               --> SYN-RECEIVED7.  SYN-SENT    <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED8.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> ESTABLISHEDRecovery from Old Duplicate SYN

3.4.1 半连接(Half-Open)

如果一个已经建立的连接的一端TCP已经关闭或放弃这个连接,而另一端并不知情,或者由于内存丢失等原因导致的连接两端不同步,那么我们称这个连接是半连接的。这时连接的任意一端发送数据都会使得连接自动重置。

如果在A端连接已经不存在了,那么B端发送的任何数据都会使得B端接收到一个RST。这个RST告知B这个连接存在错误,因此它需要放弃这个连接。

3.4.2 reset生成

作为一个通用准则,每当一个显然不是用于当前连接的段到达时,必须发送reset(RST)。如果不清楚情况是否如此,则不得发送重置。

总共有三种状态分类:


CLOSED

如果连接不存在(CLOSED),那么任何到达的段(除了reset)都会触发reset。特别地,这种方式可以拒绝到达一个不存在的连接的SYN。

如果到达的段有ACK域,那么reset从这个段的ACK域中获取自己的sequence number,否则这个reset的sequence number为0并且ACK域被设置成到达段的sequence number加段长度。连接维持CLOSED状态。


LISTEN, SYN-SENT, SYN-RECEIVED

如果连接在任意一个非同步状态,并且到达的段acknowledge了还没有发送的内容(段携带了一个不可被接收的ACK),或者一个到达的段的security等级及compartment和当前连接的不匹配,那么会发送回一个reset。

如果我们的SYN尚未确认,并且传入段的优先级别高于请求的优先级别,那么要么提高本地优先级别(如果用户和系统允许),要么发送重置。或者,如果传入段的优先级别低于请求的优先级别,则继续,如同优先级别完全匹配一样(如果远程TCP无法提高优先级别以匹配我们的优先级别,则将在它发送的下一个段中检测到该优先级别,然后将终止连接)。如果我们的SYN已经被确认(可能在这个传入段中),传入段的优先级别必须与本地优先级别完全匹配,如果没有,则必须发送重置。

如果到达的段有ACK域,那么reset从这个段的ACK域中获取sequence number,否则将reset的sequence number置0并且将ACK域设置为到达段的sequence number加到达段的长度。连接会继续维持在原状态。


ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

如果连接位于同步状态,那么任何不可被接收的段(sequence number位于接收窗口外或者acknowledgment number不可接收)都会触发一个空的确认段,其中包含当前发送序列号和一个表示预期接收的下一个序列号的确认,并且连接保持相同的状态。

If an incoming segment has a security level, or compartment, or precedence which does not exactly match the level, and compartment, and precedence requested for the connection,a reset is sent and connection goes to the CLOSED state. The reset takes its sequence number from the ACK field of the incoming segment.

查看RFC 5961内容

3.4.3 reset处理

在所有的除了SYN-SENT的状态,所有的RST段通过检查SEQ域进行验证。如果一个reset的sequence number在有效窗口内,那么它是有效的。在SYN-SENT状态时(发送SYN后收到了RST),那么当RST的ACK域acknowledge了发送的SYN时,这个RST才是可接收的。

RST的接收方首先会进行验证,然后才会改变状态。如果接收方位于LISTEN状态,那么忽略这个RST。如果接收方位于SYN-RECEIVED状态并且曾经位于LISTEN状态,那么接收方返回到LISTEN状态,否则接收方会放弃这个连接并且返回到CLOSED状态。如果接收方在任何其他的状态,那么它会放弃这个链接并且提示用户然后进入CLOSED状态。

(这里应该是在后续的RFC中进行了修改)

3.9 事件处理

本节中描述的处理是一种可能的实现方式。

TCP的活动可以被表示为对事件的回应,这些事件可以被分成三类:用户调用、段到达以及超时。这一节描述了TCP回应这三类事件的操作。在许多情况下,所采用的处理方式取决于连接的状态。

对事件的具体描述如下:

User calls

  • OPEN
  • SEND
  • RECEIVE
  • CLOSE
  • ABORT
  • STATUS

Arriving Segments

  • SEGMENT ARRIVES

Timeouts

  • USER TIMEOUT
  • RETRANSMISSION TIMEOUT
  • TIME-WAIT TIMEOUT

TCP/user接口的模型是,用户的命令会收到立刻的return或通过时间/伪中断收到一个延迟的response。在以下描述中,术语“signal”意指引起延迟response。

错误response以字符串形式返回。例如,用户命令如果引用了一个不存在的连接,那么会收到"error: connection not open"。

考虑处理传入段的一种方式是,假设首先对它们进行适当的序列号测试(即,它们的内容位于序列号空间中预期的“接收窗口”的范围内),然后它们通常按序列号顺序queue和处理。

当一个段与其他已经接收到的段重叠时,我们重建该段来使得其仅包含新数据,并调整首部字段以保持一致。

3.9.1 open call


CLOSED STATE(此时TCB并不存在)

创建一个新的TCB来保存连接状态信息。填充local socket identifier, foreign socket, precedence, security/compartment, and user timeout信息。注意有一部分foreign socket在passive OPEN下是未指定的,它们利用到达SYN段中的参数进行填充。检测security以及precedence,如果不符合返回"error: precedence not allowed"或者"error: security/compartment not allowed"。如果是passive,那么进入LISTEN状态并返回。如果是active并且foreign socket没有指定,那么返回"error: foreign socket unspecified";如果是active并且foreign socket已经指定,那么产生一个SYN段,并且选取一个initial send sequence number (ISS) 。此时会发送形式如<SEQ=ISS><CTL=SYN>的SYN段。将SND.UNA设置为ISS, 将SND.NXT设置为ISS+1,进入SYN-SENT状态并且返回。

如果调用者没有指定的local socket的访问权限,那么返回 “error: connection illegal for this process”。如果没有空间来创造一个新的连接,那么返回 “error: insufficient resources”。


LISTEN STATE

如果处于active并且foreign socket已经指定,那么将连接状态从passive改变为active,选取一个ISS,发送一个SYN段,将SND.UDA设置为ISS,将SND.NXT设置为ISS+1,进入SYN-SENT状态。和SEND一起的数据有可能随着SYN段进行传输,也有可能先进入传输队列中,进入ESTABLISTHED状态后才进行传输。如果命令中要求了urgent bit,则必须与该命令发送的数据段一起发送。如果没有足够空间queue这个请求,那么回应"error: insufficient resources"。

如果没有指定foreign socket,那么会返回错误"error: foreign socket unspecified"。


SYN-SENT STATE
SYN-RECEIVED STATE
ESTABLISHED STATE
FIN-WAIT-1 STATE
FIN-WAIT-2 STATE
CLOSE-WAIT STATE
CLOSING STATE
LAST-ACK STATE
TIME-WAIT STATE

返回”error: connection already exists"

3.9.2 SEND Call


CLOSED STATE(例如TCB不存在)

如果用户没有访问这个连接的权限,那么返回"error: connection illegal for this process"。

否则,返回"error: connection does not exist"


LISTEN STATE

如果foreign socket已经指定,那么将连接从passive改为active,选择一个ISS。发送一个SYN段,将SND.UNA设置为ISS,将SND.NXT设置为ISS+1。进入SYN-SENT状态。和SEND一起的数据有可能随着SYN段进行传输,也有可能先进入传输队列中,随着进入ESTABLISTHED状态后才进行传输。如果命令中要求了urgent bit,则必须与该命令发送的数据段一起发送。如果没有足够空间queue这个请求,那么回应"error: insufficient resources"。如果foreign socket没有指定,那么返回"error: foreign socket unspecified"。


SYN-SENT STATE
SYN-RECEIVED STATE

queue需要传输的数据直到进入ESTABLISHED状态,如果没有足够空间queue,那么回应"error: insufficient resources"。


ESTABLISHED STATE
CLOSE-WAIT STATE

将缓冲区分段,并使用piggybacked acknowledgement(acknowledgement value=RCV.NXT)发送它。如果没有足够的空间来储存这个缓冲区,只需返回“error: insufficient resources”。

如果设置了紧急标志,则将SND.UP设置为SND.NXT-1并在输出段中设置紧急指针。


FIN-WAIT-1 STATE
FIN-WAIT-2 STATE
CLOSING STATE
LAST-ACK STATE
TIME-WAIT STATE

返回"error: connection closing"并且不处理这个请求

3.9.3 RECEIVE Call


CLOSED STATE (i.e., TCB does not exist)

如果用户没有对这个连接的权限,返回"error: connection illegal for this process"。否则,返回"error: connection does not exist"。


LISTEN STATE
SYN-SENT STATE
SYN-RECEIVED STATE

queue直到进入ESTABLISHED状态才进行处理,如果没有足够空间queue这个请求,那么回应"error: insufficient resources"。


ESTABLISHED STATE
FIN-WAIT-1 STATE
FIN-WAIT-2 STATE

如果已经被queued的段不能满足请求,则queue这个请求。如果没有queue空间来存储RECEIVE,则使用“error: insufficient resources”进行响应。

将queued的传入段重新组装到接收缓冲区并返回给用户。如果是这种情况,标记“push seen”(PUSH)。

如果RCV.UP优于在当前传递给用户的数据,则通知用户存在紧急数据。


CLOSE-WAIT STATE

因为远程端已经发送了FIN,所以RECEIVE必须由已经拿到并且还没有交付给用户的文本来满足。如果没有文本等待传递,则RECEIVE将得到“error:connection closing”响应。否则,任何剩余的文本都可以用来满足RECEIVE。


CLOSING STATE
LAST-ACK STATE
TIME-WAIT STATE

返回"error: connection closing"

3.9.4 CLOSE CAll


CLOSED STATE (i.e., TCB does not exist)

如果用户没有对这个连接的权限,返回"error: connection illegal for this process"。否则,返回"error: connection does not exist"。


LISTEN STATE

任何未完成的RECEIVE都会返回“error:closing”响应。删除TCB,进入CLOSED状态,然后返回。


SYN-SENT STATE

删除TCB并对任何queued的SEND或RECEIVE返回“error: closing”响应。


SYN-RECEIVED STATE

如果没有发起SEND,也没有待发送的数据,则生成FIN段并发送,并进入FIN-WAIT-1状态;否则,等待到进入ESTABLISHED状态后queued后再处理。


ESTABLISHED STATE

排队等待,直到前面的所有SEND都被分段,然后形成一个FIN段并发送它。在任何情况下都会进入FIN-WAIT-1状态。


FIN-WAIT-1 STATE
FIN-WAIT-2 STATE

Strictly speaking, this is an error and should receive a “error: connection closing” response. An “ok” response would be acceptable, too, as long as a second FIN is not emitted (the first FIN may be retransmitted though).


CLOSE-WAIT STATE

Queue this request until all preceding SENDs have been segmentized; then send a FIN segment, enter CLOSING state.


CLOSING STATE
LAST-ACK STATE
TIME-WAIT STATE

Respond with “error: connection closing”.

3.9.5 ABORT Call

//待补充

3.9.6 STATUS Call

//待补充

3.9.7 SEGMENT ARRIVES


CLOSED(例如TCB不存在)

所有传入段中的数据都被抛弃。一个到达的RST段会直接被抛弃。一个到达的非RST段会导致产生一个RST段作为回应被发送。

如果传入段的ACK位没有置位,那么sequence number使用0,否则使用传入段的ACK,ACK没有置位的情况:

<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

ACK置位的情况:

<SEQ=SEG.ACK><CTL=RST>

LISTEN

第一步检测RST

如果到来的是RST,那么会被忽略,返回。

第二步检测ACK

任何一个到达仍然处于LISTEN状态连接的acknowledgment都是不正确的。应该为任何到达的ACK段生成一个可接受的RST段。这个RST的格式应当如下所示:

<SEQ=SEG.ACK><CTL=RST>

然后返回。

第三步检测SYN

如果SYN标志位置位,那么检查security。如果到达段的security/compartment和TCB中的security/compartment并不完全匹配,那么发送一个置位段并返回:

<SEQ=SEG.ACK><CTL=RST>

如果SEG.PRC大于TCB.PRC,那么如果用户同意,系统会设置TCB.PRC为SEG.PRC,如果用户没有同意,那么发送一个reset并返回:

<SEQ=SEG.ACK><CTL=RST>

如果SEG.PRC小于TCB.PRC那么继续。

将RCV.NXT设置为SEG.SEQ+1,将IRS设置为SEG.SEQ并且任何其他的control或text会被queue,稍后进行处理。此时还应当选取一个ISS并且发送一个如下格式的SYN:

<SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>

将SND.NXT设置为ISS+1,将SND.UNA设置为ISS。此时连接状态改变为SYN-RECEIVED。注意其他到来的control或数据(和SYN组合起来的)会在SYN-RECEIVED状态下进行处理,但是不会重复处理SYN以及ACK。如果LISTEN状态之前没有完全指定(foreign socket没有指定),那么此时未指定的域需要进行填充。

第四步处理其他text或者control

Any other control or text-bearing segment (not containing SYN) must have an ACK and thus would be discarded by the ACK processing. An incoming RST segment could not be valid, since it could not have been sent in response to anything sent by this incarnation of the connection. So you are unlikely to get here, but if you do, drop the segment, and return.


SYN-SENT

第一步检查ACK标志位

如果ACK标志位置位

如果SEG.ACK<=ISS,或者SEG.ACK>SND.NXT,那么发送一个reset(除非到达段的RST标志位已经置位,这时丢掉这个段并返回):

<SEQ=SEG.ACK><CTL=RST>

如果SND.UNA<=SEG.ACK<=SND.NXT,那么这个ACK是可接收的

第二步检查RST标志位

如果RST标志位置位

如果ACK是可接收的,那么通知用户"error: connection reset",丢掉这个段并进入CLOSED状态,删除TCB并且返回。否则(ACK标志位没有置位)丢掉这个段并返回。

第三步检查security以及precedence

如果段中的security/compartment并不完全匹配TCB中的security/compartment,那么发送回一个reset

如果有ACK,那么:

<SEQ=SEG.ACK><CTL=RST>

否则:

<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

如果有ACK,那么段中的precedence必须和TCB中的完全匹配,否则发送回一个reset:

<SEQ=SEG.ACK><CTL=RST>

如果没有ACK

如果段中的precedence高于TCB中的precedence,则如果用户和系统允许,将TCB中的precedence提高到段中的precedence,如果不允许提高precedence,则发送reset:

<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>

如果段中的precedence低于TCB中的precedence,那么继续。

如果发送了一个reset,那么丢掉这个段并返回。

第四步检查SYN标志位

只有在ACK通过测试或者没有ACK或者段中不包括RST时才会到达这步。


SYN-RECEIVED
ESTABLISHED
FIN-WAIT-1
FIN-WAIT-2
CLOSE-WAIT
CLOSING
LAST-ACK
TIME-WAIT

第一步检测sequence number

到达段按顺序进行处理。对到达段的初始检测用于丢弃旧的重复段,更进一步的处理按照SEG.SEQ的顺序进行。如果一个段的内容横跨了新旧的边界,那么只有新的部分会被处理。

对于一个新到达段有如下四种测验:

        Segment Receive  TestLength  Window------- -------  -------------------------------------------0       0     SEG.SEQ = RCV.NXT0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND>0       0     not acceptable>0      >0     RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WNDor RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND

如果RCV.WND为0,此时不会接收段,但是此时可以接收有效的ACKs、URGs以及RSTs。

如果一个到达的段是不可接收的,那么应当发送回一个acknowledgment作为回应(除非RST标志位置位,此时丢弃这个段并返回):

<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

发送这个acknowledgment后,丢掉这个不可接受的段并返回。

在下文中,假设该段是从RCV.NXT开始且不超过窗口的理想段。我们可以裁剪实际的片段来适应这个假设,方法是修剪掉窗口外的任何部分(包括SYN和FIN),并且只有在片段从RCV.NXT开始时才进一步处理。具有较高起始序列号的段可被保留以供后续处理。

第二步检测RST标志位

SYN-RECEIVED

如果这个连接是用一个passive OPEN创建的(例如从LISTEN状态),那么将这个连接返回到LISTEN状态并返回。此时用户会被告知。如果这个连接是用一个active OPEN创建的(例如从SYN-SENT状态)那么这个连接会被拒绝,此时告知用户“connection refused”。在任何一种情况下,所有在传输队列上的段都会被移除。在active OPEN的情况下,进入CLOSED状态并且删除TCB,然后返回。

ESTABLISHED
FIN-WAIT-1
FIN-WAIT-2
CLOSE-WAIT

如果RST标志位置位,那么任何未处理的RECEVIE以及SEND都会收到“reset”回复。所有段队列都需要进行刷新。用户还会收到一个未经请求的“connection reset”信号。此时进入CLOSED状态,删除TCB并返回。

CLOSING STATE
LAST-ACK STATE
TIME-WAIT

如果RST标志位置位,那么进入CLOSED状态,删除TCB并返回。

第三步检查security以及precedence

SYN-RECEIVED

如果段中的security/compartment以及precedence并不完全匹配TCB中的security/compartment以及precedence,那么发送一个reset并返回。

ESTABLISHED STATE

如果段中的security/compartment以及precedence并不完全匹配TCB中的security/compartment以及precedence那么发送回一个reset,任何未处理的RECEIVE以及SEND都会收到“reset”回应。所有的段queue会进行刷新。用户会收到一个未请求的“connection reset”信号。进入CLOSED状态,删除TCB并返回。

注意这个检查在sequence检查后来避免这两个端口间的旧连接的段(有着不同的security或precedence)来导致对当前连接的终止。

第四步检查SYN标志位

SYN-RECEIVED
ESTABLISHED STATE
FIN-WAIT STATE-1
FIN-WAIT STATE-2
CLOSE-WAIT STATE
CLOSING STATE
LAST-ACK STATE
TIME-WAIT STATE

如果SYN置位,那么这是一个错误。发送回一个reset,任何未处理的RECEIVE以及SEND都会收到“reset”回应。所有的段queue会进行刷新。用户会收到一个未请求的“connection reset”信号。进入CLOSED状态,删除TCB并返回。

第五步检查ACK域

如果ACK标志位没有置位,那么丢掉这个段并返回。

如果ACK标志位置位

SYN-RECEIVED

如果SND.UNA≤SEG.ACK≤SND.NXTSND.UNA\le SEG.ACK\le SND.NXTSND.UNASEG.ACKSND.NXT那么进入ESTABLISTHED状态并且继续处理

如果段acknowledgment是不可接收的,那么生成一个reset段并发送:

<SEQ=SEG.ACK><CTL=RST>

ESTABLISHED

如果SND.UNA<SEG.ACK≤SND.NXTSND.UNA< SEG.ACK\le SND.NXTSND.UNA<SEG.ACKSND.NXT,那么将SND.UNA的值改为SEG.ACK。然后更新retransmission queue,删除这次已经acknowledge的段。此时用户也会收到positive acknowledgment来告知已经完全发送并acknowledged的buffer(例如,SEND buffer应当用“ok”作为返回)。如果ACK是重复的(SEG.ACK<SND.UNASEG.ACK<SND.UNASEG.ACK<SND.UNA),那么它可以被忽略。如果ACK acknowledge了还没有发送的段(SEG.ACk>SND.NXTSEG.ACk>SND.NXTSEG.ACk>SND.NXT),那么发送一个ACK,丢掉这个段并返回。

如果SND.UNA<SEG.ACK≤SND.NXTSND.UNA< SEG.ACK\le SND.NXTSND.UNA<SEG.ACKSND.NXT,此时发送窗口也应该进行更新。如果(SND.WL1<SEG.SEQSND.WL1<SEG.SEQSND.WL1<SEG.SEQ或者(SND.WL1=SEG.SEQandSND.WL2≤SEG.ACKSND .WL1=SEG.SEQ \quad and \quad SND.WL2\le SEG.ACKSND.WL1=SEG.SEQandSND.WL2SEG.ACK)),将SND.WNDSND.WNDSND.WND设置为SEG.WND,将SND.WL1SND.WL1SND.WL1设置为SEG.SEQSEG.SEQSEG.SEQ,并且将SND.WL2SND.WL2SND.WL2设置为SEG.ACKSEG.ACKSEG.ACK

Note that SND.WND is an offset from SND.UNA, that SND.WL1 records the sequence number of the last segment used to update SND.WND, and that SND.WL2 records the acknowledgment number of the last segment used to update SND.WND. The check here prevents using old segments to update the window.

RFC 793翻译(TCP的主体内容)相关推荐

  1. python获取已打开网页的html,【已解决】Python的BeautifulSoup去实现提取带tag的HTML网页主体内容...

    折腾: [未解决]Python的html网页主体内容提取 期间,去试试BeautifulSoup提取HTML网页主体内容 先去随便找个合适的网页 -> 简单看了看网页内容结构: 发现是: 网页主 ...

  2. 火车头采集器文章翻译插件(文章标题内容中英双语对照|自动插入相关图片)

    火车头采集器文章翻译插件(文章标题内容中英双语对照|自动插入相关图片) 为了保护接口压力防止被封IP: 请把采集的间隔时间调整为10000~100000 火车头采集器文章翻译插件(文章标题内容中英双语 ...

  3. tcp linux 报文内容,linux – tcpdump – 只是逐行输出数据包内容

    我正在尝试在DEFCON数据包上使用tcpdump. 这是我正在使用的命令: tcpdump -qns 0 -X -r ulogd.eth0.pcap 这是我得到的输出: 10:39:12.35641 ...

  4. 口译翻译类别及服务内容

    一.口译服务工作类别 1. 交替传译:当源语言使用者讲话停顿或结束等候翻译时,口译员用目标语清楚.准确.完整地表达源语言的信息内容,简称"交传". 陪同交传:译员陪同客户参与涉外活 ...

  5. tcp linux 报文内容,【Linux】TCP报文中的PSH和URG字段的介绍

    TCP协议 TCP报文格式 源端口和目的端口 各自占用两个字节,用来表示主机中的通信进程.端口号和IP组合即为套接字 序号 也叫发送序号,TCP将发送的每一个数据流都进行了编号,整个数据的起始序号在开 ...

  6. RFC 4904 翻译

    RFC4904 网络工作组                                         V. Gurbani RFC:  4904            Bell Laborato ...

  7. html+css 制作小米商城主体内容的商品展示

    这个是效果图,源代码放下面了,欢迎一起交流讨论 这里是html <!-- 主体部分 --><div class="home-main"><div cl ...

  8. Docx4j 简单操作文字图片(包含页眉页脚和主体内容)

    docx4j官方提供了一些例子 - v3.2.2,本文只是其中一部分应用的简单例子. 需要注意的地方是页眉和页脚,必须创建对应关系才能起作用. 页眉和页脚添加图片的时候,调用的createImageP ...

  9. 在线翻译网站的介绍内容

    在线翻译详细介绍:在线翻译(www.zxfy.net)的免费翻译服务可提供简体中文和另外 100 多种语言之间的互译功能,可让您即时翻译字词.短语和网页内容.

  10. TCP 为什么需要三次握手?

    TCP 协议是我们每天都在使用的一个网络通讯协议,因为绝大部分的网络连接都是建立在 TCP 协议上的,比如你此刻正在看的这篇文章是建立在 HTTP(Hypertext Transfer Protoco ...

最新文章

  1. 掩码计算工具netmask
  2. 嵌入式系统低功耗管理(备忘)
  3. element ui 多个子组件_ElementUI 技术揭秘(2) 组件库的整体设计
  4. 国产IT彪起来了,后浪要将前浪拍死在沙滩上
  5. citrix服务器共享文件夹,如何使用citrix XenApp 发布远程共享文件夹,及其故障解决...
  6. C语言实现超简单贪吃蛇(代码是抄的),我做一下讲解
  7. vb.net 教程 3-1 窗体编程基础 2
  8. 群晖让usb打印机变成网络打印机
  9. 杭电数据结构课程实践-重言式判别
  10. Android 编写WiFi探针,一种WiFi探针路由器的制作方法
  11. 如何使用禅道集成钉钉
  12. uni-app 快速集成 IM 即时通信的方法——TUIKit 来啦
  13. 手机端上传照片压缩功能canvas
  14. 小米手机、华为手机、一加手机、小米手环NFC刷门禁卡教程!
  15. “框架效应”--如何说话让人喜欢?
  16. 【组合数学】全错位排列的递推公式推导
  17. 不仅仅是技术——亚马逊云科re:Invent2022
  18. flink sql 知其所以然(十四):维表 join 的性能优化之路(上)附源码
  19. 国庆临近,字节后端开发3+4面
  20. 区块链开发最流行的编程语言有哪些?

热门文章

  1. Python 3 实现选择排序
  2. Java的注解和反射
  3. Flutter之GridView简析
  4. 微信小程序开发--【Hello World 及代码结构】(二)
  5. ajax beforesend xhr对象,浅谈jQuery中Ajax事件beforesend及各参数含义
  6. python中列表去重有哪几种方法_python列表里的字典元素去重
  7. js 中添加php数组,浅谈javascript中数组Array的添加/删除操作
  8. 求计算机技术在创新上的应用,计算机技术在企业中的应用
  9. php socket端口监听端口号,swoole websocket服务器中添加监听tcp的端口
  10. python实战代码目录信息