P2P/Server
WebRTC传输基本知识
- NAT(Network Address Translator)
- STUN(Simple Traversal of UDP Through NAT)
- TURN(Traversal Using Relays around NAT)
- ICE(Interactive Connectivity Establishment)
NAT
作用
产生原因
- 由于IPv4的地址不够
- 出于网络安全
NAT种类
- 完全锥型NAT(Full Cone NAT)
- 地址限制锥型NAT(Address Restricted Cone NAT)
- 端口限制锥型NAT(Port Restricted Cone NAT)
- 对称型NAT(Symmetric NAT)
NAT穿越原理
穿越步骤
- C1,C2向STUN发消息
- 交换公网IP及端口
- C->C2,C2->C1,端口猜测
NAT穿越组合
NAT类型判断
STUN
- STUN的目的就是进行NAT穿越
- STUN是典型的客户端/服务器模式
RFC STUN规范
- RFC3489/STUN Simple Traversal of UDP Through NAT --UDP
- RFC5389/STUN Seesion Traversal Utilities for NAT --TCP
协议具体
协议组成 | 具体描述 |
---|---|
20字节的STUN header | |
Body中可以有0个或多个Attribute |
STUN Header
- 2个字节16bit类型
- 2个字节16bit消息长度,不包括消息头
- 16个字节128bit食物ID,请求与响应事务ID相同
格式
STUN Message Type
- 前两位必须是00,区分复用同一端口时STUN协议
- 2位用于分类,C0和C1
- 12位用于定义请求/指示
格式
C0C1
- 0b00:表示一个请求
- 0b01:表示一个指示
- 0b10:请求成功的响应
- 0b11:请求失败的响应
消息类型
大小端模式
- 大端:数据的高字节保存再内存的低地址中
- 小端:数据的高字节保存在内存的高地址中
- 网络字节顺序:采用大端排序方式
Transaction ID
- 4字节,32位,固定值0x2112A442。判断客户端是否可以识别某些属性。
- 12字节,96位,标识同一个事物的请求和响应
STUN Message Body
- 消息头后有0或多个属性
- 每个属性进行TLV 编码:Type,Length,Value
TURN
- 解决对称NAT无法穿越的问题
- 建立再STUN之上,消息格式使用STUN格式消息
- TURN Client要求服务端分配一个公共IP和Port用于接收或发送数据
图例
TURN发送机制
- Send和Data
- Channel
图例
ICE
功能
- 收集所有通路
- 检测所有通路
ICE Candidate
大概
- 每个candidate是一个地址
- 如 a=candidate:...UDP ... 192.169.1.12
- 每个candidate都包括:协IP、端口和类型
类型
- 主机候选者
- 反射候选者
- 中继候选者
做什么?
收集 Candidate
- Host Candidate:本机所有IP和指定端口
- Reflexive Candiate: TURN/STRUN
- Relay Candiate:TURN
对 Candidate Pair 排序
- 一方收集到所有 candidate 后,通过信令传给对方
- 另一方收到 candidate 后,也做收集工作
- 当双方拿到全部列表后,将 candidate 形成匹配对
连通性检查
- 对 candidate 进行优先级排序
- 对每个 candidate 进行发送检测
- 对每个 candidate 进行接收检测
图示
SDP
Session Description Protocol 一种信息格式的描述标准,本身不属于传输协议,但是可以被其他传输协议用来交换必要的信息。
例子
网络协议分析
常用工具
Linux 服务端用 tcpdump
tcpdump -i eht0 src port 80 -xx -Xs 0 -w test.cap
-i:指定网卡
src:指明包的来源
port:指明端口号
-xx:抓到包以16进制显示
-X:ASCII码显示
-s 0:抓到整个包
-w:写到文件中
WireShark
-
逻辑运算
与:and && 或:or || 非:not !
-
判断语句
等于: eq == 小于:It < 大于:gt > 小于等于:le <= 大于等于:ge >= 不等于:ne !=
-
按协议过滤
stun tcp udp
-
按IP 过滤
ip.dst==192.168.1.2 //ddestionation ip.src==192.168.1.2 //source ip.addr==192.168.1.2 //address
-
按port过滤
tcp.port==8080 udp.port==3478 udp.dstport==3478 udp.srcport==3478
-
按长度过滤
udp.length<30 tcp.length<30 http.content_length<30
图示
WebRTC端对端连接
RTCPeerConnection
基本格式
pc=new RTCPeerConnection([configuration])
方法分类
- 媒体协商
- Stream/Track
- 传输相关方法
- 统计相关方法
媒体协商过程
媒体协商方法
-
createOffer
promise=pc.createOffer([options])
-
createAnswer
promise=pc.createAnswer([options])
-
setLocalDescription
promise=pc.setLocalDescription(sessionDescription)
-
setRemoteDescription
promise=pc.setRemoteDescription(sessionDescription)
Track方法
-
addTrack
rtpSender=pc.addTrack(track,stream)
-
removeTrack
pc.removeTrack(rtpSender)
重要事件
-
onnegotiationneeded
-
onicecandidate
端到端连接
SDP 规范
- 会话层
- 媒体层
会话层
- 名称和目的
- 存活时间
- 会话中包括多个媒体信息
媒体信息
- 媒体格式
- 传输协议
- 传输IP和端口
- 媒体负载类型
SDP格式
- 由多个=组成
- 一个会话级描述
- 多个媒体级描述
SDP结构
-
Session Description
v=(protocol version) o=(owner/create and session identifier) s=(session name) c=*(conn info -optional if included at session -level) a=*(zero or more session attribute lines)
-
Time Description
t=(time the session is active) r=*(zero or more repeat times)
-
Media Description
m=(media name and transport address) c=*(conn info -optional if included at session -level) b=*(bandwidth information) a=*(zero or more session attribute lines)
-
字段含义
Version 必选 v=0 SDP的版本号,不包括次版本号 Session Name 必选 s=<session name>会话名,s=- 表示忽略会话名 Origin/Owner 必选 o=<username><session id><version><network type><addresstype><address> Connection Date 可选 c=<network type><address type><connection address> //c=IN IP4 0.0.0.0 Media Announcements 必选 m=<meida><port><transport><fmt/playload type list> //m=audio 1024 UDP/TLS/RTP/SAVPF 111 103... Suggested Attribute 可选 a=<TYPE> a=<TYPE>:<VALUES> //a=framerate:<帧速率> rtpmap 可选 a=rtpmap:<fmt/playload type><encoding name>/<clock rate>[/<encodingparameters>] //a=rtpmap:103 ISAC/16000 fmtp 可选 a=fmtp:<format/playload type> parameters //a=fmtp:103 apt=106
WebRTC中的SDP
WebRTC中的 offer/answer sdp
- ulpfec 冗余包
- nack 重传包
小结
关于WebRTC中的TURN和STUN以及网络传输这一块的内容是比较重要也是比较难的,后期花更多时间去理解实践。