1. 程式人生 > >SIP協議詳解&eXosip原始碼庫用法分析

SIP協議詳解&eXosip原始碼庫用法分析

1、概述

1.1 SIP概念

      會話初始協議SIP(Session Initiation Protocol)是一個應用層的控制協議,可以建立、修改和結束多媒體的會話。它是由IETF提出並主持研究的一個在IP網路上進行多媒體通訊的應用層控制協議,它被用來建立、修改、和終結一個或多個參加者參加的會話程序。這些會話包括Internet多媒體會議、Internet電話、遠端教育以及遠端醫療等。即所有的因特網上互動式兩方或多方多媒體通訊活動,統稱為多媒體會話。參加會話的成員可以通過組播方式、單播聯網方式或者兩者結合的方式進行通訊。
      總的來說,SIP能夠支援下列五種多媒體通訊的信令功能:

          User location(使用者定位):確定參加通訊的終端使用者的位置
          User capabilities(使用者能力):確定通訊的媒體型別和引數
          User availability(使用者的可用性):決定被叫方是否願意參加通訊
          Call setup(呼叫建立):振鈴,在主叫和被叫直接建立呼叫的引數
          Call handling(呼叫處理):包括來電轉駁和終止

2、協議訊息

2.1 訊息型別

      SIP訊息基於10646文字編碼,且不區分大小寫字元,分為請求訊息響應訊息

  • 請求訊息

請求訊息

訊息含義

INVITE

發起會話請求,邀請使用者加入一個會話,會話描述含於訊息體中。對於兩方呼叫來說,主叫方在會話描述中指示其能夠接受的媒體型別及其引數。被叫方必需在成功響應訊息的訊息體中指明其希望接受哪些媒體,還可以指示其行將傳送的媒體。如果收到的是關於參加會議的邀請,被叫方可以根據Call-ID或者會話描述中的標識確定使用者已經加入該會議,並返回成功響應訊息。

ACK

證實已收到對於INVITE請求的最終響應。該訊息僅和INVITE訊息配套使用。

BYE

結束會話

CANCEL

取消尚未完成的請求,對於已完成的請求(即已收到最終響應的請求)則沒有影響

REGISTER

註冊

OPTIONS

查詢伺服器的能力

  • 響應訊息

序號

狀態碼

訊息功能

1xx

資訊響應(呼叫進展響應)

表示已經接收到請求訊息,正在對其進行處理

100

試呼叫

180

振鈴

181

呼叫正在前轉

182

排隊

2xx

成功響應

表示請求已經被成功接受、處理

200

OK

3xx

重定向響應

表示需要採取進一步動作,以完成該請求

300

多重選擇

301

永久遷移

302

臨時遷移

303

見其它

305

使用代理

380

代換服務

4xx

客戶出錯

表示請求訊息中包含語法錯誤或者SIP伺服器不能完成對該請求訊息的處理

400

錯誤請求

401

無權

402

要求付款

403

禁止

404

沒有發現

405

不允許的方法

406

不接受

407

要求代理權

408

請求超時

410

消失

413

請求實體太大

414

請求URI太大

415

不支援的媒體型別

416

不支援的URI方案

420

分機無人接聽

421

要求轉機

423

間隔太短

480

暫時無人接聽

481

呼叫腿/事務不存在

482

相環探測

483

跳頻太高

484

地址不完整

485

不清楚

486

線路忙

487

終止請求

488

此處不接受

491

代處理請求

493

難以辨認

5xx

伺服器出錯

表示SIP伺服器故障不能完成對正確訊息的處理

500

內部伺服器錯誤

501

沒實現的

502

無效閘道器

503

不提供此服務

504

伺服器超時

505

SIP版本不支援

513

訊息太長

6xx

全域性故障

表示請求不能在任何SIP伺服器上實現

600

全忙

603

拒絕

604

都不存在

606

不接受

 2.2 訊息結構

2.3 訊息引數

      請求訊息和響應訊息都包括SIP頭欄位和SIP訊息欄位。SIP請求命令由起始行、訊息頭和訊息體組成,通過換行符區分訊息頭中的每一條引數行。對於不同的請求訊息,有些引數可選。

  • Call-ID

