P2P之ICE协议(二)

news2025/1/19 23:15:48

名词解释

Transport Address:包含IP、port和传输协议。

Candidate:除了Transport Address 外还包括类型、优先级、foundation还有Base。

Base:Host candidate 关联一个 Server reflexive candidate 。

ICE的建连过程

ICE实现NAT穿透的所要完成的核心处理包括候选地址信息的收集,之后对收集到的地址进行排序、配对,然后执行连通性检查。一个终端有多种候选传输地址(ip地址和端口用于特定传输协议)用以与其他终端进行通信, 它可能包含:

  • 直接连接的网络接口上的传输地址(网卡地址)
  • NAT公共端的翻译后的传输地址 (Server reflexive 服务反向地址)
  • turn 服务分配的传输地址 (Relayed address 服务中继地址)

 候选地址收集

终端必须确定所有的候选的地址。这些地址包括本地网络接口的地址和由它派生的其他所有地址。本地网络地址包括本地网卡地址、VPN 网络地址、MIP 网络地址等。派生地址指的是通过本地地址向 STUN 服务器发送 STUN 请求获得的网络地址,这些地址分为两类,一类是通过 STUN 的绑定得到的地址,称为服务器反向候选地址(Server Reflexive Candidates)或服务器反向地址。另一类是通过 turn 服务中继得到的,称为中继候选地址(Relay Candidates)。

 终端通过各个主机候选地址向 STUN server 发送一个 Bind Request 和向 Turn server 发送 Allocate 消息获取额外的服务器反向地址和服务器中继地址。下图描述的是通过 turn 服务同时发现 Server Reflexive Candidates 和Relay Candidates 的过程:

 当终端发送 turn allocate 消息从IP为IP端口为 Port(主机候选地址)经过NAT,NAT将绑定一个IP为IP1和端口为Port1的地址,映射该候选服务器反向地址到主机候选地址。数据包从主机候选地址出来后,被NAT转换成服务器反向地址;最后发往目标地址。发往服务器反向候选地址的数据包,被NAT转换为主机候选地址,并转发到终端。

当终端和 STUN 服务器之间存在多重 NAT,那么 STUN 请求将会针对每一个NAT创建一个绑定,但是,只有最外部的服务器反向地址会被终端发现。如果终端不在任何NAT之后,那么,base候选传输地址将与服务器反向地址相同,服务器反向地址可以忽略。

当 turn allocate 到达 turn server 后,turn 服务器为该请求分配一个IP为IPy端口为 Porty 的地址,并加此信息到产生的应答消息中,同时把服务器反向地址IP1及 Port1 也加到应答消息中发回终端。turn server 提供中继,把将要加入会话的终端携带的信息转发给对端,这样终端不但有了自己的本地候选地址信息,还有对端的候选地址信息,为后续的建连提供了地址信息基础。

候选地址排序、配对

终端1收集到所有的候选地址后,就将它们按优先级高低进行排序,再通过信令信道发送给终端2。这些候选地址作为 SDP 请求的属性被传输。当终端2收到请求,它执行相同的地址收集过程,并且把它自己的候选地址作为响应消息发给请求者。这样,每个终端都将有一个完整的包含了双方候选地址的列表,然后准备执行连通性检查。连通性检查的基本原理是:

  • 按照优先顺序对候选地址进行排序;
  • 利用每个候选地址发送一个检查包;
  • 收到另一个终端的认可检查包。 

 终端将本地地址集和远程地址集进行配对,如本地有2个地址,对端有3个地址,那么配成2*3=6对地址对。终端A选择本地的一个候选地址向终端B的的服务器反向地址发送一个 STUN 请求,并收到了 Stun 的 response,称该地址对是可接收的。当终端A地址对中的本地地址收到地址对中远程地址的一个STUN请求,并成功地响应,则称该地址对为可发送的。若一个地址对是可接收的,同时又是可发送的,则称该地址对是有效的,即这个地址对通过连通性检查。以上描述的是一个地址对的筛选过程,多个地址对同时进行多次这样的往返交互终端A和终端B就可以筛查出所有的有效地址对。

对候选地址进行排序

由于收集候选地址时,收集的是所有的候选地址,为了能够更快更好的找到能够正常工作的候选地址对,对所有组合进行排序是势在必行的。在此说明进行排序的两个基本原则:

  1. 终端为它的每个候选地址设置一个数值的优先级,这个优先级连同候选地址对一起发送给通信的对端。
  2. 综合本地的和远程的候选地址的优先级,计算出候选地址对的优先级,这样,双方的同一个候选地址对的优先级相同。以此排序,则通信双方的排序结果相同。

