首页 > SIP协议的传输层原理报文解析(解读rfc3581)(待排版)

SIP协议的传输层原理报文解析(解读rfc3581)(待排版)



关于rfc3581/rport参数的阐述

一:简述

一般情况下,服务器在接收到request后,应答发向哪里呢?服务器在计算回应应答的算法是一种混合模式,具体说来是这样的:

1,IP:从哪里接收到的就会给哪里,即ip包上记录的源地址

2,port:根据sip报文的头解析出来,

对于处理被NAT包裹的环境中的客户端,请求是可以发出去的,但是应答却无法穿透NAT,就要借助rport这个位于via 类型header的param来处理了

  附:目前还借助了“received”这个param in topmost via header,原理是这样的

 

         服务器会将自己实际从哪个ip上接收到的请求记录在“received”,通过他可以有助于让应答穿越NAT。但是没有指定port,那怎么半呢?

 

二,客户端

可以在其声称的请求中,包含"rport" 这个参数in the top  via header,但是不能有值,这个只是表示我支持该扩展属性。

当客户端使用udp将请求发送出去后,他必须在其发送请求的那个ip:port上准备好接收回来的应答,

同时,他还需要在“sent-by”中指定的端口上准备接收。

 

一旦在客户端和服务器之间有一个NAT存在,那么当请求经过NAT的时候会在nat上创建一条绑定,这个绑定记录还要保有一个超时时间,保证在这个时间内能够接收到服务器端的应答。

大部分的udp NAT,这个超时时间设置的是1min,这个远远超过了non-invite传输的时间。所以,对于non-invite请求,接收到应答是没问题的。

而,INVITE传输则可以是任意的超时时长,所以为了不让nat把我关掉,客户端应该每20s就传一次,这种重传必须一直延续着,尽管接收到临时应答了

 

三,服务端

服务器(这里的服务器包括proxy 或者 UAS)在接收到请求之后,会检查topmost via的头域,如果头域中包含“rport”参数 with no value,则把该值设置成接收到请求的源端口号

这个原理等同于服务端在向topmost via中insert “reseived”一样。实际上,服务端必须要insert一个包含接收请求的源地值的 “reseived”到via中,即使这个源地值域sent-by是一样的。

注:以上处理域传输层协议无关

当一个服务器想要发送应答的时候,他会检查应答中的topmost via ,如果“sent-protocol”组件指示要使用不可靠传输协议比如udp,那么时不可以有“maddr”这个参数的,但是有 “reseived”和“rport”参数,

这个应答必须发送给“reseived”中列出的所有ip,对应的端口为“rport”中指定的,而这个应答必须经由接收请求的那个ip:port发送出去,这么做是为了穿越对称NAT

当一个server监听在多interface或者多port上时,他需要记住从哪一个上接收到了请求。对于有状态proxy,在传输期间存储这些信息也不是什么难题。然而对于无状态proxy,不会存储请求和应答的关系,所以不能记住从哪里接收到的请求。

所以,为了实现上述的要求,一个无状态的proxy就需要把请求中的目的地址和端口号编码进via 头域中,一旦这个应答来了,他就可以提取这个信息用于指导如何转发应答。

 

四,例子

1,A client sends an INVITE to a proxy server which looks like, in part:INVITE sip:[email protected] SIP/2.0Via: SIP/2.0/UDP 10.1.1.1:4540;rport;branch=z9hG4bKkjshdyff


这个INVITE 请求从源地址:10.1.1.1:4540这个客户端发出来的,想要到达的目的地是[email protected]
服务proxy的地址为192.0.2.2即proxy.example.com,他会在5060和5070端口上。
于是,请求会发向proxy的5060端口

这个过程会经过nat,所以ip包上的源地值会变成192.0.2.1,而端口号变成9988

proxy接收请求再转发,但是转发之前要把
"rport"参数insert到via中,于是头变成了这样:
INVITE sip:[email protected] SIP/2.0Via: SIP/2.0/UDP proxy.example.com;branch=z9hG4bKkjsh77   ---因为经过了一个proxy嘛,所以肯定要加一个viaVia: SIP/2.0/UDP 10.1.1.1:4540;received=192.0.2.1;rport=9988;branch=z9hG4bKkjshdyff      ---因为发现接收request的源ip和via中指定的ip不同,所以这里要加上received和rportThis request generates a response which arrives at the proxy:

(wxy:针对这个请求,proxy会生成一个应答,是如下这个样子的:)SIP/2.0 200 OKVia: SIP/2.0/UDP proxy.example.com;branch=z9hG4bKkjsh77Via: SIP/2.0/UDP 10.1.1.1:4540;received=192.0.2.1;rport=9988;branch=z9hG4bKkjshdyff



The proxy strips its top Via header field value, and then examinesthe next one. It contains both a "received" parameter and an "rport"parameter. The server follows the rules specified in Section 4 andsends the response to IP address 192.0.2.1, port 9988, and sends itfrom port 5060 on 192.0.2.2:
   proxy首先找到top via header,然后检查他的下一个,他既包含了received也包含了rport参数

于是这个服务器就会根据之前说的原则,将应答发给192.0.2.1:9988,并且是从192.0.2.2:5060上发出去的
   SIP/2.0 200 OKVia: SIP/2.0/UDP 10.1.1.1:4540;received=192.0.2.1;rport=9988;branch=z9hG4bKkjshdyffThis packet matches the binding created by the initial request.Therefore, the NAT rewrites the destination address of this packetback to 10.1.1.1, and the destination port back to 4540.  It forwardsthis response to the client, which is listening for the response onthat address and port.  The client properly receives the response.

 

转载于:https://www.cnblogs.com/shuiguizi/p/11235982.html

更多相关:

  • 一、代码结构概览1.核心部分configs:储存各种网络的yaml配置文件datasets:存放数据集的地方detectron2:运行代码的核心组件tools:提供了运行代码的入口以及一切可视化的代码文件。2.Tutorial部分demo:显而易见就是demodocs: 同样显而易见。。tests:提供了一些测试代码projects:...

  •     我刚刚接手这个项目的时候就被一系列不知所措的文件命名给深深的震惊了,那种振聋发聩不亚于听到赌王离世的消息。 首先请看,文件本来是用于处理“请假审批”,但是文件名居然叫做“teaApprove”,不要欺负我的初中英语不好,这个teaApprove我第一个感觉就是和“喝茶、茶叶”有关的业务,可是和我们这个项目八竿子打不着...

  • 这个问题简单,不做过多描述,如题所述,如果因为这个导致错误,请安装 npm install stylus-loader css-loader style-loader -D...

  • 使用这个宏TS_VERSION_MAOR来判断,这个宏定义在编译时生成在apidefs.h,它包含在ts/ts.h中,所以请在插件这包含...

  • linux valgrind Memcheck–内存检查工具 使用方法: 注意,这里要用debug版本,如果是release的运行文件,则用debug编译出来的可执行文件替换 输出到终端: valgrind --tool=memcheck --leak-check=full ./test.out 输出到文件: valgri...

  • 限流器是后台服务中十分重要的组件,在实际的业务场景中使用居多,其设计在微服务、网关、和一些后台服务中会经常遇到。限流器的作用是用来限制其请求的速率,保护后台响应服务,以免服务过载导致服务不可用现象出现。限流器的实现方法有很多种,例如 Token Bucket、滑动窗口法、Leaky Bucket等。在 Golang 库中官方给我们提供...

  • HTTP和HTTPSHTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法。HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)简单讲是HTTP的安全版,在HTTP下加入SSL层。SSL(Secure...

  •     注意!!!(修改于2020年7月18日)   在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据 报错截图如下 报错内容: {"message": "Network Error","name": "Error","stack": "Err...

  • 一.  GET_POST与开发者工具 1.      浏览器的基本工作规则 浏览器请求访问服务器,服务器返回数据 (1)    请求的格式 GET:长度不能大于2k参数明文显示在地址栏,不保密,通常用在查询请求 POST:长度可以很大,参数写在请求体内,相对保密,通常用是提交内容的请求 上图中a.com是域名,x...

  • JSP相当于在HTML页面中加上Java代码,一般在标签中放入主要代码。 在JSP里用<%...%>把Java代码包含起来的。   Servlet的生命周期: ①被服务器实例化后,容器运行init方法。 ②当请求(Request)到达时,运行service方法,service方法会运行与请求对应的doXXX方法(d...