Call-ID:本地標識@主機

            示例:

            其中, call-837575-3是全域性唯一的本地標識,192.168.1.13是主機的IP地址。

  •  From


            該欄位稱為命令序號。客戶在每個請求中應加入此欄位,它由命令名稱和一個十進位制序號組成,該序號有請求客戶端選定,在Call-ID範圍內唯一確定。序號初值可為任意值,其後具有相同的Call-ID值,但不同命令名稱、訊息體的請求,其Cseq序號應加1。重發的訊息序號保持不變。伺服器將請求中的序號複製到響應訊息中,將請求和其觸發的響應關聯。一般格式為:

Cseq:序號 命令名稱

            示例:

 Cseq:2426 INVITE

            所有的請求和響應必須包含此欄位,以指示請求的發起者。伺服器將此欄位從請求訊息複製到響應訊息。一般格式為:

From:顯示名<SIP-URI>;tag=xxxx

            示例:

From:<sip:[email protected]>;tag=1c17a5

            其中,顯示名為使用者介面上顯示的字元,如果系統不予顯示,應置顯示名為匿名。tag稱為標記,為16進位制數字串,中間可帶連線符‘-’,且該置必須全域性唯一。

  •  To

            該欄位指明請求的接收者,格式與From相同,僅第一個關鍵詞用To替代From。

  •  Cseq

            該欄位稱為命令序號。客戶在每個請求中應加入此欄位,它由命令名稱和一個十進位制序號組成,該序號有請求客戶端選定,在Call-ID範圍內唯一確定。序號初值可為任意值,其後具有相同的Call-ID值,但不同命令名稱、訊息體的請求,其Cseq序號應加1。重發的訊息序號保持不變。伺服器將請求中的序號複製到響應訊息中,將請求和其觸發的響應關聯。一般格式為:

Cseq:序號 命令名稱

            示例:

 Cseq:2426 INVITE

  •  Via

           該欄位用於指示請求歷經的路徑。它可以防止請求訊息傳送產生環路,並確保響應和請求訊息選擇同樣的路徑,以保證通過防火牆或滿足其它特定的選路要求。發起請求的客戶必須將其自身的主機名或網路地址插入請求的Via欄位,如果未採用預設埠號,還需插入此埠號。在請求前傳過程中,每個代理伺服器必須將其自身地址作為一個新的Via欄位加在已有的Via欄位之前。如果代理伺服器收到一個請求,發現其自身地址位於Via頭部中,則必須回送響應“檢測到環路”。
            當請求訊息通過NAT(如防火牆等)時,請求的源地址和埠號可能被改變,此時Via欄位就不能成為響應訊息選路的依據。為了防止這一點,代理伺服器應校驗頂端Via欄位,如果發現其值和代理伺服器檢測到的前站地址不符,則應在該Via欄位中加入“receive”引數,如此修改後的欄位稱為“接收方標記Via頭部欄位”。例如:

Via:SIP/2.0/UDP softx3000.bell-telephone.com:5060
Via:SIP/2.0/UDP 10.0.0.1:5060;received=191.169.12.30 

            代理伺服器或UAC收到Via頭部欄位時的處理規則是:
1、第1個Via頭部欄位應該指示本代理伺服器或UAC。如果不是,丟棄該訊息,否則,刪除該Via欄位。
2、如果沒有第2個Via頭部欄位,則該響應已經到達目的地。否則繼續做如下處理。
3、如果第2個頭部欄位包含“maddr”引數,則按該引數指示的多播地址傳送響應,埠號由“傳送方”引數指明,如未指明,就使用埠號5060。響應的生存期應置為“生存期(ttl)”引數指定的值,如未指明,則置為1。
4、如果第2個Via欄位不包含“maddr”引數,但有一個接收方標記欄位,則應將該響應發往“received”引數指示的地址。
5、如果既無“maddr”引數又無標記,就按傳送方引數指示的地址傳送響應。

            Via欄位的一般格式為:

