《UNIX网络编程 卷1:套接字联网API(第3版)》——2.8 SCTP关联的建立和终止

简介: 客户通过调用connect或者发送一个隐式打开该关联的消息进行主动打开。这使得客户SCTP发送一个INIT消息(初始化),该消息告诉服务器客户的IP地址清单、初始序列号、用于标识本关联中所有分组的起始标记、客户请求的外出流的数目以及客户能够支持的外来流的数目。

本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第2章,第2.8节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.8 SCTP关联的建立和终止

与TCP一样,SCTP也是面向连接的,因而也有关联的建立与终止的握手过程。不过SCTP的握手过程不同于TCP,我们在此加以说明。

2.8.1 四路握手
建立一个SCTP关联的时候会发生下述情形(类似于TCP)。

(1)服务器必须准备好接受外来的关联。这通常通过调用socket、bind和listen这3个函数来完成,称为被动打开。

(2)客户通过调用connect或者发送一个隐式打开该关联的消息进行主动打开。这使得客户SCTP发送一个INIT消息(初始化),该消息告诉服务器客户的IP地址清单、初始序列号、用于标识本关联中所有分组的起始标记、客户请求的外出流的数目以及客户能够支持的外来流的数目。

(3)服务器以一个INIT ACK消息确认客户的INIT消息,其中含有服务器的IP地址清单、初始序列号、起始标记、服务器请求的外出流的数目、服务器能够支持的外来流的数目以及一个状态cookie。状态cookie包含服务器用于确信本关联有效所需的所有状态,它是数字化签名过的,以确保其有效性。

(4)客户以一个COOKIE ECHO消息回射服务器的状态cookie。除COOKIE ECHO外,该消息可能在同一个分组中还捆绑了用户数据。

(5)服务器以一个COOKIE ACK消息确认客户回射的cookie是正确的,本关联于是建立。该消息也可能在同一个分组中还捆绑了用户数据。

以上交换过程至少需要4个分组,因此称之为SCTP的四路握手(four-way handshake)。图2-6展示了这4个分节。

screenshot

SCTP的四路握手在很多方面类似于TCP的三路握手,差别主要在于作为SCTP整体一部分的cookie的生成。INIT(随其众多参数一道)承载一个验证标记Ta和一个初始序列号J。在关联的有效期内,验证标记Ta必须在对端发送的每个分组中出现。初始序列号J用作承载用户数据的DATA块的起始序列号。对端也在INIT ACK中承载一个验证标记Tz,在关联的有效期内,验证标记Tz也必须在其发送的每个分组中出现。除了验证标记Tz和初始序列号K外,INIT的接收端还在作为响应的INIT ACK中提供一个cookie C。该cookie包含设置本SCTP关联所需的所有状态,这样服务器的SCTP栈就不必保存所关联客户的有关信息。SCTP关联设置的细节参见[Stewart and Xie 2001]的第4章。

四路握手过程结束时,两端各自选择一个主目的地址(primary destination address)。当不存在网络故障时,主目的地址将用作数据要发送到的默认目的地。

在SCTP中使用四路握手是为了避免一种将在4.5节讨论的拒绝服务攻击。

SCTP使用cookie的四路握手定形了一种防护这种攻击的方法。TCP的许多实现也使用类似的方法。两者的主要差别在于,TCP中cookie状态必须编码到只有32位长的初始序列号中。SCTP为此提供了一个任意长度的字段,并且要求实施基于加密的安全性以防护攻击。

2.8.2 关联终止
SCTP不像TCP那样允许“半关闭”的关联。当一端关闭某个关联时,另一端必须停止发送新的数据。关联关闭请求的接收端发送完已经排队的数据(如果有的话)后,完成关联的关闭。图2-7展示了这一交换过程。

screenshot

SCTP没有类似于TCP的TIME_WAIT状态,因为SCTP使用了验证标记。所有后续块都在捆绑它们的SCTP分组的公共首部标记了初始的INIT块和INIT ACK块中作为起始标记交换的验证标记;由来自旧连接的块通过所在SCTP分组的公共首部间接携带的验证标记对于新连接来说是不正确的。因此,SCTP通过放置验证标记值就避免了TCP在TIME_WAIT状态保持整个连接的做法。

2.8.3 SCTP状态转换图
SCTP涉及关联建立和关联终止的操作可以用状态转换图(state transition diagram)来说明,如图2-8所示。

