知行合一
全部博文(31)
分类: 系统运维
2009-07-24 15:36:24
探明如何路由SIP包并不是一件容易的事。我们将在这一节中说明通过代理服务器路由SIP包的一些基本概念。第一个重要的基本概念包含事务和对话。
一个事务通常由一个请求开始,由一个响应码(a response code)结束。VIA头域中的branch参数用来标识一个事务。对话可以是开始于一个INVITE事务,结束于一个BYE事务。一个对话由FROM,TO和CALL-ID头域的结合所标识。并不是所有的SIP方法都可以启动一个对话,REGISTER和MESSAGE方法就不行。
了解初始和接续请求消息之间的区别是很重要的。对于初始请求,你必须决定如何使用发现机制来进行路由,通常它是基于DNS或是位置表(a
location table)。
初始请求使用VIA头域来记录路由信息,如果你打开record-routing,那么也可以使用ROUTE头域来进行记录。在一个事务中,SIP包将被路由回到之前经过的返回到的每一个代理的VIA头域记录的地址。随后的请求则使用CONTACT头域中的地址进行路由。然而,如果你打开record-routing,接下来的请求则会使用被发现的路由集合路由回去。
你可以用TO头域中的TAG参数来分辨初始和接续请求。
在一个事务中所有的请求都使用VIA头域来进行路由。所以,在到达最终的目的地之前,所有的响应都会经过代理。如果你使用函数t_relay()来路由请求,那么SIP代理会处在有状态模式下,则你可以使用区段onreply_route[]和failure_route[]来处理响应和失败。
同一个对话中的接续请求将直接使用CONTACT头域来进行点到点(peer-to-peer)的路由。不过大部分时间你会希望一些接续事务,例如BYE,可以通过代理,这样就可以进行计费和对话控制。你可以打开record-routing来完成这项工作。这样做将指示脚本来进行record-routes.
之后,你可以使用之前记录过的路由信息,也就是我们知道的路由集合(route set),来进行接续请求的前转。这是最通常的配置,也是默认的配置文件中的配置。
在这个实验中,我们将使用一个简化了的脚本来理解路由的概念。我们用函数appenc_hf()来添加一个头域到包中以标记包被脚本处理的位置信息。
步骤1:使用下面的脚本(openser.chapter4-2)。重启OpenSER并且重新注册电话。
route{
ngrep -p -q -W byline port 5060 >rr-stateful
步骤3:由1000到1001发起一通通话(任何注册的话机都可以)
步骤4:用CTRL-C来终止ngrep的运行
使用文本编辑器来检查包并观察P-Hint头域。他们应该要和实验开始时的那幅图中的一样才是。
如果你使用函数forward()来替代函数t_relay(),那么SIP代理将运行在无状态的模式下。所有的工作还在进行,但是你将不能处理响应消息。代理在这时候将无法将同一个事务中请求和响应关联上。响应仍将使用VIA头域来处理。
步骤1:使用forward()函数替代t_relay()函数。
Replace:
if (!t_relay()) {
forward()
步骤2:重启OpenSER,重新注册话机
步骤3:使用ngrep抓取请求和响应到一个文件中
ngrep -p -q -W byline port 5060 > rr-stateless
步骤4:1000打给1001一通电话
步骤5:结束通话后,终止ngrep
步骤6:使用文本编辑器查看rr-stateless文件。你将注意到响应消息中没有了P-Hint头域。这表明他们没有被区段onreply_route处理。所以,如果你使用无状态模式,除了将消息前转至目的地外,你将无法对回复的消息进行任何处理。
在这个实验中,我们将停止记录路由。对话中的接续请求将绕过SIP代理,直接由一台话机传到另外一台上。当然,使用了CONTACT头域的消息。
步骤1:将负责记录路由的那一行注释掉
#if (!method=="REGISTER") record_route();
步骤2:重启OpenSER并重新注册话机
步骤3:使用ngrep来抓取请求和响应消息存入文件
ngrep –p –q –W byline port 5060 >norr-stateless
步骤4:1000打给1001一通电话
步骤5:结束通话后,终止ngrep
步骤6:使用文本编辑器查看norr-stateless文件。现在,你将注意到,无法看到BYE和ACK请求。因为他们此时直接由一端传到了另一端。如果你想对通话计费,那么你是不想要SIP代理进行这个实验的行为的。
在这一章中,你已经学到了openser.cfg配置文件中每个区段的一些状态。这是最简单的一个配置文件。在下一章中,我们将增加脚本的功能和复杂度。这一章只是作为开发更高级脚本的一个起点。即使它比较简单,但是这样的一个脚本也已经可以让你能够连接两台话机,并能够互相通话了。