pjsip伺服器媒體轉發的簡單介紹

本文目錄一覽:

webrtc P2P之turn協議介紹

TURN的全稱為Traversal Using Relays around NAT,是STUN/RFC5389的一個拓展,主要添加了Relay功能。如果終端在NAT之後,那麼在特定的情景下,有可能使得終端無法和其對等端(peer)進行直接的通信,這時就需要公網的伺服器作為一個中繼, 對來往的數據進行轉發。這個轉發的協議就被定義為TURN。TURN和其他中繼協議的不同之處在於,它允許客戶端使用同一個中繼地址(relay address)與多個不同的peer進行通信。

使用TURN協議的客戶端必須能夠通過中繼地址和對等端進行通訊,並且能夠得知每個peer的的IP地址和埠(確切地說,應該是peer的伺服器反射地址)。而這些行為如何完成,是不在TURN協議範圍之內的。其中一個可用的方式是客戶端通過email來告知對等端信息,另一種方式是客戶端使用一些指定的協議,如「introduction」 或 「rendezvous」,詳見RFC5128

如果TURN使用於ICE協議中,relay地址會作為一個候選,由ICE在多個候選中進行評估,選取最合適的通訊地址。一般來說中繼的優先順序都是最低的。TURN協議被設計為ICE協議(Interactive Connectivity Establishment)的一部分,而且也強烈建議用戶在他們的程序里使用ICE,但是也可以獨立於ICE的運行。值得一提的是,TURN協議本身是STUN的一個拓展,因此絕大部分TURN報文都是STUN類型的,作為STUN的一個拓展,TURN增加了新的方法(method)和屬性(attribute)。

在典型的情況下,TURN客戶端連接到內網中,並且通過一個或者多個NAT到達公網,TURN伺服器架設在公網中,不同的客戶端以TURN伺服器為中繼和其他peer進行通信,如下圖所示:

在上圖中,左邊的TURN Client是位於NAT後面的一個客戶端(內網地址是10.1.1.2:49721),連接公網的TURN伺服器(默認埠3478)後,伺服器會得到一個Client的反射地址(Reflexive Transport Address, 即NAT分配的公網IP和埠)192.0.2.1:7000,此時Client會通過TURN命令創建或管理ALLOCATION,allocation是伺服器上的一個數據結構,包含了中繼地址的信息。伺服器隨後會給Client分配一個中繼地址,即圖中的192.0.2.15:50000,另外兩個對等端若要通過TURN協議和Client進行通信,可以直接往中繼地址收發數據即可,TURN伺服器會把發往指定中繼地址的數據轉發到對應的Client,這裡是其反射地址。

Server上的每一個allocation都唯一對應一個client,並且只有一個中繼地址,因此當數據包到達某個中繼地址時,伺服器總是知道應該將其轉發到什麼地方。但值得一提的是,一個Client可能在同一時間在一個Server上會有多個allocation,這和上述規則是並不矛盾的。

在協議中,TURN伺服器與peer之間的連接都是基於UDP的,但是伺服器和客戶端之間可以通過其他各種連接來傳輸STUN報文,比如TCP/UDP/TLS-over-TCP. 客戶端之間通過中繼傳輸數據時候,如果用了TCP,也會在服務端轉換為UDP,因此建議客戶端使用

UDP來進行傳輸. 至於為什麼要支持TCP,那是因為一部分防火牆會完全阻擋UDP數據,而對於三次握手的TCP數據則不做隔離.

要在伺服器端獲得一個中繼分配,客戶端須使用分配事務. 客戶端發送分配請求(Allocate request)到伺服器,然後伺服器返回分配成功響應,並包含了分配的地址.客戶端可以在屬性欄位描述其想要的分配類型(比如生命周期).由於中繼數據實現了安全傳輸,伺服器會要求對客戶端進行驗證,主要使用STUN的long-term credential mechanism.

一旦中繼傳輸地址分配好,客戶端必須要將其保活.通常的方法是發送刷新請求(Refresh request)到服務端.這在TURN中是一個標準的方法.刷新頻率取決於分配的生命期,默認為10分鐘.客戶端也可以在刷新請求里指定一個更長的生命期,而伺服器會返回一個實際上分配的時間. 當客戶端想中指通信時,可以發送一個生命期為0的刷新請求.

伺服器和客戶端都保存有一個成為五元組(5-TUPLE)的信息,比如對於客戶端來說,五元組包括客戶端本地地址/埠,伺服器地址/埠,和傳輸協議;伺服器也是類似,只不過將客戶端的地址變為其反射地址,因為那才是伺服器所見到的. 伺服器和客戶端在分配

