一、总述

webrtc的数据通道可以走三种协议:1、SCTP;2、RTP;3、QUIC。这里先研究第一种,SCTP。

webrtc使用SCTP over DTLS方式传输数据通道报文。 

DTLS的作用是给数据通道数据加密(保证数据安全性)、增加链路证书校验机制(防止网络攻击)。

与TLS over TCP不同,UDP层没有对数据报文的乱序、丢包做处理,会导致链路证书校验协商无法保证。所以:

1、DTLS在创建连接时的握手消息里面,需要增加可靠性传输机制。

2、由于UDP对数据的实时性要求比较高,所以链路建立稳定后,传输应用数据时,没有提供数据可靠性传输机制,需要SCTP协议或者应用层保证。

二、DTLS

1)握手消息全协商流程

2)握手消息可靠性设计流程

  • 包丢失

一旦Client传输了ClientHello消息,它会期望收到从Server发来的一个 HelloVerifyRequest。然而,如果这个Server的消息丢失了,Client就会知道ClientHello或HelloVerifyRequest已经丢失,然后重传。当Server收到重传包时,它就会知道重传发生了。Server也维护了一个重传定时器,当其超时后会重传。

需要注意超时和重传并不应用于HelloVerifyRequest,因为这需要在Server上创建状态。HelloVerifyRequest被设计的足够小以避免自身被分片,因此可以不用考虑多个HelloVerifyRequest交叉的情况。

  • 包重排

在DTLS中,每个握手消息会在握手中被分配一个明确的序列号。当一个客户端收到一个握手消息时,它能快速确定这个消息是否是它所期望接收的下一个消息。如果是,它会进行处理。如果不是,它会将其放入队列中,等所有缺失的报文都收到后再进行处理。

  • 包大小

TLS和DTLS握手消息可能会相当大(理论上可以达到的上限是2^24-1字节,实际上是很多个K字节)。相比值之下,UDP报文通常被限制在小于1500字节,如果不想要IP分片的话。为了适应这个限制,每个DTLS握手消息可以在几个DTLS记录中进行分片,每个DTLS记录都会试图适应一个单个IP数据报。每个DTLS握手消息包含一个分片偏移和分片长度。因此,一个拥有一个握手消息所有字节的接受者能够重组原始的未分片消息。

3)DTLS报文格式

  • ContentType type定义

          20:change_cipher_spec   密码变更(每次变更epoch要加一)
          21:alert    报警消息
          22:handshake   握手消息
          23:application_data    应用数据

  • ProtocolVersion version

          DTLS version 1.2版本使用的是{254, 253}

  • uint16 epoch

          计数值,随着每次加密状态改变而递增

  • uint48 sequence_number

          本记录的序列号

  • uint16 length

          fragment数据长度,不能超过2^14次方。

  • 握手消息定义

  • 握手消息抓包示例

  • 应用数据抓包示例

 

三、SCTP

最早STCP是把窄带7号信令的可靠性传输机制引入到IP协议、优化TCP协议的不能分帧传输的局限性提出来的。不过后来应用不是很广泛。

webrtc使用的是改良剪切版的STCP协议。由于SCTP协议是承载在DTLS协议上,所以SCTP的Multi homing功能,在webrtc的数据通道没有被使用。

有两个草案描述webrtc的改良方法《draft-ietf-rtcweb-data-channel-13》、《draft-ietf-rtcweb-data-protocol-09》,根据描述webrtc根据实际场景,引入了:可靠传输模式、部分可靠传输模式、不可靠传输模式等。

这几种模式在DataChannelInit结构体中配置。

当ordered配置成false、maxRetransmits配置成0,这里实现的就是不可靠传输,类似UDP协议。

当ordered配置成true、maxRetransmits配置成-1、maxRetransmits配置成-1,这里实现的就是可靠传输,类似TCP协议。

也可以根据需要配置成部分可靠性传输。

四、webrtc实现

  • 创建数据通道

CreateDataChannel
->CreateSctpTransport_n
->CreateDtlsTransport_n
->CreateDtlsTransportChannel_n
->new DtlsTransport

备注:WebRtcSession::Initialize里面有限制,使用SCTP通道须开启DTLS功能。

接收发送DTLS报文,及处理DTLS的握手消息等,在DtlsTransport类中实现。

 

五、附录

https://en.wikipedia.org/wiki/Stream_Control_Transmission_Protocol

https://www.html5rocks.com/en/tutorials/webrtc/datachannels/

https://bloggeek.me/sctp-data-channel/

《rfc6347》

《rfc5246》

《draft-ietf-rtcweb-data-protocol-09》

《draft-ietf-rtcweb-data-channel-13》

 

Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