QUIC | |
---|---|
Desenvolvido por | IETF |
Introduzido | 12 de outubro de 2012 |
Pilha de protocolos TCP/IP |
---|
Camada de aplicação |
Camada de transporte |
Camada de rede |
Camada de enlace de dados |
QUIC é um protocolo de rede de camada de transporte[1] para propósitos gerais[2] inicialmente concebido por Jim Roskind no Google,[3] implementado e implantado em 2012,[4] anunciado publicamente em 2013, à medida que a experimentação se alarga[5][6][7] e descrito em uma reunião da IETF.[8] O QUIC é utilizado por mais de metade de todas as conexões do navegador Web Chrome para os servidores da Google.[9] Microsoft Edge,[10] Firefox,[11] e Safari[12] oferecem suporte, mesmo se não habilitado por padrão.
Embora seu nome tenha sido inicialmente proposto como o acrônimo de "Quick UDP Internet Connections",[3][8] o uso da palavra QUIC pela IETF não é um acrônimo; é simplesmente o nome do protocolo.[2] O QUIC melhora o desempenho das aplicações web orientadas para a conexão que estão atualmente utilizando TCP.[1][9] Ele faz isso estabelecendo várias conexões multiplexadas entre dois pontos finais usando o protocolo User Datagram Protocol (UDP), e é projetado para tornar o TCP obsoleto na camada de rede para muitas aplicações, ganhando assim o protocolo o ocasional apelido "TCP/2".[13]
O QUIC trabalha lado a lado com as conexões multiplexadas do HTTP/2, permitindo que múltiplos fluxos de dados cheguem a todos os pontos terminais de forma independente e, portanto, independente de perdas de pacotes envolvendo outros fluxos. Em contraste, o HTTP/2 hospedado no Protocolo de Controle de Transmissão (TCP) pode sofrer atrasos de bloqueio de cabeça de linha de todos os fluxos multiplexados se algum dos pacotes TCP for atrasado ou perdido.
Os objetivos secundários do QUIC incluem a redução da latência da ligação e do transporte, e a estimativa da largura de banda em cada direção para evitar congestionamentos. Também move algoritmos de controle de congestionamento para o espaço de usuário em ambos os pontos terminais, em vez do espaço de núcleo, o que, segundo se afirma, permitirá que estes algoritmos melhorem mais rapidamente. Além disso, o protocolo pode ser alargado com a correção de erros em avanço (FEC) para melhorar ainda mais o desempenho quando são esperados erros, o que é visto como o próximo passo na evolução do protocolo.
Em Junho de 2015, foi apresentado à IETF, para normalização, um projeto de especificação do QUIC na Internet.[14][15] Em 2016, foi criado um grupo de trabalho QUIC.[16] Em Outubro de 2018, os Grupos de Trabalho HTTP e QUIC da IETF decidiram conjuntamente chamar ao mapeamento HTTP sobre o QUIC "HTTP/3", antes de o tornarem um padrão mundial.[17] Em maio de 2021, a IETF padronizou o QUIC no RFC 9000, com suporte no RFC 8999, RFC 9001 e RFC 9002.[18]
O Protocolo de Controle de Transmissão, ou TCP, tem como objetivo fornecer uma interface para o envio de fluxos de dados entre dois pontos finais. Os dados são entregues ao sistema TCP, o que garante que os dados cheguem à outra ponta exatamente da mesma forma, ou a conexão indicará que existe uma condição de erro.[19][20][21][22][23]
Para fazer isso, o TCP divide os dados em pacotes de rede e adiciona pequenas quantidades de dados a cada pacote. Esses dados adicionais incluem um número de sequência usado para detectar pacotes que são perdidos ou chegam fora de ordem, e uma soma de verificação que permite a detecção de erros nos dados dos pacotes. Quando um desses problemas ocorre, o TCP usa o pedido de repetição automático (ARQ) para solicitar ao remetente que reenvie o pacote perdido ou danificado.[19][20][21][22][23]
Na maioria das implementações, o TCP verá qualquer erro em uma conexão como uma operação de bloqueio, interrompendo outras transferências até que o erro seja resolvido ou a conexão seja considerada com falha. Se uma única conexão estiver sendo usada para enviar vários fluxos de dados, como é o caso do protocolo HTTP/2, todos esses fluxos serão bloqueados, embora apenas um deles possa ter um problema. Por exemplo, se ocorrer um único erro ao baixar uma imagem GIF usada para um favicon, o resto da página aguardará enquanto esse problema for resolvido.[19][20][21][22][23]
Como o sistema TCP foi projetado para se parecer com um "canal de dados", ou fluxo, ele contém deliberadamente pouco entendimento dos dados que transmite. Se esses dados tiverem requisitos adicionais, como criptografia usando TLS, eles deverão ser configurados por sistemas executando sobre o TCP, usando o TCP para se comunicar com software semelhante na outra ponta da conexão. Cada um desses tipos de tarefas de configuração requer seu próprio processo de handshake. Isso geralmente requer várias viagens de ida e volta até que a conexão seja estabelecida. Devido à latência inerente das comunicações de longa distância, isso pode adicionar uma sobrecarga significativa à transmissão geral.[19][20][21][22][23]
O QUIC tem como objetivo ser quase equivalente a uma conexão TCP, mas com latência muito reduzida. Isso é feito principalmente por meio de duas alterações que dependem da compreensão do comportamento do tráfego HTTP.[19][20][21][22][23]
A primeira alteração é reduzir significativamente a sobrecarga durante a configuração da conexão. Como a maioria das conexões HTTP exigirá TLS, o QUIC torna a troca de chaves de configuração e de protocolos suportados parte do processo inicial de handshake. Quando um cliente abre uma conexão, o pacote de resposta inclui os dados necessários para que pacotes futuros usem criptografia. Isso elimina a necessidade de configurar a conexão TCP e de negociar o protocolo de segurança usando pacotes adicionais. Outros protocolos podem ser atendidos da mesma maneira, combinando várias etapas em uma única solicitação-resposta. Esses dados podem ser usados tanto para as seguintes solicitações na configuração inicial, quanto para solicitações futuras que, de outra forma, seriam negociadas como conexões separadas.[19][20][21][22][23]
A segunda alteração é usar UDP em vez de TCP como base, o que não inclui a recuperação de perdas. Em vez disso, cada fluxo QUIC é controlado separadamente e os dados perdidos são retransmitidos no nível do QUIC, não no UDP. Isso significa que, se ocorrer um erro em um fluxo, como no exemplo de favicon acima, a pilha de protocolos poderá continuar atendendo outros fluxos independentemente. Isso pode ser muito útil para melhorar o desempenho em links suscetíveis a erros, pois na maioria dos casos dados adicionais consideráveis podem ser recebidos antes que o TCP note que um pacote está ausente ou quebrado, e todos esses dados são bloqueados ou mesmo reinicializados enquanto o erro é corrigido. No QUIC, esses dados podem ser processados livremente enquanto o único fluxo multiplexado é reparado.[24]
O QUIC inclui várias outras alterações mais comuns que também melhoram a latência e a taxa de transferência gerais. Por exemplo, os pacotes são criptografados individualmente, para que não resultem em dados criptografados aguardando por pacotes parciais. Isso geralmente não é possível no TCP, onde os registros de criptografia estão em um bytestream e a pilha de protocolos não tem conhecimento dos limites da camada superior nesse fluxo. Eles podem ser negociados pelas camadas executadas no topo, mas o QUIC visa fazer tudo isso em um único processo de handshake.[8]
Outro objetivo do sistema QUIC era melhorar o desempenho durante eventos de comutação de rede, como o que acontece quando um usuário de um dispositivo móvel passa de um ponto de acesso WiFi local para uma rede móvel. Quando isso ocorre no TCP, um processo demorado é iniciado, onde todas as conexões existentes atingem o tempo limite, uma por uma, e são restabelecidas sob demanda. Para resolver esse problema, o QUIC inclui um identificador de conexão que identifica exclusivamente a conexão com o servidor, independentemente da origem. Isso permite que a conexão seja restabelecida simplesmente enviando um pacote, que sempre contém esse ID, pois o ID da conexão original ainda será válido, mesmo que o endereço IP do usuário seja alterado.[25]
O QUIC pode ser implementado no espaço do aplicativo, em vez de estar no núcleo do sistema operacional. Isso geralmente cria sobrecarga adicional devido as trocas de contexto à medida que os dados são movidos entre aplicativos. No entanto, no caso do QUIC, a pilha de protocolos deve ser usada por um único aplicativo, com cada aplicativo usando o QUIC tendo suas próprias conexões hospedadas no UDP. Por fim, a diferença pode ser muito pequena, porque grande parte da pilha HTTP/2 já está nos aplicativos (ou em suas bibliotecas, mais comumente). A colocação das partes restantes nessas bibliotecas, essencialmente a correção de erros, tem pouco efeito no tamanho da pilha HTTP/2 ou na complexidade geral.[8]
Essa organização permite que alterações futuras sejam feitas mais facilmente, pois não requer alterações no núcleo para atualizações. Um dos objetivos de longo prazo do QUIC é adicionar novos sistemas para correção antecipada de erros (FEC) e para controle aprimorado de congestionamento.[25]
Uma preocupação sobre a migração do TCP para o UDP é que o TCP é amplamente adotado e muitas das "caixas intermediárias" na infraestrutura da Internet são otimizadas para TCP e limitam a taxa de transmissão ou até bloqueiam o UDP. O Google realizou uma série de experiências exploratórias para caracterizar isso e descobriu que apenas um pequeno número de conexões foi bloqueado dessa maneira.[3] Isso levou ao uso de um rápido sistema de fallback para TCP; a pilha de rede do Chromium abre uma conexão QUIC e uma conexão TCP tradicional ao mesmo tempo, o que permite o fallback com latência negligível.[26]
O protocolo que foi criado pelo Google e levado para a IETF sob o nome QUIC (já em 2012 em torno da versão 20 do QUIC) é bem diferente do QUIC que continuou a evoluir e a ser refinado dentro da IETF. O QUIC original do Google foi projetado para ser um protocolo de uso geral, embora tenha sido inicialmente implantado como um protocolo para suportar HTTP(S) no Chromium, enquanto a evolução atual do protocolo IETF QUIC é o protocolo de transporte de uso geral. Os desenvolvedores de Chromium continuaram acompanhando a evolução dos esforços de padronização da IETF QUIC para adotar e cumprir totalmente com os padrões mais recentes da Internet para QUIC no Chromium.
O código do QUIC foi desenvolvido experimentalmente no Google Chrome a partir de 2012[4] e foi anunciado como parte do Chromium versão 29 (lançada em 20 de agosto de 2013).[17] No momento, está ativado por padrão no Chromium. No navegador Chrome, o suporte experimental ao QUIC pode ser ativado em chrome://flags. Há também uma extensão do navegador[27] para indicar quais páginas são servidas pelo QUIC.
Da mesma forma, ele foi introduzido no Opera 16,[28] pode ser ativado em opera://flags/#enable-quic, e sessões ativas podem ser vistas em opera://net-internals/#quic.
O suporte no Firefox Nightly chegou em novembro de 2019.[29][30]
A biblioteca cronet para QUIC e outros protocolos está disponível para aplicativos do Android como um módulo carregável via Google Play Services.[31]
A Apple adicionou suporte experimental ao motor WebKit por meio do Safari Technology Preview 104 em abril de 2020.[32] O suporte oficial foi adicionado no Safari 14, incluído no macOS Big Sur e iOS 14, [33] mas o recurso deve ser ativado manualmente.[11]
Curl 7.66, lançado em 11 de setembro de 2019, suporta HTTP/3 (e, portanto, QUIC).[34][35]
Em outubro de 2020, o Facebook anunciou[36] que migrou com sucesso seus aplicativos, incluindo Instagram, e infraestrutura de servidor para QUIC, com já 75% de seu tráfego de Internet usando QUIC.
Todos os aplicativos móveis do Google suportam QUIC, incluindo YouTube e Gmail.[37][38] O aplicativo móvel do Uber também usa QUIC.[38]
Desde 2017[update], existem quatro implementações ativamente mantidas. Os servidores do Google oferecem suporte ao QUIC e o Google publicou um protótipo de servidor.[39] A Akamai Technologies suporta o QUIC desde julho de 2016.[40][41] Uma implementação em Go chamada quic-go[42] também está disponível, e fornece suporte experimental ao QUIC no servidor Caddy.[43] Em 11 de julho de 2017, a LiteSpeed Technologies começou oficialmente a oferecer suporte ao QUIC em seus produtos balanceador de carga (WebADC)[44] e LiteSpeed Web Server.[45] Desde junho de 2021[update], 98,6% dos sites em QUIC usavam o LiteSpeed e 2,7% usavam o Nginx.[46] Embora, inicialmente, apenas os servidores do Google tenham suporte para conexões HTTP-sobre-QUIC, o Facebook também lançou a tecnologia em 2018,[17] e a Cloudflare oferece suporte a QUIC em versão beta desde 2018.[47] Desde junho de 2021[update], 5,6% de todos os sites usam QUIC.[48]
Além disso, existem vários projetos antigos da comunidade: libquic[49] foi criado extraindo a implementação do QUIC no Chromium e modificando-a para minimizar os requisitos de dependências, e a goquic[50] fornece ligações em Go da libquic. Por fim, quic-reverse-proxy[51] é uma imagem para o Docker que atua como um servidor proxy reverso, traduzindo solicitações QUIC em HTTP sem criptografia que pode ser entendido pelo servidor de origem.
O .NET 5 introduz suporte experimental para QUIC usando a biblioteca MsQuic.[52]
Implementação | Licença | Linguagem | Descrição |
---|---|---|---|
Chromium | Livre | C++ | Este é o código-fonte do navegador Web Chrome e a implementação de referência do gQUIC. Ele contém um cliente e servidor gQUIC e QUIC independentes que podem ser usados para teste. Código fonte navegável. Esta versão também é a base do stellite usado pelo LINE e do cronet desenvolvido pela Google. |
QUIC Library (mvfst) | Licença MIT | C++ | O mvfst é uma implementação de cliente e de servidor do protocolo IETF QUIC em C ++ desenvolvido pelo Facebook. |
LiteSpeed QUIC Library (lsquic) | Licença MIT | C | Esta é a implementação do QUIC e do HTTP/3 usada pelo LiteSpeed Web Server e pelo OpenLiteSpeed. |
ngtcp2 | Licença MIT | C | Esta é uma biblioteca QUIC que é agnóstica para bibliotecas criptográficas e funciona com OpenSSL ou GnuTLS. Para HTTP/3, ele precisa de uma biblioteca separada como nghttp3. |
Quiche | Licença BSD de 2 cláusulas | Rust | Independente do soquete e expõe uma API em C para uso em aplicativos C/C++. |
quicly | Licença MIT | C | Esta biblioteca é a implementação do QUIC para o servidor web H2O. |
quic-go | Licença MIT | Go | Esta biblioteca fornece suporte ao QUIC no servidor web Caddy. A funcionalidade de cliente também está disponível. |
Quinn | Licença Apache 2.0 | Rust | |
Neqo | Licença Apache 2.0 | Rust | Esta implementação da Mozilla está planejada para ser integrada ao Necko, uma biblioteca de rede usada no navegador web Firefox. |
aioquic | Licença BSD de 3 cláusulas | Python | Essa biblioteca possui uma API sem E/S apropriada para incorporação em clientes e em servidores. |
picoquic | Licença BSD de 3 cláusulas | C | Uma implementação mínima do QUIC alinhada com as especificações do IETF. |
pquic | Licença MIT | C | Uma implementação do QUIC extensível que inclui uma máquina virtual eBPF capaz de carregar dinamicamente extensões como plugins. |
MsQuic | Licença MIT | C | Uma implementação do QUIC multiplataforma da Microsoft projetada para ser uma biblioteca QUIC de uso geral. |
QUANT | Licença BSD de 2 cláusulas | C | Quant suporta plataformas POSIX tradicionais (Linux, MacOS, FreeBSD, etc.), bem como sistemas embarcados. |
quic | Licença BSD de 3 cláusulas | Haskell | Este pacote implementa QUIC com base em threads leves de Haskell. |
netty-incubator-codec-quic | Licença Apache 2.0 | Java | Este pacote implementa QUIC em netty baseado na implementação Quiche. |