Via:傳送協議 傳送方;隱藏引數;生存期引數;多播地址引數;接收方標記,分支引數

             其中,傳送協議格式為:協議名/協議版本/傳送層,協議名和協議版本的預設值分別為SIP和UDP。傳送方為通常的傳送方主機和埠號。隱藏引數就是關鍵詞hidden,如有此引數,表示該欄位已由上游代理予以加密,以提供隱私服務。多播地址引數和接收方標記的意義如前所述。生存期引數與多播地址引數配用。分支引數用於代理伺服器並行分發請求時標記各個分支,當響應到達時,代理可判定是哪一分支的響應。
             簡單來說,就是請求時一層一層在開頭新增主機名或地址,響應時一層一層剝離地址。

  •  Contact

              該欄位用於INVITE、ACK和REGISTER請求以及成功響應、呼叫進展響應和重定向響應訊息,其作用是給出和使用者直接通訊的地址。INVITE和ACK請求中的Contact欄位指示該請求發出的位置,這樣被叫可以直接將請求發往該地址,而不必藉助Via欄位經由一系列代理伺服器返回。對INVITE請求的成功響應訊息可包含Contact欄位,它使其後SIP請求(如ACK請求)可直接發往該欄位給定的地址。該地址一般是被叫主機的地址,如果該主機位於防火牆之後,則為代理伺服器地址。
對應於INVITE請求的呼叫進展響應訊息中包含的Contact欄位的含義和成功響應訊息相同。但是,CANCEL請求不能直接發往該地址,必須沿原請求傳送的路徑前傳。
REGISTER請求中的Contact欄位指明使用者可達位置。該請求還定義了通配Contact欄位“*”,它只能和值為0的“失效”欄位配用,表示去除某使用者的所有登記。Contact欄位也可設定“失效”引數(任選),給定登記的失效時間。如果沒有設定該引數,則用“失效”欄位值作為其預設值。如果兩者均無,則認為SIP URI的失效時間為1小時。
              REGISTER請求的成功響應訊息中的Contact欄位返回該使用者當前可達的所有位置。
              重定向響應訊息,如使用者臨時遷移、永久遷移、地址模糊等訊息中的Contact欄位給出供重試的其它可選地址,可用於對BYE、INVITE和OPTIONS請求的響應訊息。
              Contact欄位的一般格式為:
                            Contact:地址;q引數;動作引數;失效引數;擴充套件屬性
              其中,地址的表示形式和To,From欄位相同。q引數,其取值範圍為[0,1],指示給定位置的相對優先順序。數值越大,優先順序越高。動作引數僅用於REGISTER請求。它表明希望伺服器對其後至該客戶的請求進行代理服務還是重定向服務。如果未含此引數,則執行動作取決於伺服器的配置。失效引數指明URI的有效時間,可用秒錶示,也可用SIP日期表示。擴充套件屬性就是副檔名。
              Contact欄位的示例為:
                            Contact: <Sip:[email protected]:5061>;q=0.7;expires=3600

  • Max-Forwards

               該欄位用於定義一個請求到達其目的地址所允許經過的中轉站的最大值。請求每經過一箇中轉站,該值減1。如果該值為0時該請求還沒有到達其目的地址,伺服器將回送“483”(Too Many Hops)響應並終止這個請求。
              設定該欄位的目的主要是為了出現環路時不會一直消耗代理伺服器的資源。該欄位的初始值為70。
              Max-Forwards欄位的一般格式為:
                            Max-Forwards:十進位制整數

  • Allow

              該欄位給出代理伺服器支援的所有請求訊息型別列表。

              Allow欄位的示例:
                            Allow: INVITE, ACK, OPTIONS, CANCEL, BYE

  • Content-Length

              該欄位表示訊息體的大小,為十進位制值。應用程式使用該欄位表示要傳送的訊息體的大小,而不考慮實體的媒體型別。如果使用基於流的協議(如TCP協議)作為傳輸協議,則必須使用此訊息頭欄位。
              訊息體的長度不包括用於分離訊息頭部和訊息體的空白行。 Content-Length值必須大於等於0。如果訊息中沒有訊息體,則Content-Length頭欄位值必須設為0。
              SDP用於構成請求訊息和2xx響應訊息的訊息體。
              Content-Length欄位的一般格式為:
                            Content-Length:十進位制值
              Content-Length欄位的示例:
                            Content-Length: 349
              表示訊息體的長度為349個位元組。

  •  Content-Type

              Content-Type欄位表示傳送的訊息體的媒體型別。如果訊息體不為空,則必須存在Content-Type 頭欄位。如果訊息體為空且Content-Type 頭欄位存在,則表示此型別的訊息體長度為0 (如一個空的聲音檔案)。
              Content-Type欄位的示例:
                            Content-Type: application/sdp

  • Supported

              SIP協議中定義的100類臨時響應訊息的傳輸是不可靠的,即UAS傳送臨時響應後並不能保證UAC端能夠接受到該訊息。
              如果需要在該響應訊息中攜帶媒體資訊,那麼就必須保證該訊息能夠可靠的傳輸到對端。100rel擴充套件為100類響應訊息的可靠傳輸提供了相應的機制。100rel新增加對臨時響應訊息的確認請求方法:PRACK。
              如果UAC支援該擴充套件,則在傳送的訊息中增加Supported:100rel頭域和欄位。如果UAS支援該擴充套件,則在傳送100類響應時增加Require:100rel頭域和欄位。UAC收到該響應訊息後需要向UAS傳送PRACK請求通知UAS已收到該臨時響應。UAS向UAC傳送對PRACK的2XX響應訊息結束對該臨時響應的確認過程。
              如果某一UA想要在傳送的臨時響應訊息中攜帶SDP訊息體,那麼UAC和UAS都必須支援和使用100rel擴充套件以保證該訊息的可靠傳輸。
              舉例:
                            Supported: 100rel

  • User-Agent

              User-Agent頭欄位包含有發起請求的使用者終端的資訊。
              顯示使用者代理的軟體版本資訊可能會令使用者在使用有安全漏洞的軟體易受到外界攻擊,因此,應該使User-Agent頭欄位成為可選配置項。
              舉例:
                            User-Agent: Softphone Beta1.5

  • Expires

              Expires頭欄位指定了訊息(或訊息內容)多長時間之後超時。
              舉例:
                            Expires: 5

  • Accept-Language

              Accept-Language頭欄位用在請求訊息中,表示原因短語、會話描述或應答訊息中攜帶的狀態應答內容的首選語言型別。如果訊息中沒有Accept-Language頭欄位,則伺服器端認為客戶端支援所有語言。
              舉例:
                            Accept-Language: en

  • Authorization

              Authorization欄位包含某個終端的鑑權證書。