冻结候选

每个候选者都和一个叫 FOUNDATION 属性相关,两个候选者的 foundation 是“相同”的--是相同的主机候选者,且用了相同的 stun 服务协议。否则它们的 foundation 是不一样的 。候选地址对也有 foundation,只是和两个候选地址相关联。初始阶段,仅有唯一 foundation 的地址对进行检测,其他的对候选地址对都是处于“冻结”状态。当可连接检测成功后,在解冻和当前 foundation 一样的候选地址对,这样可以避免重复检查表面上看起来更可能连接成功,但实际上会失败的候选地址对。

Foundations计算,两个候选地址要有相同的 foundation ID:

o 一样的类型(主机、服务器映射、中继、对端映射)。

o Base 有相同的IP(端口可以不一样)。

o 用的相同的传输协议。

o 服务器反向和中继地址,当 stun 或则 turn server 获取到它的IP是一样的。

否则就要用不同的ID。

候选地址对的排序

候选地址 priority 的计算公式:

priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID)

 类型首选项必须是0到126(含0和126)之间的整数,0为最低优先级,126为最大优先级。

本地首选项必须是0到65535(含0和65535)之间的整数。0为最低优先级,65535为最高优先级。

The component ID必须是0到256(含0和256)之间的整数。

角色的选择

对于ICE流程中的每个会话,每个终端都扮演一个角色。有两个角色--控制和被控制。被控制终端负责最后一对候选配对的选择,用于通信。这意味着提名候选地址对,用于每个媒体流。控制终端被告知哪些候选对用于每个媒体流。决定角色的规则如下:

  • 双端都是全实现(ICE-FULL):一端在发起请求的时候是控制者,另外一端则是被控制者,双端都要跑ICE的状态机,做可连接性检测。
  • 一端是全实现(ICE-FULL), 另外一端是轻实现(ICE-LITE):全实现的发起请求作为控制者跑ICE的状态机,做可连接性检测;轻实现者作为被控制者。
  • 双端都是轻实现:一端在发起请求的时候是控制者,另外一端则是被控制者.

 在一些特殊的流程下,可能会导致会话的双方都认为自己是控制者或者被控制者。为了解决角色冲突,在 connectivity check 的阶段,发送的 bind request 要求携带 role 相关的 STUN 属性,ICE-CONTROLLED 或者是 ICE-CONTROLLING,这两个属性都会携带一个 Tie breaker(取值0- 2^64 - 1)这样的字段,其中包含 一个本机产生的随机值。收到该 bind request 的一方会检查这两个字段,如果和当前本机的 role 冲突,则检查本机的 tie breaker 值和消息中携带的 tie breaker 值进行判定本机合适的role。判定的方法为 Tie breaker 值大的一方为 controlling。如果判定本端变更角色,就会直接修改;如果判定对端变更角色,则对此 bind request 发送487错误响应,收到此错误响应的一端改变角色就可以了。(这里就用到了STUN 请求新增的属性 0x8029 ICE-CONTROLLED 0x802A ICE-CONTROLLING 以及STUN错误反馈487 Role Conflict: 终端指定的角色和 server 指定的角色冲突)。

候选地址对优先级计算及排序

一旦候选地址对确定好后,就要给它们计算优先级。G为控制端地址的优先级,D为被控制端的地址优先级。候选地址对的优先级计算公式:

pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)

 一旦分配了候选对优先级,就会候选对按优先级降序配对。如果两对具有相同的优先级,它们之间的顺序是任意的。

候选地址对状态机

  •  开始的时候终端将所有的候选地址对的状态设置为Frozen;
  • 终端检查第一个媒体流中的列表:对于所有具有相同Foudation的候选对,把最小componentID的地址对设置为Wait状态,如果数量超过一个,那么具有最高优先级的地址对设置为Wait状态;
  • 处理过程的结果要么成功要么失败。

 连接检查

此流程只有全量实现才有,又分为平常检查和触发检查,两者都是由定时驱动。终端持有一个先进先出队列,称为触发队列,里面放着下次有机会触发的candidate pair。当定时器触发后,终端从触发队列里拿出最上面的candidate pair,执行连接检查,设置该candidate pair状态为In Progress。如果触发队列为空,就执行平常检查。一旦终端完成组织好candidate pairs后,就给个这些活动的检查列表设置定时器,有N个就设置N个定时器,时间间隔为Ta*N秒。当定时器触发后但没有触发检查可发送,终端必须切换到平常检查流程如下:

