TURN协议简要介绍
參考:https://www.rfc-editor.org/rfc/rfc5766.html?
?????? ? https://www.rfc-editor.org/rfc/rfc5389.html
目錄
1、新的STUN方法
2、新的STUN屬性
2.1、CHANNEL-NUMBER
2.2、LIFETIME
2.3、XOR-PEER-ADDRESS
2.4、DATA
2.5、XOR-RELAYED-ADDRESS
2.6、EVEN-PORT
2.7、REQUESTED-TRANSPORT
2.8、DONT-FRAGMENT
2.9、RESERVATION-TOKEN
3、新的STUN錯誤返回碼
4、詳細示例
TURN,在RFC5766中定義,英文全稱Traversal Using Relays around NAT(TURN):Relay Extensions to Session Traversal Utilities for NAT(STUN),即使用中繼穿透NAT:STUN的中繼擴展。簡單的說,TURN與STUN的共同點都是通過修改應用層中的私網地址達到NAT穿透的效果,異同點是TURN是通過兩方通訊的“中間人”方式實現穿透。
如果一個主機位于NAT的后面,在某些情況下它不能夠與其他主機點對點直接連接。在這些情況下,它需要使用中間網點提供的中繼連接服務。TURN協議就是用來允許主機控制中繼的操作并且使用中繼與對端交換數據。TURN與其他中繼控制協議不同的是它能夠允許一個客戶端使用一個中繼地址與多個對端連接。
TURN協議被設計為ICE的一部分,用于NAT穿越,雖然如此,它也可以在沒有ICE的地方單獨使用。
在典型配置中,TURN客戶端連接到專用網絡[RFC1918]并通過一個或多個NAT連接到公共互聯網。公共互聯網上有一個TURN服務器。互聯網上的其他地方是TURN客戶端希望與之通信的一個或多個對等體。這些對等體可能支持也可能不支持一個或多個NAT。客戶端使用服務器作為中繼向這些對等體發送數據包,并從這些對等體接收數據包。
圖1顯示了一個典型的部署。在此圖中,TURN客戶端和TURN服務器由NAT分開,客戶端位于NAT的私有端,服務器位于NAT的公共端。這個NAT被認為是一個“壞”NAT;例如,它可能具有“地址和端口相關映射”的映射屬性(參見[RFC4787])。
由于客戶端位于NAT之后,服務器將來自客戶端的數據包視為來自NAT本身的傳輸地址。這個地址被稱為客戶端的服務器反射傳輸地址;由服務器發送到客戶機的服務器反射傳輸地址的數據包將由NAT轉發到客戶機的主機傳輸地址。
客戶端使用TURN命令在服務器上創建和操作ALLOCATION。ALLOCATION是服務器上的數據結構。該數據結構包含分配的中繼(RELAYED)傳輸地址等。中繼傳輸地址是服務器上的傳輸地址,對等方可以使用它讓服務器將數據中繼到客戶端。分配由其中繼傳輸地址唯一標識。
一旦創建了allocation,客戶端可以向服務器發送應用程序數據以及數據將被發送到哪個對等體的指示,并且服務器將把該數據中繼到適當的對等體??蛻舳嗽赥URN消息中向服務器發送應用數據;在服務器上,數據從TURN消息中提取,并以UDP數據報的形式發送給對等方。相反,對等體可以將UDP數據報中的應用數據發送到中繼傳輸地址進行分配;然后,服務器將把這些數據封裝在TURN消息中,并將其發送給客戶端,同時指明是哪個對等方發送了這些數據。因為TURN消息總是包含客戶端正在與哪個對等體通信的指示,所以客戶端可以使用單個分配來與多個對等體通信。
當對等點位于NAT之后時,客戶端必須使用其服務器反射傳輸地址而不是主機傳輸地址來識別對等點。例如,在上面的示例中,要向對Peer A發送應用程序數據,客戶端必須指定192.0.2.150:32102(Peer A的服務器反射傳輸地址),而不是192.168.100.2: 49582(Peer A的主機傳輸地址)。
在圖2中,客戶端向服務器發送一個沒有憑據的Allocate請求。由于服務器要求使用stun的長期憑據機制對所有請求進行身份驗證,因此服務器會使用401(未授權)錯誤代碼拒絕該請求??蛻舳巳缓笤俅螄L試,這次包括憑證(未示出)。這一次,服務器接受Allocate請求,并返回Allocate成功響應,其中包含分配給分配的中繼傳輸地址。稍后,客戶端決定刷新Allocate,從而向服務器發送刷新請求。刷新被接受,服務器回復刷新成功響應。
1、新的STUN方法
本節列出了本規范中定義的新STUN方法的代碼點。有關這些新方法的語義,請參見本文的其他部分。
?? 0x003? :? Allocate????????? (only request/response semantics defined)
?? 0x004? :? Refresh?????????? (only request/response semantics defined)
?? 0x006? :? Send????????????? (only indication semantics defined)
?? 0x007? :? Data????????????? (only indication semantics defined)
?? 0x008? :? CreatePermission? (only request/response semantics defined
?? 0x009? :? ChannelBind?????? (only request/response semantics defined)
2、新的STUN屬性
這個STUN擴展定義了以下新屬性:
???? 0x000C: CHANNEL-NUMBER
???? 0x000D: LIFETIME
???? 0x0010: Reserved (was BANDWIDTH)
???? 0x0012: XOR-PEER-ADDRESS
???? 0x0013: DATA
???? 0x0016: XOR-RELAYED-ADDRESS
???? 0x0018: EVEN-PORT
???? 0x0019: REQUESTED-TRANSPORT
???? 0x001A: DONT-FRAGMENT
???? 0x0021: Reserved (was TIMER-VAL)
???? 0x0022: RESERVATION-TOKEN
其中一些屬性的長度不是4的倍數。根據STUN規則,任何長度不是4字節倍數的屬性都必須緊跟1到3個填充字節,以確保下一個屬性(如果有的話)從4字節邊界開始(參見[RFC5389])。
2.1、CHANNEL-NUMBER
CHANNEL-NUMBER屬性包含頻道號。該屬性的值部分為4字節長,由一個16位無符號整數組成,后跟一個二進制八位數RFFU (保留供將來使用)字段,該字段在傳輸時必須設置為0,在接收時必須忽略。
2.2、LIFETIME
LIFETIME屬性表示在沒有refresh的情況下服務器將維持allocation的持續時間。該屬性的值部分為4字節長,由一個32位無符號整數值組成,該整數值表示截止前剩余的秒數。
2.3、XOR-PEER-ADDRESS
XOR-PEER-ADDRESS指定TURN服務器上看到的peer的地址和端口。(例如,如果peer在NAT之后,則為peer的服務器反射傳輸地址。)其編碼方式與XOR-MAPPED-ADDRESS [RFC5389]相同
2.4、DATA
DATA屬性出現在所有Send和Data indication中。該屬性的值部分是可變長度的,由應用程序數據組成(也就是說,如果數據是在客戶端和peer之間直接發送的,將緊跟在UDP報頭之后的數據)。如果該屬性的長度不是4的倍數,則必須在該屬性之后添加填充。
2.5、XOR-RELAYED-ADDRESS
XOR-RELAYED-ADDRESS出現在Allocate響應中。它指定服務器分配給客戶端的地址和端口。它的編碼方式與XOR-MAPPED-ADDRESS[RFC5389]相同。
2.6、EVEN-PORT
此屬性允許客戶端請求中繼傳輸地址中的端口是偶數,并且(可選地)服務器保留下一個更高的端口號。該屬性的值部分長度為1字節。其格式是:
該值包含一個1位標志:
R:? 如果為1,則請求服務器保留下一個更高的端口號(在同一IP地址上)用于后續分配。如果為0,則不請求此類預訂。
屬性值的其他7位必須在傳輸時設置為零,在接收時忽略。
由于該屬性的長度不是4的倍數,填充必須緊跟在該屬性之后。
2.7、REQUESTED-TRANSPORT
客戶端使用該屬性為分配的傳輸地址請求特定的傳輸協議。此屬性的值為4字節,格式如下:
Protocol字段指定所需的協議。此字段中使用的代碼點取自IPv4報頭的協議字段和IPv4報頭[Protocol-Numbers]中的NextHeader字段中允許的代碼點。該規范只允許使用碼點17(User Datagram Protocol,UDP)。
RFFU字段在傳輸時必須設置為零,在接收時必須忽略。它是留作將來使用的。
2.8、DONT-FRAGMENT
客戶端使用該屬性請求服務器在將應用程序數據轉發給peer時設置IP報頭中的DF (Don't Fragment,不分段)位。該屬性沒有值部分,因此屬性長度字段為0。
2.9、RESERVATION-TOKEN
RESERVATION-TOKEN屬性包含唯一標識服務器保留的中繼傳輸地址的token。服務器在成功響應中包括該屬性,以告訴客戶端關于token的信息,并且客戶端在隨后的Allocate請求中包括該屬性,以請求服務器使用該中繼傳輸地址進行分配。
屬性值為8字節,包含token值。
3、新的STUN錯誤返回碼
本文檔定義了以下新的錯誤響應代碼:
? ? ? ? 403? (Forbidden,禁止):請求有效,但由于管理或類似限制而無法執行。
? ? ? ? 437 (Allocation Mismatch,Allocation不匹配):服務器收到請求,要求allocation到位,但不存在allocation;或者收到請求,? ? ? ? ? ? ? ? 不要求allocation,但存在allocation。
? ? ? ?441 (Wrong Credentials,錯誤的憑據):(非Allocate)請求中的憑據與用于創建allocation的憑據不匹配。
?????? 442 (Unsupported Transport Protocol,不支持的傳輸協議): Allocate請求要求服務器在服務器和peer之間使用服務器不支持? ? ? ? ? ? ? ? 的傳輸協議。注意:這不是指5元組中使用的傳輸協議。
?????? 486? (Allocation Quota Reached,已達到Allocation配額):目前無法使用此用戶名創建更多Allocation。
?????? 508? (Insufficient Capacity,容量不足):由于達到了某些容量限制,服務器無法執行請求。在Allocate響應中,這可能是因為? ? ? ? ? ? ? ? ?服務器當時沒有可用的中繼傳輸地址,沒有具有所請求屬性的地址,或者對應于指定預留token的地址不可用。
4、詳細示例
本節給出了TURN的使用示例,詳細顯示了所交換消息的內容。該示例使用概述中顯示的網絡圖(圖1)。
對于每條消息,都會顯示消息中包含的屬性及其值。為了方便起見,值以人類可讀的格式顯示,而不是顯示實際的八位字節;例如,"XOR-RELAYED-ADDRESS=192.0.2.15:9000"表示XOR-RELAYED-ADDRESS屬性包括192.0.2.15地址和9000端口,這里地址和端口在異或操作完成之前顯示。對于具有類似字符串值的屬性(例如,SOFTWARE="Example client, version 1.03"和NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm"),屬性的值以引號顯示,以提高可讀性,但這些引號不會出現在實際值中。
客戶端首先選擇一個用于TURN會話的主機傳輸地址;在這個例子中,客戶端選擇了10.1.1.2: 49721,如圖1所示??蛻舳巳缓笤诜掌鱾鬏數刂废蚍掌靼l送Allocate請求。客戶端為此事務隨機選擇96位事務0xA56250D3F17ABE679422DE85;這在固定頭的事務id字段中編碼??蛻舳税?strong>SOFTWARE屬性,該屬性給出關于客戶端軟件的信息;這里的值是"Example client, version 1.03",表示這是被稱為示例客戶端的1.03版??蛻舳税?strong>LIFETIME屬性,因為它希望分配具有比默認的10分鐘更長的生命周期;該屬性的值為3600秒,相當于1小時??蛻舳吮仨毷冀K在分配請求中包含REQUESTED-TRANSPORT屬性,并且該規范允許的唯一值是17,這表示服務器和對等方之間的UDP傳輸??蛻舳诉€包括DONT-FRAGMENT屬性,因為它希望稍后在發送指示中使用DONT-FRAGMENT屬性;這個屬性只包含一個屬性頭,沒有值部分。我們假設客戶端最近沒有與服務器交互,因此客戶端不包括USERNAME, REALM, NONCE, 或 MESSAGE-INTEGRITY屬性。最后,注意消息中屬性的順序是任意的(除了MESSAGE-INTEGRITY 和 FINGERPRINT),客戶端可能使用了不同的順序。
服務器要求對任何請求進行身份驗證。因此,當服務器收到初始Allocate請求時,它會拒絕該請求,因為該請求不包含身份驗證屬性。遵循STUN [RFC5389]的長期憑證機制的過程,服務器包括值為401(Unauthorized)的ERROR-CODE屬性、指定服務器所使用的認證領域的REALM屬性(在本例中是服務器的域“example.com”),以及NONCE屬性中的nonce值。服務器還包括一個SOFTWARE屬性,它提供了關于服務器軟件的信息。如下圖:
客戶端在接收到401錯誤后,重新嘗試Allocate請求,這次包括認證屬性。客戶端選擇一個新的事務id,然后用與以前相同的屬性填充新的Allocate請求??蛻舳税║SERNAME屬性,并使用從服務器接收的realm值來幫助它確定使用哪個值;在這里,客戶端被配置為將用戶名“george”用于領域“example.com”??蛻舳诉€包括REALM和NONCE屬性,它們是從401錯誤響應中復制的。最后,客戶端將MESSAGE-INTEGRITY屬性作為消息中的最后一個屬性,其值是Hashed消息。如下圖:
認證碼-安全哈希算法1 (HMAC-SHA1)對消息內容進行哈希處理(顯示為“...”以上);該HMAC-SHA1計算包括密碼值。因此,攻擊者不知道秘密密碼就無法計算message integrity。
服務器在收到認證的分配請求后,檢查一切正常,然后創建allocation。服務器以Allocate成功響應進行回復。服務器包括給出Allocate壽命的LIFETIME命屬性;這里,服務器已經將客戶端請求的1小時生命周期減少到20分鐘,因為該特定服務器不允許超過20分鐘的生命周期。服務器包括XOR-RELAYED-ADDRESS屬性,其值是分配的中繼傳輸地址。服務器包括XOR-MAPPED-ADDRESS屬性,其值是客戶端的服務器反射地址;該值不會反過來被使用,而是為了方便客戶端而返回。服務器包括MESSAGE-INTEGRITY屬性,以認證響應并確保其完整性;請注意,響應不包含USERNAME, REALM, 和 NONCE屬性。服務器還包括軟件屬性。如下圖:
然后,客戶端創建對Peer A的許可,為向其發送一些應用程序數據做準備。這是通過CreatePermission請求完成的。XOR-PEER-ADDRESS屬性包含為其建立許可的IP地址(peer A的ip地址);請注意,屬性中的端口號在CreatePermission請求中使用時會被忽略,這里它被設置為0;此外,請注意客戶端如何使用Peer A的服務器反射IP地址,而不是其(私有)主機地址??蛻舳耸褂门c上一次分配請求中相同的username, realm, 和 nonce。雖然允許這樣做,但客戶端選擇不在該請求中包含SOFTWARE屬性。
服務器接收CreatePermission請求,創建相應的權限,然后用CreatePermission成功響應進行回復。像客戶端一樣,服務器選擇不在其回復中包含SOFTWARE屬性。同樣,請注意成功響應如何包含MESSAGE-INTEGRITY屬性(假設服務器使用長期憑據機制),但不包含用USERNAME, REALM, 和NONCE屬性。
客戶端現在使用發送指示(indication)向Peer A發送應用程序數據。Peer A的服務器反射傳輸地址在XOR-PEER-ADDRESS屬性中指定,應用程序數據(此處僅顯示為“...”)在DATA屬性中指定。客戶端在應用層執行一種路徑MTU發現,因此指定(通過包含DONT-FRAGMENT屬性),服務器應該在UDP數據報中設置DF位以發送給peer。無法使用STUN的長期憑據機制對指示進行身份驗證,因此消息中不包含MESSAGE-INTEGRITY屬性。希望確保其數據不被更改或偽造的應用程序必須在應用程序級別完整保護其數據。
當接收到Send指示時,服務器提取應用數據,并在UDP數據報中將其發送到Peer A,中繼的傳輸地址作為數據報的源傳輸地址,DF位按請求設置。請注意,如果客戶端之前沒有為對Peer A的服務器反射IP地址建立權限,那么服務器會默默地丟棄發送指示。
Peer A然后用它自己的包含應用程序數據的UDP數據報進行回復。數據報被發送到服務器上的中繼傳輸地址。當它到達時,服務器創建一個Data指示,在XOR-PEER-ADDRESS屬性中包含UDP數據報的源,在DATA屬性中包含來自UDP數據報的數據。結果DATA指示隨后被發送到客戶端。
客戶端現在將channel綁定到Peer B,在CHANNEL-NUMBER屬性中指定空閑channel號(0x4000),在XOR-PEER-ADDRESS屬性中指定Peer B的傳輸地址。如前所述,客戶端重新使用消息中最后一次請求的username, realm, 和 nonce。
收到請求后,服務器將channel號綁定到peer,為Peer B的IP地址安裝權限,然后用ChannelBind成功響應進行回復。
客戶端現在向服務器發送一個包含去往Peer B的數據的ChannelData消息,ChannelData消息不是STUN消息,因此沒有事務ID。相反,它只有三個字段: channel號、數據和數據長度;這里的channel號字段是0x4000(客戶端剛剛綁定到對Peer B的通道)。當服務器接收到ChannelData消息時,它檢查channel當前是否被綁定(它是綁定的),然后使用中繼的傳輸地址作為源傳輸地址,使用192.0.2.210:49191(ChannelBind請求中XOR-PEER-ADDRESS屬性的值)作為目的傳輸地址,將數據以UDP數據報的形式向前發送到Peer B。
稍后,Peer B將UDP數據報發送回中繼傳輸地址。這導致服務器向客戶端發送包含UDP數據報數據的ChannelData消息。由于UDP數據報到達的中繼傳輸地址,服務器知道向哪個客戶端發送ChannelData消息,并且知道使用channel 0x4000,因為這是綁定到192.0.2.210:49191的channel。請注意,如果沒有任何channel號綁定到該地址,服務器會使用Data指示來代替。
在20分鐘生命周期結束之前,客戶端會刷新allocation。這是使用Refresh請求完成的。和以前一樣,客戶端在請求中包含最新的username, realm, 和 nonce。客戶端還包括SOFTWARE屬性,遵循推薦的做法,總是在Allocate and Refresh消息中包括該屬性。當服務器收到刷新請求時,它會注意到隨機數值已經過期,因此在給定新隨機數值的情況下,會以438(Stale Nonce)錯誤進行回復。然后,客戶端重新嘗試請求,這次使用新的nonce值。第二次嘗試被接受,服務器以成功響應進行回復。請注意,客戶端在請求中沒有包含LIFETIME屬性,因此服務器會刷新默認生命周期10分鐘的分配(從成功響應中的LIFETIME屬性可以看出)。
總結
以上是生活随笔為你收集整理的TURN协议简要介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 脑电波 睡眠分期 分类 预测 MATLA
- 下一篇: WebRTC之STUN、TURN和ICE