作者:johney_zhou
链接:https://www.jianshu.com/p/a51bd7380894
关键词:
SIP BFCP交互流程NAT双流SDP
摘要:
我司三代高清SP4开始支持BFCP功能,下文为初探BFCP协议,如有出错欢迎大家多提意见。
案例描述
将BFCP应用于SIP双流中,主要是用BFCP消息来控制SIP双流的开启与关闭。针对SIP双流,在实现过程中我们用BFCP建立一个新的通道来记录双流。而通过将BFCP协议中所提到的层与双流通道进行关联,通过对层的请求与释放来达到间接控制双流的目的。----《BFCP协议简介及应用》
案例分析
1、BFCP在通信协议中如何体现?
2、BFCP在SIP对通中的流程分析?
3、BFCP是如何完成双流交互?
概述
BFCP功能开发主要基于如下RFC文档:
RFC4582:该文档描述了BFCP协议通信模型,BFCP消息类型及编码方式,BFCP通信举例。是BFCP协议的主要参考文档。
RFC4583:该文档主要描述了BFCP协议和SIP协议的结合使用,在SDP中如何添加BFCP能力的m行。
以上是BFCP协议开发所参考的两个主要文档,此外还参考了其他RFC文档,如RFC4145(主要描述了BFCP协议所涉及的Setup及Connection属性等),RFC4574(主要描述了BFCP协议所涉及的Label属性等)。
BFCP在通信协议中的体现
以三代高清为例,如何通过抓包查看我们终端是否真的启用BFCP协议
BFCP是标准协议,他在RFC4583文档《rfc4583.Session
Description Protocol (SDP) Format for
Binary Floor Control Protocol (BFCP)
Streams》中明确了BFCP协议可以封装在SDP协议中的。
加入BFCP后,对于SIP SDP能力的改变主要体现在两个方面:
(1)SDP能力里多了一个m行来标识BFCP,如下图所示:
M行
(2)SDP中对于视频通道能力多了一个content及label描述项,如下图所示:
label描述
标识视频通道的有两个m行。第一个m行下面有属性content为main,表示该通道为主流视频通道,其label值为1;而第二个m行的content属性值为slides,表示该通道为双流视频通道。除了上述两点外,支持BFCP对于视频通道要求是sendrecv属性(如图中m行所示)。
BFCP是如何完成双流交互
下图为我司现在SIP双流交互流程:
交互流程
上图中,用红色标识的是BFCP消息,蓝色是正常的SIP信令,图中的部分SIP信令及BFCP消息是可选的,这里说明如下(假设主被叫两端均支持BFCP):
SIP信令(1~8)及BFCP消息(A、B)这些流程是在呼叫开始后就会完成的,不管参与呼叫的两端是否有发双流的请求。因此要求主被叫两端在呼叫之前就事先确定好本地的双流收发能力(即开启BFCP后,协议栈内部自动完成两次INVITE交互)。其中在第二次INVITE交互的过程中参与呼叫的双方协商出本端的BFCP角色(Client/Server)。一旦一方确定了自己为BFCP Server,它即会在指定的端口开启监听。另一方确定自己为BFCP Client,它会与对端建立tcp连接,之后向对端发出BFCP消息Hello。至此BFCP初步交互完成。
接下来的双流发送根据终端是否改变双流能力分为两种情况:
(1)若双流发送方改变双流能力,则SIP信令(9~11)会执行,重新进行双流的协商;
(2)若双流发送方不改变双流能力,则SIP信令(9~11)跳过。
双流的发送与关闭也与发出请求的终端所处的BFCP角色有关。上图BFCP消息(C~F)对应的是BFCP Client发双流及关双流。其中BFCP消息C、D对应发双流,E、F对应关双流。其中BFCP server向BFCP Client回复的FloorRequestStatus消息中携带了对请求的floor状态的回复,只有该状态为Granted时才默认成功。
上图BFCP消息G、H对应的是BFCP Server发双流与关双流,其中BFCP消息G对应发双流,H对应关双流。与BFCP Client请求不同的是,BFCP Server发双流及关双流均不需要等待Client的回复,BFCP Server在发双流时会定时向BFCP Client发送状态为Granted的FloorStatus消息,直到关双流消息发出。
BFCP穿越NAT
问题1:过NAT环境,终端A(内网)和终端B(外网)都开启BFCP,建立点对点会议,且开启音频视频的防火墙端口映射;终端A(内网)终端发起双流,终端B没有建立通道。
疑问:BFCP是基于TCP连接的为何内网无法与外网进行交互呢?
环境:终端A:172.16.177.127;终端B:192.168.60.91;NAT服务器:192.168.60.11;
在终端A处抓包,搜索条件ip.addr==172.16.177.127&&ip.addr==192.168.60.91&&tcp.port==5555:
ip.addr==172.16.177.127&&ip.addr==192.168.60.91&&tcp.port==5555
终端B抓的包中TCP与NAT防火墙进行交互时都建立连接失败了!
结论:由于BFCP建立连接机制,终端A发起双流最为客户端向终端B发起请求,由终端A主动发起BFCP双流能力交换,而此时却被防火墙给阻止了(原因是终端B找不到终端A)。
解决方法:在NAT上添加TCP5555端口映射到终端A上。
问题2:过NAT环境且NAT上添加TCP5555端口映射,终端A(内网)和终端B(外网)都开启BFCP,建立点对点会议,且开启音频视频的防火墙端口映射;终端A(内网)终端发起双流成功后,挂断会议,重新开启会议发送双流,发送超时。
经排除发现是由于端口释放问题导致:
端口
但由于端口释放需要一定时间所以我们解决问题的思路如下:
让BFCP做如下策略:
1、只要发现端口被占用,终端侧监听端口往上加一,如5555端口被占有,则开启5556;
2、每次检测端口是否被占有从5555开始往上叠加;
3、NAT处开启10个TCP端口映射(5555~5564)来保证发起双流成功;