ICE Restart

终端可能为媒体流重启ICE,那么原来的又变回到了新的状态。和新的会话不同的点就是在重启的过程中,媒体依然可以从前面有效的地址对发送。一个终端必须重启ICE,当列情况出现的时候:

  • 生成offer是为了更改指定的媒体流。换句话说,如果终端想生成一个更新的offer,而ICE又没有使用,将会为该媒体流重启ICE;
  • 终端更改它的实现级别,这通常只发生在第三方呼叫控制用例中
  • 这些规则意味着将 c 行中的 IP 地址设置为0.0.0.0 将导致 ICE 重启。因此,ICE 实现不得使用此机制进行呼叫保持,而必须使用sdp协议中的a=inactive 和 a=sendonly 。要重新启动 ICE,代理必须更改offer中媒体流的 ice-pwd 和 ice-ufrag。

地址信息的传递

我们都知道ICE协议只负责收集通信地址对它们进行排序,要让通信双方都知道自己处在的网络环境和通信地址,还要通过服务器中继,多媒体通信一般都通过SDP[ RFC 4566]协议进行封装。下面是用于ICE协议的attribute extensions。

a=ice-pwd:asd88fgpdd777uzjYhagZg a=ice-ufrag:8hhY

sdp中传递ice-ufrag和ice-pwd用于stun信息的安全有效校验。candidate属性携带有效的通信地址信息,依次是从1开始递增的component-id、通信协议(tcp或udp)、foundation、IP、port、type、relate_address、network-id和network-cost。

参考文献:

STUN:https://datatracker.ietf.org/doc/rfc5389/

SDP:https://datatracker.ietf.org/doc/rfc4566/

ICE:https://datatracker.ietf.org/doc/rfc8445/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/93099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

影像组学——一个入门级汇报

影像组学1 相关综述2 发展历程3 研究背景4 影像组学工作流程5 临床应用6 影像组学的问题及挑战7 发展趋势1 相关综述 1. Radiomics the process and the challenges 2. Radiomics Extracting more information from medicalimages 3. Integrating pathomics with radiomics an…

Qt新手入门指南——创建一个基于Qt Widget的文本查找器(二)

Qt是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 本教程将介绍如何使用…

原生JS之sort排序方法详解

在JavaScript中排序主要用到的api就是sort了,但是使用sort有几个坑需要注意,让我们一起来看看 排序原理-不使用参数时 sort() 方法用于对数组的元素进行排序。排序顺序可以是字母或数字,并按升序或降序。 默认排序顺序为按字典升序。 在不…

CSS 如何实现羽化效果?

最近碰到这样一个问题,在一张封面上直接显示书名,可能会存在书名看不太清楚的情况(容易受到背景干扰),如下 为了解决这个问题,设计师提了一个“究极”方案,将书名背后的图片模糊一下&#xff0c…

【OpenCV-Python】教程:6-1 相机标定

OpenCV Python 相机标定 【目标】 摄像机引起的失真类型如何找到相机的内参和外参如何基于这些特性校正这些图像 【理论】 一些针孔相机会导致图像发生严重失真,主要有两种,一是径向畸变,一是切向畸变。 径向畸变使直线看起来弯曲。距离…

Spring MVC学习 | 报文信息转换

文章目录一、HttpMessageConverter二、获取请求报文信息2.1 使用原生servletAPI2.2 使用RequestBody注解获取请求体信息2.3 使用RequestEntity对象获取请求报文信息三、设置响应报文信息3.1 使用原生的servletAPI3.2 使用ResponseBody注解设置响应体信息3.3 ResponseEntity类的…

Docker 镜像构建可以分享的快乐

通过上一篇 Dockerfile 语法与指令的学习,本节就开始使用Dockerfile 来制作自己的 Docker 镜像啦。 Docker 镜像构建 新建 app.py 文件 from flask import Flaskapp Flask(__name__)app.route(/) def hello():return Hello World! Hogwarts.本代码主要功能是当我…

二十八—— 四十三

二十八、JavaScript——if-else语句 if-else语句- 语法: if(条件表达式) { 语句 }else{ 语句。。。 } - 执行流程 if-else执行时,先对条件表达式进行判断 如果结果为true,则执行if后得而语句 如果结果为false,则执行else后的语句 if-else if-…

