RTCQuicTransport chega a um teste de origem perto de você (Chrome 73)

O quê?

O RTCQuicTransport é uma nova plataforma da Web API que permite a troca de dados arbitrários com pares remotos usando o QUIC protocolo. Ele se destina a casos de uso ponto a ponto e, portanto, é usado com um RTCIceTransport autônomo; para estabelecer uma conexão ponto a ponto por meio de ICE (links em inglês). Os dados são transportados de maneira confiável e em ordem (consulte a seção abaixo para obter detalhes sobre entrega não confiável). Por ser um termo genérico, transporte de dados bidirecional, pode ser usado para jogos, transferências de arquivos, transporte de mídia, mensagens etc.

Por quê?

Uma API de transporte de dados avançada e de baixo nível pode ativar aplicativos (como aplicativos comunicações) para fazer coisas novas na Web. É possível criar com base na API, criar suas próprias soluções, indo além dos limites do que pode ser feito com conexões de peering, por exemplo, desbloqueando botões personalizados de alocação de taxa de bits. Em no futuro, um suporte maior para mídia codificada poderia até viabilizar a criação de seu próprio aplicativo de comunicação por vídeo com controles de baixo nível. Esforço de NV do WebRTC é migrar para APIs de nível inferior, e testar logo isso valiosas.

Por que o QUIC?

O protocolo QUIC é ideal para comunicações em tempo real. Ele é construído sobre de UDP, tem criptografia integrada, controle de congestionamento e é multiplexado sem bloqueio de cabeçalho de linha. O RTCQuicTransport oferece habilidades muito semelhantes às a API RTCDataChannel, mas usa o QUIC em vez do SCTP como transporte. protocolo. Como a RTCQuicTransport é uma API independente, ela não tem o overhead da API RTCPeerConnection, que inclui a mídia em tempo real pilha.

Como?

Visão geral da API

A API tem três abstrações principais: RTCIceTransport e RTCQuicTransport. e RTCQuicStream.

Diagrama do RTCQuicTransport mostrando a arquitetura da API

RTCIceTransport

O ICE é um protocolo para estabelecer conexões ponto a ponto pela Internet e é usado no WebRTC atualmente. Esse objeto fornece uma API autônoma para estabelecer uma conexão ICE. Ele é usado como transporte de pacotes para a conexão QUIC, e o RTCQuicTransport a usa no construtor.

RTCQuicTransport

Representa uma conexão QUIC. Ele é usado para estabelecer uma conexão QUIC criar streams do QUIC. Ele também expõe estatísticas relevantes para a conexão QUIC nível

RTCQuicStream

Usado para ler e gravar dados de/para o lado remoto. Transporte de streams de maneira confiável e em ordem. É possível criar vários streams a partir do mesmo RTCQuicTransport e, uma vez que os dados são gravados em um stream, ele dispara um evento "onquicstream" no transporte remoto. Com os streams, você pode distinguir dados diferentes na mesma conexão QUIC. Exemplos comuns podem enviar arquivos separados em fluxos separados, pequenos blocos de dados diferentes streams ou tipos de mídia em streams separados. RTCQuicStreams são leves, são multiplexadas por uma conexão QUIC e não causam bloqueio de cabeçalho de linha para outros RTCQuicStreams.

Configuração da conexão

Veja a seguir um exemplo de configuração de uma conexão QUIC ponto a ponto. Como RTCPeerConnection, a API RTCQuicTransport requer o uso de uma um canal de sinalização seguro para negociar os parâmetros da conexão, incluindo os parâmetros de segurança. O RTCIceTransport negocia que é ICE (ufrag e senha), bem como RTCIceCandidates.

Diagrama do RTCQuicTransport mostrando a arquitetura da API

