您当前的位置是:  首页 > 资讯 > 国内 >
 首页 > 资讯 > 国内 >

会话边界控制器(SBC)/SIP路由以及相关业务问题浅析

2020-09-03 15:39:31   作者: james.zhu   来源:Asterisk开源派   评论:0  点击:


  SIP网络环境中,特别是涉及了多个应用节点或多个网络要素环境的SIP呼叫中,因为涉及的网络节点比较复杂,所以SIP路由所涉及的路径就比较多,例如注册服务,定位服务等,另外,因为目前的SIP网络环境中,很多SIP呼叫业务又涉及了SBC,使用SBC作为一个SIP安全的保护机制,因此,在SIP路由或呼叫中增加了SBC处理的场景。因此,很多SIP网络用户就对这些相关的问题感到非常困惑。今天,笔者针对SBC和SIP路由以及所涉及的相关业务问题进行浅析和说明,希望读者能够对SBC,SIP路由以及路由策略有一个大概的理解。
  笔者首先说明,因为篇幅有限,笔者很难在比较短的篇幅涵盖所有细节。另外,很多基本概念在以前的历史文档中也早已有完整深入的介绍,所以,笔者在这里可能简单重复介绍一些基本的概念,或者不再介绍一些基本的概念,读者可以查阅历史文档学习或者补充相关知识。最后,因为涉及到具体的业务应用,笔者只能比较宽泛地讨论一些经常使用的或者相对规范的应用场景,特别具体场景这里不再做更多讨论。
  针对本文章所需要涉及到的内容,笔者首先讨论一些基本的针对SIP路由的相关的概念和处理流程,另外因为SIP业务服务器可能需要经过SBC的调度处理,笔者将针对SIP路由经过SBC以后的一些流程进行讨论。
  1、关于SIP注册服务介绍
  在SIP技术中,非常重要的一个概念就是注册(Registrar)。注册本身就是一种服务的处理流程,他一般是一个数据库存储Registrar地址,终端用户通过地址查找来实现其可达性的状态查询。如何发现注册地址,读者可以参考RFC10.2.6的规范细节。笔者也发布过历史文档,此文档中比较详细说明了注册和定位的处理流程,读者可以参考此文档做进一步学习:
  深入理解SIP服务器的注册和定位服务流程
  在实际SIP网络或者IP网络的应用场景中,特别是现在的移动端的使用中,IP地址可能会经常发生变化,而且一个SIP终端账号有几种表现形式(一个分机同时有物理终端,PC端分机或者APP分机)。这些IP地址一般又是临时地址,这样的话,服务器端对终端状态的管理存在很多挑战。因此,在SIP应用场景中,SIP协议使用了一个永久地址来匹配一个SIP账号信息,这个地址就是AOR地址(address of record)。这里,笔者提醒读者,在一般的企业通信或者IPPBX的讨论中,我们经常使用的是SIP分机的说法。那种说法或者称谓仅在一个比较小型的内网环境的说法,我们有时为了简单方便也使用这样的称谓,但是SIP呼叫流程决不仅仅是一个分机的概念,希望一些初级用户不要对这些概念迷惑。进一步讲,即使是一个IPPBX表示也集成了以下示例的所有功能模块,在逻辑上都是独立的,仅表现为一个一体服务器形式而已。如果是大型的服务器或者其他分布式部署的服务器,这些服务器端都各自有自己表示的逻辑功能,包括图例中使用的注册服务器,定位服务器,路由服务器和域名解析等等。

