当前位置: 首页 > 编程日记 > 正文

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:user@example.com SIP/2.0Via: SIP/2.0/UDP 10.1.1.1:4540;rport;branch=z9hG4bKkjshdyff

这个INVITE 请求从源地址:10.1.1.1:4540这个客户端发出来的,想要到达的目的地是user@example.com
服务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:user@example.com 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

相关文章:

listener.ora、sqlnet.ora、tnsnames.ora 详解

三个配置文件 listener.ora、sqlnet.ora、tnsnames.ora,都是放在$oracle_home\network\admin目录下。 重点:三个文件的作用和使用 sqlnet.ora-----作用类似于linux或者其他unix的nsswitch.conf文件,通过这个文件来决定怎么样找一个连接中出现…

简单图片放大效果

在今天我创造了一个小的代码段在JQuery,这次是关于图像缩放盘旋,这种特征可能适合一个网络摄影展,现场有许多内容,给一个小快速预览关于该物品。 <!DOCTYPE html><html><head><title>JQuery Zoom Hover</title><meta http-equiv"Content…

使用datatables实现列宽设置、水平滚动条、显示某列部分内容

示例 1、//使用 columnDefs 给列设置宽度 $(#example).DataTable( { "columnDefs": [ //给第一列指定宽度为表格整个宽度的20% { "width": "20%", "targets": 0 } ] } ); //使用 columns 给列设置宽度 $(#example).DataTable( { &q…

使用jvisualvm远程监控tomcat(阿里云ECS)

写在前面&#xff1a; 使用jvisualvm远程监控tomcat(阿里云ECS)&#xff0c;连接是报错&#xff1a;service:jmx:rmi:jndi/rmi:IP:端口// 连接到 IP:端口&#xff0c;网上找了很多资料&#xff0c;未能解决&#xff0c;现已解决&#xff0c;记录下&#xff0c;供参考 本文为本…

【蓝桥java】递归基础之振兴中华

题目&#xff1a; 小明参加了学校的趣味运动会&#xff0c;其中的一个项目是&#xff1a;跳格子。 地上画着一些格子&#xff0c;每个格子里写一个字&#xff0c;如下所示&#xff1a;&#xff08;也可参见下图&#xff09; 从我做起振 我做起振兴 做起振兴中 起振兴中华 比赛时…

*p++,*(p++),(*p)++,printf过程调用

#include<stdio.h> int main() { printf(); } 答案为D 执行完(*ptr)123;后arr[]{129,7,8,9,10} 执行printf("%d.%d\n",*ptr,*(ptr));时&#xff0c;根据c语言中的函数参数压栈顺序--从右向左&#xff0c;首先计算表达式*(ptr)并将其压入栈中&#xff0c;…

docker实战部署Javaweb项目

一、部署环境说明 docker服务版本&#xff1a;version 18.09.0nginx服务版本&#xff1a;version: nginx/1.15.10redis服务版本&#xff1a;version: redis/5.0.3tomcat服务版本&#xff1a;version: tomcat/8.5.30JDK服务版本&#xff1a;alpine-oraclejdk8 二、安装docker服务…

父子表关联在窗体中的绑定显示和浏览

