SMU29009: QoS e a Camada de Transporte

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

Próxima aula

Uma aplicação multimidia

A concepção de uma aplicação multimidia:

  • Serviço a ser oferecido
  • Requisitos funcionais
  • Requisitos não-funcionais

VMS (Video Management System)

A aplicação escolhida foi um VMS capaz de apresentar as imagens de múltiplas câmeras IP.

  • API gráfica: Gtk 3
  • Linguagem: Python3
  • Decoder/renderer de media: libvlc

Requisitos funcionais:

  • reproduzir video e audio
  • ser capaz de apresentar video de mutiplas cameras em uma única tela, compostas em uma grade
  • ser capaz de apresentar uma única camera em tela cheia, acompanhada de seu audio
  • ser capaz de receber alarme de camera, apresentando-a em tela cheia acompanhada de seu audio
  • ser capaz de gravar as filmagens das cameras configuradas (em apresentação ou não)
  • ser capaz de sinalizar a camera com RTSP
  • ser capaz de sinalizar a camera com SIP


Referências:


Um exemplo minimalista em Python: mostra uma tela qualquer a partir de seu arquivo .glade
#!/usr/bin/python3

import gi
from gi.repository import Gtk
import sys

builder = Gtk.Builder()
builder.add_from_file('ptc1.glade')
janela = builder.get_object('window1')
janela.show_all()

Gtk.main()

sys.exit(0)

Camada de transporte

Uma aplicação multimidia distribuída se comunica usando serviços da camada de transporte. Nessa camada há protocolos que implementam um serviço de comunicação fim-a-fim entre processos e através de uma rede não-confiável. As características dos protocolos de transporte influenciam o desempenho da aplicação multimidia, e por isso faz-se necessária uma revisão sobre os principais protocolos.

TCP

Negociação em três vias

O estabelecimento de conexão TCP envolve o intercâmbio de três mensagens entre o iniciador (cliente) e o atendente da conexão (servidor).

SMU-Three-way.svg
Intercâmbio de mensagens para estabelecimento de conexão


Para o desempenho de uma aplicação, a principal consequência é a percepção de uma latência para iniciar a comunicação de fato. Para aplicações que transmitem frequentemente pequenas quantidades de dados, o estabelecimento de nova conexão para cada transmissão reduz a taxa efetiva de dados obtida (além da latência). Uma proposta para atenuar o problema se chama TCP Fast Open, aplicável em situações em que ocorrem múltiplas conexões sucessivas entre um mesmo par cliente-servidor. Essa melhoria possibilita que, a partir da segunda conexão, o lado servidor comece a transmitir dados imediatamente após a recepção da mensagem SYN.

Controle e prevenção de congestionamento

O controle de congestionamento é um importante serviço do TCP, o qual evita sobrecarga de tráfego em uma rede e seu consequente colapso devido a congestionamento. Fazem parte dele o controle de fluxo, a partida lenta, e a prevenção de congestionamento.

As consequências para o desempenho de uma aplicação são:

  • Baixa taxa efetiva de dados para pequenas transferências de dados (e sensível ao atraso fim-a-fim)
  • Variações abruptas na taxa de dados caso qualquer erro ocorra (necessidade de retransmissão)

Produto da largura de banda pelo atraso

O produto da largura de banda pelo atraso corresponde à quantidade de dados em trânsito e ainda não confirmados. Ele se define pelo produto da capacidade dos links pelo atraso fim-a-fim. Esse produto tem implicação importante nos tamanhos das janelas de recepção tanto do cliente quanto do servidor. A janela de recepção deve ser ajustada em função do RTT e da taxa de dados estimada. Se as janelas de recepção forem inferiores a esse produto, um transmissor deve pausar a transmissão para esperar confirmações (devido ao controle de fluxo), quando poderia transmitir mais dados. Isso tem impacto negativo no desempenho de uma aplicação.

Apesar de o tamanho da janela de receção se ajustar automaticamente com as condições da comunicação, há que cuidar para que seu limite superior não se torne um gargalo. Para uma aplicação que precise de maior desempenho, deve-se conferir se a opção de multiplicação da janela (Window Scaling Option) está ativada no sistema operacional.

Head-of-line blocking

O bloqueio da frente da fila no TCP se deve ao seu mecanismo de garantia de entrega ordenada. Se uma mensagem se perde, o transmissor a retransmite, porém todas as mensagens subsequentes já recebidas no lado servidor ficam bloqueadas à espera da recepção da mensagem perdida. A aplicação que espera receber esses dados fica bloqueada até que a sequência bufferizada se complete, e possa ter acesso aos dados. Como consequência, isso causa uma variação imprevisível nos intervalos entre dados recebidos, chamado de jitter.