請求中都帶有5-TUPLE信息,並且也在接下來的信息傳輸中使用,因此彼此都知道哪一次分配對應哪一次傳輸.

如上圖所示,客戶端首先發送Allocate請求,但是沒帶驗證信息,因此STUN伺服器會返回error response,客戶端收到錯誤後加上所需的驗證信息再次請求,才能進行成功的分配.

client和peer之間有兩種方法通過TURN server交換應用信息,第一種是使用Send和Data方法(method),第二種是使用通道(channels),兩種方法都通過某種方式告知伺服器哪個peer應該接收數據,以及伺服器告知client數據來自哪個peer.

Send Mechanism使用了Send和Data指令(Indication).其中Send指令用來把數據從client發送到server,而Data指令用來把數據從server發送到client.當使用Send指令時,客戶端發送一個Send Indication到服務端,其中包含:

當伺服器收到Send Indication之後,會將DATA部分的數據解析出來,並將其以UDP的格式轉發到對應的端點去,並且在封裝數據包的時候把client的中繼地址作為源地址.從而從對等端發送到中繼地址的數據也會被伺服器轉發到client上.值得一提的是,Send/Data Indication是不支持驗證的,因為長效驗證機制不支持對indication的驗證,因此為了防止攻擊,TURN要求client在給對等端發送indication之前先安裝一個到對等端的許可(permission),如下圖所示,client到Peer B沒有安裝許可,導致其indication數據包將被伺服器丟棄,對於peer B也是同樣:

TURN支持兩種方式來創建許可,一種是發送CreatePermission request

對於一些應用程序,比如VOIP(Voice over IP),在Send/Data Indication中多加的36位元組格式信息會加重客戶端和服務端之間的帶寬壓力.為改善這種情況,TURN提供了第二種方法來讓client和peer交互數據.該方法使用另一種數據包格式,即ChannelData message,信道數據報文. ChannelData message不使用STUN頭部,而使用一個4位元組的頭部,包含了一個稱之為信道號的值(channel number).每一個使用中的信道號都與一個特定的peer綁定,即作為對等端地址的一個記號.

要將一個信道與對等端綁定,客戶端首先發送一個信道綁定請求(ChannelBind Request)到伺服器,並且指定一個未綁定的信道號以及對等端的地址信息.綁定後client和server都能通過ChannelData message來發送和轉發數據.信道綁定默認持續10分鐘,並且可以通過重新發送ChannelBind Request來刷新持續時間.和Allocation不同的是,並沒有直接刪除綁定的方法,只能等待其超時自動失效.

上圖中0x4001為信道號,即ChannelData message的頭部中頭2位元組,值得一提的是信道號的選取有如下要求:

在上一章也提到過,因為RFC是標準協議,因此實現上往往有良好的兼容性和拓展性.現存的開源P2P應用程序,如果按照標準來設計,可以很容易與之對接.其中比較著名的就是PJSIP,PJSIP是一個開源的多媒體通信庫,實現了許多標準協議,如SIP, SDP, RTP, STUN, TURN 和 ICE. 當然我們也能自己實現.比如GitHub上的TurnServer就是其中一個對TURN服務端的實現.下面在區域網環境下對TURN數據包進行簡要分析.首先有如下機器情況:

這裡使用wireshark來抓包分析,首先TurnClient發送Allocation請求:

可以看到第一次requst被伺服器拒絕,因為後者要求nonce驗證信息,伺服器的返回中包含了nonce信息,除此之外還包含了ERROR-CODE,SOFTWARE,FINGERPRINT屬性.

在下一次request請求中,客戶端加上了收到的nonce,以及USERNAME和REALM等屬性,再次發送到TurnServer:

伺服器如果通過驗證,就會返回success response,隨後Client可以通過上文說到的兩種方法與Peer進行通訊,比如下面的Send indication方法:

如何用c++調用pjsip庫實現一個簡單的sip伺服器

1、開源的sip伺服器端,比較好用的是Asterisk,標準C程序實現,代碼清晰。

2、sip的client相對比較多,主要有exosip,pjsip和opal。exosip簡單易用,在PC上用比較方便。但是涉及的相關資源太多,用了osip,srtp,ms2等眾多的開源庫,ms2下面還用到了ffmpeg,別的不說,光編譯就是噩夢。opal功能最強,雖然也用到了ffmpeg ,但是自己封裝的非常好,採用插件方式,調用靈活。opal採用class方式提供封裝,介面非常友好。感覺唯一不爽的地方,就是低層使用了ptlib,雖然多平台下都很好用,但放在嵌入式下感覺稍龐大了一些。pjsip精巧,方便移植,嵌入式下應該是首選。不過視頻頻支持方面擴展起來比opal麻煩。個人感覺,對於windows開發者來說,pjsip最大的好處就是代碼調試方便。整個工程一次編譯通過,另外兩個庫還要找很多相關的資源

