在前面的blog中,我们已经讨论了为什么会有语音单通问题。在这篇blog中,我们继续讨论如何解决这个问题。
正如我们看到的,sip电话(100)将自己的私有地址告诉给sip软终端(101),这就导致了语音单通问题。因此我们自然想到:为什么不将它的公共地址8.8.8.8告诉给sip软终端呢?如果它能做到这点,sip软终端自然可以将它的语音流发送给这个公共地址,路由器也会将这个语音流转发给sip电话,sip电话也就可以听到sip软终端侧的声音了。对吗?
非常正确!这是个很好的解决方案。但是我们接着需要问:sip电话(100)如何才能知道它自己的外网地址呢?
答案就是STUN。STUN是“Simple Traversal of User Datagram Protocol (UDP) through Network Address Translators (NATs)基于UDP协议对网络地址转换的简单穿越”的缩写。这是个非常拗口的定义啊。简单而言,STUN就是用来私网内设备获取外网地址的一种协议工具。
请参考下面这张图:
– STUN process
在SIP电话拨打电话之前,它先向STUN服务器请求获取外部地址。完成之后,SIP电话开始发起呼叫,它告诉对方说:喂,我是100,我的语音地址是8.8.8.8:100,请发送语音流给我。
顺便说一下,在本文中一个公共地址由一个公共IP地址+一个端口号组成。例如“8.8.8.8:10000”,“8.8.8.8”是公共IP地址,“10000”是端口号。”8.8.8.8:10001″是另外一个不同的公共地址(因为虽然IP地址一样,但是端口变了)。
既然8.8.8.8是公共地址,因此SIP软终端毫无疑问能将它的语音流发送到这个地址。因此呼叫双方现在都能听到对方的语音。
几乎所有的SIP设备,无论是SIP电话还是SIP软终端,都能支持STUN协议。我们唯一需要知道的是设置STUN服务器地址。在我们的step by step文档中,我们针对X-lite给出了一个简单的示例:
https://www.myvoipapp.com/docs/faq/setup_ippbx_for_small_business_step_by_step/index_cn.html#faq_stun
支持STUN后,是否能解决所有的语音单通问题呢?
很不幸,不能。在多数情况下,STUN能很好的工作,但是它无法解决所有的语音单通问题。这取决于私网的类型。简单而言,取决于路由器(当然,在某些网络,也可能是防火墙设备)。
– Special network for STUN
请参考上面这张图。图中描绘了两个会话:一个会话是SIP电话向STUN服务器请求获取公共地址。另一个会话是SIP电话与SIP软终端之间的呼叫。
众所周知,路由器将维持私网地址与公网地址之间的映射关系。缺省情况下,大多数路由器对来自私网内同一个设备同一个端口的不同会话,会分配并维持同一个外部地址映射关系。因此SIP电话在这两个会话中,会有同一个外部地址。
但是有些路由器会为不同的会话分配不同的映射关系,也就是说SIP电话在这两个不同的会话中会有两个不同的外部地址对应,因此实际上在与sip软终端的对话中,SIP电话还是无法知道对应的外部地址。
如果STUN不能解决语音单通的问题,根本原因就是路由器或者私网类型导致。此时,最终的解决方案就是建立VPN网络,将所有的SIP电话和SIP终端至于同一个逻辑网络内。这就是另外一个讨论议题了。(补充说明:也有可能采用ICE协议解决私网穿越问题,但是不是所有的设备都能支持ICE协议。)