Ainda que uma aplicação não precise de entrega ordenada, ela está sujeita a essa penalidade. Por exemplo, uma aplicação que transmite mensagens individuais não precisa necessariamente que elas sejam entregues em ordem. Outro exemplo é uma aplicação em que novas mensagens substituem mensagens anteriores completamente (ex: mensagens de atualização de status de sensores): nesse caso, a entrega confiável se torna desnecessária. Em ambos casos, o protocolo TCP pode causar uma redução de desempenho, uma vez que não é possível desativar esses serviços. Para uma aplicação em que essas questões sejam críticas, pode ser mais adequado outro protocolo de transporte (ex: UDP ou DCCP).

Otimização para uso do TCP

Atividade

  1. Desative o recurso TCP Fast Open:
    sudo sysctl -w net.ipv4.tcp_fastopen=0
    
  2. Teste obter repetidas vezes um recurso via HTTP. Cada novo acesso deve ser feito com uma nova conexão. O recurso a ser obtido pode ser uma página qualquer. Procure estimar o seguinte:
    • Qual a taxa de dados efetiva média dos acessos
    • Qual a latência média para os acessos (i.e. o tempo entre o início da conexão e a recepção dos dados)
  3. Repita o teste anterior, porém habilite o recursos TCP Fast Open:
    sudo sysctl -w net.ipv4.tcp_fastopen=1
    
  4. Repita o teste anterior, porém estabeleça a conexão uma única vez e envie múltiplas requisições HTTP através dessa conexão. Refaça as medições e compare com os resultados anteriores. Analise os resultados em ambos os casos.
  5. Faça uma transferência de um arquivo de grande tamanho, de forma a medir a taxa de dados efetiva durante a transferência.
    • Faça a transferência com o tamanho máximo de buffer predefinido do sistema operacional
    • Faça a transferência com o tamanho máximo de buffer predefinido, porém sem opção de ajuste da janela:
      sudo sysctl -w net.ipv4.tcp_window_scaling=0
      
    • Faça a transferência com o tamanho máximo de buffer definido para 64 kB, e sem opção de ajuste da janela.
      sudo sysctl -w net.core.rmem_max=65536
      
    • Faça a transferência com o tamanho máximo de buffer definido para 32 kB, e sem opção de ajuste da janela
    • Faça a transferência com o tamanho máximo de buffer definido para 16 kB, e sem opção de ajuste da janela

UDP

O protocolo UDP nada mais faz do que implementar um serviço orientado a datagramas e com multiplexação baseado em ports sobre o protocolo IP. Assim, pode-se listar o que o UDP NÃO faz (comparando-o com TCP):

  • Sem garantia de entrega de mensagem
  • Sem garantia de entrega ordenada
  • Sem conexão
  • Sem controle de congestionamento

UDP e NAT

Na Internet em que ainda predomina o uso de IPv4, ou sua presença é ainda relevante, o uso de NAT continua necessário. Como UDP é um protocolo sem estado, os tradutores NAT precisam memorizar os endereços IP e ports de cada datagrama UDP sainte, para permitir a entrada de datagramas UDP em sentido contrário que tenham as mesmas características. Se a comunicação ficar ociosa mais tempo do que o tempo de memorização do tradutor NAT, datagramas UDP entrantes não conseguem mais atravessar o tradutor NAT. Uma aplicação precisa então transmitir com uma frequência suficiente para que o tradutor NAT mantenha em memória as informações sobre o fluxo UDP.

Outro problema relacionado com NAT se dá com comunicações UDP com aplicações que estão atrás de um tradutor NAT, as quais usam ports UDP randômicos e cujos endereços IP são variáveis (ex: telefones IP, Google Talk). Nesse caso, para que a comunicação ocorra é necessário primeiro que a aplicação identifique o endereço IP externo apresentado pelo tradutor NAT, para então oferecê-lo como endereço de contato para aplicações fora de sua rede. Para situações assim se criaram serviços como STUN, TURN e ICE.

STUN: Session Traversal Utilities for NAT


Ou: um quebra-galho para resolver os problemas de outro quebra-galho ...


O serviço STUN (Session Traversal Utilities for NAT) possibilita que uma aplicação baseada em UDP descubra seu endereço IP e port UDP visíveis para quem estiver do outro lado do gateway NAT. A figura abaixo ilustra como o STUN poderia ser usado para essa finalidade.

STUN.png
Cenário em que se poderia usar STUN


O STUN foi criado para ser usado imediatamente antes de iniciar uma transmissão UDP. Como mostrado na figura abaixo, um cliente envia a um servidor STUN uma mensagem de pedido de vinculação (binding request), que deve usar como port UDP de origem o mesmo port que se pretende usar para a stream de áudio. Esse servidor STUN deve estar fora da rede, de forma que o pedido de vinculação por ele recebido seja modificado pelo NAT. A resposta do servidor STUN (binding response) contém o endereço IP e número de port UDP que apareceram no pedido de vinculação. Com isso o cliente consegue descobrir como esses valores deverão aparecer após passarem pelo NAT. Assim, a mensagem SDP pode ser preenchida com os valores apropriados para a stream de áudio.


