使用OpenSER构建电话通信系统——第四章(2)

注:以下文章如需转载,请注明所属作者,转载地址,谢谢!


路由基础(Routing Basics

探明如何路由SIP包并不是一件容易的事。我们将在这一节中说明通过代理服务器路由SIP包的一些基本概念。第一个重要的基本概念包含事务和对话。

事务和对话(Transactions and Dialogs

一个事务通常由一个请求开始,由一个响应码(a response code)结束。VIA头域中的branch参数用来标识一个事务。对话可以是开始于一个INVITE事务,结束于一个BYE事务。一个对话由FROMTOCALLID头域的结合所标识。并不是所有的SIP方法都可以启动一个对话,REGISTERMESSAGE方法就不行。

初始和接续请求(Initial and Sequential Requests

了解初始和接续请求消息之间的区别是很重要的。对于初始请求,你必须决定如何使用发现机制来进行路由,通常它是基于DNS或是位置表(a location table)。

初始请求使用VIA头域来记录路由信息,如果你打开record-routing,那么也可以使用ROUTE头域来进行记录。在一个事务中,SIP包将被路由回到之前经过的返回到的每一个代理的VIA头域记录的地址。随后的请求则使用CONTACT头域中的地址进行路由。然而,如果你打开record-routing,接下来的请求则会使用被发现的路由集合路由回去。

你可以用TO头域中的TAG参数来分辨初始和接续请求。

事务的上下文中的路由过程(Routing in a Context of a Transaction

在一个事务中所有的请求都使用VIA头域来进行路由。所以,在到达最终的目的地之前,所有的响应都会经过代理。如果你使用函数t_relay()来路由请求,那么SIP代理会处在有状态模式下,则你可以使用区段onreply_route[]failure_route[]来处理响应和失败。

对话的上下文中的路由过程(Routing in the Context of a Dialog

同一个对话中的接续请求将直接使用CONTACT头域来进行点到点(peer-to-peer)的路由。不过大部分时间你会希望一些接续事务,例如BYE,可以通过代理,这样就可以进行计费和对话控制。你可以打开record-routing来完成这项工作。这样做将指示脚本来进行record-routes.


之后,你可以使用之前记录过的路由信息,也就是我们知道的路由集合(route set),来进行接续请求的前转。这是最通常的配置,也是默认的配置文件中的配置。


实验——跟踪一个完整的对话(Lab------Tracking a Complete Dialog

在这个实验中,我们将使用一个简化了的脚本来理解路由的概念。我们用函数appenc_hf()来添加一个头域到包中以标记包被脚本处理的位置信息。

步骤1:使用下面的脚本(openser.chapter4-2)。重启OpenSER并且重新注册电话。

route{

     # All messages, except for REGISTER will pass here

     if (!method=="REGISTER") record_route();

     # subsequent messages withing a dialog should take the

     # path determined by record-routing

     if (loose_route()) {

            # mark routing logic in request

            append_hf("P-hint: (1)rr-enforced\r\n");

            route(1);

     };

     # We will route only intra-domain requests

     if (!uri==myself) {

            exit();

     };

     # main routing of intra-domain requests

     if (uri==myself) {

            if (method=="REGISTER") {

                   save("location");

                   exit;

            };

            # native SIP destinations are handled using our USRLOC DB

            if (!lookup("location")) {

                   sl_send_reply("404", "Not Found");

                   exit;

            };

            append_hf("P-hint: (2)usrloc applied\r\n");

     };

     route(1);

 }

 route[1] {

     # send it out now; use stateful forwarding

     t_on_reply("1");

     t_on_failure("1");

         if (!t_relay()) {

            sl_reply_error();

     };

     exit;

 }

 onreply_route[1] {

     append_hf("P-hint: (3)passed thru onreply_route[1]\r\n");

 }

 failure_route[1] {

     append_hf("P-hint: (4)passed thru failure_route[1]\r\n");

 }

  步骤2:使用ngrep抓取请求和响应包,并存入文件

ngrep -p -q -W byline port 5060 >rr-stateful

步骤3:由10001001发起一通通话(任何注册的话机都可以)

步骤4:用CTRLC来终止ngrep的运行

使用文本编辑器来检查包并观察P-Hint头域。他们应该要和实验开始时的那幅图中的一样才是。

实验——无状态运行(Lab-------Running Stateless

如果你使用函数forward()来替代函数t_relay(),那么SIP代理将运行在无状态的模式下。所有的工作还在进行,但是你将不能处理响应消息。代理在这时候将无法将同一个事务中请求和响应关联上。响应仍将使用VIA头域来处理。

步骤1:使用forward()函数替代t_relay()函数。

Replace

if (!t_relay()) {

            sl_reply_error();

 };

  By

forward()

步骤2:重启OpenSER,重新注册话机

步骤3:使用ngrep抓取请求和响应到一个文件中

ngrep -p -q -W byline port 5060 > rr-stateless

步骤41000打给1001一通电话

步骤5:结束通话后,终止ngrep

步骤6:使用文本编辑器查看rr-stateless文件。你将注意到响应消息中没有了P-Hint头域。这表明他们没有被区段onreply_route处理。所以,如果你使用无状态模式,除了将消息前转至目的地外,你将无法对回复的消息进行任何处理。

实验——关闭record-routeLab--------Disabling record-route

在这个实验中,我们将停止记录路由。对话中的接续请求将绕过SIP代理,直接由一台话机传到另外一台上。当然,使用了CONTACT头域的消息。

步骤1:将负责记录路由的那一行注释掉

#if (!method=="REGISTER") record_route();

步骤2:重启OpenSER并重新注册话机

步骤3:使用ngrep来抓取请求和响应消息存入文件

ngrep –p –q –W byline port 5060 >norr-stateless

步骤41000打给1001一通电话

步骤5:结束通话后,终止ngrep

步骤6:使用文本编辑器查看norr-stateless文件。现在,你将注意到,无法看到BYEACK请求。因为他们此时直接由一端传到了另一端。如果你想对通话计费,那么你是不想要SIP代理进行这个实验的行为的。

概要(Summary

在这一章中,你已经学到了openser.cfg配置文件中每个区段的一些状态。这是最简单的一个配置文件。在下一章中,我们将增加脚本的功能和复杂度。这一章只是作为开发更高级脚本的一个起点。即使它比较简单,但是这样的一个脚本也已经可以让你能够连接两台话机,并能够互相通话了。

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1068) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-07-27 14:41:08

呵呵,感谢你的翻译!

评论热议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值