Perspectiva do cliente:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
  quicKey: quicTransport.getKey(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, candidate}) => {
  if (iceParams) {
    iceTransport.start(iceParams);
    quicTransport.connect();
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

Perspectiva do servidor:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, quicKey, candidate}) => {
  if (iceParams && quicKey) {
    iceTransport.start(iceParams);
    quicTransport.listen(quicKey);
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

Transferência de dados

A transferência de dados pode ser feita usando as APIs RTCQuicStream para leitura e escrevendo:

RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);

Armazenando em buffer

As promessas retornadas pelos métodos waitFor* permitem armazenar dados em buffer quando O JavaScript está ocupado. A pressão de retorno é aplicada no lado do remetente quando o buffer de leitura fica cheio no lado do recebimento. O lado de envio tem uma gravação que pode ser preenchido quando a pressão de contrapressão é aplicada. o lado de gravação também tem um método waitForWriteBufferedAmountBelow para permitir a espera pela gravação do espaço no buffer. Mais informações sobre os dados de gravação/leitura podem ser encontrados na documentação documentação.

Entrega não solicitada/não confiável

Embora um RTCQuicStream só ofereça suporte ao envio de dados de maneira confiável e em ordem, a entrega não confiável/não ordenada pode ser alcançada por outros meios. Para entrega desordenada, pode-se enviar pequenos pedaços de dados em fluxos separados porque os dados não são ordenados entre os streams. Para uma entrega não confiável, pode enviar pequenos blocos de dados com final definido como verdadeiro, seguidos por reset() no stream após um tempo limite. O tempo limite deve depender de quantas retransmissões são desejadas antes de descartar os dados.

Quando?

O teste de origem começará na versão do Chrome 73 e estará disponível incluindo a versão M75. Depois disso, o teste de origem fim. Com base no feedback e no interesse, vamos fazer as mudanças apropriadas enviar a API, continuar com um novo teste de origem dessa API ou descontinuar a API.

Onde?

Navegador Chrome em todas as plataformas, menos no iOS.

O que mais?

Feedback

Um dos principais objetivos do teste de origem é receber feedback, desenvolvedores. Temos interesse em:

  • O que essa API permite para você?
  • Como essa API melhora em relação a outras APIs de transporte de dados (WebSockets ou RTCDataChannel do WebRTC)? Como isso poderia melhorar?
  • Desempenho
  • Ergonomia da API

Inscreva-se no teste de origem

  1. Solicite um token para sua origem.
  2. Adicione o token às suas páginas. Há duas maneiras de fornecê-lo na todas as páginas da sua origem:
    • Adicione uma tag origin-trial <meta> ao cabeçalho de qualquer página. Por exemplo: a aparência será semelhante a esta: <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Se for possível configurar o servidor, você também poderá fornecer o token nas páginas usando um cabeçalho HTTP Origin-Trial. O cabeçalho de resposta resultante deve semelhante a: Origin-Trial: TOKEN_GOES_HERE

Especificação da Web

O rascunho de especificação foi adiantado em relação à API no teste de origem incluindo:

  • Streams unidirecionais que estão mais alinhados aos streams WhatWG
  • Como desativar retransmissões
  • Datagramas (em breve)

Estamos interessados em implementar a especificação completa e além (incluindo suporte a transmissões WhatWG), mas queremos ouvir seu feedback primeiro.

Segurança

A segurança no handshake do QUIC é aplicada com o uso de uma chave pré-compartilhada para estabelecer uma conexão QUIC P2P criptografada. É preciso sinalizar a chave um canal seguro e fora de banda com garantias de confidencialidade e integridade. A chave será exposta ao JavaScript.

Ataque ativo

Ao contrário do DTLS-SRTP, que exige apenas integridade para sinalizar o certificado impressão digital, sinalizando que a chave pré-compartilhada exige integridade e confidencialidade. Se o PSK estiver comprometido (digamos, pelo servidor na sinalização canal), um invasor ativo poderia montar um ataque man-in-the-middle contra o handshake do QUIC.

Status atual

Etapa Status
1. Criar explicação Concluído
**2a. Especificação RTCQuicTransport ** **Em andamento**
**2b. Especificação RTCIceTransport ** **Em andamento**
**3. Colete feedback e iterar no design** **Em andamento**
4. Teste de origem Começa no Chrome 73!
5. Lançamento Não iniciado

Links úteis