screenshot

与图2-4一样,本状态机中从一个状态到另一个状态的转换由SCTP规则基于当前状态及在该状态下所接收的块规定。举例来说,当某个应用进程在CLOSED状态下执行主动打开时,SCTP将发送一个INIT,且新的状态是COOKIE-WAIT。如果这个SCTP接着接收到一个INIT ACK,它将发送一个COOKIE ECHO,且新的状态是COOKIE-ECHOED。如果该SCTP随后接收到一个COOKIE ACK,它将转换成ESTABLISHED状态。这个最终状态是绝大多数数据传送发生点的状态,尽管DATA块也可以由COOKIE ECHO块或COOKIE ACK块所在消息捆绑捎带。

从ESTABLISHED状态引出的两个箭头处理关联的终止。如果某个应用进程在接收到一个SHUTDOWN之前调用close(主动关闭),那就转换到SHUTDOWN-PENDING状态。否则,如果某个应用进程在ESTABLISHED状态期间接收到一个SHUTDOWN(被动关闭),那就转换到SHUTDOWN-RECEIVED状态。

2.8.4 观察分组
图2-9展示一个作为样例的SCTP关联所发生的实际分组交换情况,包括关联建立、数据传送和关联终止3个阶段。图中还展示了每个端点所历经的SCTP状态。

screenshot

本例中,客户在COOKIE ECHO块所在分组中捎带了它的第一个DATA块,服务器则在作为应答的COOKIE ACK块所在分组中捎带了数据。一般而言,当网络应用采用一到多接口式样时(我们将在9.2节中讨论一到一和一到多这两种接口式样),COOKIE ECHO通常捎带一个或多个DATA块。

SCTP分组中信息的单位称为块(chunk)。块是自描述的,包含一个块类型、若干个块标记和一个块长度。这样做方便了多个块的绑缚,只要把它们简单地组合到一个SCTP外出消息中([Stewart and Xie 2001]的第5章给出了块捆绑和常规数据传输过程的细节)。

2.8.5 SCTP选项
SCTP使用参数和块方便增设可选特性。新的特性通过添加这两个条目之一加以定义,并允许通常的SCTP处理规则汇报未知的参数和未知的块。参数类型字段和块类型字段的高两位指明SCTP接收端该如何处置未知的参数或未知的块([Stewart and Xie 2001]的3.1节给出了更多的细节)。

当前如下两个对SCTP的扩展正在开发中。

(1)动态地址扩展,允许协作的SCTP端点从已有的某个关联中动态增删IP地址。

(2)不完全可靠性扩展,允许协作的SCTP端点在应用进程的指导下限制数据的重传。当一个消息变得过于陈旧而无须发送时(按照应用进程的指导),该消息将被跳过而不再发送到对端。这意味着不是所有数据都确保到达关联的另一端。

相关文章
|
网络协议 API 数据处理
【网络编程】第2章(2) 应用程序接口(API)
【网络编程】第2章(2) 应用程序接口(API)
|
11月前
|
Unix 程序员 Linux
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
239 0
|
2月前
|
开发框架 Unix Linux
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
41 0
|
5月前
|
网络协议 Dubbo Java
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
36 0
|
5月前
|
缓存 JSON API
IOS网络编程:什么是 RESTful API?如何使用 RESTful 风格设计 API?
IOS网络编程:什么是 RESTful API?如何使用 RESTful 风格设计 API?
128 3
|
5月前
|
XML JSON API
Python 的网络编程:解释什么是 RESTful API?
Python 的网络编程:解释什么是 RESTful API?
51 1
|
11月前
|
存储 网络协议 API
网络编程必备:深入理解TCP/IP协议栈(含posix API实现)(下)
网络编程必备:深入理解TCP/IP协议栈(含posix API实现)
|
11月前
|
网络协议 算法 API
网络编程必备:深入理解TCP/IP协议栈(含posix API实现)(上)
网络编程必备:深入理解TCP/IP协议栈(含posix API实现)
|
Unix Linux
Linux本地套接字(Unix域套接字)----SOCK_DGRAM方式
这里介绍一下Linux进程间通信的socket方式---Local socket。这篇主要是介绍下SOCK_DGRAM方式的通信,即数据包的方式(与UDP类似),面向无连接。
293 0
|
Unix Shell API
Unix 进程 API 介绍
Unix 进程 API 介绍
134 0
下一篇
无影云桌面