此图片和以下图片资源均来自于互联网资源
  另外,在实际应用环境中,我们还有一个contact地址。这两个基本的地址就可以绑定大部分的呼叫业务流程。针对这两个容易混淆的地址,读者可以简单理解为:AOR是告知服务器端SIP终端是谁(唯一的),Contact告诉服务器SIP终端此时此刻在哪里(绑定多个contacts)。呼叫SIP终端时,应该首先检查AOR地址,然后逐一检查contact地址状态,最后呼叫到有效contact地址。
  在以上图例中,两个SIP终端注册都分别经过了4个处理流程(M1/M2,M3/M4)。
  2、关于SIP proxy路由介绍
  在以上讨论中,除了进行注册以外,SIP终端双方如果需要呼叫对方的话,仍然需要借助于第三方的其他服务功能实现路由等处理流程。Proxy或者代理服务器就是其中一个必要的逻辑实体。一般来说,代理服务器负责处理域名检查,然后做相应的路由处理转发。代理服务器首先必须检查请求中的SIP Request-URI,因为此参数中可能包含必要的路由的头域参数,例如Route/Route-Record,代理服务器根据这些路由头进行下一步的路由转发处理。当我们讨论proxy时,另外一个比较重要的概念就是B2BUA,如果读者对Proxy或者B2BUA迷惑的话,可以参考笔者历史文档:
  B2BUA/SBC/Proxy的SIP消息重构和RFC7092详解
  笔者这里不再做更多重复介绍,请读者仔细阅读以上链接文档。代理服务器获得了Route头以后,它就会根据代理服务器的列表强制执行这些路由转发处理。Route-Record则是被proxy记录在请求中并且强制将来的请求通过此代理服务器。当然,这些通过代理服务器的路由还要结合本地的策略处理,这些策略处理很大程度上会影响这些记录值。以上图例是一个非常典型的也是一个基本的SIP呼叫拓扑示例图。在SIP终端呼叫过程中,双方经过了(P1,P3,P2,流程为U1 -> P1 -> P3->P2 -> U2和其相反流程)三个代理服务器的处理。现在,我们根据以上处理流程来分析一下代理的record-routing细节。
  首先,UA1呼叫了一个P1外呼的代理服务器,其请求如下(M5):
  INVITE sip:callee@office.com SIP/2.0
  Contact: sip:caller@u1.example.com
  这里,P1代理服务器没有对office.com 负责处理,它没有P1代理服务器和此域名没有任何绑定关系,因此,它交给domin解析服务器进行解析查询,然后把消息继续路由到P3,并且增加了一个Route-Record,表示通过了P1代理服务器。这里,contact地址发送了变化,并且增加了一个路由记录。
  INVITE sip:callee@office.com SIP/2.0
  Contact: sip:caller@u1.example.com
  Record-Route:
  P3收到以上路由的请求以后,仍然没有查询到相应的office.com地址,它继续向下一个代理进行转发路由,转发到P2代理服务器。Record-Route: 在这里的最顶部记录中(M7)。
  INVITE sip:callee@office.com SIP/2.0
  Contact: sip:caller@u1.example.com
  Record-Route: // 注意,最新代理记录总是在最顶部
  Record-Route:
  在P2收到P3路由过来的请求以后,P2检查定位服务器,对其身份进行查询定位。它发现了这个domain office.com 以后,P2代理服务器执行了两个任务,首先重写了Request-URI值,另外,它增加了一个最新的Record-Route值,记录了office.com domain(M8)。到此为止,SIP终端双方的呼叫明确了呼叫的最终目的地地址。
  INVITE sip:callee@u2.office.com SIP/2.0 // 重写了请求URL
  Contact: sip:caller@u1.example.com
  Record-Route: // 在顶部增加了最新Record-Route
  Record-Route:
  Record-Route:
  这里读者一定要注意,因为Route 头,代理服务器可以使用请求的URL(Request-URI)来决定最终的呼叫用户地址,因此,代理服务器使用地址u2.office.com对被呼叫方callee进行呼叫。U2被呼叫后,返回一个响应消息(M9)流程。因为篇幅所限,其他呼叫挂机和发送BYE消息或者ACK的流程这里不再做太多讨论,笔者可参考历史文档学习。
  3、Record-Route 修改引起的问题以及解决办法
  在前面的讨论中,两个SIP终端分别发布在不同的网络空间(leftspace和rightspace),这两个SIP终端之间的呼叫需要借助于proxy(P1)来重写Record-Route完成(U1->P1->U2)。P1相当于一个网关来实现SIP终端之间的呼叫路由处理。U1发送的请求:
  INVITE sip:callee@gateway.leftprivatespace.
  com SIP/2.0
  Contact:
  P1然后通过定位服务,查询domain地址,对U2发送请求消息:
  INVITE sip:callee@rightprivatespace.com
  SIP/2.0
  Contact:
  Record-Route:
  com;lr>
  然后U2对P1发送 200 OK:
  SIP/2.0 200 OK
  Contact:
  Record-Route:
  com;lr>
  P1然后重写其Record-Route地址,支持U1所需要的地址参数,发送到U1:
  SIP/2.0 200 OK
  Contact:
  com>
  Record-Route:
  com;lr>
  如果U1稍晚对U2发送BYE请求时,首先发送到P1:
  BYE sip:callee@u2.rightprivatespace.com
  SIP/2.0
  Route:
  然后P1返回到U2:
  BYE sip:callee@u2.rightprivatespace.com
  SIP/2.0
  以上是一个简单的针对不同网络空间,两个SIP终端通过proxy进行的一个关于Record-Route重写的处理流程。在实际使用过程中,读者可能会有遇到VIA的处理,关于VIA和Record-Route处理,建议读者阅读笔者的历史文档:
  SIP系列讲座-关于VIA和Record-Route header
  这里需要特别注意,在关于Record-Route时,如果网络环境在多宿主机环境或者传输协议需要切换或者IPv4-IPv6的环境中,这种处理方式不是一个处理Record-Route记录的最佳办法。大部分情况下,通过Proxy以后,IP地址的匹配是没有什么问题的,但是,有时Proxy需要一定的策略修改,修改时就会生成问题。