3、訊息流程

              使用者每次開機時都需要向伺服器註冊,當SIP Client的地址發生改變時也需要重新註冊。註冊資訊必須定期重新整理。具體流程參考SIP協議詳解。

4、exosip用法分析

              以exosip原始碼中的示例程式分析,流程如下:

//初始化
  context_eXosip = eXosip_malloc ();
  if (eXosip_init (context_eXosip)) {
    syslog_wrapper (LOG_ERR, "eXosip_init failed");
    exit (1);
  }
  if (eXosip_listen_addr (context_eXosip, IPPROTO_UDP, NULL, port, AF_INET, 0)) {
    syslog_wrapper (LOG_ERR, "eXosip_listen_addr failed");
    exit (1);
  }

  if (localip) {
    syslog_wrapper (LOG_INFO, "local address: %s", localip);
    eXosip_masquerade_contact (context_eXosip, localip, port);
  }

  if (firewallip) {
    syslog_wrapper (LOG_INFO, "firewall address: %s:%i", firewallip, port);
    eXosip_masquerade_contact (context_eXosip, firewallip, port);
  }

  eXosip_set_user_agent (context_eXosip, UA_STRING);

  if (username && password) {
    syslog_wrapper (LOG_INFO, "username: %s", username);
    syslog_wrapper (LOG_INFO, "password: [removed]");
    if (eXosip_add_authentication_info (context_eXosip, username, username, password, NULL, NULL)) {
      syslog_wrapper (LOG_ERR, "eXosip_add_authentication_info failed");
      exit (1);
    }
  }

  {
    osip_message_t *reg = NULL;
    int i;

    regparam.regid = eXosip_register_build_initial_register (context_eXosip, fromuser, proxy, contact, regparam.expiry * 2, &reg);
    if (regparam.regid < 1) {
      syslog_wrapper (LOG_ERR, "eXosip_register_build_initial_register failed");
      exit (1);
    }
    i = eXosip_register_send_register (context_eXosip, regparam.regid, reg);
    if (i != 0) {
      syslog_wrapper (LOG_ERR, "eXosip_register_send_register failed");
      exit (1);
    }
  }