公众号名称排名优化

HTML 实例解释 <p> 元素&#xff1a; <p>This is my first paragraph.</p> 这个 <p> 元素定义了 HTML 文档中的一个段落。 这个元素拥有一个开始标签 <p>&#xff0c;以及一个结束标签 </p>。 元素内容是&#xff1a;This is my firs…

生产环境LVM卷ext4文件系统故障修复处理

一、问题描述 某项目因存储视频流泪数据,数据量较大,生产环境当时已达158TB,采用LVM+Ext4存储,在某次LVM在线扩容过程中,扩容失败,报错:inode_counter 溢出,从字面看就i节点数量超过最大限制了,被lvresize命令忽略,报出警告:Invalid argument While checking for on…

Ac-GA-K(Ac)-AMC,577969-56-3

Ac- gak (Ac)-AMC&#xff0c;在蛋白酶偶联试验中测量组蛋白去乙酰化酶I类(HDAC 1、2、3和8)和II类(HDAC 6和10)活性的荧光底物。hdac催化Lys脱乙酰生成Ac-GAK-AM。 Ac-GAK(Ac)-AMC, fluorogenic substrate for measuring histone deacetylase class I (HDAC 1, 2, 3, and 8) a…

朴素二进制表示法

思路方案 在安全领域的研究中我们发现&#xff0c;很多数据预处理的步骤&#xff0c;在不同的场景下中都可以相互 借鉴&#xff0c;甚至可以进行直接复用。例如&#xff0c;对于加密流量相关的数据&#xff0c;当算法工程师 获取到一批加密流量的 pcap 包之后&#xff0c;不论他…

「Docker学习系列教程」基础篇小总结及高级篇预告

通过前面十来篇的学习&#xff0c;我们已经把docker基础篇学习完了。这篇文章&#xff0c;咱们就来小总结下基础篇学习的东西以及介绍接下来高级篇中&#xff0c;将会学习到哪些知识点。 基础篇总结&#xff1a; 第一篇&#xff0c; 凯哥就介绍了怎么在Centos系统中安装D…

【微服务之分布式全局Id】分布式全局ID生成

分布式全局ID解决方案 1、UUID 最容易想到的就是 UUID (Universally Unique Identifier) 了&#xff0c; UUID 的标准型式包含 32 个 16 进制数字&#xff0c;以连字号分为五段&#xff0c;形式为 8-4-4-4-12 的 36 个字符&#xff0c;这个是 Java 自带的&#xff0c;用着也简…

DBCO-PEG-Silane|DBCO-PEG-SIL|二苯并环辛炔-聚乙二醇-硅烷

DBCO-PEG-Silane&#xff0c;DBCO 试剂是一类点击化学标记试剂&#xff0c;含有非常活泼的 DBCO&#xff08;&#xff08;二苯并环辛炔&#xff09;基团&#xff0c;DBCO 试剂可以通过无铜点击化学与叠氮化物标记的分子或生物分子发生反应。DBCO 点击化学可以在水性缓冲液中运行…

用噪点滤镜回忆童年电视机的雪花屏

介绍 相信很多人80,90后的同学对童年里电视机的突然出现刺啦刺啦的雪花屏记忆犹新&#xff0c;本期将用 pixi.js 来完成一个电视机播放动漫然后突然出现雪花屏的动画&#xff0c;里面主要讲解了如何使用pixi.js播放帧动画和如何用噪点滤镜制造雪花屏。 演示 正文 初始化渲染…

web前端网页设计期末课程大作业:关于城市旅游的HTML网页设计 ——北京

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

微服务框架 SpringCloud微服务架构 多级缓存 48 多级缓存 48.2 OpenResty 快速入门

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存48 多级缓存48.2 OpenResty 快速入门48.2.1 直接开干48 多级缓存 48.2 OpenResty 快速入门 48.2.1 直…

Linux(三) makefile与gdb调试

makefile mkefile文件中定义了一系列的规则来指定&#xff0c;哪些文件需要线编译&#xff0c;哪些后编译&#xff0c;哪些需要重新编译&#xff0c;甚至进行更复杂的功能操作&#xff0c;因为makefile就像一个Shell脚本一样&#xff0c;其中也可以执行操作系统的命令。 mkef…

java计算机毕业设计基于安卓Android的教学考勤系统APP

项目介绍 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设…