SCTP
IETF定義的傳輸層協議
SCTP(Stream Control Transmission Protocol,流控制傳輸協議)是IETF(Internet Engineering Task Force,網際網路工程任務組)在2000年定義的一個傳輸層(Transport Layer)協議,是提供基於不可靠傳輸業務的協議之上的可靠的數據報傳輸協議。SCTP的設計用於通過IP網傳輸SCN(Signaling Communication Network,信令通信網)窄帶信令消息。後期廣泛用於EPC網路中的S6a/S1/Sgs/Sv等介面中。
協議棧是指網路中各層協議的總和,它形象的反映了網路中消息的傳輸過程:即由上層應用協議到底層協議,再由底層傳輸協議到上層協議。
例如MSCS(Mobile Switching Center Server,移動交換中心伺服器)與MGW(Media GateWay,媒體網關)網元之間是由H.248協議進行控制的,它通過SCTP協議進行消息的傳輸,這兩個網元介面上的協議棧有兩種情形,如圖1所示。
圖1 MSCS和MGW網元的介面協議棧示例
SCTP是一個面向連接的流傳輸協議,它可以在兩個端點之間提供穩定、有序的數據傳遞服務。SCTP可以看做是TCP協議的改進,它繼承了TCP較為完善的擁塞控制並改進TCP的一些不足之處:
l SCTP與TCP的最大不同之處在於它是多宿主(Multi-homing)連接,而TCP是單地址連接。
l 一個TCP連接只能支持一個流,一個SCTP連接可以支持多個流(Multi-streaming)。在SCTP協議中,流(Stream)是指從一個SCTP端點到另一端點之間建立的單向邏輯通路,通常情況下所有用戶消息在流中按序傳遞。
l SCTP有更好的安全性。
SCTP實際上是一個面向連接的協議,但SCTP偶聯的概念要比TCP的連接具有更廣的概念,SCTP對TCP的缺陷進行了一些完善,使得信令傳輸具有更高的可靠性,SCTP的設計包括適當的擁塞控制、防止泛濫和偽裝攻擊、更優的實時性能和多歸屬性支持。
SCTP最初是被設計用於在IP上傳輸電話,把SS7(Signaling System No. 7,七號信令系統)信令網路的一些可靠特性引入IP。IETF的這方面的工作稱為信令傳輸SIGTRAN。與此期間,也提出了這個協議的其他一些用途。
SCTP提供如下服務:
l 確認用戶數據的無錯誤和無複製傳輸;
l 數據分段以符合發現路徑最大傳輸單元的大小;
l 在多數據流中用戶信息的有序發送,帶有一個選項,用戶信息可以按到達順序發送;
l 選擇性的將多個用戶信息綁定到單個SCTP包;
l 通過關聯的一個終端或兩個終端多重宿主支持來為網路故障規定容度。
移動通信網路中,SCTP協議在IP承載連接的情況下廣泛得到應用,網路示意圖中多條網元連接均有SCTP協議的運用,如圖2所示。
圖2 SCTP協議應用示例圖
l MGW與MSCS之間,如果採用M3UA,協議棧為IP/SCTP/M3UA/H.248,同時H.248也可以直接承載在SCTP之上;
l HLR(Home Location Register,歸屬位置寄存器)與MSCS/VLR之間,如果採用M3UA,協議棧為IP/SCTP/M3UA/SCCP/TCAP/MAP;
l PSTN(Public Switched Telephone Network,公共交換電話網)與MSCS之間,SCTP協議在完成傳統的七號信令和IP網路之間信息傳輸起到了重要作用。
作為一個傳輸層協議,SCTP兼有TCP及UDP兩者的特點。SCTP可以稱為是TCP的改進協議,但它們之間仍然存在著較大的差別。
l 首先SCTP和TCP之間的最大區別是SCTP的連接可以是多宿主連接的,TCP則一般是單地址連接的。在進行SCTP建立連接時,雙方均可聲明若干IP地址(IPv4,IPv6或主機名)通知對方本端所有的地址。若當前連接失效,則可切換到另一個地址,而不需要重新建立連接。
l 其次SCTP是基於消息流,而TCP則是基於位元組流。所謂基於消息流,是指發送數據和應答數據的最小單位是消息包(chunk)。一個SCTP連接(Association)同時可以支持多個流(stream),每個流包含一系列用戶所需的消息數據(chunk)。而TCP則只能支持一個流。
l 在網路安全方面,SCTP增加了防止惡意攻擊的措施。不同於TCP連接採用的三次握手機制,SCTP連接採用四次握手機制,有效的防止了類似於SYN Flooding的防範拒絕服務攻擊。SCTP主要的貢獻是對多重聯外線路的支持,一個端點可以由多於一個IP地址組成,使得傳輸可在主機間或網卡間做到透明的網路容錯備援。
SCTP
源埠、目的埠、校驗碼的意義同TCP中的意義相似。確認標籤保存著在SCTP握手中第一次交換的初始標籤的值。在關聯中,任何SCTP數據包若不包含這樣一個標籤,當到達時會被接收端丟棄。
在每個塊中,TLV包括塊類型、傳輸處理標記、塊長度。不同的塊類型可用來傳輸控制信息或數據。
TSN(Transmission Sequence Number,傳輸順序號)和SSN(Stream Sequence Number,流順序號)是兩種不同的序列號,TSN保證整個關聯的可靠性,而SSN保證整個流的有序性,這樣,在傳輸中,將數據的可靠性與有序性獨立分開。
在兩個SCTP主機間的正常數據交換。SCTP主機發送SACK(Selective Acknowledgement,選擇性確認)塊,用來確認每一個收到的SCTP包。因為SACK能完整地描述接收端的狀態,因此,依據SACK,發送端能做出重傳判決。SCTP支持類似於TCP中的快速重傳和time-out重傳演演算法。
對於數據包丟失發現,SCTP和TCP採用截然不同的機制:當TCP發現接收序號有缺口時,會等到該缺口被填上后,才發送序列號高於丟失數據包的數據。然而,SCTP即使發現接收序號有缺口或順序錯亂,仍會發送後面的數據。
作為面向連接的傳輸協議,SCTP也運用三路握手來關閉一個關聯,但與TCP有一點不同:一個TCP終端在“關聯關閉”的過程中能夠保持連接開啟,並從對端接收新的數據,而SCTP不支持TCP的這種“半關閉”狀態。
1.主機A發出“關閉”(SHUTDOWN)塊來終止與主機B的關聯,主機A進入“SHUTDOWN-PENDING”狀態,對應的動作是:不再接受上層應用的數據,只發送隊列中剩餘的數據,進入“SHUTDOWN-SENT”狀態。
2.主機B一旦接收到“關閉”塊,就進入“SHUTDOWN-RECEIVED”狀態,同主機A一樣,不再接受上層應用的數據,只發送隊列中剩餘的數據。
3.主機A再次發送“關閉”塊,通知主機B所發送的剩餘數據已到達,並且重申了關聯正在關閉。
4.當第二次收到“關閉”塊時,主機B發送“確認關閉”塊。
5.主機A隨後發送“關閉結束”塊,完成本次關聯的關閉。
多宿主
多宿主為應用程序提供了比TCP更高的可用性。多宿主主機就是一台具有多個網路介面的主機,因此可以通過多個IP地址來訪問這台主機。在TCP中,連接(connection)是指兩個端點之間的一個通道(在這種情況下,就是兩台主機的網路介面之間的一個套接字)。SCTP引入了聯合(association)的概念,它也是存在於兩台主機之間,但可以使用每台主機上的多個介面進行協作。圖2闡述了TCP連接與SCTP聯合之間的區別。
SCTP
該圖的上面部分是TCP連接,每個主機都只包含一個網路介面;連接是在每個客戶機和伺服器之間的單個介面之間建立的。在建立連接時,就被綁定到了每個介面上。在該圖的下面部分中,您可以看到這樣一個架構:每台主機上都包含兩個網路介面。通過獨立網路提供了兩條路徑,一條是從介面C0到S0,另外一條是從介面C1到S1。在SCTP中,這兩條路徑可以合併到一個聯合中。
SCTP負責使用內嵌的heartbeat機制來監視聯合的路徑;在檢測到一條路徑失效時,協議就會通過另外一條路徑來發送通信數據。應用程序甚至都不必知道發生了故障恢復。故障轉移也可以用於維護網路應用程序的連通性。例如,讓我們來考慮一台包含一個無線802.11介面和一個乙太網介面的筆記本的例子。當筆記本放到固定的位置上時,我們傾向於使用高速的乙太網介面(在SCTP中稱為主地址(primaryaddress));但是在這個連接丟失時(例如離開了固定位置),連接可遷移到無線介面上。在返回固定位置時,乙太網連接會被重新檢測到,通信就可以在這個介面上恢復。這是一種能提供更高的可用性和可靠性的強大機制。
多流
從某種意義上來講,SCTP連接與TCP連接類似,不同之處只是SCTP能夠在一個聯合中支持多流機制。一個聯合中的所有流都是獨立的,但均與該聯合相關(參見圖3)。
SCTP
每個流都給定了一個流編號,它被編碼到SCTP報文中,通過聯合在網路上傳送。多流非常重要,因為阻塞的流(例如等待重傳的流會導致報文的丟失)不會影響同一聯合中的其他流。這個問題統稱為head-of-lineblocking(對頭阻塞)。TCP很容易出現這類阻塞問題。
多流如何在傳輸數據時提供更好的響應性呢?例如,HTTP協議會在相同套接字上共享控制和數據。Web客戶機從伺服器上請求一個文件,伺服器通過相同的連接將這個文件發回給客戶機。多流的HTTP伺服器可以提供更好的交互能力,因為在聯合中各單獨的流上可以處理多個請求。這種功能可以并行化響應,儘管速度不一定會更快,但可以同時載入HTML和圖像映像,從而表現出更好的響應性。
多流處理是SCTP的一個重要特性,尤其是在協議的設計中考慮一些控制和數據的問題時更是如此。在TCP中,控制和數據通常都是通過相同的連接進行共享的,這可能會產生問題,因為控制報文可能會在數據報之後延時。如果控制和數據被劃分成單獨的流,控制數據就可以以一種更及時的方式進行處理,從而可以更好地利用可用資源。
初始化保護
TCP和SCTP中對新連接的初始化是通過報文握手來完成的。在TCP中,這種機制稱為三次握手(three-wayhandshake)。客戶機向伺服器首先發送一個SYN報文(Synchronize的簡寫),伺服器使用一個SYN-ACK報文進行響應(Synchronize-Acknowledge)。最後,客戶機使用一個ACK報文確認已接收到報文(請參見圖4)。
圖4.TCP和STCP握手使用的報文交換
當惡意客戶機使用虛假的源地址來偽造一個IP報文時,TCP就會出現問題了,這會大量TCPSYN報文攻擊伺服器。伺服器在接收SYN報文之前,要為連接分配資源,但是在大量產生SYN報文的情況下,最終會耗盡自己的資源,從而無法處理新的請求。這種情況就稱為服務拒絕(DenialofService)(DoS)攻擊。
SCTP可以通過一種4次握手的機制並引入cookie的概念來有效地防止這種攻擊的產生。在SCTP中,客戶機使用一個INIT報文發起一個連接。伺服器使用一個INIT-ACK報文進行響應,其中就包括了cookie(標識這個連接的惟一上下文)。客戶機然後就使用一個COOKIE-ECHO報文進行響應,其中包含了伺服器所發送的cookie。伺服器要為這個連接分配資源,並通過向客戶機發送一個COOKIE-ACK報文對其進行響應。
要解決使用這種4次握手機制解決延時數據移動的問題,SCTP允許把數據包含到COOKIE-ECHO和COOKIE-ACK報文中。
消息分幀
使用消息分幀機制,就可以保護消息只在一個邊界內通過socket進行通信;這意味著如果客戶機向伺服器先發送100個位元組,然後又發送50個位元組。那麼伺服器就會在兩次讀取操作中分別讀取到100個位元組和50個位元組。UDP也是這樣進行操作,這對於面向消息的協議非常有益。
與此不同,TCP是按照位元組流的方式進行操作。如果沒有分幀機制,一端接收到的數據可能比另外一端發送的數據多或少(這會將一次寫操作劃分成多次操作,或者將多次寫操作合併到一個讀操作中)。這種行為需要在TCP之上進行操作的面向消息的協議可以在應用層中提供數據緩衝和消息分幀機制(這可能是一項複雜的任務)。
SCTP在數據傳輸中提供了消息分幀功能。當一端對一個套接字執行寫操作時,可確保對等端讀出的數據大小與此相同(請參見圖5)。對於面向流的數據來說,例如音頻和視頻數據,可以沒有分幀機制。
SCTP
可配置的無序發送
SCTP中的消息的傳輸十分可靠,但未必是按照想要的次序來傳輸的。TCP可以確保數據是按照次序發送的(考慮到TCP是一種流協議,這是一件好事)。UDP無法確保有序地發送數據。但是如果需要,您也可以在SCTP中配置流來接受無序的消息。這種特性在面向消息的協議中可能非常有用,因為其中的消息都是獨立的,次序並不重要。另外,您可以在一個聯合中按照逐個流配置無序發送。
平滑關閉
TCP和SCTP都是基於連接的協議,而UDP則是一種無連接的協議。TCP和SCTP都需要在對等的兩端建立和拆除連接。SCTP與TCP中關閉連接的不同之處在於TCP中連接的刪除是半關閉(half-close)的。圖6給出了TCP和SCTP的關閉序列。
圖6TCP和SCTP的連接結束序列
TCP中,一端可以關閉自己這端的socket(這樣會導致發送一個FIN報文),但是仍然可以繼續接收數據。FIN說明這個端點不會再發送數據,但是在這一端關閉自己這端的套接字之前,它一直可以繼續傳輸數據。應用程序很少使用這種半關閉狀態,因此SCTP的設計者就選擇放棄這種狀態,並將其替換成了一個顯式的終結序列。當一端關閉自己的套接字時(導致產生一個SHUTDOWN原語),對等的兩端全部需要關閉,將來任何一端都不允許再進行數據的移動了。
SCTP四路握手及抵抗SYN Flooding攻擊的原理
一個SCTP關聯定義為:[主機A的一組IP地址]+[主機A的埠]+ [主機B的一組IP地址]+[主機B的埠]。因此,每一端對應組中的任何一個IP地址都可作為相應的源/目的地址來標示本次關聯,通過四路握手,兩端SCTP主機交換通信狀態。
SYN Flooding利用了TCP/IP的固有漏洞,面向連接的TCP三次握手是SYN Flooding存在的基礎。
SYN Flooding攻擊的原理是:惡意的攻擊者大量向伺服器發送SYN報文,伺服器在發出SYN+ACK應答報文後無法收到客戶端的ACK報文(第三次握手無法完成),伺服器端將為維護一個非常大的半連接列表而消耗非常多的CPU時間和內存資源,還要不斷對這個列表中的IP進行SYN+ACK的重試。伺服器端將忙於處理攻擊者偽造的TCP連接請求而無暇理睬客戶的正常請求,此時從正常客戶的角度看來,伺服器失去響應。
而在一次SCTP四路握手中,INIT(Initiation,開始)消息的接收端不必保存任何狀態信息或者分配任何資源,這樣就可防範SYN Flooding等DoS攻擊。它在發送INIT-ACK消息時,採用了一種機制“狀態Cookie”,該Cookie具有發送端要建立自己狀態所需的全部信息。
SCTP產生一個狀態Cookie的過程如下:
1.使用收到的INIT和發出的INIT-ACK塊中的信息創建一個關聯的TCB(Transmission Control Block,傳輸控制塊)。
2.在TCB中,將當前日期設為創建日期,將協議參數“有效Cookie時間”設為生存期間。
3.根據TCB,收集重建TCB所需的最小信息子集,將該子集和密鑰產生一個MAC(Message Authentication Code,消息驗證碼)。
4.結合上述最小信息子集和MAC產生狀態Cookie。
5.在發送完INIT ACK(包含狀態Cookie參數)后,發送方必須刪除TCB以及任何與新關聯有關的本地資源。
INIT和INIT-ACK都必須包含建立初始狀態所需的參數:一組IP地址,保證可靠傳輸的初始TSN,每個被接收的SCTP包中必須含有的初始標籤,每一端請求發出的流數目和每一端能支持接收的流數目。
交換完這些消息之後,INIT的發送端以COOKIE-ECHO消息的方式發送回狀態Cookie。接收端根據所接收到的COOKIE-ECHO中的狀態Cookie,完整地重建自己的狀態,並回送COOKIE-ACK來確認關聯已建立。COOKIE-ECHO和COOKIE-ACK都可將用戶數據消息綁定到各自的包中。
由此可見,採用以上這種方式,即使接收再多的INIT消息,接收端也沒有任何資源的消耗:它既不分配任何系統資源,也不保存此次新關聯的狀態,它只是把相應重建狀態所用的狀態Cookie作為參數,包含在每一個回送的INIT-ACK消息中,最後該狀態Cookie會被COOKIE-ECHO消息發送回來。
SCTP是一個相當新的協議,它在2000年10月份才成為一個RFC規範。從那以後,它開始進入所有的主流操作系統,包括GNU/Linux、BSD和Solaris。在Microsoft Windows操作系統上也有第三方的商業包可以使用。
在獲得高可用性的同時,應用程序也已經開始使用SCTP作為自己的主要傳輸機制。諸如FTP(File Transfer Protocol,文件傳輸協議)和HTTP(Hypertext Transfer Protocol,超文本傳輸協議)之類的傳統應用程序已經在SCTP的特性基礎上進行了構建。其他一些協議也正在開始使用SCTP,例如SIP(Session Initiation Protocol,會話初始化協議)和SS7(Signaling System No.7,七號信令系統)。在商業領域中,您可以在Cisco的IOS(Inter-Operation Specification,互操作規範)中找到SCTP的影子。
隨著SCTP 被吸納到2.6版本的Linux內核中,我們可以構建並部署高可用性、高可靠性的網路應用程序。作為一種基於IP的協議,SCTP不但可以無縫地替換TCP和UDP,而且擴展了很多新服務,例如多宿主、多流,並且對安全性也有了很大的提高。