//處理

   for (;;) {
    eXosip_event_t *event;

    if (!(event = eXosip_event_wait (context_eXosip, 0, 1))) {
      osip_usleep (10000);
      continue;
    }

    eXosip_automatic_action (context_eXosip);
    switch (event->type) {
    case EXOSIP_REGISTRATION_SUCCESS:
      syslog_wrapper (LOG_INFO, "registrered successfully");
      break;
    case EXOSIP_REGISTRATION_FAILURE:
      regparam.auth = 1;
      break;
    default:
      syslog_wrapper (LOG_DEBUG, "recieved unknown eXosip event (type, did, cid) = (%d, %d, %d)", event->type, event->did, event->cid);

    }
    eXosip_event_free (event);
  }

              eXosip_malloc、eXosip_init等初始化SIP連結的一些記憶體和引數,這些都是直接呼叫原始碼,可以直接沿用。下面的處理流程,是解析伺服器下發的報文,並按列舉巨集的形式分別處理。

              總體來說,exosip呼叫的邏輯比較清晰,原始碼鑽研的意義對本人來說意義不大,所以能寫的比較少,就這樣貼出來做一個參考吧。

相關推薦

SIP協議&eXosip原始碼用法分析

1、概述 1.1 SIP概念       會話初始協議SIP(Session Initiation Protocol)是一個應用層的控制協議,可以建立、修改和結束多媒體的會話。它是由IETF提出並主持研究的一個在IP網路上進行多媒體通訊的應用層控制協議,它被用來建立、修改、

sip協議 系列(二)

Sip的核心請求訊息 INVITE、ACK、OPTIONS、BYE、CANCEL 和 REGISTER INVITE • INVITE可以在郵件正文中包含主叫方的媒體資訊。 • 如果INVITE已經接收到成功響應(2xx)或已經發送ACK,則會話被認為是建立的。 • 成功的INVIT

sip協議 系列(一)

近期一直在研究視訊通話,裡面有sip或者xmpp,之前也不瞭解, 準備整體瞭解sip並整理相關內容。 Sip概述 SIP(Session Initiation Protocol,會話初始協議)是由IETF(Internet Engineering Task Force,因特網工程任務組)

SIP協議(中文)-6

這些展示的問題需要定義一個架構來把拒絕服務攻擊造成的影響最小化,並且需要在安全機制中對這類攻擊特別留意。26.2 安全機制從上邊講述的威脅來看,我們得到了SIP協議所需要的基本安全服務,他們是:保護訊息的隱私性和完整性,保護重現(replay)攻擊或者訊息欺騙,提供會話參與者的身份認證和隱私保護,保護拒絕服務

SIP 協議

## SIP 協議詳解 2013年參與過一個“視訊通訊的App”專案,使用Sip協議通訊。當時通訊協議這塊不是自己負責,加上時間緊、任務重等方面的原因,一直未對Sip協議進行過深入的瞭解。 2020年春天疫情突發,宅在家裡終於有了空餘時間。這裡來詳細瞭解一下Sip協議。 以下內容大致分為以下幾個部分:

第20課 SPI協議及裸機程式開發分析

第001節_SPI協議介紹 市面上的開發板很少接有SPI裝置,但是SPI協議在工作中經常用到。我們開發了SPI模組,上面有SPI Flash和SPI OLED。OLED就是一塊顯示器。 我們裸板程式會涉及兩部分: 用GPIO模擬SPI 用S3C2440的

Wireshark基本用法 && 過濾規則 && 協議

air 就會 mage ica 生存 創建 cati -o 偏移 基本使用: https://www.cnblogs.com/dragonir/p/6219541.html 協議解析: https://www.jianshu.com/p/a384b8e32b67

