基於OpenSIPS作註冊服務下,場景A打B,一方發起BYE掛斷後收到500,另外一方沒法掛斷的問題

基於OpenSIPS作註冊服務下,場景A打B,一方發起BYE掛斷後收到500,另外一方沒法掛斷的問題
 
 
最近在工做中遇到一個看似很奇怪的,排除起來很費勁,但最後的解決方式又及其簡單的問題,下面咱們一塊兒來看看具體發生了什麼吧!
 
一句話歸納:那都是OpenSIPS  Dialog模塊的default_timeout 惹的禍(學業不精,木辦法呀……)
 
問題現象:
  1. A打B,電話接通後,持續經過話5分鐘後,任意一方掛斷電話,另外一方沒法正常掛斷,另外一方電話始終顯示正在通話中。
  2. 若是通話時長在4分鐘之內,任何一方掛斷,則另外一方都能正常結束。
 
運行環境:
    OpenSIPS      2.4.2
    FreeSWITCH  1.6.20
 
 
業務場景:
  • OpenSIPs爲分機提供註冊服務
  • OpenSIPs爲FreeSWITCH提供Load balance服務,將電話轉接至相應FreeSWITCH
  • OpenSIPs爲FreeSWITCH提供Gateway服務
    以下圖所示,不管分機互打,9001撥打9003,OpenSIPs都是先將INVITE發送至FS,FS 再將電話經過OpenSIPS呼叫到 9003
        

   

問題分析:
  1. 經過抓包分析,發現主被叫任意一方掛斷後,FS收到bye後,直接回給OpenSIPS 500 (Internal Server Error), 而致使OpenSIPS沒能將bye信號發給另外一方電話終端
  2. OpenSIPS 給FS和電話終端發OPTIONS檢測會話狀態只發4分鐘後,就再也不發了,而且主被雙方能夠繼續通話
  3. 若是OpenSIPS關閉掉對FS的dialog會話OPTIONS檢測,FS收到BYE後,能轉發到另外一方電話終端,但終端會返回500
  4. 四分以內正常掛斷的BYE報文,跟超過4分鐘沒法掛斷的BYE報文構造形式徹底相同
      SIP信令時序圖部份內容以下所示:
           
 
    下面是FreeSWITCH 收到 分機9003 發起的BYE以後的SIP報文狀況:
 1 ------------------------------------------------------------------------
 2 recv 839 bytes from udp/[10.2.32.112]:5060 at 20:13:12.270989:
 3    ------------------------------------------------------------------------
 4    BYE sip:9001@10.2.32.116:5080;transport=udp SIP/2.0
 5    Via: SIP/2.0/UDP 10.2.32.112:5060;branch=z9hG4bK4a88.a1534783.0
 6    Via: SIP/2.0/UDP 10.32.26.19:1150;branch=z9hG4bK-d87543-eb259935be711165-1--d87543-
 7    Max-Forwards: 69
 8    Contact: <sip:9003@10.32.26.19:1150;transport=udp>
 9    To: "9001"<sip:9001@10.2.32.112>;tag=p4v8FyNvv3S5D
10    From: "9003"<sip:9003@10.2.32.112>;tag=e7553b0b
11    Call-ID: NzA5YjM0OGVlM2JmMDA4NTAyZDliZmNhZWE2NjhiMDA.
12    CSeq: 3 BYE
13    Proxy-Authorization: Digest username="9003",realm="10.2.32.112",nonce="5f2bf37b000000d2afc1e61869246645da21b40ab086deaf",uri="sip:9001@10.2.32.116:5080;transport=udp",response="6a89ecdf3476a98ce0a89ee15ba29312",algorithm=MD5
14    User-Agent: eyeBeam release 1011d stamp 40820
15    Reason: SIP;description="User Hung Up"
16    Content-Length: 0
17 
18    ------------------------------------------------------------------------
19 send 375 bytes to udp/[10.2.32.112]:5060 at 20:13:12.271131:
20    ------------------------------------------------------------------------
21    SIP/2.0 500 Internal Server Error
22    Via: SIP/2.0/UDP 10.2.32.112:5060;branch=z9hG4bK4a88.a1534783.0
23    Via: SIP/2.0/UDP 10.32.26.19:1150;branch=z9hG4bK-d87543-eb259935be711165-1--d87543-
24    From: "9003"<sip:9003@10.2.32.112>;tag=e7553b0b
25    To: "9001"<sip:9001@10.2.32.112>;tag=p4v8FyNvv3S5D
26    Call-ID: NzA5YjM0OGVlM2JmMDA4NTAyZDliZmNhZWE2NjhiMDA.
27    CSeq: 3 BYE
28    Content-Length: 0
View Code

 

問題緣由:
    經過上面分析,咱們能夠猜想這是因爲OpenSIPS對dialog作OPTIONS探測引發的。仔細檢測OpenSIPS的dialog 模塊配置,我發現dialog模塊的 default_timeout = 240 (秒)。
    這就能充分解釋上面‘問題分析’中的第2點了(只發4分鐘OPTIONS), 由於4分鐘後dialog就過時了,OpenSIPS再也不發送探測包。
 
    FreeSWITCH 和 電話終端(如Yealink話機) 都遵循 SIP 協議規範,若是一通已創建的電話,在通話過程當中,FS或電話終端有收到上游(如OpenSIPS)的OPTIONS探測,那麼電話從接通到掛斷,都必須收到週期性的進行OPTIONS探測,
    若是超過週期時長了,FS或電話終端仍沒有收到OPTIONS探測, 那麼FS和電話終端就會認爲通話存在錯誤,後面在收到BYE時,就會返回 500 (Internal Server Error)。
 
 
解決辦法:
    將 OpenSIPS 的 default_timeout 值改大,如改爲10800 即3小時,重啓OpenSIPS便可解決問題。 
loadmodule "dialog.so"
modparam("dialog", "db_mode", 1)
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 10800) # 3 hours timeout 【正確配置】 #modparam("dialog", "default_timeout", 240) # 4 mins 【錯誤配置 :若是使用了create_dialog("Pp"),當一同電話超過 default_timout + options_pint_interval ,就會出現終端返回500】
modparam("dialog", "profiles_with_value", "caller ; callee")
modparam("dialog", "options_ping_interval", 60) # 1 mins

route{
   if (is_method("INVITE")) {
      if ( !create_dialog("Pp") ) { # 對OpenSIPS上進出兩個dialog(如主/被叫)都進行OPTIONS探測
         xlog("create_dialog error : Internal Server Error");
         send_reply("500","Internal Server Error");
         exit();
      }
   }
}
相關文章
相關標籤/搜索