Stun-diagram.png
Exemplo de mensagens trocadas com STUN


Deve-se notar que o STUN não faz milagre ! Como apontado no início do texto, STUN é um quebra-galho criado para tentar resolver os problemas de outro quebra-galho (no caso, o NAT). Para que o STUN funcione, o NAT deve permitir que datagramas UDP vindos de outro endereço IP (o telefone VoIP na outra ponta da ligação) acessem o endereço IP e port UDP que foram alocados quando da consulta do cliente para o servidor STUN. Isso nem sempre é possível, pois depende do tipo de NAT: se for do tipo simétrico, o STUN sozinho não funcionará. E muitos NAT em equipamentos proprietários são do tipo simétrico (ao contrário do Linux, que implementa um NAT port restricted cone) ...


Existe uma implementação de um servidor STUN para Linux (disponível no Ubuntu via apt). Basta instalá-lo em um computador e usá-lo como servidor STUN, contanto que ele esteja do outro lado do NAT. No entanto, existem inúmeros servidores STUN públicos, alguns deles listados aqui.

TURN

o serviço TURN implementa um tipo de proxy UDP, para realizar o relay de datagramas UDP quando o uso de STUN não é suficiente.

SMU-Turn.jpg
Cenário de uso de TURN

Nesse caso, a aplicação se registra no servidor TURN, e então pode anunciar que seu endereço IP e port para recepção de datagramas UDP são aqueles do do servidor TURN. Ao receber um datagrama UDP destinado ao port registrado pela aplicação, o servidor TURN o encaminha para a aplicação de destino registrada.

ICE

O protocolo Interactive Connectivity Establishment (ICE) implementa mecanismos e procedimentos para facilitar a travessia de tradutores NAT. Ele facilita a seleção do método mais adequado de travessia: STUN se possível, caso contrário usando TURN.

Atividade

  1. Instale o programa stun em seu computador:
    sudo apt install stun
    
  2. Use o programa stun para descobrir qual o endereço IP público associado a seus datagramas:
    stun stun1.l.google.com:19302 -v
    

DCCP


O protocolo DCCP (Datagram Connection Control Protocol), especificado pelo IETF na RFC 4340, oferece um serviço de entrega não-confiável, porém com controle de congestionamento. Mais especificamente ele apresenta estas características:

  • orientado à conexão
  • orientado a mensagem (datagrama)
  • sem garantia de entrega
  • sem garantia de ordenamento
  • controle de congestionamento


De certa forma, o DCCP é um meio termo entre TCP e UDP. TCP oferece garantia de entrega e entrega ordenada, além de controle de congestionamento. Seus mecanismos de garantia de entrega podem causar variações acentuadas no atraso fim-a-fim, e mesmo interrupções momentâneas de transmissão, o que é prejudicial para aplicações multimidia. Por outro lado, seu controle de congestionamento evita que a rede entre em colapso devido a congestionamento. O UDP não oferece garantia de entrega nem controle de congestionamento, o que evita variações acentuadas de atraso fim-a-fim, porém, se usado em larga escala, pode fazer a rede entrar em colapso. O DCCP aproveita as características desejáveis de ambos protocolos, do ponto de vista de aplicações multimidia, por não implementar garantia de entrega porém fazer controle de congestionamento.


O controle de congestionamento do DCCP se chama CCID (Congestion Control Identifier) e é extensível, podendo ser selecionado pela aplicação. Atualmente dois CCID foram padronizados:

  • CCID2: implementa um controle de congestionamento semelhante ao AIMD do TCP.
  • CCID3: implementa um controle de congestionamento baseado no receptor, que informa periodicamente estatísticas de recepção ao transmissor, que as uitiliza para adaptar sua taxa de transmissão usando a função TFRC (TCP-Friendly Congestion Control).

O protocolo DCCP está implementado pelo menos nos sistemas Linux e FreeBSD. Até o presente momento, nenhuma aplicação conhecida o utiliza.

Atividade

Com base nos exemplos mostrados neste artigo, deve-se realizar um teste de transmissão com DCCP.

  1. Abra o wireshark, e inicie a captura de todos pacotes com endereço IP de origem ou destino ab.c.d
  2. Carregue o módulo dccp do Linux:
    sudo modprobe dccp
    
  3. Implemente um cliente DCCP que se conecte ao servidor a.b.c.d port 5566, e receba os dados enviados desses servidor, e os escreva na saída padrão.
  4. Execute seu programa desta forma:
    ./seu_cliente.py | mplayer -
    
    ... e assista o video.
  5. No wireshark analise a comunicação com DCCP, e os intervalos entre pacotes recebidos.

SCTP