private BindingManagerBase bm1 null;private BindingManagerBase bm2 null;private void DataScanInForm2_Load(object sender, EventArgs e) {string sqlString1 "select * from 客户";string sqlString2 "select * from 订单";string[] sql…

【Excel】使用Excel函数计算二项分布泊松分布概率

例&#xff1a; 计算如下参数的二项分布和泊松分布 二项分布 1、选中单元框&#xff0c;添加函数 2、选中统计类函数 3、选择二项分布概率函数 4、输入相应的参数 注&#xff1a; &#xff08;1&#xff09;在输入参数时点击相应的单元格即可 &#xff08;2&#xff09;最后…

万能android调用webservice方法——参数类型不受限制

说明&#xff1a;只是个例子&#xff0c;扩展性、复用性不好&#xff0c;只是提出一个思路&#xff0c;返回的XML解析代码写的也很烂聪明的你&#xff0c;拿来代码的时候&#xff0c;肯定能解决这些问题关键代码&#xff1a; try{//发帖机原理&#xff0c;模拟浏览器finalStrin…

Vue轮播图插件---Vue-Awesome-Swiper

轮播图插件 Vue-Awesome-Swiper 地址&#xff1a;https://github.com/surmon-china/vue-awesome-swiper 安装&#xff1a;npm install vue-awesome-swiper --save 局部引入&#xff1a;import swiper/dist/css/swiper.cssimport { swiper, swiperSlide } from vue-awesome-swip…

linux下遇到的小问题与解决方法

Linux下执行.sh脚本错误&#xff1a;bin/sh^M: bad interpreter: No such file or directory 原因是.sh脚本在windows系统下用记事本文件编写的。不同系统的编码格式引起的。 转行文件的编码格式&#xff1a; 1、确保用户对文件有读写及执行权限 oraclelinux-106:~/RMAN/bin&g…

阶段1 语言基础+高级_1-3-Java语言高级_04-集合_05 List集合_1_List集合_介绍常用方法...

有序的&#xff0c;还包含索引&#xff0c;允许有重复的值、 add 打印出来的不是地址&#xff0c;说明重写了toString的方法 remove方法 返回的是被移除的元素 set方法 get 索引越界异常 几种越界的异常转载于:https://www.cnblogs.com/wangjunwei/p/11237813.html

【蓝桥java】进制与整除之天平秤重

题目&#xff1a; 用天平称重时&#xff0c;我们希望用尽可能少的砝码组合称出尽可能多的重量。 如果只有5个砝码&#xff0c;重量分别是1&#xff0c;3&#xff0c;9&#xff0c;27&#xff0c;81 则它们可以组合称出1到121之间任意整数重量&#xff08;砝码允许放在左右两个盘…

分享一个C#使用AT指令控制语音猫的例子

阅读全文&#xff1a;http://www.cckan.net/forum.php?modviewthread&tid61 先来说说 最近公司让开发一个语音猫充值的软件&#xff0c;就是拨打10086&#xff08;虚拟&#xff09;进行话费充值操作&#xff0c;虚拟流程如下&#xff1b; 1.先拨通10086 2.按1进行话费充值…

个人银行账户管理程序

这个程序是一个银行账户管理的程序&#xff0c;是用C来实现程序功能的&#xff0c;该程序包含六个文件&#xff0c;其中有date.h头文件 是日期类的头文件&#xff0c;date.cpp是日期类的实现文件&#xff0c;accumulator.h是按日将数值累加的accumulator类的头文件&#xff0c;…

两个关于水花的测试。

海面上的水花的特效&#xff0c;水花是在浪尖处发射出来的&#xff0c;目前还没有让发射参数自动化的方法&#xff0c;都是表达式。一旦改变浪的性质&#xff0c;发射的粒子就要重新写动态了。 Splash on the ocean emitted from the crisp faces on top of the wave, the whit…

泛型在三层中的应用

一说到三层架构&#xff0c;我想大家都了解&#xff0c;这里就简单说下&#xff0c;三层架构一般包含&#xff1a;UI层、DAL层、BLL层&#xff0c;其中每层由Model实体类来传递&#xff0c;所以Model也算是三层架构之一了&#xff0c;例外为了数据库的迁移或者更OO点&#xff0…

【蓝桥java】进制与整除之尼姆堆

题目&#xff1a; 有3堆硬币&#xff0c;分别是3,4,5 二人轮流取硬币。 每人每次只能从某一堆上取任意数量。 不能弃权。 取到最后一枚硬币的为赢家。 求先取硬币一方有无必胜的招法。 在提供代买前做几条补充&#xff1a; &#xff08;1&#xff09;这里有一个不是很好理解的…

RSA遭骇 Token 换?不换?

RSA SecurID Token召回更换的动作仍然持续进行中&#xff0c;根据外电报导&#xff0c;美国有些企业已经要求更换Token&#xff0c;如花旗集团、美国银行、富国银行、摩根大通、澳盛银行、澳洲西太平洋银行。于此同时&#xff0c;一些竞争供应商也动作频频&#xff0c;例如Safe…

二叉树的镜像(数组,前后 遍历重建二叉树)

题目描述 操作给定的二叉树&#xff0c;将其变换为源二叉树的镜像。输入描述: 二叉树的镜像定义&#xff1a;源二叉树 8/ \6 10/ \ / \ 5 7 9 11镜像二叉树8/ \10 6/ \ / \11 9 7 5 #include <iostream> #include <cstdio> #include <cstdlib> #in…

tp5实现Redis的简单使用

方法1&#xff1a; Controller <?php namespace app\index\controller;use think\Controller; use think\session\driver\Redis;class Index extends Controller {public function index(){$redis new Redis();if(!$redis->has(str)){var_dump($redis->set(str,this…

Linux下getsockopt/setsockopt 函数说明

【getsockopt/setsockopt系统调用】 功能描述&#xff1a; 获取或者设置与某个套接字关联的选 项。选项可能存在于多层协议中&#xff0c;它们总会出现在最上面的套接字层。当操作套接字选项时&#xff0c;选项位于的层和选项的名称必须给出。为了操作套接字层的选项…

【蓝桥java】进制与整除之最大公约数 最小公倍数

补充&#xff1a; &#xff08;1&#xff09;欧几里得定理&#xff08;辗转相除法&#xff09;&#xff1a;A和B的最大公约数 B和A%B 的最大公约数 &#xff08;2&#xff09;将两个数乘起来再除以最大公约数就是最小公倍数 package cn.zzunit.jnvi;/***寻找最大公约数* autho…

学习C#要养成的好习惯

1. 避免将多个类放在一个文件里面。2. 一个文件应该只有一个命名空间&#xff0c;避免将多个命名空间放在同一个文件里面。3. 一个文件最好不要超过500行的代码&#xff08;不包括机器产生的代码&#xff09;。4. 一个方法的代码长度最好不要超过25行。5. 避免方法中有超过5个参…

3.1、final、finally、 finalize

final 可以用来修饰类、方法、变量&#xff0c;分别有不同的意义&#xff0c;final 修饰的 class 代表不可以继承扩展&#xff0c;final 的变量是不可以修改的&#xff0c;而 final 的方法也是不可以重写的&#xff08;override&#xff09;。 finally 则是 Java 保证重点代码一…

Android模拟器学framework和driver之传感器篇1(linux sensor driver)

对于android模拟器开发环境的搭建这里我就不多说了&#xff0c;网上google下一大堆&#xff0c;还有就是android 模拟器的kernel使用的是goldfish的kernel&#xff0c;可以使用git得到源码&#xff0c;然后就可以编译了&#xff0c;大家还是可以参考罗老师的博客。。。 在这里我…

【java】Lombok的使用

介绍&#xff1a;lombok在编译entity文件时自动生成get set toString hashCode等方法&#xff0c;这样方法生成就不用写在代码里了&#xff0c;可以简化代码。 使用方法&#xff1a; 一、在pom文件里引入lombok的依赖 代码实现&#xff1a; <dependency><groupId&g…

自己开发开源jquery插件--给jquery.treeview加上checkbox

很多时候需要把树状的数据显示除来&#xff0c;比如分类&#xff0c;中国省份、城市信息&#xff0c;等&#xff0c;因此这方面的javascript插件也有很多.比如性能优异的jquery.treeview和国人开发的功能强大的zTree. 我最近在一个项目中用到了jquery.treeview&#xff0c;但是…

SQL Server 2000安装时不出现安装界面,进程中存在解决

在XP和Server 2003系统中安装SQL Server 2000过程中&#xff0c;点击安装后&#xff0c;一直不出现安装界面&#xff0c;查看进程中也有&#xff0c;一直无反应。 解决办法&#xff1a; 首先重新启动机器&#xff0c;或者任务管理器里面结束2个sql进程 1. 在 SQLServer 安装向导…