UA多网口地址处理
IPv4到IPv6转换
TCP到UDP转换
  这样处理的结果可能是,呼叫方看到的route set和被呼叫方看到的route set是不同的,并且还有可能带来其他的影响。关于针对重写Record-Route所引起的争议问题读者可以查阅RFC5658。针对重写Record-Route引起的问题,RFC5658规范推荐使用Double Record-Routing来解决以上这些问题。以下示例图例描述了在多宿主网络和传输协议切换时使用Double Record-Routing的解决方案:
  根据以上图例的流程,首先,呼叫方对P1发出一个INVITE呼叫。这里的P1带有两个IP地址,一个是IPv4地址和另外一个IPv6地址。
  INVITE sip:joe@howell.network.com SIP/2.0
  Route: // P1的IPv4地址
  From: Joe ;tag=1234
  To: Ken
  Contact:
  然后,P1收到呼叫请求以后,通过修改Route-Record地址,增加另外一个IPv6的地址继续进行路由转发。P1然后通过IPv6地址对U2继续进行呼叫(两个Route-Record):
  INVITE sip: joe@howell.network.com SIP/2.0
  Record-Route:   // P1的ipv6地址
  Record-Route: // P1的IPv4地址
  From: Joe
  com>;tag=1234
  To: Ken
  Contact:
  在U2客户端的状态消息中,最终被呼叫方看到的是这样的结果:
  Local URI = sip:ken@atlanta.network.com
  Remote URI = sip:joe@howell.network.com
  Remote target = sip:joe@192.0.2.1
  Route Set = sip:[2001:db8::1];lr // 通过P1的 路由set
  sip:192.0.2.254:5060:lr
  然后,U2就知道,它可以通过路由set中的IPv6地址发送此地址一个200 OK。
  SIP/2.0 200 OK
  Record-Route:
  Record-Route:
  From: Joe
  com>;tag=1234
  To: Ken
  com>;tag=4567
  Contact:
  P1收到此200 OK以后,继续返回给U1一个200 OK:
  SIP/2.0 200 OK
  Record-Route:
  Record-Route:
  From: Joe
  com>;tag=1234
  To: Ken
  Contact:
  这时,在U1端看到的dialog状态中的Route-Record地址是:
  Local URI = sip:joe@howell.network.com
  Remote URI = sip:ken@atlanta.network.com
  Remote target = sip:ken@[2001:db8::33]
  Route Set = sip:192.0.2.254:5060:lr
  sip:[2001:db8::1];lr
  通过双Route-Record记录以后,双方看到的最终结果是一致的。通过double Route-Record就实现了双方地址的统一,也不会产生地址不一致的错误。其他处理流程和呼叫请求的处理方式是相同的,这里不再累述。
  4、传输协议切换引起的Record-Route重写
  在前面的讨论中,我们也简单涉及了如果传输协议切换可能导致的Record-Route重写问题。在本章节,我们重点详解关于TCP环境和UDP环境下的Record-Route修改问题。这里,U1使用的是TCP传输,U2则使用的是UDP传输,proxy P1作为一个协议转换网关进行它们之间的通信转发处理。
  以上图例中,我们可以看到,一般情况下,U1使用TCP发送到P1,然后P1经过传输协议转换以后,通过UDP把U1的呼叫请求发送到U2。这里的使用场景是一个比较简单化的场景,在这种比较简单化的场景中,如果没有涉及传输协议其他参数的使用的话,这种场景可能可以正常工作。但是,如果有大量的类似U1的SIP终端通过P1时,并且因为不同的需求,TCP传输要求支持其他参数支持时,或者在U2 端的UDP需要增加参数支持时,这样的简单场景就不能适应传输协议的支持。U1通过TCP发送呼叫请求到P1的消息示例:
  INVITE sip:ken@atlanta.network.com SIP/2.0
  Route:
  From: Joe
  com>;tag=1234
  To: Ken
  Contact:
  com;transport=tcp>
  P1收到请求以后,然后通过UDP对U1发送到呼叫请求:
  INVITE sip: ken@atlanta.network.
  com;transport=udp SIP/2.0
  Record-Route: (注意,这里没有使用任何传输协议参数)
  From: Joe
  com>;tag=1234
  To: Ken
  Contact: < sip:joe@u1.howell.network.com;transport=tcp>
  但是,在实际生产环境中,一些代理服务器存在一些兼容性问题,或者不能支持要求的传输,也可能某些代理强制使用TCP来避免UDP拥塞,这就会导致传输协议切换时Record-Route存在无效解析问题。因此,使用double Record-Route增加一些兼容性支持仍然是解决这些问题的比较好的办法。
  Record-Route:
  com;transport=udp>
  Record-Route:
  com;transport=sctp>. // 增加对sctp支持
  另外,除了我们讨论的这种简单场景中关于传输协议的切换以外,很多SIP网络环境中涉及了NAT问题。在NAT处理中,传输协议也需要增加相应的传输参数,这就要求Record-Route做相应的修改和Via修改,包括端口修改等参数设置。
  5、SBC环境中关于拨号和路由SIP呼叫/ACK处理
  以上介绍了关于SIP路由中经过比较重要的概念和相关补充说明。接下来我们针对具体的SIP服务器的业务系统-SBC呼叫进行讨论。根据RFC3261的规范说明,SIP服务器端收到SIP终端的呼叫请求以后,可以根据其服务器端定义的呼叫路由规则来针对呼叫请求进行路由处理。具体的处理规则可以是:
  • 是否对此呼叫请求执行代理或者重定位转发处理
  • 可以转发到每个URL地址
  • 是否可以执行分叉呼叫
  • 是否执行递归查询
  • 是否执行并行处理或者按续查询处理
  以上是SIP服务器端根据其各种决定因素对呼叫请求进行路由的几个规则。但是,在实际的业务处理过程中,特别是SIP网络边界控制器的呼叫处理中还有更多具体的呼叫路由策略。此部分内容和后续章节都将基于SBC的功能对SIP呼叫进行讨论。再次说明,如果读者对SBC或者会话边界控制器不是非常了解的话,读者可阅读笔者历史文档关于SBC和业务功能的具体详解说明,这里不再过多强调其具体概念和场景说明:
  • 边界会话控制器-SBC部署协议-RFC5853
  • 图解边界会话控制器(SBC)的20个最常用功能
  • SBC十大使用场景-如何实现SIP-SBC冗余解决方案
  • 必知的十大会话边界控制器-SBC经典使用场景
  • 图解会话边界控制器(SBC)十八个必知高级功能
  • 如何搭建一个完整免费的边界会话控制器(SBC)测试场景
  • SIP系列讲座-边界会话控制器-SBC全面剖析
  呼叫任何电话或者SIP终端都需要首先通过拨号盘输入电话号码,号码规范和位数需要遵从ITU-T E.164,最大支持15位数号码。
  在SIP呼叫请求发起以后携带两个头消息参数(To和Request-URI)来确认呼叫目的地。一种方式是通过SIP URL/SIPS URL,另外一种是通过Tel URL的方式来标识呼叫目的地号码。
  如果终端用户通过IP网络进行呼叫时,双方终端至少需要两个不同的企业通信实体系统。在各自的企业通信平台的边界处,企业通信系统支持了SBC来实现SIP网络的安全控制。根据笔者前面章节的描述,在SIP呼叫路由过程中,Via和Record-Route都需要按照呼叫路由规则进行处理。
  在请求路由过程中支持了strict routing(严格路由)和 loose routing(松散路由)两种路由方式。strict routing由RFC2543定义,而loose routing 则由RFC3261定义。严格路由使用Request-URI作为下一跳的URL,而松散路由除了使用Request-URI作为目的地URL以外,代理服务器将使用最顶部的Route header作为下一跳的目的地地址。这两种请求路由的区别会引起路由头的处理不同,因此,如果经过多个代理服务器时,它们分别支持不同的路由方式,读者排查问题时需要特别注意这些差别。
  除了在请求呼叫中使用Record-Route,在不同的代理服务器或者SBC增加路由记录以外,这个Record-Route也会影响ACK的处理流程,同时可能影响SBC的处理:
  所有ACK请求流程中都使用了Record-Route。
  所有ACK请求流程中,其中一个代理服务器没有插入Record-Route
  双方终端直接通过SBC进行通信。U1通过业务服务器,SBC呼叫对端SBC,业务服务器和U2终端。
  6、SBC环境中呼叫路由类型讨论
  当SIP呼叫INVITE进入到SBC以后,SBC可以根据不同的呼叫路由类型做不同的呼叫路由。具体的呼叫路由类型包括:
  DID匹配系统内部分机或者其他终端,例如,通过Request-URI的号码9865556003路由到系统分机 (56003)。当然,此目的地路由还可以是其他SIP 终端,SBC或者SIP trunk,甚至于TDM 接口。
  基于URL或者domain或者email格式的呼叫,一般情况下,这种路由根据SIP的domain做其他基于消息的路由切换。
  基于呼叫源目的地的路由。此路由模式根据呼叫发起方的地址做呼叫路由。这样可以保证呼叫方能够正确路由到相关的目的地分机,例如呼叫中心的一些VIP服务呼叫。
  基于中继组的呼叫路由。这种情况通常是SBC可以同时支持TDM trunk和SIP trunk时SBC设置的路由组策略。在某些特定的需求或者使用场景中,SBC可能使用TDM/PSTN作为一个备用线路或者在本地落地,因此呼叫进入到SBC以后就需要做相应的呼叫分类管理。
  基于运营商的呼叫路由。这种路由更多适用于当运营商提供了某些呼叫服务,例如toll-free号码或者运营商的其他服务号码。SBC需要根据其运营商的号码特性做相应的呼叫路由。RFC4694对其Tel URL号码有完整的规范说明,如果运营商的服务遵从其规范的话,可能某些地区有一些免费的服务,SBC可通过这些免费的数据服务来查询更多的绑定业务。
  除了以上几种比较常见的呼叫路由服务以外,不同的SBC厂家针对呼叫路由还有很多不同的处理方式,包括一些非常灵活的自定义脚本的处理方式支持大并发部署中的各种路由管理。这种方式可以满足以上路由处理以外,同时可以根据路由脚本实现更加强大的路由策略。具体的实现方式包括动态路由,静态路由,标识路由和第三方签权认证路由方式。通过脚本路由的方式,可以实现针对某些特定SIP头或者URL进行修改,可以增加黑白名单管理,可以实现负载均衡等非常常见的SBC呼入管理策略。
  www.freesbc.cn SBC/SIP INVITE 脚本路由策略
  7、SBC环境中的下一跳处理机制
  SBC对SIP呼叫请求进行了路由处理以后,需要针对下一个hop做处理来决定下一跳的状态和有效性。SBC可以使用以下几个参数来决定下一跳处理:
  IP地址,支持下一跳的IP地址,这里的IP地址可以是IPv4或者IPv6地址,传输方式可以是TCP,UDP或者TLS。
  主机名称,支持下一跳以主机名称的格式出现,避免如果下一跳使用IP地址,地址发送变动后出现的连接问题。SBC将会使用DNS来对主机名称进行支持。
  服务domain/服务器组, SBC可以通过DNS SRV对IP地址,协议,端口,传输方式进行组合实现对下一跳的支持。因为,一些SBC不仅仅支持SIP协议,也可能同时支持H323协议,协议可以利用不同的端口组合和地址组合实现对下一跳的支持,例如以下组合方式:
  • SIP+D2U—SIP over UDP
  • SIP+D2T—SIP over TCP
  • SIP+D2S—SIP over Stream Control Transmission Protocol (SCTP)
  • SIPS+D2T—Secure SIP over Transport Layer Security (TLS)
  • SIPS+D2S—Secure SIP over SCTP
  除了通过各种组合形式对下一跳支持以外,SBC必须有能力检测到下一跳的有效性状态。SBC不断对对端发送option消息来检查其有效性。如果发生故障时,需要SIP重传的话,根据定时器的设置对对端进行重传。以下是一个通过UDP重传的处理流程:
  一般SBC可以使用两种方式对下一跳进行整体检测。比较典型的下一跳的检测方式是通过SBC发送option消息,执行ping 命令。另外一种就是使用ICMP方式进行检测。很多时候,ICMP的方式可能被过滤,因此,大部分情况下,一般建议还是使用SIP option的方式来发送检测消息。通过SBC,准确性地对下一跳发送检测消息来验证其活动状态。当然,有的服务器为了减少数据交互,可能关闭其option检测。
  8、SBC环境中的呼叫跟踪
  除了以上关于下一跳的讨论以为,在SIP网络环境中,我们经常会需要排查一些端对端的呼叫,跟踪各种呼叫流程。因为涉及了太多的呼叫路径和必要的参数设置支持,并且涉及了不同的拨号规则路由规则和号码变换等问题,笔者不能完全介绍这些手段和工具,读者只能根据具体的环境进行排查。比较欣慰的是,一些SBC厂家的产品本身带了一些呼叫测试的工具,因为SBC是一个B2BUA,因此,SBC测试工具可以测试外网终端,也可以测试内网IPPBX服务器端。
  通过SBC生成对外呼叫测试(freesbc)
  9、总结
  在以上的内容讨论中,笔者首先介绍了关于SIP呼叫中所需要了解到基本概念做了一些分享,同时结合历史文档,帮助读者能够全面掌握SIP呼叫过程中的基本的流程。然后,笔者主要针对SIP呼叫路径中不同的代理服务器之间通信和一些头消息的处理。最后,笔者结合目前使用比较普遍的SBC和SIP企业通信服务器之间的处理,重点介绍了关于SBC路由时的一些影响要素和相关的问题。
  需要说明的是,以为篇幅关系,以及SBC和SIP服务器之间的业务复杂度的关系,很多功能包括路由功能,一些业务媒体服务器也可以实现SBC所具备的一些功能,因此,笔者没有花费太多时间做过多介绍。
  参考资料:
  https://www.rfc-editor.org/rfc/rfc5658
  https://www.rfc-editor.org/rfc/rfc4694
  www.asterisk.org.cn
  www.freesbc.cn
  https://docs.telcobridges.com/tbwiki/Toolpack:Tsbc_Call_Routes_Settings_3.1

【免责声明】本文仅代表作者本人观点,与CTI论坛无关。CTI论坛对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。

专题

CTI论坛会员企业