背景
SCTP協定是眾多網路通信協定中的一種,為更好的理解SCTP協定,我們先來介紹協定棧的概念。協定棧是指網路中各層協定的總和,它形象的反映了網路中訊息的傳輸過程:即由上層套用協定到底層協定,再由底層傳輸協定到上層協定。
例如MSCS(MobileSwitchingCenterServer,移動交換中心伺服器)與MGW(MediaGateWay,媒體網關)網元之間是由H.248協定進行控制的,它通過SCTP協定進行訊息的傳輸,這兩個網元接口上的協定棧有兩種情形,如圖所示。
具體來說,MSCS網元傳送的H.248訊息向下經過SCTP的處理,增加了訊息頭、本端地址、對端地址等信息,經過IP傳輸到對方,對端收到之後,則像剝洋蔥一樣一層一層的剝開,最終解出H.248訊息交給MGW網元上層套用進行處理。
簡介
SCTP是一個面向連線的流傳輸協定,它可以在兩個端點之間提供穩定、有序的數據傳遞服務。SCTP可以看做是TCP協定的改進,它繼承了TCP較為完善的擁塞控制並改進TCP的一些不足之處:
SCTP與TCP的最大不同之處在於它是多宿主(Multi-homing)連線,而TCP是單地址連線。
一個TCP連線只能支持一個流,一個SCTP連線可以支持多個流(Multi-streaming)。在SCTP協定中,流(Stream)是指從一個SCTP端點到另一端點之間建立的單向邏輯通路,通常情況下所有用戶訊息在流中按序傳遞。
SCTP有更好的安全性。
SCTP實際上是一個面向連線的協定,但SCTP偶聯的概念要比TCP的連線具有更廣的概念,SCTP對TCP的缺陷進行了一些完善,使得信令傳輸具有更高的可靠性,SCTP的設計包括適當的擁塞控制、防止泛濫和偽裝攻擊、更優的實時性能和多歸屬性支持。
SCTP最初是被設計用於在IP上傳輸電話,把SS7(SignalingSystemNo.7,七號信令系統)信令網路的一些可靠特性引入IP。IETF的這方面的工作稱為信令傳輸SIGTRAN。與此期間,也提出了這個協定的其他一些用途。
SCTP提供如下服務:
確認用戶數據的無錯誤和無複製傳輸;
數據分段以符合發現路徑最大傳輸單元的大小;
在多數據流中用戶信息的有序傳送,帶有一個選項,用戶信息可以按到達順序傳送;
選擇性的將多個用戶信息綁定到單個SCTP包;
通過關聯的一個終端或兩個終端多重宿主支持來為網路故障規定容度。
套用
移動通信網路中,SCTP協定在IP承載連線的情況下廣泛得到套用,網路示意圖中多條網元連線均有SCTP協定的運用,如圖所示。RNS(RadioNetworkSubsystem,無線網路子系統)與MSCS之間:如果採用M3UA(MTP3-UserAdaptationlayerprotocol,MTP第三層的用戶適配層協定),協定棧為IP/SCTP/M3UA/SCCP/RANAP;
MGW與MSCS之間,如果採用M3UA,協定棧為IP/SCTP/M3UA/H.248,同時H.248也可以直接承載在SCTP之上;
HLR(HomeLocationRegister,歸屬位置暫存器)與MSCS/VLR之間,如果採用M3UA,協定棧為IP/SCTP/M3UA/SCCP/TCAP/MAP;
PSTN(PublicSwitchedTelephoneNetwork,公共交換電話網)與MSCS之間,SCTP協定在完成傳統的七號信令和IP網路之間信息傳輸起到了重要作用。
關係
作為一個傳輸層協定,SCTP兼有TCP及UDP兩者的特點。SCTP可以稱為是TCP的改進協定,但它們之間仍然存在著較大的差別。
首先SCTP和TCP之間的最大區別是SCTP的連線可以是多宿主連線的,TCP則一般是單地址連線的。在進行SCTP建立連線時,雙方均可聲明若干IP地址(IPv4,IPv6或主機名)通知對方本端所有的地址。若當前連線失效,則可切換到另一個地址,而不需要重新建立連線。
其次SCTP是基於訊息流,而TCP則是基於位元組流。所謂基於訊息流,是指傳送數據和應答數據的最小單位是訊息包(chunk)。一個SCTP連線(Association)同時可以支持多個流(stream),每個流包含一系列用戶所需的訊息數據(chunk)。而TCP則只能支持一個流。
在網路安全方面,SCTP增加了防止惡意攻擊的措施。不同於TCP連線採用的三次握手機制,SCTP連線採用四次握手機制,有效的防止了類似於SYNFlooding的防範拒絕服務攻擊。SCTP主要的貢獻是對多重聯外線路的支持,一個端點可以由多於一個IP位址組成,使得傳輸可在主機間或網卡間做到透明的網路容錯備援。
包結構
一個數據SCTP包首部可跟一個或多個可變長的塊。塊採用TLV(Type/Length/Value,類型/長度/值)的格式。
源連線埠、目的連線埠、校驗碼的意義同TCP中的意義相似。確認標籤保存著在SCTP握手中第一次交換的初始標籤的值。在關聯中,任何SCTP數據包若不包含這樣一個標籤,當到達時會被接收端丟棄。
在每個塊中,TLV包括塊類型、傳輸處理標記、塊長度。不同的塊類型可用來傳輸控制信息或數據。
TSN(TransmissionSequenceNumber,傳輸順序號)和SSN(StreamSequenceNumber,流順序號)是兩種不同的序列號,TSN保證整個關聯的可靠性,而SSN保證整個流的有序性,這樣,在傳輸中,將數據的可靠性與有序性獨立分開。
數據交換
在兩個SCTP主機間的正常數據交換。SCTP主機傳送SACK(SelectiveAcknowledgement,選擇性確認)塊,用來確認每一個收到的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)的概念,它也是存在於兩台主機之間,但可以使用每台主機上的多個接口進行協作。圖片闡述了TCP連線與SCTP聯合之間的區別。該圖的上面部分是TCP連線,每個主機都只包含一個網路接口;連線是在每個客戶機和伺服器之間的單個接口之間建立的。在建立連線時,就被綁定到了每個接口上。在該圖的下面部分中,您可以看到這樣一個架構:每台主機上都包含兩個網路接口。通過獨立網路提供了兩條路徑,一條是從接口C0到S0,另外一條是從接口C1到S1。在SCTP中,這兩條路徑可以合併到一個聯合中。
SCTP負責使用內嵌的heartbeat機制來監視聯合的路徑;在檢測到一條路徑失效時,協定就會通過另外一條路徑來傳送通信數據。應用程式甚至都不必知道發生了故障恢復。故障轉移也可以用於維護網路應用程式的連通性。例如,讓我們來考慮一台包含一個無線802.11接口和一個乙太網接口的筆記本的例子。當筆記本放到固定的位置上時,我們傾向於使用高速的乙太網接口(在SCTP中稱為主地址(primaryaddress));但是在這個連線丟失時(例如離開了固定位置),連線可遷移到無線接口上。在返回固定位置時,乙太網連線會被重新檢測到,通信就可以在這個接口上恢復。這是一種能提供更高的可用性和可靠性的強大機制。
多流
從某種意義上來講,SCTP連線與TCP連線類似,不同之處只是SCTP能夠在一個聯合中支持多流機制。一個聯合中的所有流都是獨立的,但均與該聯合相關(參見右圖)。每個流都給定了一個流編號,它被編碼到SCTP報文中,通過聯合在網路上傳送。多流非常重要,因為阻塞的流(例如等待重傳的流會導致報文的丟失)不會影響同一聯合中的其他流。這個問題統稱為head-of-lineblocking(對頭阻塞)。TCP很容易出現這類阻塞問題。
多流如何在傳輸數據時提供更好的回響性呢?例如,HTTP協定會在相同套接字上共享控制和數據。Web客戶機從伺服器上請求一個檔案,伺服器通過相同的連線將這個檔案發回給客戶機。多流的HTTP伺服器可以提供更好的互動能力,因為在聯合中各單獨的流上可以處理多個請求。這種功能可以並行化回響,儘管速度不一定會更快,但可以同時載入HTML和圖像映像,從而表現出更好的回響性。
多流處理是SCTP的一個重要特性,尤其是在協定的設計中考慮一些控制和數據的問題時更是如此。在TCP中,控制和數據通常都是通過相同的連線進行共享的,這可能會產生問題,因為控制報文可能會在數據報之後延時。如果控制和數據被劃分成單獨的流,控制數據就可以以一種更及時的方式進行處理,從而可以更好地利用可用資源。
初始化保護
TCP和SCTP中對新連線的初始化是通過報文握手來完成的。在TCP中,這種機制稱為三次握手(three-wayhandshake)。客戶機向伺服器首先傳送一個SYN報文(Synchronize的簡寫),伺服器使用一個SYN-ACK報文進行回響(Synchronize-Acknowledge)。最後,客戶機使用一個ACK報文確認已接收到報文(請參見右圖)。當惡意客戶機使用虛假的源地址來偽造一個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在數據傳輸中提供了訊息分幀功能。當一端對一個套接字執行寫操作時,可確保對等端讀出的數據大小與此相同(請參見右圖)。對於面向流的數據來說,例如音頻和視頻數據,可以沒有分幀機制。
可配置無序傳送
SCTP中的訊息的傳輸十分可靠,但未必是按照想要的次序來傳輸的。TCP可以確保數據是按照次序傳送的(考慮到TCP是一種流協定,這是一件好事)。UDP無法確保有序地傳送數據。但是如果需要,您也可以在SCTP中配置流來接受無序的訊息。這種特性在面向訊息的協定中可能非常有用,因為其中的訊息都是獨立的,次序並不重要。另外,您可以在一個聯合中按照逐個流配置無序傳送。
平滑關閉
TCP和SCTP都是基於連線的協定,而UDP則是一種無連線的協定。TCP和SCTP都需要在對等的兩端建立和拆除連線。SCTP與TCP中關閉連線的不同之處在於TCP中連線的刪除是半關閉(half-close)的。右圖給出了TCP和SCTP的關閉序列。TCP中,一端可以關閉自己這端的socket(這樣會導致傳送一個FIN報文),但是仍然可以繼續接收數據。FIN說明這個端點不會再傳送數據,但是在這一端關閉自己這端的套接字之前,它一直可以繼續傳輸數據。應用程式很少使用這種半關閉狀態,因此SCTP的設計者就選擇放棄這種狀態,並將其替換成了一個顯式的終結序列。當一端關閉自己的套接字時(導致產生一個SHUTDOWN原語),對等的兩端全部需要關閉,將來任何一端都不允許再進行數據的移動了。
四路握手
一個SCTP關聯定義為:[主機A的一組IP位址]+[主機A的連線埠]+[主機B的一組IP位址]+[主機B的連線埠]。因此,每一端對應組中的任何一個IP位址都可作為相應的源/目的地址來標示本次關聯,通過四路握手,兩端SCTP主機交換通信狀態。
SYNFlooding利用了TCP/IP的固有漏洞,面向連線的TCP三次握手是SYNFlooding存在的基礎。
SYNFlooding攻擊的原理是:惡意的攻擊者大量向伺服器傳送SYN報文,伺服器在發出SYN+ACK應答報文後無法收到客戶端的ACK報文(第三次握手無法完成),伺服器端將為維護一個非常大的半連線列表而消耗非常多的CPU時間和記憶體資源,還要不斷對這個列表中的IP進行SYN+ACK的重試。伺服器端將忙於處理攻擊者偽造的TCP連線請求而無暇理睬客戶的正常請求,此時從正常客戶的角度看來,伺服器失去回響。
而在一次SCTP四路握手中,INIT(Initiation,開始)訊息的接收端不必保存任何狀態信息或者分配任何資源,這樣就可防範SYNFlooding等DoS攻擊。它在傳送INIT-ACK訊息時,採用了一種機制“狀態Cookie”,該Cookie具有傳送端要建立自己狀態所需的全部信息。
SCTP產生一個狀態Cookie的過程如下:
1.使用收到的INIT和發出的INIT-ACK塊中的信息創建一個關聯的TCB(TransmissionControlBlock,傳輸控制塊)。
2.在TCB中,將當前日期設為創建日期,將協定參數“有效Cookie時間”設為生存期間。
3.根據TCB,收集重建TCB所需的最小信息子集,將該子集和密鑰產生一個MAC(MessageAuthenticationCode,訊息驗證碼)。
4.結合上述最小信息子集和MAC產生狀態Cookie。
5.在傳送完INITACK(包含狀態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。在MicrosoftWindows作業系統上也有第三方的商業包可以使用。
在獲得高可用性的同時,應用程式也已經開始使用SCTP作為自己的主要傳輸機制。諸如FTP(FileTransferProtocol,檔案傳輸協定)和HTTP(HypertextTransferProtocol,超文本傳輸協定)之類的傳統應用程式已經在SCTP的特性基礎上進行了構建。其他一些協定也正在開始使用SCTP,例如SIP(SessionInitiationProtocol,會話初始化協定)和SS7(SignalingSystemNo.7,七號信令系統)。在商業領域中,您可以在Cisco的IOS(Inter-OperationSpecification,互操作規範)中找到SCTP的影子。
隨著SCTP被吸納到2.6版本的Linux核心中,我們可以構建並部署高可用性、高可靠性的網路應用程式。作為一種基於IP的協定,SCTP不但可以無縫地替換TCP和UDP,而且擴展了很多新服務,例如多宿主、多流,並且對安全性也有了很大的提高。