RTCQuicTransport sta per iniziare una prova dell'origine vicino a te (Chrome 73)

Cosa?

RTCQuicTransport è una nuova API della piattaforma web che consente di scambiare dati arbitrari con peer remoti utilizzando il protocollo QUIC. È destinato ai casi d'uso peer-to-peer e pertanto viene utilizzato con un'API RTCIceTransport autonoma per stabilire una connessione peer-to-peer tramite ICE. I dati vengono trasportati in modo affidabile e in ordine (vedi la sezione che segue per i dettagli sulla consegna non ordinata e non affidabile). Trattandosi di un trasporto di dati generico e bidirezionale, può essere utilizzato per giochi, trasferimenti di file, trasporto multimediale, messaggistica e così via.

Perché?

Una potente API di trasporto dati di basso livello può consentire alle applicazioni (come le comunicazioni in tempo reale) di fare nuove cose sul web. Puoi basarti sull'API, creando soluzioni personalizzate, spingendo i limiti di ciò che può essere fatto con connessioni peer to peer, ad esempio sbloccando manopole personalizzate di allocazione della velocità in bit. In futuro, un ulteriore supporto per i contenuti multimediali codificati potrebbe persino consentirti di creare la tua applicazione di comunicazione video con controlli di basso livello. L'impegno di NV di WebRTC è quello di passare alle API di livello inferiore e la sperimentazione anticipata di queste funzionalità è preziosa.

Perché QUIC?

Il protocollo QUIC è auspicabile per le comunicazioni in tempo reale. È basato su UDP, integra la crittografia e il controllo della congestione ed è multiplexato senza blocco dell'head of line. RTCQuicTransport offre funzionalità molto simili all'API RTCDataChannel, ma utilizza QUIC anziché SCTP come protocollo di trasporto. Poiché RTCQuicTransport è un'API autonoma, non ha il sovraccarico dell'API RTCPeerConnection, che include il media stack in tempo reale.

Come?

Panoramica generale dell'API

L'API prevede 3 astrazioni principali: RTCIceTransport, RTCQuicTransport e RTCQuicStream.

Diagramma RTCQuicTransport che mostra l'architettura dell'API

RTCIceTransport

ICE è un protocollo per stabilire connessioni peer-to-peer su Internet, attualmente utilizzato in WebRTC. Questo oggetto fornisce un'API autonoma per stabilire una connessione ICE. Viene utilizzato come trasporto di pacchetti per la connessione QUIC e RTCQuicTransport lo acquisisce nel suo costruttore.

RTCQuicTransport

Rappresenta una connessione QUIC. Viene utilizzato per stabilire una connessione QUIC e creare flussi QUIC. Mostra inoltre statistiche pertinenti per il livello di connessione QUIC.

RTCQuicStream

Utilizzato per la lettura e la scrittura di dati da/verso il lato remoto. I flussi trasportano i dati in modo affidabile e in ordine. È possibile creare più flussi dallo stesso RTCQuicTransport e, una volta che i dati vengono scritti in un flusso, viene attivato un evento "onquicstream" sul trasporto remoto. I flussi offrono un modo per distinguere dati diversi sulla stessa connessione QUIC. Esempi comuni possono essere l'invio di file separati in flussi separati, piccoli blocchi di dati in flussi diversi o diversi tipi di contenuti multimediali in flussi separati. Gli elementi RTCQuicStream sono leggeri, sono multiplexati su una connessione QUIC e non causano blocco dell'head of line su altri RTCQuicStream.

Configurazione della connessione

Di seguito è riportato un esempio di configurazione di una connessione QUIC peer-to-peer. Come RTCPeerConnection, l'API RTCQuicTransport richiede l'utilizzo di un canale di segnalazione sicuro per negoziare i parametri della connessione, inclusi i relativi parametri di sicurezza. RTCIceTransport negozia i propri parametri ICE (ufrag e password) e RTCIceCandidate.

Diagramma RTCQuicTransport che mostra l'architettura dell'API

Punto di vista del 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);
  }
};

Punto di vista del server:

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);
  }
};

Data Transfer

Il trasferimento dei dati può essere eseguito utilizzando le API RTCQuicStream per la lettura e la scrittura:

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

Buffering