String用法(equal原始碼 ==和equal的解釋、字面賦值和new賦值效率、重寫了hashcode的方法解釋)

String  a = “abc”;//在字串池中找abc,如果有,就直接返回地址,如果沒有就加值abc然後再返回地址(此方式的值是存放在字串池中) String  b =  “abc”; String  c  =   new String("abc");//在字串池中找a

2020了你還不會Java8新特性?(五)收集器比較器用法原始碼剖析

收集器用法詳解與多級分組和分割槽 為什麼在collectors類中定義一個靜態內部類? static class CollectorImpl<T, A, R> implements Collector<T, A, R> 設計上,本身就是一個輔助類,是一個工廠。作用是給開發者提供常見的

網絡協議

網絡協議 test 未能 第一個 為什麽 體系 index 緩存 hyper 目錄:::::: 一、網絡協議 二、TCP(Transmission Control Protocol,傳輸控制協議) TCP頭格式 TCP協議中的三次握手和四次揮手

HTTP協議(真的很經典)

cnp 運用 web應用 media 服務器端 所有 長度 request bad 轉載:http://e7kan.com/?p=264& 引言 HTTP是一個屬於應用層的面向對象的協議,由於其簡捷、快速的方式,適用於分布式超媒體信息系統。它於1990年提出,經過幾

http協議

表單 pos 換行 none 必須掌握 通信 pow print expires HTTP是一個屬於應用層的面向對象的協議,由於其簡捷、快速的方式,適用於分布式超媒體信息系統。它於1990年提出,經過幾年的使用與發展,得到不斷地完善和擴展。目前在WWW中使用的是HTTP/1

HTTP 協議

範圍 文件傳輸 ext text 繼續 warn 分組 asi nsf 前言:   之前買過一本《圖解 HTTP》這本書,作者好像是個小日本,也繼承了小日本在動漫方面的天賦,30% 的內容都是 Q 版畫圖。   之後沒有引起我的重視,書一借出去,然後,之後 .. 之後,

Http 協議筆記

code sps 網頁 提示 agent tor 指定 6.0 lec HTTP是一個屬於應用層的面向對象的協議,由於其簡捷、快速的方式,適用於分布式超媒體信息系統。它於1990年提出,經過幾年的使用與發展,得到不斷地完善和擴展。目前在WWW中使用的是HTTP/1.0的第六

HTTPS協議(二):TLS/SSL工作原理

-c 基本 公鑰加密 工作方式 通信 使用 sha2 公開 原理 HTTPS協議的主要功能基本都依賴於TLS/SSL協議,本節分析TLS/SSL協議工作原理。 TLS/SSL的功能實現主要依賴於三類基本算法:散列函數 Hash、對稱加密和非對稱加密,其利用非對稱加密實

HTTPS協議(四):TLS/SSL握手過程

其它 對數 hello 減少 受保護 改版 text gin 組裝 1、握手與密鑰協商過程 基於RSA握手和密鑰交換的客戶端驗證服務器為示例詳解TLS/SSL握手過程 再看一張手繪時序圖 (1).client_hello 客戶端發起請求,以明文傳輸請求信息,包

HTTPS協議(三):PKI 體系

客戶 判斷 節點 無法 三方 證書無效 進行 證書 roo 1、RSA身份驗證的隱患 身份驗證和密鑰協商是TLS的基礎功能,要求的前提是合法的服務器掌握著對應的私鑰。但RSA算法無法確保服務器身份的合法性,因為公鑰並不包含服務器的信息,存在安全隱患: 客戶端C和

FC協議

fc標題索引本文出自 “一步一印,有印為證” 博客,謝絕轉載!FC協議詳解

RTSP協議

5.1 handler 詳解 finally 運行 綁定 prot mage accepted RTSP簡介 RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP網絡上傳輸流媒

(三)GET和POST協議

str 打印 http 類別 多個 表現 pro 版本 prot 一、GET請求報文分析: 1、 請求行:   a) GET(描述該請求采用了什麽請求方法),HTTP協議中包含8種請求方法: GET 請求獲取Request-URI 所標識的資源 POST