In the process of data transmission, the factor of transmission security mechanism has been continuously emphasized in recent years. webrtc
When ensuring data transmission, it is adopted DTLS 协议
, and the specific protocol method can be viewed in related documents.
DTLS (Datagram Transport Layer Security) is a TLS protocol customized and improved for UDP based on the reality that data packets may be lost or reordered in UDP scenarios. Where DTLS is used in WebRTC includes two parts: negotiating and managing SRTP keys and providing encrypted channels for DataChannel.
The data of DataChannel uses DTLS
the channel, encrypts and then sends to the opposite end through udp. In webrtc, a channel can send data or video. Different data forms use different protocols. For example, audio and video data transmission uses the RTP protocol, while dataChannel uses the SCTP (stream control transmission protocol) protocol.
We all know the shortcomings of tcp and udp. On this basis, SCTP has been redesigned to have flow control, congestion control, etc., and can perform stable data transmission.
How to implement it in pion
DTLSTransport
The protocol is implemented in DTLS
, which is convenient for our calls. t.conn
After we get it, it will be used as a data channel.
// Start DTLS transport negotiation with the parameters of the remote DTLS transport
func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error {
...
t.srtpEndpoint = t.iceTransport.newEndpoint(mux.MatchSRTP)
t.srtcpEndpoint = t.iceTransport.newEndpoint(mux.MatchSRTCP)
t.remoteParameters = remoteParameters
cert := t.certificates[0]
t.onStateChange(DTLSTransportStateConnecting)
...
// Connect as DTLS Client/Server, function is blocking and we
// must not hold the DTLSTransport lock
if role == DTLSRoleClient {
dtlsConn, err = dtls.Client(dtlsEndpoint, dtlsConfig)
} else {
dtlsConn, err = dtls.Server(dtlsEndpoint, dtlsConfig)
}
...
t.conn = dtlsConn
t.onStateChange(DTLSTransportStateConnected)
return t.startSRTP()
}
sctp.Client
The channel in is, that is dtlsTransport.conn
, it will be used to send data later.
func (r *SCTPTransport) Start(remoteCaps SCTPCapabilities) error {
...
sctpAssociation, err := sctp.Client(sctp.Config{
NetConn: dtlsTransport.conn,
MaxReceiveBufferSize: r.api.settingEngine.sctp.maxReceiveBufferSize,
LoggerFactory: r.api.settingEngine.LoggerFactory,
})
if err != nil {
return err
}
...
go r.acceptDataChannels(sctpAssociation)
return nil
}