Le promesse restituite dai metodi waitFor* consentono il buffering dei dati quando JavaScript è occupato. La contropressione viene applicata sul lato di invio quando il buffer di lettura si riempie sul lato di ricezione. Il lato di invio ha un buffer di scrittura che può riempire quando viene applicata la contropressione, pertanto anche il lato di scrittura ha un metodo waitForWriteBufferedAmountBelow per consentire di attendere la scrittura nel buffer. Ulteriori informazioni sulla scrittura/lettura dei dati sono disponibili nell'ulteriore documentazione per gli sviluppatori.

Consegna non ordinata/non affidabile

Mentre un RTCQuicStream supporta solo l'invio di dati in modo affidabile e in ordine, una consegna non affidabile/non ordinata può essere ottenuta con altri mezzi. Per la consegna non ordinata, è possibile inviare piccoli blocchi di dati in flussi separati perché i dati non vengono ordinati tra i flussi. Per una consegna inaffidabile, è possibile inviare piccoli blocchi di dati con il valore di fine impostato su true, seguito dalla chiamata a reset() nello stream dopo un timeout. Il timeout dovrebbe dipendere dal numero di ritrasmissioni desiderate prima di eliminare i dati.

Quando?

La prova dell'origine inizierà nella versione di Chrome 73 e sarà disponibile fino alla versione M75 inclusa. Dopodiché, la prova dell'origine terminerà. In base al feedback e all'interesse, apporteremo le modifiche necessarie e invieremo l'API, proseguiremo con una nuova prova dell'origine di questa API o interromperemo l'API.

Dove?

Browser Chrome in tutte le piattaforme tranne iOS.

Che altro?

Feedback

Uno degli obiettivi principali della prova dell'origine è ricevere un feedback da te, in quanto sviluppatori. Siamo interessati a:

  • Che cosa ti consente di fare questa API?
  • In che modo questa API migliora rispetto ad altre API di trasporto dei dati (WebSocket o RTCDataChannel di WebRTC)? Come potrebbe migliorare?
  • Esibizione
  • Ergonomia delle API

Registrati alla prova dell'origine

  1. Richiedi un token per la tua origine.
  2. Aggiungi il token alle tue pagine. Esistono due modi per fornire questo token su qualsiasi pagina della tua origine:
    • Aggiungi un tag <meta> origin-trial all'intestazione di qualsiasi pagina. Ad esempio, potrebbe essere simile al seguente: <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Se puoi configurare il server, puoi fornire il token anche sulle pagine utilizzando un'intestazione HTTP Origin-Trial. L'intestazione della risposta risultante dovrebbe essere simile al seguente: Origin-Trial: TOKEN_GOES_HERE

Specifiche web

La bozza di specifica è stata avanzata rispetto all'API nella prova dell'origine, tra cui:

  • Stream unidirezionali che sono più allineati con gli stream WHATWG
  • Disattivazione delle ritrasmissioni
  • Datagrammi (disponibili a breve)

Siamo interessati all'implementazione della specifica completa e non solo (compresa il supporto dello streaming WhatWG), ma vorremmo ricevere prima il tuo feedback.

Sicurezza

La sicurezza nell'handshake QUIC viene applicata tramite l'utilizzo di una chiave precondivisa per stabilire una connessione QUIC P2P criptata. Questa chiave deve essere segnalata tramite un canale out of band sicuro con garanzie di riservatezza e integrità. Tieni presente che la chiave sarà esposta a JavaScript.

Attacco attivo

A differenza di DTLS-SRTP, che richiede solo l'integrità per la segnalazione dell'impronta digitale del certificato, la segnalazione della chiave precondivisa richiede integrità e riservatezza. Se la PSK viene compromessa (ad esempio dal server nel canale di segnalazione), un utente malintenzionato attivo potrebbe attuare un attacco man in the middle contro l'handshake QUIC.

Stato attuale

Passaggio Stato
1. Crea messaggio esplicativo Completato
**2a. Specifiche RTCQuicTransport ** **In corso**
**2b. Specifiche RTCIceTransport ** **In corso**
**3. Raccogli feedback e riformula il design** **In corso**
4. Prova dell'origine Inizia in Chrome 73.
5. Avvia Not started

Link utili