3、其他的一些協議棧也調試過,比如reSipphone,好象是這個名字,還有Yate,不過從快速開發角度看,都不太合適。現在搞sip開發的,一開始就是先找好協議棧。linphone,ekiga什麼的,但龐大。對於剛開始做的,最好是一個精簡的demo。後來找到pjsip下面的幾個例子,慢慢地了解了sip的工作流程,當然少不了抓包工具和tcpdump。

不過,其實,sip沒有想像中的那麼麻煩。現在回頭看,剛開始做項目,使用協議棧絕對不是好想法。如果換個方向,先熟悉SIP基本協議,然後自己改造一個,或完全寫一個,可能效果更好。

pjsip開發——sip日誌分析

  這一節將通過一個簡單的例子來介紹一些基本的 SIP 操作。先讓我們來診視下圖展示的兩個用戶代理之間的消息順序。關於SIP協議詳細流程,可以參考 RFC3261-SIP協議 ,當然如果不習慣的話可以參考中文翻譯版 RFC3261-SIP協議中文版

  收到180響應時建立dialog叫做早期對話(early dialog),收到2XX的應答開始才是真正的dialog建立。

當然,這個代理可以有多個代理,其實也就就是多了代理伺服器之間的轉發過程,如下圖:

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/258052.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-15 12:48
下一篇 2024-12-15 12:48

相關推薦

  • Python簡單數學計算

    本文將從多個方面介紹Python的簡單數學計算,包括基礎運算符、函數、庫以及實際應用場景。 一、基礎運算符 Python提供了基礎的算術運算符,包括加(+)、減(-)、乘(*)、除…

    編程 2025-04-29
  • Python滿天星代碼:讓編程變得更加簡單

    本文將從多個方面詳細闡述Python滿天星代碼,為大家介紹它的優點以及如何在編程中使用。無論是剛剛接觸編程還是資深程序員,都能從中獲得一定的收穫。 一、簡介 Python滿天星代碼…

    編程 2025-04-29
  • 伺服器安裝Python的完整指南

    本文將為您提供伺服器安裝Python的完整指南。無論您是一位新手還是經驗豐富的開發者,您都可以通過本文輕鬆地完成Python的安裝過程。以下是本文的具體內容: 一、下載Python…

    編程 2025-04-29
  • Python海龜代碼簡單畫圖

    本文將介紹如何使用Python的海龜庫進行簡單畫圖,並提供相關示例代碼。 一、基礎用法 使用Python的海龜庫,我們可以控制一個小海龜在窗口中移動,並利用它的「畫筆」在窗口中繪製…

    編程 2025-04-29
  • STUN 伺服器

    STUN 伺服器是一個網路伺服器,可以協助網路設備(例如 VoIP 設備)解決 NAT 穿透、防火牆等問題,使得設備可以正常地進行數據傳輸。本文將從多個方面對 STUN 伺服器做詳…

    編程 2025-04-29
  • 解決docker-compose 容器時間和伺服器時間不同步問題

    docker-compose是一種工具,能夠讓您使用YAML文件來定義和運行多個容器。然而,有時候容器的時間與伺服器時間不同步,導致一些不必要的錯誤和麻煩。以下是解決方法的詳細介紹…

    編程 2025-04-29
  • Python櫻花樹代碼簡單

    本文將對Python櫻花樹代碼進行詳細的闡述和講解,幫助讀者更好地理解該代碼的實現方法。 一、簡介 櫻花樹是一種圖形效果,它的實現方法比較簡單。Python中可以通過turtle這…

    編程 2025-04-28
  • Python大神作品:讓編程變得更加簡單

    Python作為一種高級的解釋性編程語言,一直被廣泛地運用於各個領域,從Web開發、遊戲開發到人工智慧,Python都扮演著重要的角色。Python的代碼簡潔明了,易於閱讀和維護,…

    編程 2025-04-28
  • 用Python實現簡單爬蟲程序

    在當今時代,互聯網上的信息量是爆炸式增長的,其中很多信息可以被利用。對於數據分析、數據挖掘或者其他一些需要大量數據的任務,我們可以使用爬蟲技術從各個網站獲取需要的信息。而Pytho…

    編程 2025-04-28
  • 如何選擇MySQL伺服器文件許可權

    MySQL是一種流行的關係型資料庫管理系統。在安裝MySQL時,選擇正確的文件許可權是保證安全和性能的重要步驟。以下是一些指導您選擇正確許可權的建議。 一、許可權選擇 MySQL伺服器需…

    編程 2025-04-27

發表回復

登錄後才能評論