No processo de transmissão de dados, o fator do mecanismo de segurança da transmissão tem sido continuamente enfatizado nos últimos anos. webrtc
Ao garantir a transmissão de dados, é adotado DTLS 协议
, e o método de protocolo específico pode ser visualizado em documentos relacionados.
DTLS (Datagram Transport Layer Security) é um protocolo TLS personalizado e aprimorado para UDP com base na realidade de que pacotes de dados podem ser perdidos ou reordenados em cenários UDP. Onde o DTLS é usado no WebRTC inclui duas partes: negociação e gerenciamento de chaves SRTP e fornecimento de canais criptografados para DataChannel.
Os dados do DataChannel usam DTLS
o canal, criptografam e depois enviam para a extremidade oposta por udp. No webrtc, um canal pode enviar dados ou vídeo. Diferentes formas de dados usam diferentes protocolos. Por exemplo, a transmissão de dados de áudio e vídeo usa o protocolo RTP, enquanto o dataChannel usa o protocolo SCTP (protocolo de transmissão de controle de fluxo).
Todos nós conhecemos as deficiências do tcp e do udp. Com base nisso, o SCTP foi redesenhado para ter controle de fluxo, controle de congestionamento, etc., e pode realizar transmissão de dados estável.
Como implementá-lo em pion
DTLSTransport
O protocolo é implementado em DTLS
, o que é conveniente para nossas chamadas, t.conn
depois que o obtivermos, ele será usado como um canal de dados.
// 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
O canal em é, ou seja dtlsTransport.conn
, será utilizado para enviar dados posteriormente.
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
}