SCTP流控制传输协议(Stream Control Transmission Protocol)是一种在网络连接两端之间同时传输多个数据流的协议。SCTP提供的服务于UDP和TCP类似。和TCP类似,SCTP是面向连接、端到端、全双工、带有流量和拥塞控制的可靠传输协议。SCTP的连接称为关联。不同之处如下
1、四次握手
SCTP的关联通过4次握手建立。相对于TCP的3次握手建立连接,SCTP的关联能够抵御拒绝服务(DoS)攻击,从而提高了安全性。数据只有在关联建立之后与关联关闭之前才可发送。SCTP的关联通过3次握手关闭,不支持类似TCP的半关闭连接。也就是在任何一方关闭关联后,对方即不再发送数据。
- 连接发起者(一般为客户端)SCTP发送一个INIT消息(初始化)。该消息包括了连接发起者的IP地址清单、初始***、用于标识本耦联中所有报文的起始标记、客户请求的外出流的数目以及客户能够支持的外来流的数目
- 对端(服务器)发送一个INITACK消息确认连接发起者的INIT消息,其中含有服务器的IP地址清单、初始***、起始标记、服务器请求的外出流的数目、服务器能够支持的外来流的数目以及一个状态cookie,状态cookie包含服务器用于确信本耦联有效所需的所有状态,cookie是经过数字签名的,因而可以确保其有效性
- 客户以一个COOKIEECHO消息返回服务器的状态cookie,除COOKIEECHO外,该消息可能在同一个报文中捆绑一个用户数据
- 服务器以一个COOKIEACK消息确认客户返回的cookie是正确的,到此时该耦联就建立成功了。该消息也可能在同一个报文中捆绑一个用户数据。
在一次SCTP四次握手中,INIT消息的接收端不必保存任何状态信息或者分配任何资源,这样就可防范SYNFlooding等DoS攻击。它在发送INIT-ACK消息时,采用了一种机制——“状态Cookie”,该Cookie具有发送端要建立自己状态所需的全部信息。
用于建立连接的INIT ACK只能在COOKIE WATI状态收到,在其它状态收到该报文时都会直接丢弃,类似的,COOKIE ACK只能在COOKIE ECHOED状态接收。
在常规的握手中,主动发起方的本地tag在发起握手时产生,主动发起方的对端tag在收到INIT ACK时产生。而连接的被动方的本地tag和对端tag都在收到INIT时产生,但是最终要到收到了COOKIE ECO后才确定并保存下来。
SCTP产生一个状态Cookie的过程如下:
使用收到的INIT和发出的INIT-ACK块中的信息创建一个关联的TCB(传输控制块)。
在TCB中,将当前日期设为创建日期,将协议参数“有效Cookie时间”设为生存期间。
根据TCB,收集重建TCB所需的最小信息子集,将该子集和**产生一个MAC(信息认证编码)。
结合上述最小信息子集和MAC产生状态Cookie。
在发送完INITACK(包含状态Cookie参数)后,发送方必须删除TCB以及任何与新关联有关的本地资源。
INIT和INIT-ACK都必须包含建立初始状态所需的参数:一组IP地址,保证可靠传输的初始***,每个被接收的SCTP报文中必须含有的验证标签,每一端请求发出的流数目和每一端能支持接收的流数目。交换完这些消息之后,INIT的发送端以COOKIE-ECHO消息的方式发送回状态Cookie。接收端根据所接收到的COOKIE-ECHO中的状态Cookie,完整地重建自己的状态,并回送COOKIE-ACK来确认关联已建立。
因此对于SCTP,即使接收再多的INIT消息,接收端也没有任何资源的消耗:它既不分配任何系统资源,也不保存此次新关联的状态,它只是把相应重建状态所用的状态Cookie作为参数,包含在每一个回送的INIT-ACK消息中,最后该状态Cookie会被COOKIE-ECHO消息发送回来。
类似于TCP,SCTP也多由客户端执行主动打开,而服务器执行被动打开。
断开连接
与TCP不同,SCTP使用三次握手来关闭一个耦联。而且SCTP不支持TCP所支持的“半关闭”状态。典型的SCTP关闭一个耦联的过程如下:
- 应用程序发出关闭请求,SCTP耦联进入SHUTDOWN-PENDING状态,并且不再接收应用程序的数据,只发送队列中还未发送的数据,再队列中没有待发送数据后,发送SHUTWODN并进入SHUTDOWN-SENT状态。这一方被称为主动关闭。
- 执行被动关闭的一方在接收到主动关闭一方的SHUTWODN消息时,进入SHUTDOWN-RECEIVED状态,此时执行被动关闭一方不再接受上层应用的数据,只发送队列中剩余的数据。在发送队列中的数据被发送完后,执行被动关闭一方发送SHUTDOWN-ACK并进入SHUTDOWN-ACK-SENT状态。
- 执行主动关闭一方收到SHUTDOWN-ACK后就发送SHUTDOWN-COMPLETE,并进入CLOSE状态。
- 执行主动关闭一端接收到SHUTDOWN-COMPLETE后就进入close状态。
面向消息的传输
SCTP是一种面向消息的传输协议,从上层应用传递下来的数据以消息的形式传输。SCTP提供消息的定界功能。在接收端,数据以消息的形式递交。为便于传输,SCTP提供消息的拆分和组装,以及消息的捆绑传输功能。(TCP是以字节为单位传输)
SCTP的数据传输基本单位是块。每个SCTP包包括一个SCTP公共头部、一个或多个块。块有两种基本类型:控制块和数据块。控制块用于SCTP的连接控制,包括连接的建立、关闭、传输路径的维护等;数据块传送应用层的用户数据。
SCTP能给在所连接的端点之间提供多个流,每个流各自可靠地按序递送消息。一个流上某个消息的丢失不会阻塞同一关联其他流上消息的投递。这种做法与TCP正好相反,就TCP而言,在单一字节流中任何位置的字节丢失都将在阻塞该连接上其后所有数据的递送,直到该丢失被修复为止。
SCTP可以多路径传输
TCP的两端都只能用一个IP来建立连接,TCP通常是单路径传输,连接建立之后就只能用这一对IP来相互收发消息了。如果这一对IP之间的路径出了问题,那这条TCP连接就不可用了。
SCTP不一样的地方是,两端都可以绑定到多个IP上,只要有其中一对IP能通,这条SCTP连接就还可以用。
体现在socket API中,TCP只能bind一个IP,而SCTP可以bind到多个IP
SCTP可以多流独立有序/无序传输
一条SCTP连接里面,可以区分多条不同的流(stream),不同的流之间的数据传输互不干扰。这样做理论上的好处是,如果其中某一条流由于丢包阻塞了,那只会影响到这一条流,其他的流并不会被阻塞。但是实际上,如果某一条流由于丢包阻塞,其他的流通常也会丢包,被阻塞,最后导致所有的流都被阻塞,SCTP连接中断。
在同一条stream里面,SCTP支持有序/无序两种传输方式,应用程序在调用sendmsg()的时候,需要指定用哪一条stream传输,以及指定这条要发送的消息是需要有序传输还是无序传输的。如果在传输过程中丢包,则有序传递模式可能会在接收端被阻塞,而无序传输模式不会在接收端被阻塞。