Você está na página 1de 140

Machine Translated by Google

Redes de Computadores: Princípios,


Protocolos e Prática
Lançamento 0,25

Oliver Boaventura

30 de outubro de 2011

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Conteúdo

1 Prefácio 3

2 Introdução 2.1 5
Serviços e protocolos . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 11
2.2 Os modelos de referência . . . . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . 20
2.3 Organização do livro . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 25

3 A Camada de Aplicação 27
3.1 Princípios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 27
3.2 Protocolos em nível de aplicação . . . . . . . . . . . . . . . . . . . . . . ..... . . . . . . . . . . 32
3.3 Escrevendo aplicações simples em rede . . . . . . . . . . . . . . . . ..... . . . . . . . . . . 55
3.4 Resumo . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 61
3.5 Exercícios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 61

4 A camada de transporte 67
4.1 Princípios de um protocolo de transporte confiável . . . . . . . . . . . . . . . ..... . . . . . . . . . . 67
4.2 O Protocolo de Datagrama do . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 87
Usuário 4.3 O Protocolo de Controle de .... . . . . . . . . . . . . . . ..... . . . . . . . . . . 89
. . . .. . . . . . . . . . . . . .
Transmissão 4.4 Resumo . . . . . . . . . . . . . . ..... . . . . . . . . . . 113
4.5 Exercícios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 114

5 A camada de rede 127


5.1 Princípios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 127
5.2 Protocolo Internet . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 140
5.3 Roteamento em redes IP . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 170
5.4 Resumo . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 195
5.5 Exercícios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 195

6 A camada de datalink e as redes locais 211


6.1 Princípios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 211
6.2 Controle de Acesso ao Meio . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 214
6.3 Tecnologias da camada Datalink . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 228
6.4 Resumo . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 246
6.5 Exercícios . . . . . . . . . . . . . ..... . . . . . . . . . . . . . . ..... . . . . . . . . . . 246

7 Glossário 249

8 Bibliografia 255

eu

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

9 Índices e tabelas 257

Bibliografia 259

Índice 273

eu

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Conteúdo 1
URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

2 Conteúdo
URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

CAPÍTULO 1

Prefácio

Este livro surgiu de uma frustração de seu autor principal. Muitos autores optaram por escrever um livro didático porque não existem
livros didáticos em sua área ou porque não estão satisfeitos com os livros didáticos existentes. Essa frustração produziu vários livros
didáticos excelentes na comunidade de networking. Numa época em que os livros didáticos sobre redes eram principalmente teóricos,
Douglas Comer optou por escrever um livro inteiramente focado no conjunto de protocolos TCP/IP [Comer1988], uma escolha difícil
naquela época. Mais tarde, ele ampliou seu livro descrevendo uma implementação TCP/IP completa, acrescentando considerações
práticas às descrições teóricas em [Comer1988]. Richard Stevens abordou a Internet como um explorador e explicou a operação dos
protocolos observando todos os pacotes que eram trocados na rede [Stevens1994]. Jim Kurose e Keith Ross reinventou os livros
didáticos de redes partindo dos aplicativos que os alunos usam e posteriormente explicou os protocolos da Internet removendo uma
camada após a outra [KuroseRoss09].

As frustrações que motivaram este livro são diferentes. Quando comecei a ensinar redes no final da década de 1990, os alunos já eram
usuários da Internet, mas seu uso era limitado. Os alunos ainda usavam livros de referência e passavam algum tempo na biblioteca.
Os alunos de hoje são completamente diferentes. Eles são usuários da web ávidos e experientes que encontram muitas informações
na web. Esta é uma atitude positiva, uma vez que são provavelmente mais curiosos do que os seus antecessores. Graças à informação
disponível na Internet, podem consultar ou obter informações adicionais sobre os temas explicados pelos seus professores. Esta
informação abundante cria vários desafios para o professor. Até ao final do século XIX, um professor era, por definição, mais conhecedor
do que os seus alunos e era muito difícil para os alunos verificarem as aulas dadas pelos seus professores. Hoje, dada a quantidade
de informações disponíveis ao alcance de cada aluno na Internet, verificar uma aula ou obter mais informações sobre um determinado
tema às vezes está a apenas alguns cliques de distância. Sites como a Wikipédia fornecem muitas informações sobre vários tópicos e
os alunos os consultam frequentemente. Infelizmente, a organização da informação nestes websites não é adequada para permitir que
os alunos aprendam com eles. Além disso, existem enormes diferenças na qualidade e profundidade da informação disponível para
diferentes tópicos.

A segunda razão é que a comunidade de redes de computadores é um participante forte no movimento do código aberto. Hoje, existem
implementações de código aberto amplamente utilizadas e de alta qualidade para a maioria dos protocolos de rede.
Isso inclui as implementações TCP/IP que fazem parte do Linux, freebsd ou o uIP pilha rodando em controladores de 8 bits, mas
também servidores como bind, não vinculado, apache ou enviar e-mail e implementações de protocolos de roteamento como xorp ou
quaga . Além disso, os documentos que definem quase todos os protocolos da Internet foram desenvolvidos no âmbito da Internet
Engineering Task Force (IETF). usando um processo aberto. A IETF publica suas especificações de protocolo na RFC disponível
publicamente e novas propostas são descritas em rascunhos da Internet.

Este livro aberto visa preencher a lacuna entre as implementações de código aberto e as especificações de rede de código aberto,
fornecendo uma descrição detalhada, mas pedagógica, dos princípios-chave que orientam a operação da Internet. O livro é lançado
sob uma licença Creative Commons. Essa licença de código aberto é motivada por dois motivos. A primeira é que esperamos que isso
permita que muitos estudantes utilizem o livro para aprender redes de computadores. A segunda é que espero que outros professores
o reutilizem, adaptem e melhorem. O tempo dirá se é possível construir uma comunidade de colaboradores para melhorar e desenvolver
ainda mais o livro. Como ponto de partida, a primeira versão contém todo o material para um primeiro semestre de graduação superior
ou um curso de pós-graduação em redes.

No momento em que este livro foi escrito, a maior parte do texto foi escrita por Olivier Bonaventure. Laurent Vanbever, Virginie Van Den

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Schriek, Damien Saucez e Mickael Hoerdt contribuíram para os exercícios. Pierre Reinbold desenhou os ícones
usado para representar interruptores e Nipaul Long redesenhou muitas figuras no formato SVG. Stéphane Bortzmeyer
enviou muitas sugestões e correções ao texto. Informações adicionais sobre o livro didático estão disponíveis em
http://inl.info.ucl.ac.be/CNP3

4 Capítulo 1. Prefácio
URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

CAPÍTULO 2

Introdução

Quando os primeiros computadores foram construídos durante a Segunda Guerra Mundial, eram caros e isolados. No entanto,
após cerca de vinte anos, à medida que os preços diminuíam gradualmente, começaram as primeiras experiências para
conectar computadores entre si. No início da década de 1960 pesquisadores como Paul Baran Donald Davies ou Joseph
Licklider publicou de forma independente os primeiros artigos descrevendo a ideia de construir redes de computadores [Baran]
[Licklider1963] . Dado o custo dos computadores, compartilhá-los a longa distância era uma ideia interessante. Nos EUA, a
ARPANET começou em 1969 e continuou até meados da década de 1980 [LCCD09]. Na França, Louis Pouzin desenvolveu a
rede Cyclades [Pouzin1975]. Muitas outras redes de pesquisa foram construídas durante a década de 1970 [Moore]. Ao mesmo
tempo, as indústrias de telecomunicações e de informática interessaram-se pelas redes de computadores. A indústria de
telecomunicações aposta no X25. A indústria de computadores adotou uma abordagem completamente diferente ao projetar
Redes Locais (LAN). Muitas tecnologias LAN, como Ethernet ou Token Ring, foram projetadas naquela época. Durante a
década de 1980, a necessidade de interconectar cada vez mais computadores levou a maioria dos fornecedores de
computadores a desenvolver seu próprio conjunto de protocolos de rede. A Xerox desenvolveu o [XNS] , a DEC escolheu o
DECNet [Malamud1991] , a IBM desenvolveu o SNA [McFadyen1976] , a Microsoft introduziu o NetBIOS [Winston2003] , a Apple apostou no Applet
Na comunidade de pesquisa, a ARPANET foi desativada e substituída pelo TCP/IP [LCCD09] e a implementação de referência
foi desenvolvida dentro do BSD Unix [McKusick1999]. As universidades que já executavam o Unix poderiam, portanto, adotar
facilmente o TCP/IP e os fornecedores de estações de trabalho Unix, como a Sun ou a Silicon Graphics, incluíram o TCP/IP
em sua variante do Unix. Paralelamente, a ISO, com o apoio dos governos, trabalhou no desenvolvimento de um conjunto
1 aberto de protocolos de rede. No final, o TCP/IP tornou-se o padrão de facto que não é usado apenas na comunidade de

pesquisa. Durante a década de 1990 e início de 2000, o crescimento do uso do TCP/IP continuou e hoje os protocolos
proprietários raramente são usados. Como mostra a figura abaixo, que fornece uma estimativa do número de hosts conectados
à Internet, a Internet tem sustentado um grande crescimento ao longo dos últimos mais de 20 anos.

Figura 2.1: Estimativa do número de hosts na Internet


1 Aberto em termos ISO contrastava com os conjuntos de protocolos proprietários cujas especificações nem sempre estavam disponíveis publicamente. O

governo dos EUA até determinou o uso dos protocolos OSI (ver RFC 1169), mas isso não foi suficiente para encorajar todos os usuários a mudar para o conjunto de
protocolos OSI, que foi considerado por muitos como muito complexo em comparação com outros conjuntos de protocolos.

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Estimativas recentes do número de hosts conectados à Internet mostram um crescimento contínuo desde há mais de 20 anos.
No entanto, embora o número de hosts conectados à Internet seja alto, ele deve ser comparado ao número de telefones celulares em uso
atualmente. Cada vez mais destes telemóveis estarão ligados à Internet. Além disso, graças à disponibilidade de implementações TCP/IP
que exigem recursos limitados, como uIP [Dunkels2003], podemos esperar um crescimento de dispositivos embarcados habilitados para
TCP/IP.

Figura 2.2: Estimativa do número de telemóveis

Antes de examinar os serviços fornecidos pelas redes de computadores, é útil concordar com alguma terminologia que é amplamente
utilizada na literatura sobre redes. Em primeiro lugar, as redes informáticas são frequentemente classificadas em função da área geográfica
que cobrem.

• LAN : uma rede local normalmente interconecta hosts que estão a algumas ou talvez algumas dezenas de quilômetros de distância.
separados.

• MAN : uma rede de área metropolitana normalmente interconecta dispositivos que estão a até algumas centenas de quilômetros
separado

2
• WAN : uma rede de longa distância que interconecta hosts que podem estar localizados em qualquer lugar do planeta

Outra classificação de redes de computadores é baseada na sua topologia física. Nas figuras a seguir, os links físicos são representados
como linhas, enquanto as caixas mostram computadores ou outros tipos de equipamentos de rede.

As redes de computadores são usadas para permitir que vários hosts troquem informações entre si. Para permitir que qualquer host envie
mensagens para qualquer outro host da rede, a solução mais fácil é organizá-las como uma malha completa, com um link direto e dedicado
entre cada par de hosts. Essa topologia física às vezes é usada, especialmente quando é necessário alto desempenho e alta redundância
para um pequeno número de hosts. No entanto, tem duas desvantagens principais:

• para uma rede contendo n hosts, cada host deve ter n-1 interfaces físicas. Na prática, o número de
interfaces físicas em um nó limitarão o tamanho de uma rede full-mesh que pode ser construída
n×(nÿ1) •
para uma rede contendo n hosts, 2
links são obrigatórios. Isso é possível quando há alguns nós na mesma sala,
mas raramente quando eles estão localizados a vários quilômetros de distância.

A segunda organização física possível, que também é utilizada dentro dos computadores para conectar diferentes placas de extensão, é o
barramento. Em uma rede de barramento, todos os hosts estão conectados a um meio compartilhado, geralmente um cabo através de uma
única interface. Quando um host envia um sinal elétrico no barramento, o sinal é recebido por todos os hosts conectados ao barramento.
Uma desvantagem das redes baseadas em barramento é que se o barramento for fisicamente cortado, a rede será dividida em duas redes
isoladas. Por esta razão, as redes baseadas em barramento são por vezes consideradas difíceis de operar e manter, especialmente
quando o cabo é longo e há muitos locais onde pode quebrar. Essa topologia baseada em barramento foi usada nas primeiras redes
Ethernet.

Uma terceira organização de uma rede de computadores é uma topologia em estrela. Nessas topologias, os hosts possuem uma única
interface física e existe um link físico entre cada host e o centro da estrela. O nó no centro da estrela pode ser um equipamento que
amplifica um sinal elétrico ou um dispositivo ativo, como uma peça

2 Neste livro, nos concentramos nas redes usadas na Terra. Estas redes às vezes incluem links de satélite. Além das tecnologias de rede

utilizadas na Terra, os pesquisadores desenvolvem técnicas de rede que podem ser utilizadas entre nós localizados em planetas diferentes.
Essa Internet Interplanetária requer técnicas diferentes daquelas discutidas neste livro. Veja RFC 4838 e as referências nele contidas para
obter informações sobre essas técnicas.

6 Capítulo 2. Introdução Fundação

URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 2.3: Uma rede Full Mesh

Figura 2.4: Uma rede organizada como Barramento

de equipamentos que entendem o formato das mensagens trocadas pela rede. É claro que a falha do nó central implica a falha da rede.
Contudo, se um link físico falhar (por exemplo, porque o cabo foi cortado), apenas um nó será desconectado da rede. Na prática, as redes
em formato de estrela são mais fáceis de operar e manter do que as redes em formato de barramento. Muitos administradores de rede
também apreciam o fato de poderem controlar a rede a partir de um ponto central. Administrado a partir de uma interface Web ou através
de uma conexão semelhante a um console, o centro da estrela é um ponto de controle útil (ativação ou desativação de dispositivos) e um
excelente ponto de observação (estatísticas de uso).

Figura 2.5: Uma rede organizada em estrela

Uma quarta organização física de uma rede é a topologia em anel. Assim como a organização do barramento, cada host possui uma única
interface física conectando-o ao anel. Qualquer sinal enviado por um host no anel será recebido por todos os hosts conectados ao anel. Do
ponto de vista da redundância, um único anel não é a melhor solução, pois o sinal só viaja em uma direção no anel; portanto, se um dos
links que compõem o anel for cortado, toda a rede falhará. Na prática, esses anéis têm sido usados em redes locais, mas agora são
frequentemente substituídos por redes em forma de estrela.
Nas redes metropolitanas, os anéis são frequentemente usados para interconectar vários locais. Neste caso, dois links paralelos, compostos
por cabos diferentes, são frequentemente utilizados para redundância. Com esse anel duplo, quando um anel falha, todo o tráfego pode ser
rapidamente transferido para o outro anel.

Uma quinta organização física de uma rede é a árvore. Essas redes são normalmente usadas quando um grande número de clientes precisa
estar conectado de maneira muito econômica. As redes de TV a cabo são frequentemente organizadas como árvores.

Na prática, a maioria das redes reais combina parte destas topologias. Por exemplo, uma rede de campus pode ser organizada como um
anel entre os edifícios principais, enquanto edifícios mais pequenos são ligados como uma árvore ou uma estrela a edifícios importantes.

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 2.6: Uma rede organizada como um Anel

Figura 2.7: Uma rede organizada como uma árvore

8 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Ou uma rede ISP pode ter uma malha completa de dispositivos no núcleo da sua rede e árvores para conectar usuários remotos.

Ao longo deste livro, nosso objetivo será compreender os protocolos e mecanismos necessários para uma rede como a mostrada
abaixo.

S R

R
ISP2
beta.be
alfa.com
R
R

R
ISP2
R
R R

ISP2 R

R S

societe.fr

PSTN R
R
ISP1 tux@linux#

ADSL

Figura 2.8: Uma interligação de redes simples

A figura acima ilustra uma interligação de redes, ou seja, uma rede que interliga outras redes. Cada rede é ilustrada como uma elipse
contendo alguns dispositivos. Explicaremos ao longo do livro os diferentes tipos de dispositivos e suas respectivas funções, permitindo
que todos os hosts troquem informações. Além disso, discutiremos como as redes estão interligadas e as regras que orientam essas
interligações. Também analisaremos como as topologias barramento, anel e malha são utilizadas para construir redes reais.

O último ponto da terminologia que precisamos discutir são os modos de transmissão. Ao trocar informações através de uma rede,
frequentemente distinguimos entre três modos de transmissão. Na transmissão de TV e rádio, a transmissão é frequentemente usada
para indicar uma tecnologia que envia um sinal de vídeo ou rádio para todos os receptores em uma determinada área geográfica.
A transmissão às vezes é usada em redes de computadores, mas apenas em redes locais onde o número de destinatários é limitado.

O primeiro e mais difundido modo de transmissão é denominado unicast . No modo de transmissão unicast, as informações são
enviadas de um remetente para um receptor. A maioria das aplicações atuais da Internet depende do modo de transmissão unicast.
O exemplo abaixo mostra uma rede com dois tipos de dispositivos: hosts (desenhados como computadores) e nós intermediários
(desenhados como cubos). Os hosts trocam informações através dos nós intermediários. No exemplo abaixo, quando o host S usa
unicast para enviar informações, ele as envia por meio de três nós intermediários. Cada um desses nós recebe as informações de seu
nó ou host upstream e, em seguida, as processa e as encaminha para seu nó ou host downstream. Isso se chama store and forward e
veremos mais tarde que esse conceito é fundamental em redes de computadores.

Um segundo modo de transmissão é o modo de transmissão multicast . Este modo é utilizado quando a mesma informação deve ser
enviada a um conjunto de destinatários. Foi usado pela primeira vez em LANs, mas mais tarde passou a ser suportado em redes de
longa distância. Quando um remetente utiliza multicast para enviar informações a N receptores, o remetente envia uma única cópia da
informação e os nós da rede duplicam essa informação sempre que necessário, para que ela possa chegar a todos os destinatários
pertencentes ao grupo de destino.

Para entender a importância da transmissão multicast, considere a fonte S que envia as mesmas informações para os destinos A, C e
E. Com o unicast, a mesma informação passa três vezes nos nós intermediários 1 e 2 e duas vezes no nó 4. Isso é um desperdício de
recursos nos nós intermediários e nos links entre eles. Na transmissão multicast, o host S envia a informação para o nó 1 que a
encaminha downstream para o nó 2. Este nó cria uma cópia da informação recebida e envia uma cópia diretamente para o host E e a
outra downstream para o nó 4. Após a recepção da informação , o nó 4 produz uma cópia e encaminha uma para o nó A e outra para
o nó C. Graças ao multicast, a mesma informação pode chegar a um grande número de receptores e ser enviada apenas uma vez em
cada enlace.

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

S
B

Figura 2.9: Transmissão Unicast

S
B

Figura 2.10: Transmissão multicast

10 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O último modo de transmissão é o modo de transmissão anycast . Foi inicialmente definido na RFC 1542. Neste modo de
transmissão, um conjunto de receptores é identificado. Quando uma fonte envia informações para este conjunto de receptores,
a rede garante que a informação seja entregue a um receptor que pertence a este conjunto. Normalmente, o receptor mais
próximo da fonte é aquele que recebe a informação enviada por esta fonte específica. O modo de transmissão anycast é útil
para garantir redundância, pois quando um dos receptores falhar, a rede garantirá que a informação será entregue a outro
receptor pertencente ao mesmo grupo. Contudo, na prática, o suporte ao modo de transmissão anycast pode ser difícil.

S
B

Figura 2.11: Transmissão Anycast

No exemplo acima, os três hosts marcados com * fazem parte do mesmo grupo anycast. Quando o host S envia informações
para este grupo anycast, a rede garante que chegará a um dos membros do grupo anycast.
As linhas tracejadas mostram uma possível entrega através dos nós 1, 2 e 4. Uma transmissão anycast subsequente do host S
para o mesmo grupo anycast poderia alcançar o host anexado ao nó intermediário 3, conforme mostrado pela linha simples.
Uma transmissão anycast atinge um membro do grupo anycast escolhido pela rede em função das condições atuais da rede.

2.1 Serviços e protocolos

Um aspecto importante a ser entendido antes de estudar redes de computadores é a diferença entre um serviço e um protocolo.

Para entender a diferença entre os dois, é útil começar com exemplos do mundo real. O Correio tradicional oferece um serviço
em que um carteiro entrega cartas aos destinatários. Os Correios definem com precisão quais tipos de cartas (tamanho, peso,
etc) podem ser entregues através do serviço Correio Padrão. Além disso, é especificado o formato do envelope (posição dos
endereços do remetente e do destinatário, posição do selo). Quem quiser enviar uma carta deve colocá-la nos Correios ou
dentro de uma das caixas de correio dedicadas. A carta será então recolhida e entregue ao seu destinatário final. Observe que
para o serviço regular os Correios normalmente não garantem a entrega de cada carta específica, algumas cartas podem ser
perdidas e algumas cartas são entregues na caixa de correio errada. Se uma carta for importante, o remetente poderá usar o
serviço registrado para garantir que a carta será entregue ao destinatário. Alguns serviços postais também oferecem um serviço
reconhecido ou um serviço de correio expresso mais rápido que o serviço normal.

Em redes de computadores, a noção de serviço é definida mais formalmente em [X200] . Pode ser melhor compreendido
considerando uma rede de computadores, qualquer que seja seu tamanho ou complexidade, como uma caixa preta que presta um serviço aos ,
usuários conforme mostrado na figura abaixo. Esses usuários podem ser usuários humanos ou processos em execução em um sistema de computador.

Muitos usuários podem estar vinculados ao mesmo provedor de serviços. Através deste provedor, cada usuário deve poder
trocar mensagens com qualquer outro usuário. Para poder entregar estas mensagens, o fornecedor de serviços deve ser capaz
de identificar inequivocamente cada utilizador. Nas redes de computadores, cada usuário é identificado por um endereço único,
discutiremos mais adiante como esses endereços são construídos e utilizados. Neste ponto, e quando se considera a
transmissão unicast, a principal característica destes endereços é que são únicos. Dois usuários diferentes conectados à rede
não podem usar o mesmo endereço.

2.1. Serviços e protocolos URL 11

Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Usuário A Usuário B

Ponto de acesso de serviço

Primitivos

Provedor de serviços ("a rede")

Figura 2.12: Usuários e provedor de serviços

Ao longo deste livro, definiremos um serviço como um conjunto de capacidades fornecidas por um sistema (e seus recursos subjacentes).
elementos) para seu usuário. Um usuário interage com um serviço por meio de um ponto de acesso de serviço. Observe que conforme mostrado na figura
acima, os usuários interagem com um provedor de serviços. Na prática, o provedor de serviços está distribuído por vários hosts,
mas estes são detalhes de implementação que não são importantes nesta fase. Essas interações entre um usuário e um
provedor de serviços são expressos em [X200] usando primitivas, conforme mostrado na figura abaixo. Esses primitivos são
uma representação abstrata das interações entre um usuário e um provedor de serviços. Na prática, essas interações
poderia ser implementado como chamadas de sistema, por exemplo.

Usuário A Usuário B

X.solicitação X.confirmar X.resposta X. indicação

Provedor de serviços ("a rede")

Figura 2.13: Os quatro tipos de primitivas

Quatro tipos de primitivas são definidos:

• X.solicitação. Este tipo de primitiva corresponde a uma solicitação emitida por um usuário a um provedor de serviços

• X.indicação. Este tipo de primitiva é gerada pelo provedor de rede e entregue a um usuário (muitas vezes
relacionado a uma primitiva X.request anterior e remota)

• X.resposta. Este tipo de primitiva é gerada por um usuário para responder a uma primitiva X.indication anterior

• X.confirmar. Este tipo de primitiva é entregue pelo serviço fornecido para confirmar ao usuário que um
A primitiva X.request foi processada com sucesso.

Os primitivos podem ser combinados para modelar diferentes tipos de serviços. O serviço mais simples em redes de computadores é
chamado de serviço sem conexão 3.
Este serviço pode ser modelado usando duas primitivas:

• Data.request(fonte,destino,SDU). Esta primitiva é emitida por um usuário que especifica, como parâmetros, seu
endereço (fonte), o endereço do destinatário da mensagem e a própria mensagem. Usaremos o serviço
Unidade de Dados (SDU) para nomear a mensagem que é trocada de forma transparente entre dois usuários de um serviço.

• Indicação.dados(fonte,destino,SDU). Esta primitiva é entregue por um provedor de serviços a um usuário. Isto


contém como parâmetros uma unidade de dados de serviço, bem como os endereços do remetente e dos usuários de destino.

Ao discutir o serviço fornecido em uma rede de computadores, muitas vezes é útil ser capaz de descrever graficamente as interações
entre os usuários e o provedor. Uma representação frequentemente usada é a sequência temporal
diagrama. Neste capítulo e posteriormente ao longo do livro, usaremos frequentemente diagramas como o da figura abaixo. A
O diagrama de sequência temporal descreve as interações entre dois usuários e um provedor de serviços. Por convenção, o
os usuários são representados nas partes esquerda e direita do diagrama, enquanto o provedor de serviços ocupa o meio do diagrama.
diagrama. Nesse diagrama de sequência temporal, o tempo flui do topo para a parte inferior do diagrama. Cada primitivo

3
Este serviço é chamado de serviço sem conexão porque não há necessidade de criar uma conexão antes de transmitir qualquer dado.
com o serviço orientado a conexão.

12 Capítulo 2. Introdução

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

é representado por uma seta horizontal simples, à qual está anexado o nome da primitiva. As linhas tracejadas são usadas para
representar o possível relacionamento entre duas (ou mais) primitivas. Tal diagrama fornece informações sobre a ordem das
diferentes primitivas, mas a distância entre duas primitivas não representa uma quantidade precisa de tempo.

A figura abaixo fornece uma representação do serviço sem conexão como um diagrama de sequência temporal. O usuário da
esquerda, com endereço S, emite uma primitiva Data.request contendo SDU M que deve ser entregue pelo provedor de serviço
ao destino D. A linha tracejada entre as duas primitivas indica que a primitiva Data.indication que é entregue ao o usuário à
direita corresponde à primitiva Data.request enviada pelo usuário à esquerda.

Fonte Fornecedor Destino

DADOS.request(S, D, "M")

DADOS.indicação(S, D, "M")

Tempo

Figura 2.14: Um serviço simples sem conexão

Existem diversas implementações possíveis do serviço sem conexão, que discutiremos mais adiante neste livro.
Antes de estudar estas realizações, é útil discutir as possíveis características do serviço sem conexão.
Um serviço sem conexão confiável é um serviço em que o provedor de serviços garante que todos os SDUs enviados em
solicitações de dados por um usuário serão eventualmente entregues ao seu destino. Tal serviço seria muito útil para os
usuários, mas garantir uma entrega perfeita é difícil na prática. Por esta razão, as redes de computadores geralmente suportam
um serviço sem conexão não confiável.

Um serviço sem conexão não confiável pode sofrer vários tipos de problemas em comparação com um serviço sem conexão
confiável. Em primeiro lugar, um serviço sem conexão não confiável não garante a entrega de todos os SDUs.
Isso pode ser expresso graficamente usando o diagrama de sequência temporal abaixo.

Na prática, um serviço não confiável e sem conexão normalmente entregará uma grande fração dos SDUs. Contudo, uma vez
que a entrega dos SDU não é garantida, o utilizador deve ser capaz de recuperar da perda de qualquer SDU.

Uma segunda imperfeição que pode afetar um serviço sem conexão não confiável é que ele pode duplicar SDUs. Alguns
provedores de serviços sem conexão não confiáveis podem entregar um SDU enviado por um usuário duas ou mais vezes. Isso
é ilustrado pelo diagrama de sequência de tempo abaixo.

Finalmente, alguns provedores de serviços sem conexão não confiáveis podem entregar a um destino um SDU diferente daquele
que foi fornecido no Data.request. Isto é ilustrado na figura abaixo.

Quando um usuário interage com um provedor de serviços, deve conhecer com precisão as limitações do serviço subjacente
para poder superar qualquer problema que possa surgir. Isto requer uma definição precisa das características do serviço
subjacente.

Outra característica importante do serviço sem conexão é se ele preserva a ordenação dos SDUs enviados por um usuário. Do
ponto de vista do usuário, esta é muitas vezes uma característica desejável. Isto é ilustrado na figura abaixo.

Contudo, muitos serviços sem ligação, e em particular os serviços não fiáveis, não garantem que preservarão sempre a
ordenação dos SDUs enviados por cada utilizador. Isto é ilustrado na figura abaixo.

2.1. Serviços e protocolos URL 13

Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Fonte Fornecedor Destino

DATA.request(S, D, "Mensagem")

Tempo

Figura 2.15: Um serviço sem conexão não confiável pode perder SDUs

Fonte Fornecedor Destino

DATA.request(S, D, "Mensagem")

DADOS.indicação(S, D, "Mensagem")

DADOS.indicação(S, D, "Mensagem")

Tempo

Figura 2.16: Um serviço sem conexão não confiável pode duplicar SDUs

14 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Fonte Fornecedor Destino

DATA.request(S, D, "Mensagem")

DADOS.indicação(S, D, "XYZ")

Tempo

Figura 2.17: Um serviço sem conexão não confiável pode entregar SDUs errados

Figura 2.18: Um serviço sem conexão que preserva a ordenação dos SDUs enviados por um determinado usuário

Fonte Fornecedor Destino

DADOS.request(S, D, "A")

DADOS.request(S, D, "B")

DADOS.indicação(S, D, "B")

DADOS.indicação(S, D, "A")

Tempo

Figura 2.19: Um serviço sem conexão que não preserva a ordenação dos SDUs enviados por um determinado usuário

2.1. Serviços e protocolos URL Saylor: 15

http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O serviço sem conexão é amplamente utilizado em redes de computadores, como veremos mais adiante neste livro. Diversas
variações deste serviço básico foram propostas. Um deles é o serviço sem conexão confirmado. Este serviço usa uma
primitiva Data.confirm além das primitivas clássicas Data.request e Data.indication. Esta primitiva é emitida pelo provedor de
serviços para confirmar a um usuário a entrega de um SDU previamente enviado ao seu destinatário. Observe que, assim
como o serviço cadastrado dos correios, o Data.confirm apenas indica que o SDU foi entregue ao usuário destino. A primitiva
Data.confirm não indica se o SDU foi processado pelo usuário de destino. Este serviço sem conexão confirmado é ilustrado
na figura abaixo.

Fonte Fornecedor Destino

DADOS.request(S, D, "M")

DADOS.indicação(S, D, "M")

DADOS.confirmar

Tempo

Figura 2.20: Um serviço sem conexão confirmado

O serviço sem conexão descrito anteriormente é frequentemente usado por usuários que precisam trocar pequenos SDUs.
Os usuários que precisam enviar ou receber vários SDUs diferentes e potencialmente grandes, ou que precisam de trocas
estruturadas, geralmente preferem o serviço orientado à conexão.

Uma invocação do serviço orientado a conexão é dividida em três fases. A primeira fase é o estabelecimento de uma conexão.
Uma conexão é uma associação temporária entre dois usuários por meio de um provedor de serviços. Podem existir várias
conexões ao mesmo tempo entre qualquer par de usuários. Uma vez estabelecida, a conexão é usada para transferir SDUs.
As conexões geralmente fornecem um fluxo bidirecional que suporta a troca de SDUs entre os dois usuários associados
através da conexão. Este fluxo é usado para transferir dados durante a segunda fase da conexão, chamada fase de
transferência de dados. A terceira fase é o término da conexão. Assim que os usuários terminam a troca de SDUs, eles
solicitam ao provedor de serviços o encerramento da conexão. Como veremos mais adiante, também existem alguns casos
em que o próprio provedor de serviços pode precisar encerrar uma conexão.

O estabelecimento de uma conexão pode ser modelado usando quatro primitivas: Connect.request, Connect.indication,
Connect.response e Connect.confirm. A primitiva Connect.request é utilizada para solicitar o estabelecimento de uma
conexão. O principal parâmetro desta primitiva é o endereço do usuário destino. O provedor de serviços entrega uma primitiva
Connect.indication para informar o usuário de destino sobre a tentativa de conexão. Se aceitar estabelecer uma conexão, ele
responde com uma primitiva Connect.response. Neste ponto, a conexão é considerada aberta e o usuário de destino pode
começar a enviar SDUs pela conexão. O provedor de serviços processa o Connect.response e entregará um Connect.confirm
ao usuário que iniciou a conexão. A entrega desta primitiva encerra a fase de estabelecimento da conexão. Neste ponto, a
conexão é considerada aberta e ambos os usuários podem enviar SDUs. Um estabelecimento de conexão bem-sucedido é
ilustrado abaixo.

O exemplo acima mostra um estabelecimento de conexão bem-sucedido. Contudo, na prática, nem todas as ligações são
estabelecidas com sucesso. Uma razão é que o usuário de destino pode não concordar, por motivos de política ou de
desempenho, em estabelecer uma conexão com o usuário inicial neste momento. Neste caso, o usuário de destino responde
à primitiva Connect.indication por uma primitiva Disconnect.request que contém um parâmetro para indicar porque a conexão
foi recusada. O provedor de serviços entregará então uma primitiva Disconnect.indication para informar o usuário inicial. Uma
segunda razão é quando o provedor de serviços não consegue entrar em contato com o usuário de destino. Isto pode
acontecer porque o usuário de destino não está atualmente conectado à rede ou devido a um congestionamento. Nesses

16 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Fonte Fornecedor Destino

CONNECT.solicitação

Indicação CONNECT

CONNECT.resposta

CONECTAR.confirmar Destino considera


conexão aberta
Fonte considera
conexão aberta
Tempo

Figura 2.21: Estabelecimento de conexão

Em alguns casos, o provedor de serviços responde ao Connect.request com uma primitiva Disconnect.indication cujo
parâmetro reason contém informações adicionais sobre a falha da conexão.

Fonte Fornecedor Destino

CONNECT.solicitação

Indicação CONNECT

DISCONNECT.solicitação

indicação DISCONNECT Conexão rejeitada pelo destino

CONNECT.solicitação

indicação DISCONNECT

Conexão rejeitada pelo


provedor
Tempo

Figura 2.22: Dois tipos de rejeição para tentativa de estabelecimento de conexão

Uma vez estabelecida a conexão, o provedor de serviços fornece dois fluxos de dados aos usuários em comunicação. O
primeiro fluxo de dados pode ser usado pelo usuário inicial para enviar SDUs. O segundo fluxo de dados permite que o
usuário respondente envie SDUs ao usuário inicial. Os fluxos de dados podem ser organizados de diferentes maneiras. Uma
primeira organização é a transferência em modo de mensagem. Com a transferência em modo de mensagem, o provedor
de serviços garante que uma e apenas uma Data.indication será entregue ao terminal do fluxo de dados para cada primitiva
Data.request emitida pelo outro terminal. A transferência em modo de mensagem é ilustrada na figura abaixo. A principal
vantagem do modo de transferência de mensagens é que o destinatário recebe exatamente os SDUs que foram enviados
pelo outro usuário. Se cada SDU contiver um comando, o usuário receptor poderá processar cada comando assim que
receber um SDU.

Infelizmente, a transferência em modo de mensagem não é amplamente utilizada na Internet. Na Internet, o serviço orientado
a conexão mais popular transfere SDUs em modo stream. Com o modo stream, o provedor de serviços fornece um fluxo de
bytes que conecta os dois usuários em comunicação. O usuário remetente envia bytes usando primitivas Data.request que
contêm sequências de bytes como SDUs. O provedor de serviços entrega SDUs contendo bytes consecutivos ao usuário
receptor usando primitivas Data.indication. O provedor de serviços garante que todos os bytes enviados em uma extremidade

2.1. Serviços e protocolos URL 17

Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Fonte Fornecedor Destino

CONNECT.solicitação

Indicação CONNECT

CONNECT.resposta

CONECTAR.confirmar

DADOS.request("A")

DADOS.indicação("A")
DADOS.request("BCD")

DADOS.indicação("BCD")
DADOS.request("EF")
DADOS.indicação("EF")

Tempo

Figura 2.23: Transferência em modo de mensagem em um serviço orientado a conexão

do fluxo são entregues corretamente na mesma ordem no outro ponto final. Contudo, o fornecedor de serviços não tenta preservar os
limites das SDUs. Não há relação imposta pelo provedor de serviços entre o número de Data.request e o número de primitivas
Data.indication. O modo de fluxo é ilustrado na figura abaixo. Na prática, uma consequência da utilização do modo stream é que se os
usuários quiserem trocar SDUs estruturados, eles precisarão fornecer os mecanismos que permitam ao usuário receptor separar SDUs
sucessivos no fluxo de bytes que recebe. Como veremos no próximo capítulo, os protocolos da camada de aplicação geralmente usam
delimitadores específicos, como o caractere de fim de linha, para delinear SDUs em um fluxo de bytes.

Fonte Fornecedor Destino

CONNECT.solicitação

Indicação CONNECT

CONNECT.resposta

CONECTAR.confirmar

DADOS.request("AB")

DADOS.indicação("A")
DADOS.request("CD")

DADOS.indicação("B")
DADOS.request("EF")
DADOS.indicação("C")

DADOS.indicação("DEF")
Tempo

Figura 2.24: Transferência em modo stream em um serviço orientado a conexão

A terceira fase de uma conexão é quando ela precisa ser liberada. Como uma conexão envolve três partes (dois usuários e um
provedor de serviços), qualquer uma delas pode solicitar o encerramento da conexão. Normalmente, as conexões são encerradas
mediante solicitação de um usuário, uma vez concluída a transferência de dados. No entanto, por vezes, o fornecedor de serviços pode
ser forçado a terminar uma ligação. Isso pode ser devido à falta de recursos dentro do provedor de serviços ou porque um dos usuários
não está mais acessível pela rede. Neste caso, o provedor de serviços emitirá primitivas Disconnect.indication para ambos os usuários.
Estas primitivas conterão, como parâmetro, algumas informações sobre o motivo do encerramento da conexão. Infelizmente, como
ilustrado na figura abaixo, quando um

18 Capítulo 2. Introdução Fundação


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Se o provedor de serviços for forçado a encerrar uma conexão, ele não poderá garantir que todos os SDUs enviados por cada usuário
tenham sido entregues ao outro usuário. Esta liberação de conexão é considerada abrupta, pois pode causar perdas de dados.

Fonte Fornecedor Destino

Conexão aberta Conexão aberta

DADOS.request("A")

DADOS.request("B")

DADOS.indicação("A")

DADOS.indicação("C")

indicação DISCONNECT indicação DISCONNECT

Tempo

Figura 2.25: Liberação abrupta de conexão iniciada pelo provedor de serviços

Uma liberação abrupta da conexão também pode ser acionada por um dos usuários. Se um usuário precisar, por qualquer motivo, encerrar
uma conexão rapidamente, ele poderá emitir uma primitiva Disconnect.request e solicitar uma liberação abrupta. O provedor de serviços
processará a solicitação, interromperá os dois fluxos de dados e entregará a primitiva Disconnect.indication ao usuário remoto o mais
rápido possível. Conforme ilustrado na figura abaixo, esta liberação abrupta da conexão pode causar perdas de SDUs.

Fonte Fornecedor Destino

Conexão aberta Conexão aberta

DADOS.request("A")

DADOS.request("B")

DADOS.indicação("A")

DISCONNECT.req(abrupto)
DADOS.request("C")

indicação DISCONNECT

Tempo

Figura 2.26: Liberação abrupta de conexão iniciada por um usuário

Para garantir uma entrega confiável dos SDUs enviados por cada usuário através de uma conexão, precisamos considerar os dois fluxos
que compõem uma conexão como independentes. Um usuário deve ser capaz de liberar o fluxo usado para enviar SDUs depois de ter
enviado todos os SDUs que planejou enviar por meio dessa conexão, mas ainda assim continuar recebendo SDUs pelo fluxo oposto. Essa
liberação de conexão normalmente é realizada conforme mostrado na figura abaixo. Um usuário emite uma primitiva Disconnect.request
para seu provedor depois de emitir todas as suas primitivas Data.request. O provedor de serviços aguardará até que todas as primitivas
Data.indication tenham sido entregues ao usuário receptor antes de emitir a primitiva Disnnnect.indication. Esta primitiva informa ao usuário
receptor que ele não receberá mais SDUs nesta conexão, mas ainda será capaz de emitir primitivas Data.request no fluxo na direção
oposta.
Depois que o usuário tiver emitido todas as suas primitivas Data.request, ele emite uma primitiva Disnnnect.request para solicitar o
encerramento do fluxo restante. O provedor de serviços processará a solicitação e entregará a Disconnect.indication correspondente ao
outro usuário assim que tiver entregue todas as primitivas Data.indication pendentes. Neste

2.1. Serviços e protocolos URL Saylor: 19

http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

ponto, todos os dados foram entregues e os dois fluxos foram liberados com sucesso e a conexão foi completamente
fechada.

Fonte Fornecedor Destino


Conexão aberta Conexão aberta
DADOS.request("A")

DADOS.request("B") DADOS.request("C")

DADOS.indicação("A")
DISCONNECT.req(elegante)
Fonte -> Conexão de DADOS.indicação("B")
destino fechada
DISCONNECT.ind(gracioso)
DADOS.indicação("C")
DADOS.request("D")

DADOS.indicação("D")
DISCONNECT.req(elegante)

DISCONNECT.ind(gracioso)

Conexão fechada Conexão fechada


Tempo

Figura 2.27: Liberação de conexão graciosa

Nota: Confiabilidade do serviço orientado a conexão

Um ponto importante a ser observado sobre o serviço orientado à conexão é a sua confiabilidade. Um serviço orientado
a conexão só pode garantir a entrega correta de todos os SDUs desde que a conexão tenha sido liberada normalmente.
Isto implica que enquanto a conexão estiver ativa, não há garantia da entrega efetiva dos SDUs trocados, pois a conexão
pode precisar ser liberada abruptamente a qualquer momento.

2.2 Os modelos de referência

Dada a crescente complexidade das redes de computadores, durante a década de 1970 os pesquisadores de redes
propuseram vários modelos de referência para facilitar a descrição de protocolos e serviços de rede. Destes, o modelo
Open Systems Interconnection (OSI) [Zimmermann80] foi provavelmente o mais influente. Serviu de base para o trabalho
de padronização realizado dentro da ISO para desenvolver padrões globais de redes de computadores. O modelo de
4.
referência que usamos neste livro pode ser considerado uma versão simplificada do modelo de referência OSI.

2.2.1 O modelo de referência de cinco camadas

Nosso modelo de referência está dividido em cinco camadas, conforme mostrado na figura abaixo.

Começando de baixo, a primeira camada é a camada Física. Dois dispositivos de comunicação estão ligados através de
um meio físico. Este meio físico é usado para transferir um sinal elétrico ou óptico entre dois dispositivos conectados
diretamente. Vários tipos de médiuns físicos são usados na prática:

• cabo eletrico. As informações podem ser transmitidas por diferentes tipos de cabos elétricos. Os mais comuns são
os pares trançados utilizados na rede telefônica, mas também em redes corporativas e cabos coaxiais. Os cabos
coaxiais ainda são usados em redes de TV a cabo, mas não são mais usados em redes corporativas.
Algumas tecnologias de rede operam através do cabo elétrico clássico.

• fibra ótica. As fibras ópticas são frequentemente utilizadas em redes públicas e empresariais quando a distância
entre os dispositivos de comunicação é superior a um quilómetro. Existem dois tipos principais de fibras ópticas:
multimodo e monomodo. O multimodo é muito mais barato que a fibra monomodo porque um LED pode ser
4
Uma interessante discussão histórica do debate OSI-TCP/IP pode ser encontrada em [Russel06]

20 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Aplicativo

Transporte

Rede

Link de dados

Físico

Meio de transmissão física


Figura 2.28: As cinco camadas do modelo de referência

usado para enviar um sinal através de uma fibra multimodo, enquanto uma fibra monomodo deve ser acionada por um laser.
Devido aos diferentes modos de propagação da luz, as fibras monomodo são limitadas a distâncias de alguns quilômetros,
enquanto as fibras multimodo podem ser usadas em distâncias superiores a várias dezenas de quilômetros. Em ambos os casos,
repetidores podem ser usados para regenerar o sinal óptico em uma extremidade de uma fibra para enviá-lo por outra fibra.

• sem fio. Neste caso, um sinal de rádio é utilizado para codificar as informações trocadas entre os dispositivos de comunicação.
Muitos tipos de técnicas de modulação são usados para enviar informações através de um canal sem fio e há muita inovação neste
campo, com novas técnicas surgindo a cada ano. Embora a maioria das redes sem fio dependa de sinais de rádio, algumas usam
um laser que envia pulsos de luz a um detector remoto. Estas técnicas ópticas permitem criar ligações ponto-a-ponto enquanto as
técnicas baseadas em rádio, dependendo da direcionalidade das antenas, podem ser utilizadas para construir redes contendo
dispositivos espalhados por uma pequena área geográfica.

Um ponto importante a ser observado sobre a camada Física é o serviço que ela oferece. Este serviço geralmente é um serviço orientado
a conexão não confiável que permite aos usuários da camada física trocar bits. A unidade de transferência de informação na camada
Física é o bit. O serviço da camada física não é confiável porque:

• a camada física pode mudar, por exemplo, devido a interferências eletromagnéticas, o valor de um bit sendo transmitido

• a camada física pode entregar mais bits ao receptor do que os bits enviados pelo remetente

• a camada física pode entregar menos bits ao receptor do que os bits enviados pelo remetente

Os dois últimos pontos podem parecer estranhos à primeira vista. Quando dois dispositivos são conectados por meio de um cabo, como é
possível que bits sejam criados ou perdidos nesse cabo?

Isto se deve principalmente ao fato de que os dispositivos de comunicação utilizam seu próprio clock para transmitir bits a uma determinada
taxa de bits. Considere um remetente com um relógio que bate um milhão de vezes por segundo e envia um bit a cada tick. A cada
microssegundo, o remetente envia um sinal elétrico ou óptico que codifica um bit. A taxa de bits do remetente é, portanto, de 1 Mbps. Se
5
o clock do receptor funcionar exatamente a cada microssegundo, ele também fornecerá 1 Mbps ao usuário. No entanto, se o clock do
receptor for um pouco mais rápido (resp. mais lento), ele fornecerá um pouco mais (resp. menos) de um milhão de bits por segundo. Isso
explica por que a camada física pode perder ou criar bits.

Nota: Taxa de bits

Nas redes de computadores, a taxa de bits da camada física é sempre expressa em bits por segundo. Um Mbps equivale a um milhão de
bits por segundo e um Gbps equivale a um bilhão de bits por segundo. Isso contrasta com as especificações de memória que geralmente
são expressas em bytes (8 bits), KiloBytes (1.024 bytes) ou MegaBytes (1.048.576 bytes). Assim, a transferência de um MByte através de
um link de 1 Mbps dura 8,39 segundos.

5 Ter relógios perfeitamente sincronizados funcionando em alta frequência é muito difícil na prática. Entretanto, algumas camadas físicas introduzem um
ciclo de feedback que permite que o relógio do receptor sincronize-se automaticamente com o relógio do remetente. No entanto, nem todas as camadas físicas
incluem este tipo de sincronização.

2.2. Os modelos de referência 21

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Taxa de bits Bits por segundo


1 Kbps 103
1Mbps 106 109
1Gbps
1 Tbps 1012

Bits
01010010100010101001010
Camada física Camada física

Meio de transmissão física

Figura 2.29: A camada Física

A camada física permite, assim, que duas ou mais entidades que estão diretamente ligadas ao mesmo meio de transmissão troquem bits.
Ser capaz de trocar bits é importante porque praticamente qualquer informação pode ser codificada como uma sequência de bits. Os
engenheiros elétricos estão acostumados a processar fluxos de bits, mas os cientistas da computação geralmente preferem lidar com
conceitos de nível superior. Um problema semelhante surge com o armazenamento de arquivos. Dispositivos de armazenamento, como
discos rígidos, também armazenam fluxos de bits. Existem dispositivos de hardware que processam o fluxo de bits produzido por um disco
rígido, mas os cientistas da computação projetaram sistemas de arquivos para permitir que os aplicativos acessem facilmente esses
dispositivos de armazenamento. Esses sistemas de arquivos também são normalmente divididos em várias camadas. Os discos rígidos
armazenam setores de 512 bytes ou mais. Os sistemas de arquivos Unix agrupam setores em blocos maiores que podem conter dados ou
inodes que representam a estrutura do sistema de arquivos. Por fim, as aplicações manipulam arquivos e diretórios que são traduzidos em
blocos, setores e eventualmente bits pelo sistema operacional.

As redes de computadores usam uma abordagem semelhante. Cada camada fornece um serviço construído acima da camada subjacente e
mais próximo das necessidades das aplicações.

A camada Datalink baseia-se no serviço fornecido pela camada física subjacente. A camada Datalink permite que dois hosts conectados
diretamente através da camada física troquem informações. A unidade de informação trocada entre duas entidades na camada Datalink é um
quadro. Um quadro é uma sequência finita de bits. Algumas camadas do Datalink usam quadros de comprimento variável, enquanto outras
usam apenas quadros de comprimento fixo. Algumas camadas de Datalink fornecem um serviço orientado a conexão, enquanto outras
fornecem um serviço sem conexão. Algumas camadas do Datalink fornecem entrega confiável, enquanto outras não garantem a entrega
correta das informações.

Um ponto importante a ser observado sobre a camada Datalink é que embora a figura abaixo indique que duas entidades da camada Datalink
trocam quadros diretamente, na realidade isso é um pouco diferente. Quando a entidade da camada Datalink à esquerda precisa transmitir
um quadro, ela emite tantas primitivas Data.request para a camada física subjacente quantos forem os bits no quadro. A camada física
converterá então a sequência de bits em um sinal eletromagnético ou óptico que será enviado pelo meio físico. A camada física no lado
direito da figura irá decodificar o sinal recebido, recuperar os bits e emitir as primitivas Data.indication correspondentes para sua entidade da
camada Datalink. Se não houver erros de transmissão, esta entidade receberá o quadro enviado anteriormente.

Link de dados Molduras Link de dados

Físico Físico

Figura 2.30: A camada Datalink

A camada Datalink permite que hosts conectados diretamente troquem informações, mas muitas vezes é necessário trocar informações entre
hosts que não estão conectados ao mesmo meio físico. Esta é a tarefa da camada de rede. A camada de rede é construída acima da camada
de enlace de dados. As entidades da camada de rede trocam pacotes. Um pacote é uma sequência finita de bytes transportada pela camada
de enlace de dados dentro de um ou mais quadros. Um pacote normalmente

22 Capítulo 2. Introdução Fundação

URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

contém informações sobre sua origem e destino e geralmente passa por vários dispositivos intermediários chamados roteadores no
caminho da origem até o destino.

Rede Pacotes Rede Pacotes Rede


Link de dados Link de dados Link de dados

Camada física Camada física Camada física

Figura 2.31: A camada de rede

A maioria das realizações da camada de rede, incluindo a Internet, não fornece um serviço confiável. No entanto, muitas aplicações
precisam trocar informações de forma confiável e, portanto, usar diretamente o serviço da camada de rede seria muito difícil para elas.
Garantir a entrega confiável dos dados produzidos pelas aplicações é tarefa da camada de transporte. Entidades da camada de transporte
trocam segmentos. Um segmento é uma sequência finita de bytes que são transportados dentro de um ou mais pacotes. Uma entidade da
camada de transporte emite segmentos (ou às vezes parte de segmentos) como Data.request para a entidade da camada de rede
subjacente.

Existem diferentes tipos de camadas de transporte. As camadas de transporte mais utilizadas na Internet são o TCP , que fornece um
serviço confiável de transporte de fluxo de bytes orientado à conexão, e o UDP , que fornece um serviço de transporte não confiável sem
conexão.

Transporte Segmentos Transporte


Rede Rede Rede
Link de dados Link de dados Link de dados

Camada física Camada física Camada física

Figura 2.32: A camada de transporte

A camada superior da nossa arquitetura é a camada de Aplicação. Esta camada inclui todos os mecanismos e estruturas de dados
necessários para as aplicações. Usaremos Application Data Unit (ADU) para indicar os dados trocados entre duas entidades da camada
de Aplicação.

Aplicativo MUITOS Aplicativo


Transporte Transporte
Rede Rede Rede
Link de dados Link de dados Link de dados

Camada física Camada física Camada física

Figura 2.33: A camada de Aplicação

2.2.2 O modelo de referência TCP/IP

Em contraste com o OSI, a comunidade TCP/IP não se esforçou muito para definir um modelo de referência detalhado; na verdade, os
objetivos da arquitetura da Internet só foram documentados após a implantação do TCP/IP [Clark88]. RFC 1122 que define os requisitos
para hosts
, da Internet, menciona quatro camadas diferentes. Começando do topo, são:

• uma camada de aplicação

• uma camada de transporte

• uma camada de Internet que é equivalente à camada de rede do nosso modelo de referência

• uma camada de link que combina as funcionalidades das camadas física e de link de dados de nossa referência de cinco camadas
modelo

Além dessa diferença nas camadas inferiores, o modelo de referência TCP/IP está muito próximo das cinco camadas que utilizamos ao
longo deste documento.

2.2. Os modelos de referência 23

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

2.2.3 O modelo de referência OSI

Comparado ao modelo de referência de cinco camadas explicado acima, o modelo de referência OSI definido em [X200] é dividido
em sete camadas. As quatro camadas inferiores são semelhantes às quatro camadas inferiores descritas acima. O modelo de
referência OSI refinou a camada de aplicação dividindo-a em três camadas:

• a camada Sessão. A camada de Sessão contém os protocolos e mecanismos necessários para organizar e sincronizar o
diálogo e gerenciar a troca de dados das entidades da camada de apresentação. Embora uma das principais funções da
camada de transporte seja lidar com a falta de confiabilidade da camada de rede, o objetivo da camada de sessão é
ocultar as possíveis falhas nas conexões de nível de transporte com a camada superior superior. Para isso, a Camada de
Sessão fornece serviços que permitem estabelecer uma ligação de sessão, suportar a troca ordenada de dados (incluindo
mecanismos que permitem a recuperação da libertação abrupta de uma ligação de transporte subjacente) e libertar a
ligação de forma ordenada.

• a camada de Apresentação foi projetada para lidar com as diferentes formas de representação de informações em
computadores. Existem muitas diferenças na forma como os computadores armazenam informações. Alguns computadores
armazenam inteiros como campos de 32 bits, outros usam campos de 64 bits e o mesmo problema surge com números
6
.
de ponto flutuante. Para informações textuais, isto é ainda mais complexo com os muitos códigos de caracteres diferentes
que têm sido utilizados. A situação é ainda mais complexa quando se considera a troca de informações estruturadas, tais
como registos de bases de dados. Para resolver este problema, a camada de Apresentação contém uma representação
comum dos dados transferidos. A notação ASN.1 foi projetada para a camada de Apresentação e ainda é usada hoje por
alguns protocolos.

• a camada de Aplicação que contém os mecanismos que não cabem nem na camada de Apresentação nem na camada de
Sessão. A camada de aplicação OSI foi dividida em vários elementos de serviço genéricos.

Nota: Onde estão as camadas ausentes no modelo de referência TCP/IP?

A referência TCP/IP coloca as camadas Apresentação e Sessão implicitamente na camada Aplicação. As principais motivações
para simplificar as camadas superiores do modelo de referência TCP/IP foram pragmáticas. A maioria das aplicações da Internet
começou como protótipos que evoluíram e foram posteriormente padronizados. Muitas dessas aplicações presumiam que seriam
usadas para trocar informações escritas em inglês americano e para as quais o código de caracteres US-ASCII de 7 bits era
suficiente. Esse foi o caso do e-mail, mas como veremos no próximo capítulo, o e-mail foi capaz de evoluir para suportar diferentes
codificações de caracteres. Algumas aplicações consideraram explicitamente as diferentes representações de dados. Por
exemplo, o FTP continha mecanismos para converter um arquivo de um formato para outro e a linguagem HTML foi definida para
representar páginas da web. Por outro lado, muitas especificações ISO foram desenvolvidas por comitês compostos por pessoas
que nem todas participaram das implementações reais. A ISO despendeu muito esforço analisando os requisitos e definindo uma
solução que atendesse a todos esses requisitos. Infelizmente, algumas das especificações eram tão complexas que era difícil
implementá-las completamente e os organismos de normalização definiram perfis recomendados que continham os conjuntos de
opções implementadas...

Figura 2.34: As sete camadas do modelo de referência OSI

6
Existe agora um consenso aproximado para o maior uso do Unicode formato de caractere. Unicode pode representar mais de 100.000 caracteres
diferentes das línguas escritas conhecidas na Terra. Talvez um dia todos os computadores usem apenas Unicode para representar todos os seus
caracteres armazenados e o Unicode possa se tornar o formato padrão para troca de caracteres, mas ainda não estamos neste estágio hoje.

24 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

2.3 Organização do livro

Este documento está organizado de acordo com o modelo de referência TCP/IP e segue uma abordagem top-down. A maioria dos
livros clássicos de redes escolheu uma abordagem bottom-up, ou seja, eles primeiro explicaram todos os detalhes elétricos e ópticos
da camada física e depois passaram para a camada de enlace de dados. Esta abordagem funcionou bem durante a infância das
redes de computadores e até o final da década de 1990. Naquela época, a maioria dos alunos não eram usuários de redes de
computadores e era útil explicar as redes de computadores construindo os protocolos correspondentes desde os mais simples, na
camada física, até a camada de aplicação. Hoje, todos os alunos são usuários ativos de aplicações da Internet, e começar a aprender
redes de computadores observando bits não é muito motivador. A partir de [KuroseRoss09], muitos livros didáticos e professores
escolheram uma abordagem de cima para baixo. Esta abordagem parte de aplicações como email e web que os alunos já conhecem
e explora as diferentes camadas, começando pela camada de aplicação. Essa abordagem funciona muito bem com os alunos de
hoje. A abordagem tradicional bottom-up poderia, de facto, ser considerada uma abordagem de engenharia, uma vez que parte de
uma rede simples que permite a troca de bits e explica como combinar diferentes protocolos e mecanismos para construir as
aplicações mais complexas. A abordagem de cima para baixo poderia, por outro lado, ser considerada uma abordagem científica.
Tal como os biólogos, parte de um sistema existente (construído pelo homem) e explora-o camada por camada.

Além da organização de cima para baixo versus organização de baixo para cima, os livros sobre redes de computadores podem ter
como objetivo uma cobertura aprofundada de um pequeno número de tópicos ou uma cobertura limitada de uma ampla gama de
tópicos. Cobrir uma ampla gama de temas é interessante para cursos introdutórios ou para estudantes que não necessitam de um
conhecimento detalhado de redes de computadores. Permite que os alunos aprendam um pouco sobre tudo e depois partam desse
conhecimento básico caso precisem entender mais detalhadamente as redes de computadores. Este livro optou por cobrir,
detalhadamente, um número menor de tópicos do que outros livros didáticos. Isto é motivado pelo fato de que as redes de
computadores muitas vezes precisam ser levadas ao seu limite. Compreender os detalhes dos principais protocolos de rede é
importante para poder compreender completamente como uma rede se comporta ou estendê-la para7 .fornecer serviços inovadores.

O livro está organizado da seguinte forma: Primeiro descrevemos a camada de aplicação no capítulo A camada de aplicação. Dado
o grande número de aplicações baseadas na Internet, é obviamente impossível abordá-las todas em detalhe. Em vez disso, nos
concentramos em três tipos de aplicações baseadas na Internet. Estudamos primeiro o Sistema de Nomes de Domínio (DNS) e
depois explicamos alguns dos protocolos envolvidos na troca de correio eletrônico. A discussão da camada de aplicação termina
com uma descrição dos principais protocolos da rede mundial de computadores.

Todas essas aplicações dependem da camada de transporte explicada no capítulo A camada de transporte. Esta é uma camada
fundamental nas redes atuais, pois contém todos os mecanismos necessários para fornecer uma entrega confiável de dados em
uma rede não confiável. Cobriremos a camada de transporte desenvolvendo primeiro um protocolo simples e confiável da camada
de transporte e depois explicando os detalhes dos protocolos TCP e UDP usados em redes TCP/IP.

Após a camada de transporte, analisamos a camada de rede no capítulo A camada de rede. Esta também é uma camada muito
importante, pois é responsável pela entrega de pacotes de qualquer origem para qualquer destino através de roteadores intermediários.
Na camada de rede, descrevemos as duas possíveis organizações da camada de rede e os protocolos de roteamento baseados em
link-state e vetores de distância. A seguir explicaremos detalhadamente os protocolos IPv4, IPv6, RIP, OSPF e BGP que são
realmente usados na Internet atual.

O último capítulo do livro é dedicado à camada de datalink. No capítulo A camada de datalink e as redes locais, começamos
explicando os princípios das camadas de datalink em links ponto a ponto. Em seguida, nos concentramos nas Redes Locais.
Descrevemos primeiro os algoritmos de controle de acesso ao meio que permitem que vários hosts compartilhem um meio de
transmissão. Consideramos técnicas oportunistas e determinísticas. Em seguida, explicamos detalhadamente dois tipos de LANs
que são importantes do ponto de vista de implantação atualmente: Ethernet e WiFi.

7
Uma citação popular diz que o diabo está nos detalhes. Esta citação reflete muito bem o funcionamento de muitos protocolos de rede, onde a mudança
de um único bit pode ter consequências enormes. Em redes de computadores, às vezes é necessário compreender todos os detalhes.

2.3. Organização do livro Saylor URL: 25

http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

26 Capítulo 2. Introdução
URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

CAPÍTULO 3

A camada de aplicação

A Camada de Aplicação é a camada mais importante e visível nas redes de computadores. Os aplicativos residem nesta
camada e os usuários humanos interagem por meio desses aplicativos na rede.

Neste capítulo, primeiro descrevemos brevemente os princípios básicos da camada de aplicação e nos concentramos nos dois
modelos de aplicação mais importantes: o modelo cliente-servidor e o modelo ponto a ponto. Em seguida, revisamos
detalhadamente duas famílias de protocolos que se mostraram muito úteis na Internet: o correio eletrônico e os protocolos que
permitem o acesso à informação na rede mundial de computadores. Também descrevemos o Sistema de Nomes de Domínio
que permite que humanos usem nomes amigáveis, enquanto os hosts usam endereços IP de 32 ou 128 bits.

3.1 Princípios
Existem dois modelos importantes usados para organizar um aplicativo em rede. O primeiro e mais antigo modelo é o modelo
cliente-servidor. Neste modelo, um servidor fornece serviços aos clientes que trocam informações com ele. Este modelo é
altamente assimétrico: os clientes enviam solicitações e os servidores executam ações e retornam respostas. Está ilustrado na
figura abaixo.

Figura 3.1: O modelo cliente-servidor

O modelo cliente-servidor foi o primeiro modelo a ser usado para desenvolver aplicações em rede. Esse modelo vem
naturalmente dos mainframes e minicomputadores que eram os únicos computadores em rede usados até a década de 1980.
Um minicomputador é um sistema multiusuário usado por dezenas ou mais usuários ao mesmo tempo. Cada usuário interage
com o minicomputador por meio de um terminal. Esses terminais eram principalmente uma tela, um teclado e um cabo
conectado diretamente ao minicomputador.

Existem vários tipos de servidores, bem como vários tipos de clientes. Um servidor web fornece informações em resposta à
consulta enviada por seus clientes. Um servidor de impressão imprime documentos enviados como consultas pelo cliente. Um
servidor de e-mail encaminhará ao destinatário as mensagens de e-mail enviadas como consultas, enquanto um servidor de
música entregará a música solicitada pelo cliente. Do ponto de vista do desenvolvedor da aplicação, as aplicações cliente e
servidor trocam mensagens diretamente (as setas horizontais denominadas Consultas e Respostas na figura acima), mas na
prática essas mensagens são trocadas graças às camadas subjacentes (as setas verticais na figura acima). figura). Neste
capítulo, concentramo-nos nestas trocas horizontais de mensagens.

27

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Os aplicativos em rede não trocam mensagens aleatórias. Para garantir que o servidor seja capaz de compreender as consultas
enviadas por um cliente, e também que o cliente seja capaz de compreender as respostas enviadas pelo servidor, ambos devem
concordar com um conjunto de regras sintáticas e semânticas. Estas regras definem o formato das mensagens trocadas bem
como a sua ordenação. Esse conjunto de regras é chamado de protocolo em nível de aplicativo.

Um protocolo em nível de aplicativo é semelhante a uma conversa estruturada entre humanos. Suponha que Alice queira
saber a hora atual, mas não tenha relógio. Se Bob passar por perto, a seguinte conversa poderá ocorrer:

• Alice: Olá

• Bob: Olá

• Alice: Que horas são?

• Bob: 11h55

• Alice: Obrigada
• Bob: De nada

Essa conversa terá sucesso se Alice e Bob falarem a mesma língua. Se Alice conhecer Tchang, que só fala chinês, ela não
poderá perguntar a hora atual. Uma conversa entre humanos pode ser mais complexa. Por exemplo, suponha que Bob seja
um guarda de segurança cujo dever é permitir que apenas agentes secretos confiáveis entrem em uma sala de reuniões. Se
todos os agentes souberem uma senha secreta, a conversa entre Bob e Trudy poderia ser a seguinte:

• Bob: Qual é a senha secreta?

• Trudy: 1234

• Bob: Esta é a senha correta, de nada

Se Alice quiser entrar na sala de reunião, mas não souber a senha, sua conversa poderá ser a seguinte:

• Bob: Qual é a senha secreta?


• Alice: 3.1415

• Bob: Esta não é a senha correta.

As conversas humanas podem ser muito formais, por exemplo, quando os soldados comunicam com a sua hierarquia, ou informais,
como quando os amigos discutem. Os computadores que se comunicam são mais parecidos com os soldados e exigem regras bem
definidas para garantir uma troca de informações bem-sucedida. Existem dois tipos de regras que definem como as informações
podem ser trocadas entre computadores:

• regras sintáticas que definem com precisão o formato das mensagens trocadas. Como apenas computadores
bits de processo, as regras sintáticas especificam como as informações são codificadas como sequências de bits

• organização do fluxo de informações. Para muitas aplicações, o fluxo de informação deve ser estruturado e existem
relações de precedência entre os diferentes tipos de informação. No exemplo de hora acima, Alice deve cumprimentar
Bob antes de perguntar a hora atual. Alice não perguntaria a hora atual primeiro e cumprimentaria Bob depois. Tais
relações de precedência também existem em aplicações em rede. Por exemplo, um servidor deve receber um nome
de usuário e uma senha válida antes de aceitar comandos mais complexos de seus clientes.

Vamos primeiro discutir as regras sintáticas. Posteriormente explicaremos como o fluxo de informações pode ser organizado
através da análise de aplicações reais em rede.

Os protocolos da camada de aplicação trocam dois tipos de mensagens. Alguns protocolos, como aqueles usados para
suportar mensagens de troca de correio eletrônico, são expressos como strings ou linhas de caracteres. Como a camada de
transporte permite que os hosts troquem bytes, eles precisam concordar com uma representação comum dos caracteres. O
primeiro e mais simples método para codificar caracteres é usar a tabela ASCII . RFC 20 fornece a tabela ASCII usada por
muitos protocolos na Internet. Por exemplo, a tabela define as seguintes representações binárias:
• R: 1000011b

• 0: 0110000b
• z: 1111010b

28 Capítulo 3. A Camada de Aplicação The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• @: 1000000b


espaço: 0100000b

Além disso, a tabela ASCII também define vários caracteres não imprimíveis ou de controle. Esses caracteres foram projetados para
permitir que um aplicativo controle uma impressora ou terminal. Esses caracteres de controle incluem CR e LF, que são usados para
encerrar uma linha, e o caractere Bell, que faz com que o terminal emita um som.

• retorno de carro (CR): 0001101b

• alimentação de linha (LF): 0001010b

• Campainha: 0000111b

Os caracteres ASCII são codificados como um campo de sete bits, mas transmitidos como um byte de oito bits cujo bit de ordem superior
é geralmente definido como 0. Os bytes são sempre transmitidos a partir do bit de ordem superior ou mais significativo.

A maioria dos aplicativos troca strings compostas por números de caracteres fixos ou variáveis. Uma solução comum para definir as
cadeias de caracteres aceitáveis é defini-las como uma gramática usando um Formulário Backus-Naur (BNF) , como o BNF Aumentado
definido na RFC 5234. Uma BNF é um conjunto de regras de produção que gera todas as cadeias de caracteres válidas. Por exemplo,
considere um aplicativo de rede que utiliza dois comandos, onde o usuário pode fornecer um nome de usuário e uma senha. A BNF para
esta aplicação poderia ser definida conforme mostrado na figura abaixo.

Figura 3.2: Uma especificação BNF simples

O exemplo acima define vários terminais e dois comandos: usercommand e passwordcommand. O terminal ALPHA contém todas as
letras maiúsculas e minúsculas. Na regra ALPHA, %x41 corresponde ao código de caracteres ASCII 41 em hexadecimal, ou seja, A
maiúsculo. Os terminais CR e LF correspondem aos caracteres de retorno de carro e de controle de avanço de linha. A regra CRLF
concatena esses dois terminais para corresponder à terminação de fim de linha padrão. O terminal DIGIT contém todos os dígitos. O
terminal SP corresponde aos caracteres de espaço em branco.
O usercommand é composto por duas strings separadas por espaço em branco. Nas regras ABNF que definem as mensagens utilizadas
pelas aplicações da Internet, os comandos não diferenciam maiúsculas de minúsculas. A regra “usuário” corresponde a todos os casos
possíveis das letras que compõem a palavra entre colchetes, ex: usuário, uSeR, USER, usER, ... Um nome de
usuário contém pelo menos uma letra e até 8 letras. Os nomes de usuário diferenciam maiúsculas de minúsculas, pois não são definidos
como uma string entre colchetes. A regra de senha indica que uma senha começa com uma letra e pode conter qualquer número de
letras ou dígitos. O espaço em branco e os caracteres de controle não podem aparecer em uma senha definida pela regra acima.

Além de cadeias de caracteres, alguns aplicativos também precisam trocar campos de 16 e 32 bits, como inteiros. Uma solução ingênua
teria sido enviar o campo de 16 ou 32 bits conforme está codificado na memória do host. Infelizmente, existem diferentes métodos para
armazenar campos de 16 ou 32 bits na memória. Algumas CPUs armazenam o byte mais significativo de um campo de 16 bits no
primeiro endereço do campo, enquanto outras armazenam o byte menos significativo neste local. Quando aplicativos em rede executados
em CPUs diferentes trocam campos de 16 bits, há duas possibilidades de transferi-los pelo serviço de transporte:

• enviar o byte mais significativo seguido pelo byte menos significativo

• enviar o byte menos significativo seguido do byte mais significativo

A primeira possibilidade foi denominada big-endian em uma nota escrita por Cohen [Cohen1980] , enquanto a segunda foi denominada
little-endian. Os fornecedores de CPUs que usavam big-endian na memória insistiam em usar a codificação big-endian em aplicativos
em rede, enquanto os fornecedores de CPUs que usavam little-endian recomendavam o contrário. Vários estudos foram escritos sobre
os méritos relativos de cada tipo de codificação, mas a discussão tornou-se quase uma questão religiosa [Cohen 1980]. Eventualmente,
a Internet escolheu a codificação big-endian, ou seja, campos multibyte são sempre transmitidos enviando primeiro o byte mais
significativo, RFC 791 refere-se a essa codificação como ordem de bytes da rede. Maioria

3.1. Princípios 29

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

1 ordem usado para escrever aplicativos em rede contém funções para converter campos multibyte da memória para o
de bytes da rede de bibliotecas e vice-versa.

Além de palavras de 16 e 32 bits, algumas aplicações precisam trocar estruturas de dados contendo campos de bits de vários comprimentos.
Por exemplo, uma mensagem pode ser composta por um campo de 16 bits seguido por oito flags de um bit, um campo de 24 bits e dois
bytes de 8 bits. As especificações do protocolo da Internet definirão tal mensagem usando uma representação como a abaixo. Nesta
representação, cada linha corresponde a 32 bits e as linhas verticais são utilizadas para delinear os campos. Os números acima das linhas
indicam as posições dos bits na palavra de 32 bits, com o bit de ordem superior na posição 0.

Figura 3.3: Formato da mensagem

A mensagem mencionada acima será transmitida a partir da palavra de 32 bits superior na ordem de bytes da rede. O primeiro campo é
codificado em 16 bits. É seguido por oito flags de um bit (AH), um campo de 24 bits cujo byte de ordem superior é mostrado na primeira
linha e os dois bytes de ordem inferior aparecem na segunda linha seguidos por dois campos de um byte. Esta representação ASCII é
frequentemente usada na definição de protocolos binários. Iremos usá-lo para todos os protocolos binários discutidos neste livro.

Discutiremos vários exemplos de protocolos em nível de aplicação neste capítulo.

3.1.1 O modelo ponto a ponto

O modelo peer-to-peer surgiu durante os últimos dez anos como outra arquitetura possível para aplicações em rede. No modelo cliente-
servidor tradicional, os hosts atuam como servidores ou como clientes e um servidor atende um grande número de clientes. No modelo
ponto a ponto, todos os hosts atuam como servidores e clientes e desempenham ambas as funções.
O modelo ponto a ponto tem sido usado para desenvolver vários aplicativos em rede, desde telefonia pela Internet até compartilhamento de
arquivos ou sistemas de arquivos em toda a Internet. Uma descrição detalhada das aplicações peer-to-peer pode ser encontrada em
[BYL2008]. Pesquisas de protocolos e aplicações peer-to-peer podem ser encontradas em [AS2004] e [LCP2005].

3.1.2 Os serviços de transporte

Os aplicativos de rede são criados com base no serviço de transporte. Conforme explicado no capítulo anterior, existem dois tipos principais
de serviços de transporte:

• o serviço sem conexão ou de datagrama

• o serviço orientado a conexão ou fluxo de bytes

O serviço sem conexão permite que os aplicativos troquem facilmente mensagens ou unidades de dados de serviço. Na Internet, este
serviço é fornecido pelo protocolo UDP que será explicado no próximo capítulo. O serviço de transporte sem conexão na Internet não é
confiável, mas é capaz de detectar erros de transmissão. Isto implica que uma aplicação não receberá uma SDU que tenha sido corrompida
devido a erros de transmissão.

O serviço de transporte sem conexão permite que aplicativos em rede troquem mensagens. Vários aplicativos em rede podem estar sendo
executados ao mesmo tempo em um único host. Cada uma dessas aplicações deve ser capaz de trocar SDUs com aplicações remotas.
Para permitir essas trocas de SDUs, cada aplicativo em rede executado em um host é identificado pelas seguintes informações:

• o host no qual o aplicativo está sendo executado

• o número da porta na qual o aplicativo escuta SDUs

1 Por exemplo, a função htonl(3) (resp. ntohl(3)) da biblioteca C padrão converte um número inteiro não assinado de 32 bits da ordem de bytes usada

pela CPU para a ordem de bytes da rede (resp. da ordem de bytes da rede para a ordem de bytes da CPU). Existem funções semelhantes em outras
linguagens de programação.

30 Capítulo 3. A Camada de Aplicação The Saylor


URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Na Internet, o número da porta é um número inteiro e o host é identificado pelo seu endereço de rede. Como veremos no capítulo A
camada de rede existem dois tipos de endereços de Internet:

• Endereços IP versão 4 com 32 bits de largura

• Endereços IP versão 6 com 128 bits de largura

Os endereços IPv4 são geralmente representados usando uma representação decimal pontilhada, onde cada número decimal corresponde
a um byte do endereço, por exemplo, 203.0.113.56. Os endereços IPv6 são geralmente representados como um conjunto de números
hexadecimais separados por ponto e vírgula, por exemplo, 2001:db8:3080:2:217:f2ff:fed6:65c0. Hoje, a maioria dos hosts da Internet
possui um endereço IPv4. Uma pequena fração deles também possui um endereço IPv6. No futuro, podemos esperar que cada vez mais
hosts tenham endereços IPv6 e que alguns deles não tenham mais endereços IPv4. Um host que possui apenas um endereço IPv4 não
pode se comunicar com um host que possui apenas um endereço IPv6. A figura abaixo ilustra dois que usam o serviço de datagrama
fornecido pelo UDP em hosts que usam endereços IPv4.

Figura 3.4: O serviço sem conexão ou datagrama

O segundo serviço de transporte é o serviço orientado à conexão. Na Internet, esse serviço costuma ser chamado de serviço de fluxo de
bytes, pois cria um fluxo de bytes confiável entre os dois aplicativos vinculados por uma conexão de transporte. Assim como o serviço de
datagrama, os aplicativos em rede que usam o serviço de fluxo de bytes são identificados pelo host no qual são executados e por um
número de porta. Esses hosts podem ser identificados por um endereço IPv4, um endereço IPv6 ou um nome. A figura abaixo ilustra duas
aplicações que utilizam o serviço de fluxo de bytes fornecido pelo protocolo TCP em hosts IPv6. O serviço de fluxo de bytes fornecido
pelo TCP é confiável e bidirecional.

Figura 3.5: O serviço orientado à conexão ou fluxo de bytes

3.1. Princípios 31

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

3.2 Protocolos em nível de aplicação

Muitos protocolos foram definidos para aplicações em rede. Nesta seção, descrevemos alguns dos aplicativos importantes usados na
Internet. Primeiro explicamos o Sistema de Nomes de Domínio (DNS), que permite que os hosts sejam identificados por nomes
amigáveis, em vez dos endereços IPv4 ou IPv6 usados pela rede. Em seguida, descrevemos o funcionamento do correio eletrônico,
uma das primeiras aplicações assassinas na Internet global, e os protocolos utilizados na rede mundial de computadores.

3.2.1 O Sistema de Nomes de Domínio

Nos primórdios da Internet, havia apenas alguns hosts (principalmente minicomputadores) conectados à rede. Os aplicativos mais
populares foram login remoto e transferência de arquivos. Em 1983, já havia quinhentos hosts conectados à Internet. Cada um desses
hosts foi identificado por um endereço IPv4 exclusivo. Forçar os usuários humanos a se lembrarem dos endereços IPv4 dos hosts
remotos que desejam usar não era fácil de usar.
Os usuários humanos preferem lembrar nomes e usá-los quando necessário. Usar nomes como apelidos para endereços é uma técnica
comum em Ciência da Computação. Simplifica o desenvolvimento de aplicações e permite ao desenvolvedor ignorar os detalhes de
baixo nível. Por exemplo, ao usar uma linguagem de programação em vez de escrever código de máquina, um desenvolvedor pode
escrever software sem saber se as variáveis que utiliza estão armazenadas na memória ou dentro de registradores.

Como os nomes estão em um nível superior aos endereços, eles permitem (tanto no exemplo de programação acima, quanto na
Internet) tratar os endereços como meros identificadores técnicos, que podem mudar à vontade. Apenas os nomes são estáveis.
Na Internet de hoje, onde mudar para outro ISP significa mudar os seus endereços IP, a facilidade de utilização dos nomes de domínio
é menos importante (não são frequentemente digitados pelos utilizadores), mas a sua estabilidade continua a ser muito importante,
podendo ser a sua propriedade mais importante.

A primeira solução que permitiu que os aplicativos usassem nomes foi o arquivo hosts.txt . Este arquivo é semelhante à tabela de
símbolos encontrada no código compilado. Contém o mapeamento entre o nome de cada host da Internet e seu endereço IP 2
associado .. Foi mantido pela SRI International que coordenou o Network Information Center (NIC). Quando um novo host era conectado
à rede, o administrador do sistema tinha que registrar seu nome e endereço IP na NIC. A NIC atualizou o arquivo hosts.txt em seu
servidor. Todos os hosts da Internet recuperavam regularmente o arquivo hosts.txt atualizado do servidor mantido pela SRI. Este
arquivo foi armazenado em um local conhecido em cada host da Internet (consulte RFC 952) e aplicativos de rede poderiam usá-lo
para encontrar o endereço IP correspondente a um nome.

Um arquivo hosts.txt pode ser usado quando houver algumas centenas de hosts na rede. Contudo, claramente não é adequado para
uma rede contendo milhares ou milhões de hosts. Uma questão fundamental em uma grande rede é definir um esquema de
nomenclatura adequado. A ARPANet inicialmente usou um espaço de nomenclatura simples, ou seja, cada host recebeu um nome
exclusivo. Para limitar as colisões entre nomes, esses nomes geralmente continham o nome da instituição e um sufixo para identificar
o anfitrião dentro da instituição (uma espécie de esquema hierárquico de nomenclatura do pobre). Na ARPANet poucas instituições
possuíam vários hosts conectados à rede.

No entanto, as limitações de um esquema de nomenclatura simples tornaram-se claras antes do final da ARPANet e da RFC 819.
propôs um esquema de nomenclatura hierárquica. Enquanto a RFC 819 discutiu a possibilidade de organizar os nomes como um grafo
direcionado, a Internet optou eventualmente por uma estrutura em árvore capaz de conter todos os nomes. Nesta árvore, os domínios
3.
de nível superior são aqueles que estão diretamente ligados à raiz. O primeiro domínio de nível superior foi .arpa. Este nome de nível
superior foi inicialmente adicionado como sufixo aos nomes dos hosts anexados à ARPANet e listados no arquivo hosts.txt. Em 1984,
os nomes de domínio genéricos de primeiro nível .gov, .edu, .com, .mil e .org foram adicionados e a RFC 1032 propôs a utilização dos
códigos de país ISO-3166 de duas letras como nomes de domínio de primeiro nível. Como a ISO-3166 define um código de duas letras
para cada país reconhecido pelas Nações Unidas, isso permitiu que todos os países tivessem automaticamente um domínio de nível
superior. Esses domínios incluem .be para a Bélgica, .fr para a França, .us para os EUA, .ie para a Irlanda ou .tv para Tuvalu, um grupo
de pequenas ilhas no Pacífico e .tm para o Turcomenistão. Hoje, o conjunto de nomes de domínio de nível superior é gerenciado pela
Internet Corporation for Assigned Names and Numbers (ICANN).
Recentemente, a ICANN adicionou uma dúzia de domínios genéricos de nível superior que não estão relacionados a um país e o
domínio de nível superior .cat foi registrado para o idioma catalão. Há discussões em andamento na ICANN para aumentar o número
de domínios de primeiro nível.

2
O arquivo hosts.txt não é mais mantido. Um instantâneo histórico recuperado em 15 de abril de 1984 está disponível em
http://ftp.univie.ac.at/netinfo/netinfo/hosts.txt
3
Consulte http://www.donelan.com/dnstimeline.html para obter uma linha do tempo dos desenvolvimentos relacionados ao DNS.

32 Capítulo 3. A Camada de Aplicação The

URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Cada domínio de nível superior é gerenciado por uma organização que decide como os nomes de subdomínios podem ser registrados. A
maioria dos nomes de domínio de nível superior usa um sistema de ordem de chegada e permite que qualquer pessoa registre nomes de
domínio, mas há algumas exceções. Por exemplo, .gov é reservado para o governo dos EUA, .int é reservado para organizações
internacionais e os nomes em .ca são reservados principalmente para empresas ou usuários presentes no Canadá.

Figura 3.6: A árvore de nomes de domínio

RFC 1035 recomendou o seguinte BNF para nomes de domínio totalmente qualificados, para permitir nomes de host com uma sintaxe que
funcione com todos os aplicativos (os próprios nomes de domínio têm uma sintaxe muito mais rica).

Figura 3.7: BNF dos nomes de host totalmente qualificados

Esta gramática especifica que um nome de host é uma lista ordenada de rótulos separados pelo caractere ponto (.). Cada etiqueta pode
4
conter letras, números e o caractere hífen (-) . Nomes de domínio totalmente qualificados são lidos da esquerda
para a direita. O primeiro rótulo é um nome de host ou nome de domínio seguido pela hierarquia de domínios e terminando com a raiz
implicitamente à direita. O nome de domínio de nível superior deve ser um dos TLDs registrados. Por exemplo, na5figura
. acima,
www.whitehouse.gov corresponde a um host chamado www dentro do domínio whitehouse que pertence ao domínio de nível superior gov.
info.ucl.ac.be corresponde ao domínio info dentro do domínio ucl que está incluído no subdomínio ac do domínio de nível superior be.

Este esquema de nomenclatura hierárquica é um componente chave do Sistema de Nomes de Domínio (DNS). O DNS é um banco de
dados distribuído que contém mapeamentos entre nomes de domínio totalmente qualificados e endereços IP. O DNS usa o modelo cliente-
servidor. Os clientes são hosts que precisam recuperar o mapeamento para um determinado nome. Cada servidor de nomes armazena parte
do banco de dados distribuído e responde às consultas enviadas pelos clientes. Existe pelo menos um servidor de nomes responsável por
cada domínio. Na figura abaixo, os domínios são representados por círculos e existem três hosts dentro do domínio dom (h1, h2 e h3) e três
hosts dentro do domínio a.sdom1.dom. Conforme mostrado na figura abaixo, um subdomínio pode conter nomes de host e subdomínios.

Figura 3.8: Uma árvore simples de nomes de domínio

4
Esta especificação evoluiu posteriormente para suportar nomes de domínio escritos usando outros conjuntos de caracteres além do us-ASCII RFC 5890. Esta extensão
É importante oferecer suporte a outros idiomas além do inglês, mas uma discussão detalhada está fora do escopo deste documento.
5
A lista oficial de nomes de domínio de nível superior é mantida por :term:'IANA em http://data.iana.org/TLD/tlds-alpha-by-domain.txt Adicional
informações sobre esses domínios podem ser encontradas em http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains

3.2. Protocolos em nível de aplicativo Saylor 33

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Um servidor de nomes responsável pelo domínio dom pode responder diretamente às seguintes perguntas:

• o endereço IP de qualquer host residente diretamente dentro do domínio dom (por exemplo, h2.dom na figura acima)

• o(s) servidor(es) de nomes responsáveis por qualquer subdomínio direto do domínio dom (ou seja, sdom1.dom e sdom2.dom na figura
acima, mas não z.sdom1.dom)

Para recuperar o mapeamento do host h2.dom, um cliente envia sua consulta ao servidor de nomes responsável pelo domínio .dom. O servidor
de nomes responde diretamente à consulta. Para recuperar um mapeamento para h3.a.sdom1.dom, um cliente DNS primeiro envia uma
consulta ao servidor de nomes responsável pelo domínio .dom. Este servidor de nomes retorna o servidor de nomes responsável pelo domínio
sdom1.dom. Este servidor de nomes agora pode ser contatado para obter o servidor de nomes responsável pelo domínio a.sdom1.dom. Este
servidor de nomes pode ser contatado para recuperar o mapeamento para o nome h3.a.sdom1.dom. Graças a esta organização dos servidores
de nomes, é possível a um cliente DNS obter o mapeamento de qualquer host dentro do domínio .dom ou de qualquer um dos seus
subdomínios. Para garantir que qualquer cliente DNS será capaz de resolver qualquer nome de domínio totalmente qualificado, existem
servidores de nomes especiais responsáveis pela raiz da hierarquia de nomes de domínio. Esses servidores de nomes são chamados de
servidores de nomes raiz. Existem atualmente cerca de uma dúzia de root
.
6 servidores de nomes

Cada servidor de nomes raiz mantém a lista de 8 7


de todos os servidores de nomes responsáveis por cada um dos servidores de nomes
nomes de domínio e seus endereços IP . raiz de nível superior são sincronizados e fornecem as mesmas respostas.
Ao consultar qualquer um dos servidores de nomes raiz, um cliente DNS pode obter o servidor de nomes responsável por qualquer nome de
domínio de nível superior. A partir deste servidor de nomes é possível resolver qualquer nome de domínio.

Para poder contatar os servidores de nomes raiz, cada cliente DNS deve conhecer seus endereços IP. Isto implica que os clientes DNS devem
9
manter uma lista atualizada dos endereços IP dos servidores de nomes raiz. Sem esta lista, é impossível contatar os servidores de nomes
raiz. Forçar todos os hosts da Internet a manter a versão mais recente desta lista seria difícil do ponto de vista operacional. Para resolver este
problema, os designers do DNS introduziram um tipo especial de servidor DNS: os resolvedores DNS. Um resolvedor é um servidor que
fornece o serviço de resolução de nomes para um conjunto de clientes. Uma rede geralmente contém alguns resolvedores. Cada host nessas
redes é configurado para enviar todas as suas consultas DNS por meio de um de seus resolvedores locais. Essas consultas são chamadas de
consultas recursivas, pois o resolvedor deve percorrer a hierarquia de servidores de nomes para obter a resposta.

Os resolvedores DNS têm várias vantagens em relação a permitir que cada host da Internet consulte diretamente os servidores de nomes. Em
primeiro lugar, os hosts regulares da Internet não precisam manter a lista atualizada dos endereços IP dos servidores raiz. Em segundo lugar,
os hosts regulares da Internet não precisam enviar consultas aos servidores de nomes em toda a Internet. Além disso, como um resolvedor de
DNS atende a um grande número de hosts, ele pode armazenar em cache as respostas recebidas. Isso permite que o resolvedor retorne
rapidamente respostas para consultas DNS populares e reduza a carga em todos os servidores DNS [JSBM2002].

O último componente do Sistema de Nomes de Domínio é o protocolo DNS. O protocolo DNS é executado acima do serviço de datagrama e
dos serviços de bytestream. Na prática, o serviço de datagrama é usado quando perguntas e respostas curtas são trocadas, e o serviço de
bytestream é usado quando respostas mais longas são esperadas. Nesta seção discutiremos apenas a utilização do protocolo DNS acima do
serviço de datagrama. Esta é a utilização mais frequente do DNS.

As mensagens DNS são compostas de cinco partes denominadas seções na RFC 1035. As três primeiras seções são obrigatórias e as duas
últimas seções são opcionais. A primeira seção de uma mensagem DNS é o seu cabeçalho. Contém informações sobre o tipo de mensagem
e o conteúdo das demais seções. A segunda seção contém a pergunta enviada ao servidor de nomes ou resolvedor. A terceira seção contém
a resposta à pergunta. Quando um cliente envia uma consulta DNS, a seção Resposta fica vazia. A quarta seção, denominada Autoridade,
contém informações sobre os servidores que podem fornecer uma resposta oficial, se necessário. A última seção contém informações
adicionais fornecidas pelo resolvedor ou servidor, mas que não foram solicitadas na pergunta.

O cabeçalho das mensagens DNS é composto por 12 bytes e sua estrutura é mostrada na figura abaixo.

O ID (identificador) é um valor aleatório de 16 bits escolhido pelo cliente. Quando um cliente envia uma pergunta a um servidor DNS, ele se
lembra da pergunta e de seu identificador. Quando um servidor retorna uma resposta, ele retorna no campo ID o identificador

6 Existem atualmente 13 servidores raiz. Na prática, alguns desses servidores raiz são implementados como um conjunto de servidores físicos distintos. Consulte http://
www.root-servers.org/ para obter mais informações sobre a localização física desses servidores.
7
Uma cópia das informações mantidas por cada servidor de nomes raiz está disponível em http://www.internic.net/zones/root.zone Até fevereiro
8
de 2008, os servidores DNS raiz tinham apenas endereços IPv4. Os endereços IPv6 foram adicionados aos servidores DNS raiz lentamente para evitar a criação de
problemas, conforme discutido em http://www.icann.org/en/committees/security/sac018.pdf Em 2010, vários servidores raiz DNS ainda não são acessíveis usando IPv6.

9 Esses endereços IP
A lista atual dos endereços IP dos servidores de nomes raiz é mantida em http://www.internic.net/zones/named.root .
são estáveis e os servidores de nomes raiz raramente alteram seus endereços IP. No entanto, os resolvedores de DNS devem manter uma cópia atualizada deste arquivo.

34 Capítulo 3. A Camada de Aplicação The Saylor

URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 3.9: Cabeçalho DNS

escolhido pelo cliente. Graças a este identificador, o cliente pode combinar a resposta recebida com a pergunta que enviou.

O sinalizador QR é definido como 0 em consultas DNS e 1 em respostas DNS. O Opcode é usado para especificar o tipo de consulta.
Por exemplo, uma consulta padrão é quando um cliente envia um nome e o servidor retorna os dados correspondentes e uma
solicitação de atualização é quando o cliente envia um nome e novos dados e o servidor então atualiza seu banco de dados.

O bit AA é definido quando o servidor que enviou a resposta tem autoridade para o nome de domínio encontrado na seção da
pergunta. Nas implantações originais do DNS, foram considerados dois tipos de servidores: servidores autoritativos e servidores não
autoritativos. Os servidores autoritativos são gerenciados pelos administradores de sistema responsáveis por um determinado
domínio. Eles sempre armazenam as informações mais recentes sobre um domínio. Servidores não autoritativos são servidores ou
resolvedores que armazenam informações DNS sobre domínios externos sem serem gerenciados pelos proprietários de um domínio.
Eles podem, portanto, fornecer respostas desatualizadas. Do ponto de vista da segurança, o bit autoritativo não é uma indicação
absoluta sobre a validade de uma resposta. Proteger o Sistema de Nomes de Domínio é um problema complexo que só foi resolvido
de forma satisfatória recentemente pela utilização de assinaturas criptográficas nas extensões DNSSEC para DNS descritas na RFC
4033. No entanto, essas extensões estão fora do escopo deste capítulo.

O bit RD (recursão desejada) é definido por um cliente quando ele envia uma consulta a um resolvedor. Diz-se que tal consulta é
recursiva porque o resolvedor recorrerá à hierarquia do DNS para recuperar a resposta em nome do cliente.
No passado, todos os resolvedores eram configurados para realizar consultas recursivas em nome de qualquer host da Internet. No
entanto, isto expõe os resolvedores a vários riscos de segurança. A mais simples é que o resolvedor pode ficar sobrecarregado por
ter muitas consultas recursivas para processar. No momento em que este livro foi escrito, a maioria10dos resolvedores permitia apenas
consultas recursivas de clientes pertencentes à sua empresa ou rede e descartava todas as outras consultas recursivas. O bit RA
indica se o servidor suporta recursão. O RCODE é usado para distinguir entre diferentes tipos de erros. Veja RFC 1035 para obter
detalhes adicionais. Os últimos quatro campos indicam o tamanho das seções Pergunta, Resposta, Autoridade e Adicionais da
mensagem DNS.

As últimas quatro seções da mensagem DNS contêm Registros de Recursos (RR). Todos os RRs têm o mesmo formato de nível
superior mostrado na figura abaixo.

Em um Registro de Recurso (RR), o Nome indica o nome do nó ao qual esse registro de recurso pertence. O campo Tipo de dois
bytes indica o tipo de registro de recurso. O campo Classe foi utilizado para suportar a utilização do DNS em outros ambientes que
não a Internet.

O campo TTL indica o tempo de vida do Registro de Recurso em segundos. Este campo é definido pelo servidor que retorna uma
resposta e indica por quanto tempo um cliente ou resolvedor pode armazenar o Registro de Recurso dentro de seu cache. Um TTL
longo indica um RR estável. Algumas empresas usam valores TTL curtos para hosts móveis e também para servidores populares.

10 Alguns resolvedores DNS permitem que qualquer host envie consultas. OpenDNS e GoogleDNS são exemplos de resolvedores abertos.

3.2. Protocolos em nível de aplicativo 35

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 3.10: Registros de recursos DNS

Por exemplo, uma empresa de hospedagem web que deseja distribuir a carga por um conjunto de centenas de servidores pode configurar
seus servidores de nomes para retornar respostas diferentes para clientes diferentes. Se cada resposta tiver um TTL pequeno, os clientes
serão forçados a enviar consultas DNS regularmente. O servidor de nomes responderá a essas perguntas fornecendo o endereço do
servidor menos carregado.

O campo RDLength é o comprimento do campo RData que contém as informações do tipo especificado no campo Tipo.

Vários tipos de DNS RR são usados na prática. O tipo A é usado para codificar o endereço IPv4 que corresponde ao nome especificado.
O tipo AAAA é usado para codificar o endereço IPv6 que corresponde ao nome especificado. Um registro NS contém o nome do servidor
DNS responsável por um determinado domínio. Por exemplo, uma consulta ao registro A associado ao nome www.ietf.org retorna a
seguinte resposta.

Esta resposta contém várias informações. Primeiro, o nome www.ietf.org está associado ao endereço IP 64.170.98.32. Segundo, o domínio
ietf.org é gerenciado por seis servidores de nomes diferentes. Três desses servidores de nomes são acessíveis via IPv4 e IPv6. Dois deles
não são acessíveis via IPv6 e ns0.ietf.org só é acessível via IPv6. Uma consulta para o registro AAAA associado a www.ietf.org retorna
2001:1890:1112:1::20 e a mesma autoridade e seções adicionais.

CNAME (ou nomes canônicos) são usados para definir aliases. Por exemplo, www.example.com pode ser um CNAME para
pc12.example.com, que é o nome real do servidor no qual o servidor web de www.example.com é executado.

Nota: DNS reverso e in-addr.arpa

O DNS é usado principalmente para encontrar o endereço IP que corresponde a um determinado nome. Contudo, às vezes é útil obter o
nome que corresponde a um endereço IP. Isso é feito usando o PTR (ponteiro) RR. A parte RData de um PTR RR contém o nome,
enquanto a parte Name do RR contém o endereço IP codificado no domínio in-addr.arpa. Os endereços IPv4 são codificados no in-
addr.arpa invertendo os quatro dígitos que compõem a representação decimal pontilhada do endereço. Por exemplo, considere o endereço
IPv4 192.0.2.11. O hostname associado a este endereço pode ser encontrado solicitando o PTR RR que corresponde a 11.2.0.192.in-
addr.arpa. Uma solução semelhante é usada para oferecer suporte a endereços IPv6, consulte RFC 3596.

36 Capítulo 3. A Camada de Aplicação The

URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 3.11: Consulta do registro A de www.ietf.org

Um ponto importante a ser observado em relação ao Sistema de Nomes de Domínio é sua extensibilidade. Graças aos campos Type e
RDLength, o formato dos registros de recursos pode ser facilmente estendido. Além disso, uma implementação de DNS que recebe um
novo registro de recurso que não compreende pode ignorar o registro e ainda ser capaz de processar as outras partes da mensagem.
Isso permite, por exemplo, que um servidor DNS que suporta apenas IPv4 ignore os endereços IPv6 listados na resposta DNS para
www.ietf.org e ainda seja capaz de analisar corretamente os Registros de Recursos que ele compreende. Essa extensibilidade permitiu
que o Sistema de Nomes de Domínio evoluísse ao longo dos anos, preservando ao mesmo tempo a compatibilidade retroativa com
implementações de DNS já implantadas.

3.2.2 Correio eletrônico

O correio eletrônico, ou e-mail, é uma aplicação muito popular em redes de computadores como a Internet. E-mail apareceu no início
da década de 1970 e permite aos usuários trocar mensagens de texto. Inicialmente, era utilizado principalmente para troca de
mensagens curtas, mas com o passar dos anos seu uso foi crescendo. Agora não é usado apenas para trocar mensagens pequenas,
mas também longas que podem ser compostas por várias partes como veremos mais tarde.

Antes de examinarmos os detalhes do email na Internet, consideremos um cenário simples ilustrado na figura abaixo, onde Alice envia
um email para Bob. Alice prepara seu e-mail usando um cliente de e-mail e envia para seu servidor de e-mail. Servidor de e-mail de
Alice extrai o endereço de Bob do e-mail e entrega a mensagem ao servidor de Bob. Bob recupera a mensagem de Alice em seu
servidor e a lê usando seu cliente de e-mail favorito ou através de sua interface de webmail.

Figura 3.12: Arquitetura simplificada do e-mail da Internet

O sistema de e-mail que consideramos neste livro é composto por quatro componentes:

• um formato de mensagem que define como as mensagens de e-mail válidas são codificadas

• protocolos, que permitem que hosts e servidores troquem mensagens de e-mail

3.2. Protocolos em nível de aplicativo 37

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• software cliente, que permite aos usuários criar e ler facilmente mensagens de e-mail

• software, que permite aos servidores trocar mensagens de e-mail com eficiência

Discutiremos primeiro o formato das mensagens de e-mail seguido pelos protocolos usados na Internet hoje para troca e recuperação de e-
mails. Outros sistemas de e-mail foram desenvolvidos no passado [Bush1993] [Genilloud1990]
[GC2000], mas hoje a maioria das soluções de e-mail migrou para o e-mail da Internet. Informações sobre o software usado para redigir e
entregar e-mails podem ser encontradas na Wikipedia entre outros, tanto para clientes de e-mail e servidores de e-mail. Informações mais
detalhadas sobre a arquitetura completa do Internet Mail podem ser encontradas na RFC 5598.

As mensagens de e-mail, assim como o correio postal, são compostas de duas partes:

• um cabeçalho que desempenha a mesma função que o papel timbrado do correio normal. Ele contém metadados sobre a mensagem.

• o corpo que contém a própria mensagem.

As mensagens de e-mail são inteiramente compostas por linhas de caracteres ASCII. Cada linha pode conter até 998 caracteres e é finalizada
pelos caracteres de controle CR e LF RFC 5322. As linhas que compõem o cabeçalho aparecem antes do corpo da mensagem. Uma linha
vazia, contendo apenas os caracteres CR e LF, marca o final do cabeçalho.
Isto é ilustrado na figura abaixo.

Figura 3.13: A estrutura das mensagens de e-mail

O cabeçalho do e-mail contém várias linhas que começam com uma palavra-chave seguida por dois pontos e informações adicionais. O
formato das mensagens de email e os diferentes tipos de linhas de cabeçalho são definidos na RFC 5322. Duas destas linhas de cabeçalho
são obrigatórias e devem aparecer em todas as mensagens de e-mail:

• O endereço do remetente. Esta linha de cabeçalho começa com From:. Contém o nome (opcional) do remetente seguido de seu
endereço de e-mail entre < e >. Os endereços de e-mail são sempre compostos por um nome de usuário seguido do sinal @ e um
nome de domínio.

• A data. Esta linha de cabeçalho começa com Data:. RFC 5322 define com precisão o formato usado para codificar uma data.

Outras linhas de cabeçalho aparecem na maioria das mensagens de e-mail. A linha de cabeçalho Assunto: permite ao remetente indicar o
tópico discutido no e-mail. Três tipos de linhas de cabeçalho podem ser usados para especificar os destinatários de uma mensagem:

• a linha do cabeçalho Para: contém os endereços de e-mail dos destinatários principais da mensagem. Os endereços 11 . Diversos

podem ser separados por vírgulas.

• a linha de cabeçalho cc: é usada pelo remetente para fornecer uma lista de endereços de e-mail que devem receber uma cópia carbono
da mensagem. Vários endereços podem ser listados nesta linha de cabeçalho, separados por vírgulas. Todos os destinatários da
mensagem de e-mail recebem as linhas de cabeçalho Para: e cc:.

• a linha de cabeçalho Cco: é usada pelo remetente para fornecer uma lista de endereços de e-mail separados por vírgulas que devem
receber uma cópia oculta da mensagem. A linha de cabeçalho Cco: não é entregue aos destinatários da mensagem de e-mail.

Uma mensagem de e-mail simples contendo as linhas de cabeçalho De:, Para:, Assunto: e Data: e duas linhas de corpo é mostrada abaixo.

11 Pode ser surpreendente que Para: não seja obrigatório dentro de uma mensagem de e-mail. Embora a maioria das mensagens de e-mail contenha esta linha de cabeçalho e

e-mail que não contém uma linha de cabeçalho To: e que depende do Cco: para especificar o destinatário também é válido.

38 Capítulo 3. A Camada de Aplicação The Saylor

URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

De: Bob Smith <Bob@machine.example> Para: Alice Doe


<alice@example.net>, Alice Smith <Alice@machine.example> Assunto: Olá Data: Seg, 8 de março de 2010 19:55:06
-0600

Este é o “Olá, mundo” das mensagens de e-mail.


Esta é a segunda linha do corpo

Observe a linha vazia após a linha de cabeçalho Date:; esta linha vazia contém apenas os caracteres CR e LF e marca o limite entre o
cabeçalho e o corpo da mensagem.

Várias outras linhas de cabeçalho opcionais são definidas na RFC 5322 e em outros lugares 12. Além disso, muitos clientes e servidores de
e-mail definem suas próprias linhas de cabeçalho começando em X-. Várias das linhas de cabeçalho opcionais definidas na RFC 5322 vale
a pena ser discutido aqui:

• a linha de cabeçalho Message-Id: é usada para associar um identificador “único” a cada email. Os identificadores de e-mail geralmente
são estruturados como string@domain, onde string é uma sequência de caracteres exclusiva ou número de sequência escolhido pelo
remetente do e-mail e domínio é o nome de domínio do remetente. Como os nomes de domínio são exclusivos, um host pode gerar
identificadores de mensagens globalmente exclusivos concatenando um identificador localmente exclusivo com seu nome de domínio.

• In-reply-to: é usado quando uma mensagem foi criada em resposta a uma mensagem anterior. Neste caso, o fim do
a linha In-reply-to: contém o identificador da mensagem original.

• a linha de cabeçalho Recebido: é usada quando uma mensagem de e-mail é processada por vários servidores antes de chegar ao
seu destino. Cada servidor de e-mail intermediário adiciona uma linha de cabeçalho Recebido:. Essas linhas de cabeçalho são úteis
para depurar problemas na entrega de mensagens de email.

A figura abaixo mostra as linhas de cabeçalho de uma mensagem de e-mail. A mensagem originou-se em um host chamado wira.firstpr.com.au
e foi recebida por smtp3.sgsi.ucl.ac.be. As linhas Received: foram quebradas para facilitar a leitura.

Recebido: de smtp3.sgsi.ucl.ac.be (Desconhecido [10.1.5.3]) por mmp.sipr-dc.ucl.ac.be (Sun


Java (tm) System Messaging Server
7u3-15.01 64 bits (construído em 12 de fevereiro de 2010) )) com ID ESMTP <0KYY00L85LI5JLE0@mmp.sipr-dc.ucl.ac.be>;
Seg, 08 de março de 2010 11:37:17 +0100 (CET)

Recebido: de mail.ietf.org (mail.ietf.org [64.170.98.32])


por smtp3.sgsi.ucl.ac.be (Postfix) com ID ESMTP B92351C60D7; Seg, 08 de março de 2010 11:36:51 +0100
(CET)
Recebido: de [127.0.0.1] (localhost [127.0.0.1]) por core3.amsl.com (Postfix) com ID ESMTP
F066A3A68B9; Seg, 08 de março de 2010 02:36:38 -0800 (PST)
Recebido: de localhost (localhost [127.0.0.1]) por core3.amsl.com (Postfix)
com ID ESMTP A1E6C3A681B para <rrg@core3.amsl.com>; Seg, 08 de março de 2010
02:36:37 -0800 (PST)
Recebido: de mail.ietf.org ([64.170.98.32])
por localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, porta 10024) com ID ESMTP erw8ih2v8VQa para
<rrg@core3.amsl.com>; Seg, 08 de março de 2010 02:36:36 -0800 (PST)

Recebido: de gair.firstpr.com.au (gair.firstpr.com.au [150.101.162.123])


por core3.amsl.com (Postfix) com ESMTP id 03E893A67ED 08 de março de 2010 para <rrg@irtf.org>; Seg,
02:36:35 -0800 (PST)
Recebido: de [10.0.0.6] (wira.firstpr.com.au [10.0.0.6])
por gair.firstpr.com.au (Postfix) com ID ESMTP D0A49175B63; Seg, 08 de março de 2010 21:36:37 +1100
(EST)
Data: Seg, 08 de março de 2010 21:36:38 +1100 De: Robin
Whittle <rw@firstpr.com.au> Assunto: Re: [rrg] Recomendação e
o que acontece a seguir Resposta para: <C7B9C21A.4FAB% tony.li@tony.li> Para: RRG
<rrg@irtf.org> ID da mensagem: <4B94D336.7030504@firstpr.com.au>

12 A lista de todas as linhas de cabeçalho de e-mail padrão pode ser encontrada em http://www.iana.org/assignments/message-headers/message-header-index.html

3.2. Protocolos em nível de aplicativo Saylor 39

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Conteúdo da mensagem removido

Inicialmente, o email era usado para troca de pequenas mensagens de texto ASCII entre cientistas da computação. No entanto, com
o crescimento da Internet, o suporte apenas para texto ASCII tornou-se uma limitação severa por dois motivos. Em primeiro lugar,
quem não fala inglês queria escrever e-mails em seu idioma nativo, o que muitas vezes exigia mais caracteres do que os da tabela
de caracteres ASCII. Em segundo lugar, muitos usuários queriam enviar por e-mail outro conteúdo além de texto ASCII, como
arquivos binários, imagens ou som.

Para resolver este problema, a IETF desenvolveu as extensões multiuso de correio da Internet (MIME). Essas extensões foram
cuidadosamente projetadas para permitir que o e-mail da Internet transportasse caracteres não-ASCII e arquivos binários sem
interromper os servidores de e-mail implantados naquele momento. Este requisito de compatibilidade com versões anteriores forçou
os designers MIME a desenvolver extensões para o formato de mensagem de e-mail existente RFC 822 em vez de definir um
formato completamente novo que seria mais adequado para suportar os novos tipos de e-mail.

RFC 2045 define três novos tipos de linhas de cabeçalho para suportar MIME:

• O cabeçalho MIME-Version: indica a versão da especificação MIME que foi usada para codificar a mensagem de email. A
versão atual do MIME é 1.0. Outras versões do MIME poderão ser definidas no futuro.
Graças a esta linha de cabeçalho, o software que processa mensagens de e-mail poderá se adaptar à versão MIME utilizada
para codificar a mensagem. As mensagens que não contêm este cabeçalho devem ser formatadas de acordo com o RFC
822 original especificação.

• A linha de cabeçalho Content-Type: indica o tipo de dados que são transportados dentro da mensagem (veja abaixo)

• A linha de cabeçalho Content-Transfer-Encoding: é usada para especificar como a mensagem foi codificada. Quando o MIME
foi projetado, alguns servidores de e-mail só eram capazes de processar mensagens contendo caracteres codificados usando
o conjunto de caracteres ASCII de 7 bits. MIME permite a utilização de outras codificações de caracteres.

Dentro do cabeçalho do email, a linha de cabeçalho Content-Type: indica como a mensagem de email MIME está estruturada. RFC
2046 define a utilização desta linha de cabeçalho. As duas estruturas mais comuns para mensagens MIME são:

• Tipo de conteúdo: multipart/misto. Esta linha de cabeçalho indica que a mensagem MIME contém vários
peças pendentes. Por exemplo, tal mensagem pode conter uma parte em texto simples e um arquivo binário.

• Tipo de conteúdo: multipart/alternativo. Esta linha de cabeçalho indica que a mensagem MIME contém diversas representações
da mesma informação. Por exemplo, uma mensagem multiparte/alternativa pode conter um texto simples e uma versão
HTML do mesmo texto.

Para suportar estes dois tipos de mensagens MIME, o destinatário de uma mensagem deve ser capaz de extrair as diferentes partes
da mensagem. Na RFC 822, uma linha vazia foi usada para separar as linhas do cabeçalho do corpo. Usar uma linha vazia para
separar as diferentes partes do corpo de um e-mail seria difícil, pois o corpo das mensagens de e-mail geralmente contém uma ou
mais linhas vazias. Outra opção possível seria definir uma linha especial, por exemplo *-LAST_LINE-* para marcar o limite entre
duas partes de uma mensagem MIME. Infelizmente, isso não é possível porque alguns e-mails podem conter esta string no corpo
(por exemplo, e-mails enviados a alunos para explicar o formato das mensagens MIME). Para resolver este problema, a linha de
cabeçalho Content-Type: contém um segundo parâmetro que especifica a string que foi usada pelo remetente da mensagem MIME
para delinear as diferentes partes. Na prática, esta string é frequentemente escolhida aleatoriamente pelo cliente de email.

A mensagem de e-mail abaixo, copiada da RFC 2046 mostra uma mensagem MIME contendo duas partes em texto simples e
codificadas usando o conjunto de caracteres ASCII. O limite simples da string é definido no cabeçalho Content-Type: como o
marcador para o limite entre duas partes sucessivas. Outro exemplo de mensagens MIME pode ser encontrado na RFC 2046.

Data: Seg, 20 de setembro de 1999 16:33:16 +0200 De:


Nathaniel Borenstein <nsb@bellcore.com>
Para: Ned Freed <ned@innosoft.com>
Assunto: Teste MIME-
Versão: 1.0
Tipo de conteúdo: multipart/misto; limite = "limite simples"

preâmbulo, para ser ignorado

--limite simples
Tipo de conteúdo: texto/simples; conjunto de caracteres=us-ascii

40 Capítulo 3. A Camada de Aplicação The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Primeira parte

--limite simples
Tipo de conteúdo: texto/simples; conjunto de caracteres=us-ascii

Segunda parte –
limite simples

O cabeçalho Content-Type: também pode ser usado dentro de uma parte MIME. Neste caso, indica o tipo de dado colocado nesta
parte. Cada tipo de dados é especificado como um tipo seguido por um subtipo. Uma descrição detalhada pode ser encontrada na
RFC 2046. Algumas das linhas de cabeçalho Content-Type: mais populares são:

• texto. A parte da mensagem contém informações em formato textual. Existem vários subtipos: text/plain para texto ASCII normal,
text/html definido na RFC 2854 para documentos em formato HTML ou no formato de texto/enriquecido definido na RFC 1896.
A linha de cabeçalho Content-Type: pode conter um segundo parâmetro que especifica o conjunto de caracteres usado para
codificar o texto. charset=us-ascii é a tabela de caracteres ASCII padrão. Outros conjuntos de caracteres frequentes incluem
charset=UTF8 ou charset=iso-8859-1. A lista de conjuntos de caracteres padrão é mantido pela IANA

• imagem. A parte da mensagem contém uma representação binária de uma imagem. O subtipo indica o formato da imagem,
como gif, jpg ou png.

• áudio. A parte da mensagem contém um clipe de áudio. O subtipo indica o formato do clipe de áudio como wav
ou mp3

• vídeo. A parte da mensagem contém um videoclipe. O subtipo indica o formato do videoclipe como avi ou
mp4

• aplicativo. A parte da mensagem contém informações binárias produzidas pelo aplicativo específico listado como subtipo. Os
clientes de e-mail usam o subtipo para iniciar o aplicativo capaz de decodificar as informações binárias recebidas.

Nota: De ASCII para Unicode

Os primeiros computadores utilizavam diferentes técnicas para representar caracteres na memória e no disco. Durante a década de
1960, os computadores começaram a trocar informações por meio de fitas ou linhas telefônicas. Infelizmente, cada fornecedor tinha
seu próprio conjunto de caracteres proprietário e a troca de dados entre computadores de diferentes fornecedores era muitas vezes
difícil. A tabela de caracteres ASCII de 7 bits RFC 20 conjunto foi adotado por vários fornecedores e por muitos protocolos de Internet.
No entanto, o ASCII tornou-se um problema com a internacionalização da Internet e com o desejo de cada vez mais utilizadores de
utilizar conjuntos de caracteres que suportem a sua própria linguagem escrita. Uma primeira tentativa de resolver este problema foi a
definição da ISO-8859 conjuntos de caracteres por ISO. Esta família de padrões especificou vários conjuntos de caracteres que
permitiram a representação de muitas línguas escritas europeias usando caracteres de 8 bits. Infelizmente, um conjunto de caracteres
de 8 bits não é suficiente para suportar alguns idiomas amplamente utilizados, como os usados em países asiáticos. Felizmente, no
final da década de 1980, vários cientistas da computação propuseram o desenvolvimento de um padrão que suportasse todas as
linguagens escritas usadas atualmente na Terra. O padrão Unicode [Unicode] já foi adotado pela maioria dos fornecedores de
computadores e software. Por exemplo, Java usa Unicode nativamente para manipular caracteres, Python pode lidar com caracteres
ASCII e Unicode. Os aplicativos da Internet estão avançando lentamente em direção ao suporte completo para os conjuntos de
caracteres Unicode, mas passar de ASCII para Unicode é uma mudança importante que pode ter um enorme impacto nas
implementações atuais implantadas. Veja, por exemplo, o trabalho para internacionalizar completamente o email RFC 4952 e nomes
de domínio RFC 5890.

A última linha do cabeçalho MIME é Content-Transfer-Encoding:. Esta linha de cabeçalho é usada após a linha de cabeçalho Content-
Type:, dentro de uma parte da mensagem, e especifica como a parte da mensagem foi codificada. A codificação padrão é usar ASCII
de 7 bits. As codificações mais frequentes são para impressão entre aspas e Base64. Ambos suportam a codificação de uma sequência
de bytes em um conjunto de linhas ASCII que podem ser transmitidas com segurança por servidores de e-mail. citado para impressão
é definido na RFC 2045. Descrevemos brevemente a base64 que é definida na RFC 2045 e RFC 4648.

Base64 divide a sequência de bytes a serem codificados em grupos de três bytes (com o último grupo possivelmente parcialmente
preenchido). Cada grupo de três bytes é então dividido em quatro campos de seis bits e cada campo de seis bits é codificado como um
caractere da tabela abaixo.

3.2. Protocolos em nível de aplicativo 41

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Codificação de valor Codificação de valor Codificação de valor Codificação de valor


0 A 17 R 34 eu 51 Com

1 B 18 S 35 52 0
2 C 19 T 36 53 1
3 D 20 U 37 etc. 54 2
4 E 21V 38 m 39 40 55 3
5 F 22 W 41 n 56 4
6 G 23X 42 o 57 5
7 H 24 e 25 43 58 6
8 EU Z 44 pq 59 7
9 J. 26 a 45 R 60 8
10K 11 27 b 46 é 61 9
eu 28 c 47 t 62 +
12 milhões 29 d 48 em 63 /
13 N 14 30 e 49 em

O 31 f 50 Em

15 P 32 x
16 P 33 ah e

O exemplo abaixo, da RFC 4648, ilustra a codificação Base64.

Dados de entrada 0x14fb9c03d97e


8 bits 00010100 11111011 10011100 00000011 11011001 01111110
6 bits 000101 001111 101110 011100 000000 111101 100101 111110
Decimais 5 15 46 28 0 61 37 62
Codificação FP uc A 9 l +

O último ponto a ser discutido sobre base64 é o que acontece quando o comprimento da sequência de bytes a ser
codificado não é um múltiplo de três. Neste caso, o último grupo de bytes pode conter um ou dois bytes em vez de
três. Base64 reserva o caractere = como caractere de preenchimento. Este caractere é usado duas vezes quando o último grupo
contém dois bytes e uma vez quando contém um byte, conforme ilustrado pelos dois exemplos abaixo.

Dados de entrada 0x14


00010100 de 8 bits
6 bits 000101 000000
Decimais 5 0
Codificação FA = =

Dados de entrada 0x14b9


8 bits 00010100 11111011
6 bits 000101 001111 101100
Decimais 5 15 44
Codificação de FPs =

Agora que explicamos o formato das mensagens de email, podemos discutir como essas mensagens podem ser trocadas pela Internet.
A figura abaixo ilustra os protocolos usados quando Alice envia um email
mensagem para Bob. Alice prepara seu email com um cliente de email ou em uma interface de webmail. Para enviar seu e-mail para
Bob, o cliente de Alice usará o Simple Mail Transfer Protocol (SMTP) para entregar sua mensagem ao servidor SMTP.
O cliente de e-mail de Alice está configurado com o nome do servidor SMTP padrão de seu domínio. Geralmente há em
pelo menos um servidor SMTP por domínio. Para entregar a mensagem, o servidor SMTP de Alice deve encontrar o servidor SMTP que
contém a caixa de correio de Bob. Isso pode ser feito usando os registros Mail eXchange (MX) do DNS. Um conjunto de MX
registros podem ser associados a cada domínio. Cada registro MX contém uma preferência numérica e o nome totalmente qualificado
nome de domínio de um servidor SMTP que é capaz de entregar mensagens de e-mail destinadas a todos os endereços de e-mail válidos deste
domínio. O DNS pode retornar vários registros MX para um determinado domínio. Neste caso, o servidor com menor
a preferência é usada primeiro. Se este servidor não estiver acessível, o segundo servidor preferido será usado, etc. SMTP de Bob
O servidor armazenará a mensagem enviada por Alice até que Bob a recupere usando uma interface de webmail ou protocolos como o
Post Office Protocol (POP) ou Internet Message Access Protocol (IMAP).

42 Capítulo 3. A Camada de Aplicação


URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 3.14: Protocolos de entrega de e-mail

O protocolo simples de transferência de correio

O Simple Mail Transfer Protocol (SMTP) definido na RFC 5321 é um protocolo cliente-servidor. A especificação SMTP distingue entre
cinco tipos de processos envolvidos na entrega de mensagens de e-mail. Mensagens de e-mail
são compostos em um Mail User Agent (MUA). O MUA geralmente é um cliente de e-mail ou webmail. O UA
envia a mensagem de email para um Mail Submission Agent (MSA). O MSA processa o e-mail recebido e encaminha
para o Agente de Transmissão de Correio (MTA). O MTA é responsável pela transmissão do email, direta ou
via MTAs intermediários para o MTA do domínio de destino. Este MTA de destino encaminhará então a mensagem para o Mail Delivery
Agent (MDA), onde será acessada pelo MUA do destinatário. SMTP é usado para
interações entre MUA e MSA 13, MSA-MTA e MTA-MTA.

SMTP é um protocolo baseado em texto como muitos outros protocolos de camada de aplicação na Internet. Depende do serviço de fluxo
de bytes. Os servidores escutam na porta 25. Os clientes enviam comandos compostos cada um por uma linha de ASCII
texto finalizado por CR+LF. Os servidores respondem enviando linhas ASCII que contêm um erro/sucesso numérico de três dígitos
código e comentários opcionais.

O protocolo SMTP, como a maioria dos protocolos baseados em texto, é especificado como BNF. A BNF completa é definida na RFC 5321.
Os principais comandos SMTP são definidos pelas regras BNF mostradas na figura abaixo.

Figura 3.15: Especificação BNF dos comandos SMTP

Nesta BNF, atext corresponde a caracteres ASCII imprimíveis. Esta regra BNF é definida na RFC 5322. Os cinco
14
os comandos principais são EHLO, MAIL FROM:, RCPT TO:, DATA e QUIT . Postmaster é o apelido do sistema
administrador responsável por um determinado domínio ou servidor SMTP. Todos os domínios devem ter um alias Postmaster.

As respostas SMTP são definidas pelo BNF mostrado na figura abaixo.

Figura 3.16: Especificação BNF das respostas SMTP

Os servidores SMTP usam códigos de resposta estruturados contendo três dígitos e um comentário opcional. O primeiro dígito de
13
Durante os últimos anos, muitos provedores de serviços de Internet, redes de campus e empresas implantaram extensões SMTP RFC 4954 sobre
seus MSAs. Essas extensões forçam a autenticação dos MUAs antes que o MSA aceite uma mensagem de e-mail do MUA.
14
As primeiras versões do SMTP usavam HELO como o primeiro comando enviado por um cliente a um servidor SMTP. Quando o SMTP foi estendido para suportar
recursos mais recentes, como caracteres de 8 bits, era necessário permitir que um servidor reconhecesse se estava interagindo com um cliente que suportasse
as extensões ou não. A EHLO tornou-se obrigatória com a publicação da RFC 2821.

3.2. Protocolos em nível de aplicativo Saylor 43

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

o código de resposta indica se o comando foi bem-sucedido ou não. Um código de resposta 2xy indica que o comando foi aceito.
Um código de resposta 3xy indica que o comando foi aceito, mas são esperadas informações adicionais do cliente. Um código
de resposta 4xy indica uma resposta negativa transitória. Isso significa que, por algum motivo, indicado pelos outros dígitos ou
pelo comentário, o comando não pode ser processado imediatamente, mas há alguma esperança de que o problema seja apenas
temporário. Basicamente, isso diz ao cliente para tentar o mesmo comando novamente mais tarde. Por outro lado, um código de
resposta 5xy indica uma falha ou erro permanente. Nesse caso, é inútil para o cliente tentar novamente o mesmo comando
posteriormente. Outros protocolos da camada de aplicação, como FTP RFC 959 ou HTTP RFC 2616 usam uma estrutura
semelhante para seus códigos de resposta. Detalhes adicionais sobre os outros códigos de resposta podem ser encontrados na
RFC 5321.

Exemplos de códigos de resposta SMTP incluem o seguinte:

500 Erro de sintaxe, comando não reconhecido 501 Erro de sintaxe


em parâmetros ou argumentos 502 Comando não implementado 503
Sequência incorreta de comandos 220
<domínio> Serviço pronto 221 <domínio> Serviço
fechando canal de transmissão 421 <domínio>
Serviço não disponível, fechando canal de transmissão 250 Correio solicitado ação
correta, concluída 450 Ação de correio solicitada não executada: caixa de correio indisponível 452 Ação
solicitada não executada: armazenamento de sistema insuficiente 550
Ação solicitada não executada: caixa de correio indisponível 354 Iniciar entrada de correio; termine
com <CRLF>.<CRLF>

Os primeiros quatro códigos de resposta correspondem a erros nos comandos enviados pelo cliente. O quarto código de resposta
seria enviado pelo servidor quando o cliente envia comandos em uma ordem incorreta (por exemplo, o cliente tenta enviar um
email antes de fornecer o endereço de destino da mensagem). O código de resposta 220 é usado pelo servidor como a primeira
mensagem quando concorda em interagir com o cliente. O código de resposta 221 é enviado pelo servidor antes de fechar a
conexão de transporte subjacente. O código de resposta 421 é retornado quando há um problema (por exemplo, falta de recursos
de memória/disco) que impede o servidor de aceitar a conexão de transporte. O código de resposta 250 é a resposta positiva
padrão que indica o sucesso do comando anterior. Os códigos de resposta 450 e 452 indicam que a caixa postal de destino está
temporariamente indisponível, por vários motivos, enquanto o código de resposta 550 indica que a caixa postal não existe ou não
pode ser usada por motivos políticos. O código de resposta 354 indica que o cliente pode começar a transmitir sua mensagem de email.

A transferência de uma mensagem de email é realizada em três fases. Durante a primeira fase, o cliente abre uma conexão de
transporte com o servidor. Uma vez estabelecida a conexão, o cliente e o servidor trocam mensagens de saudação (comando
EHLO). A maioria dos servidores insiste em receber mensagens de saudação válidas e alguns deles interrompem a conexão de
transporte subjacente se não receberem uma saudação válida. Depois que as saudações forem trocadas, a fase de transferência
do e-mail pode começar. Durante esta fase, o cliente transfere uma ou mais mensagens de email indicando o endereço de email
do remetente (comando MAIL FROM:), o endereço de email do destinatário (comando RCPT TO:) seguido dos cabeçalhos e do
corpo da mensagem de email (comando DADOS). Assim que o cliente terminar de enviar todas as mensagens de e-mail
enfileiradas para o servidor SMTP, ele encerra a associação SMTP (comando QUIT).

Uma transferência bem-sucedida de uma mensagem de e-mail é mostrada abaixo

S: 220 smtp.example.com ESMTP MTA information C: EHLO mta.example.org


S: 250 Olá mta.example.org, prazer em
conhecê-lo C: MAIL FROM:<alice@example.org> S: 250 Ok

C: RCPT PARA:<bob@example.com> S: 250


Ok
C: DADOS
S: 354 Finalize os dados com <CR><LF>.<CR><LF>
C: De: "Alice Doe" <alice@example.org> C: Para: Bob Smith
<bob@example.com> C: Data: Seg, 9 de março de 2010
18:22:32 +0100 C: Assunto: Olá

C:
C: Olá Bob
C: Esta é uma pequena mensagem contendo 4 linhas de texto.
C: Atenciosamente,

44 Capítulo 3. A Camada de Aplicação The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

C: Alice
C: .
S: 250 Ok: na fila como 12345
C: SAIR
S: 221 Tchau

No exemplo acima, o MTA em execução em mta.example.org abre uma conexão TCP com o servidor SMTP no host
smtp.example.com. As linhas prefixadas com S: (resp. C:) são as respostas enviadas pelo servidor (resp. os comandos enviados
pelo cliente). O servidor envia suas saudações assim que a conexão TCP for estabelecida. O cliente então envia o comando
EHLO com seu nome de domínio totalmente qualificado. O servidor responde com o código de resposta 250 e envia suas
saudações. A associação SMTP agora pode ser usada para trocar um email.

Para enviar um email, o cliente deve primeiro fornecer o endereço do destinatário com RCPT TO:. Em seguida, utiliza MAIL
FROM: com o endereço do remetente. Tanto o destinatário quanto o remetente são aceitos pelo servidor. O cliente agora pode
emitir o comando DATA para iniciar a transferência da mensagem de email. Após receber o código de resposta 354, o cliente
envia os cabeçalhos e o corpo da sua mensagem de email. O cliente indica o final da mensagem. caractere (ponto) 15. O servidor
o que está na fila para entrega ou confirma que a mensagem de e-mail foi enviada enviando uma linha contendo apenas
transmissão com um código de resposta 250. O cliente emite o comando QUIT para encerrar a sessão e o servidor confirma com
resposta -code 221, antes de fechar a conexão TCP.

Nota: Abra retransmissões SMTP e spam

Desde a sua criação em 1971, o e-mail tem sido uma ferramenta muito útil, utilizada por muitos usuários para trocar muitas
informações. No início, todos os servidores SMTP eram abertos e qualquer pessoa podia usá-los para encaminhar e-mails ao
seu destino final. Infelizmente, ao longo dos anos, alguns usuários inescrupulosos encontraram maneiras de usar o e-mail para
fins de marketing ou para enviar malware. O primeiro abuso documentado de e-mail para fins de marketing ocorreu em 1978,
quando um profissional de marketing que trabalhava para um fornecedor de computadores enviou um e-mail de marketing para
muitos usuários da ARPANET. Naquela época, a ARPANET só podia ser usada para fins de pesquisa e isso era um abuso da
política de uso aceitável. Infelizmente, dado o custo extremamente baixo do envio de e-mails, o problema dos e-mails não
solicitados não parou. E-mails não solicitados agora são chamados de spam e um estudo realizado pela ENISA em 2009 revela
que 95% dos emails eram spam e esse número parece continuar a crescer. Isto sobrecarrega a infraestrutura de e-mail dos
provedores de serviços de Internet e das grandes empresas que precisam processar muitas mensagens inúteis.

Dada a quantidade de mensagens de spam, os servidores SMTP não estão mais abertos à RFC 5068. Várias extensões do
SMTP foram desenvolvidas nos últimos anos para lidar com esse problema. Por exemplo, o esquema de autenticação SMTP
definido na RFC 4954 pode ser usado por um servidor SMTP para autenticar um cliente. Várias técnicas também foram propostas
para permitir que servidores SMTP autentiquem as mensagens enviadas por seus usuários RFC 4870 RFC 4871 .

O protocolo dos correios

Quando as primeiras versões do SMTP foram projetadas, a Internet era composta por minicomputadores usados por todo um
departamento universitário ou laboratório de pesquisa. Esses minicomputadores eram usados por muitos usuários ao mesmo tempo.
O e-mail era usado principalmente para enviar mensagens de um usuário em um determinado host para outro usuário em um
host remoto. Naquela época, o SMTP era o único protocolo envolvido na entrega dos e-mails, pois todos os hosts conectados à
rede executavam um servidor SMTP. Nesses hosts, um e-mail destinado a usuários locais era entregue colocando-o em um
diretório ou arquivo especial de propriedade do usuário. No entanto, a introdução dos computadores pessoais na década de 1980
mudou esse ambiente. Inicialmente, os usuários desses computadores pessoais usavam aplicativos como o telnet para abrir uma
sessão remota no minicomputador local para ler seus e-mails. Isso não era fácil de usar. Uma solução melhor apareceu com o
desenvolvimento de aplicativos clientes de e-mail fáceis de usar em computadores pessoais. Vários protocolos foram projetados
para permitir que esses aplicativos clientes recuperassem as mensagens de e-mail destinadas a um usuário de seu servidor.
Dois desses protocolos tornaram-se populares e ainda são usados hoje. O Post Office Protocol (POP), definido na RFC 1939, é
o mais simples. Permite que um cliente baixe todas as mensagens destinadas a um determinado usuário de seu servidor de e-
mail. Descrevemos brevemente o POP nesta seção. O segundo protocolo é o Internet Message Access Protocol (IMAP), definido
na RFC 3501. O IMAP é mais poderoso, mas também mais complexo que o POP. O IMAP foi projetado para permitir que
aplicativos clientes acessem de forma eficiente e em tempo real mensagens armazenadas em várias pastas em servidores. IMAP
15
Isto implica que uma mensagem de e-mail válida não pode conter uma linha com um ponto seguido de CR e LF. Se um usuário digitar tal linha em um e-mail,
seu cliente de e-mail adicionará automaticamente um caractere de espaço antes ou depois do ponto ao enviar a mensagem por SMTP.

3.2. Protocolos em nível de aplicativo 45

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

assume que todas as mensagens de um determinado usuário estão armazenadas em um servidor e fornece as funções necessárias
para pesquisar, baixar, excluir ou filtrar mensagens.

POP é outro exemplo de protocolo simples baseado em linha. O POP é executado acima do serviço bytestream. Um servidor POP
geralmente escuta a porta 110. Uma sessão POP é composta de três partes: uma fase de autorização durante a qual
o servidor verifica a credencial do cliente, uma fase de transação durante a qual o cliente baixa mensagens e um
fase de atualização que conclui a sessão. O cliente envia comandos e as respostas do servidor são prefixadas por +OK
para indicar um comando bem-sucedido ou por -ERR para indicar erros.

Quando um cliente abre uma conexão de transporte com o servidor POP, este envia como banner uma linha ASCII começando
com + OK. A sessão POP está nesse momento na fase de autorização. Nesta fase o cliente pode enviar seu
nome de usuário (resp. senha) com o comando USER (resp. PASS). O servidor responde com +OK se o nome de usuário
(resp. senha) é válido e -ERR caso contrário.

Uma vez validados o nome de usuário e a senha, a sessão POP entra na fase de transação. Nisso
fase, o cliente pode emitir vários comandos. O comando STAT é usado para recuperar o status do servidor.
Ao receber este comando, o servidor responde com uma linha que contém +OK seguida do número de
mensagens na caixa de correio e o tamanho total da caixa de correio em bytes. O comando RETR, seguido de um espaço e
um número inteiro, é usado para recuperar a enésima mensagem da caixa de correio. O comando DELE é usado para marcar para exclusão
a enésima mensagem da caixa de correio.

Depois que o cliente tiver recuperado e possivelmente excluído os e-mails contidos na caixa de correio, ele deverá emitir o QUIT
comando. Este comando encerra a sessão POP e permite ao servidor excluir todas as mensagens que foram
foi marcado para exclusão usando o comando DELE.

A figura abaixo fornece uma sessão POP simples. Todas as linhas prefixadas com C: (resp. S:) são enviadas pelo cliente (resp.
servidor).

S: +OK Servidor POP3 pronto


C: USUÁRIO Alice
S: + OK
C PASSE 12345 passe
S: +OK, o maildrop de Alice tem 2 mensagens (620 octetos)
C: ESTADO

S: + OK 2 620
C: LISTA
S: +OK 2 mensagens (620 octetos)
S: 1 120
S: 2 500
S: .
C: RETR 1
S: +OK 120 octetos
S: <o servidor POP3 envia a mensagem 1>
S: .
C: DELE 1
S: +OK mensagem 1 excluída
C: DESISTIR

S: +OK servidor POP3 desconectando (1 mensagem restante)

Neste exemplo, um cliente POP contata um servidor POP em nome da usuária chamada Alice. Observe que neste exemplo,
A senha da Alice é enviada de forma clara pelo cliente. Isto implica que se alguém for capaz de capturar os pacotes enviados por
Alice, ele saberá a senha 16 de Alice . Então o cliente de Alice emite o comando STAT para saber o número de
mensagens armazenadas em sua caixa de correio. Em seguida, ele recupera e exclui a primeira mensagem da caixa de correio.

3.2.3 O protocolo de transferência de hipertexto

Nos primórdios da Internet, a Internet era usada principalmente para acesso remoto a terminais com telnet, e-mail e transferência de arquivos.
O protocolo de transferência de arquivos padrão, FTP, definido na RFC 959 foi amplamente utilizado e clientes e servidores FTP ainda são
incluído na maioria dos sistemas operacionais.

16

RFC 1939 define o esquema de autenticação APOP que não é vulnerável a tais ataques.

46 Capítulo 3. A Camada de Aplicação

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Muitos clientes FTP oferecem uma interface de usuário semelhante a um shell Unix e permitem que o cliente navegue no sistema de
arquivos no servidor e envie e recupere arquivos. Os servidores FTP podem ser configurados em dois modos:

• autenticado: neste modo o servidor FTP só aceita usuários com nome de usuário e senha válidos. Uma vez
autenticados, eles podem acessar os arquivos e diretórios de acordo com suas permissões

anônimo: neste modo, os clientes fornecem o ID do usuário anônimo e seu endereço de e-mail como senha. Esses clientes
recebem acesso a uma zona especial do sistema de arquivos que contém apenas arquivos públicos.

O FTP era muito popular na década de 1990 e no início de 2000, mas hoje foi substituído em grande parte por protocolos mais recentes.
O acesso autenticado aos arquivos é feito principalmente usando o Secure Shell (ssh) protocolo definido em RFC 4251 e suportado por
clientes como scp ou sftp. Hoje em dia, o acesso anônimo é fornecido principalmente por protocolos web.

No final da década de 1980, físicos de altas energias que trabalhavam no CERN tiveram que trocar documentos de forma eficiente sobre
seus experimentos em andamento e planejados. Tim Berners-Lee avaliou diversas técnicas de compartilhamento de documentos
disponíveis naquela época [B1989]. Como nenhuma das soluções existentes atendeu aos requisitos do CERN, eles optaram por
desenvolver um sistema de compartilhamento de documentos completamente novo. Este sistema foi inicialmente chamado de malha, mas
foi rapidamente renomeado como rede mundial de computadores. O ponto de partida para a rede mundial de computadores são os
documentos de hipertexto. Um documento hipertexto é um documento que contém referências (hiperlinks) a outros documentos que o
leitor pode acessar imediatamente. O hipertexto não foi inventado para a rede mundial de computadores. A ideia de documentos de
hipertexto foi proposta em 1945 [Bush1945] e os primeiros experimentos foram feitos durante a década de 1960 [Nelson1965]
[Myers1998] . Em comparação com os documentos de hipertexto utilizados no final da década de 1980, a principal inovação introduzida
pela rede mundial de computadores foi permitir hiperlinks para referenciar documentos armazenados em máquinas remotas.

Figura 3.17: Clientes e servidores da World Wide Web

Um sistema de compartilhamento de documentos como a rede mundial de computadores é composto de três partes importantes.

1. Um esquema de endereçamento padronizado que permite a identificação inequívoca de documentos

2. Um formato de documento padrão: a linguagem de marcação de hipertexto

3. Um protocolo padronizado que facilita a recuperação eficiente de documentos armazenados em um servidor

Nota: Padrões abertos e implementações abertas

Os padrões abertos desempenharam e ainda desempenham um papel fundamental no sucesso da rede mundial de computadores como
a conhecemos hoje. Sem padrões abertos, a rede mundial de computadores nunca teria atingido o tamanho atual. Além dos padrões
abertos, outro fator importante para o sucesso da web foi a disponibilidade de implementações abertas e eficientes desses padrões.
Quando o CERN começou a trabalhar na web, seu objetivo era construir um sistema em execução que pudesse ser usado por físicos.
Eles desenvolveram implementações de código aberto dos primeiros servidores web e clientes da web. Essas implementações de código
aberto eram poderosas e podiam ser usadas como estão, por instituições dispostas a

3.2. Protocolos em nível de aplicativo 47

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

compartilhar informações na web. Eles também foram estendidos por outros desenvolvedores que contribuíram com novos recursos. Para
exemplo, NCSA adicionou suporte para imagens em seu navegador Mosaic que acabou sendo usado para criar o Netscape
Comunicações.

Os primeiros componentes da rede mundial de computadores são os Identificadores Uniformes de Recursos (URI), definidos na RFC 3986. A
URI é uma sequência de caracteres que identifica inequivocamente um recurso na rede mundial de computadores. Aqui está um subconjunto do
BNF para URIs

TIPO = esquema ":" "//" caminho de autoridade [ "?" consulta ] [fragmento "#"]
esquema =ALFA *(ALFA / DÍGITO / "+" / "-" / "." )
autoridade = [userinfo "@"] host [":" porta]
= *( pchar / "/" / "?" )
fragmento = *( pchar / "/" / "?" )
de consulta pchar = não reservado / codificado em pct / subdelims / ":" / "@"
= *( pchar / "/" / "?" )
fragmento = *( pchar / "/" / "?" )
de consulta codificado em pct = "%" HEXDIG HEXDIG
sem reserva = ALPHA / DIGIT / "-" / "." / "_" / "~"
reservado = gen-delims / sub-delims
gen-delims sub- = ":" / "/" / "?" / "#" / "[" / "]" / "@"
delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

O primeiro componente de um URI é o seu esquema. Um esquema pode ser visto como um seletor, indicando o significado do
campos depois dele. Na prática, o esquema geralmente identifica o protocolo da camada de aplicação que deve ser usado pelo cliente
para recuperar o documento, mas nem sempre é o caso. Alguns esquemas não implicam nenhum protocolo e alguns
não indica um documento recuperável 17. O esquema mais frequente é o http que será descrito mais adiante. Um URI
esquema pode ser definido para quase qualquer protocolo da camada de aplicação [#furilist]_. Os caracteres ': e // seguem o
esquema de qualquer URI.

A segunda parte do URI é a autoridade. Com URI recuperável, isso inclui o nome DNS ou o endereço IP
do servidor onde o documento pode ser recuperado usando o protocolo especificado através do esquema. Este nome pode
ser precedido por alguma informação sobre o usuário (por exemplo, um nome de usuário) que está solicitando a informação. Mais cedo
definições do URI permitiram a especificação de um nome de usuário e uma senha antes do caractere @ ( RFC
1738), mas isso agora está obsoleto porque colocar uma senha dentro de um URI é inseguro. O nome do host pode ser seguido
pelo caractere de ponto e vírgula e um número de porta. Um número de porta padrão é definido para alguns protocolos e a porta
número só deve ser incluído no URI se um número de porta não padrão for usado (para outros protocolos, técnicas
como registros DNS de serviço são usados).

A terceira parte do URI é o caminho para o documento. Este caminho é estruturado como nomes de arquivos em um host Unix (mas
isso não significa que os arquivos sejam realmente armazenados dessa forma no servidor). Se o caminho não for especificado, o servidor
retornará um documento padrão. As duas últimas partes opcionais do URI são usadas para fornecer uma consulta e indicar um
parte específica (por exemplo, uma seção de um artigo) do documento solicitado. Exemplos de URIs são mostrados abaixo.

http://tools.ietf.org/html/rfc3986.html
mailto:infobot@example.com?subject=problema atual
http://docs.python.org/library/basehttpserver.html?highlight=http#BaseHTTPServer.BaseHTTPRequestH
telnet://[2001:6a8:3080:3::2]:80/
ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm

O primeiro URI corresponde a um documento denominado rfc3986.html que está armazenado no servidor denominado tools.ietf.org e
pode ser acessado usando o protocolo http em sua porta padrão. O segundo URI corresponde a uma mensagem de email,
com o assunto problema atual, que será enviado ao usuário infobot no domínio exemplo.com. O esquema mailto: URI é
definido na RFC 6068. O terceiro URI faz referência à parte BaseHTTPServer.BaseHTTPRequestHandler do
documento basehttpserver.html que está armazenado no diretório da biblioteca no servidor docs.python.org. Este documento pode
ser recuperado usando o protocolo http. A consulta destaque=http está associada a este URI. O quarto exemplo é um
servidor que opera o telnet protocolo, usa o endereço IPv6 2001:6a8:3080:3::2 e é acessível na porta 80. O último
URI é um tanto especial. A maioria dos usuários presumirá que corresponde a um documento armazenado em cnn.example.com

17
Um exemplo de URI não recuperável é urn:isbn:0-380-81593-1 que é um identificador exclusivo para um livro, por meio do esquema de urna
(ver RFC 3187). É claro que qualquer URI pode ser recuperada através de um servidor dedicado ou de um novo protocolo, mas este não possui protocolo explícito. A
mesma coisa para a tag do esquema (consulte RFC 4151), frequentemente usado em distribuição na Web (consulte RFC 4287 sobre o formato de distribuição Atom).
Mesmo quando o esquema é recuperável (por exemplo, com http'), muitas vezes é usado apenas como um identificador, e não como uma forma de obter um recurso. Ver
http://norman.walsh.name/2006/07/25/namesAndAddresses para uma boa explicação.

48 Capítulo 3. A Camada de Aplicação

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

servidor. Entretanto, para analisar esse URI, é importante lembrar que o caractere @ é usado para separar o nome do usuário do
nome do host na parte de autorização de um URI. Isso implica que o URI aponta para um documento chamado top_story.htm no
host com endereço IPv4 10.0.0.1. O documento será recuperado usando o protocolo FTP com o nome de usuário definido como
cnn.example.com&story=breaking_news.

O segundo componente da word wide web é a HyperText Markup Language (HTML). HTML define o formato dos documentos que
são trocados na web. A primeira versão do HTML foi derivado da Standard Generalized Markup Language (SGML) que foi
padronizada em 1986 pela ISO. SGML foi projetado para permitir que documentos de grandes projetos em setores como governo,
direito ou aeroespacial sejam compartilhados de forma eficiente e legível por máquina. Estas indústrias exigem que os documentos
permaneçam legíveis e editáveis durante dezenas de anos e insistem num formato padronizado suportado por vários fornecedores.
Hoje, a SGML não é mais amplamente utilizado além de aplicações específicas, mas seus descendentes, incluindo HTML e XML ,
estão agora difundidos.

Uma linguagem de marcação é uma forma estruturada de adicionar anotações sobre a formatação do documento dentro do próprio
documento. Exemplos de linguagens de marcação incluem troff, que é usado para escrever as páginas de manual do Unix ou Latex.
HTML usa marcadores para anotar texto e um documento é composto de elementos HTML. Cada elemento geralmente é composto
por três itens: uma tag inicial que potencialmente inclui alguns atributos específicos, algum texto (geralmente incluindo outros
elementos) e uma tag final. Uma tag HTML é uma palavra-chave entre colchetes angulares. A forma genérica de um elemento
HTML é

<tag>Algum texto a ser exibido</tag>

Elementos HTML mais complexos também podem incluir atributos opcionais na tag inicial

<tagtributo1="valor1" atributo2="valor2">algum texto a ser exibido</tag>

O documento HTML mostrado abaixo é composto de duas partes: um cabeçalho, delineado pelos marcadores <head> e </head>,
e um corpo (entre os marcadores <body> e </body>). No exemplo abaixo, o cabeçalho contém apenas um título, mas outros tipos
de informações podem ser incluídos no cabeçalho. O corpo contém uma imagem, algum texto e uma lista com três hiperlinks. A
imagem é incluída na página web indicando seu URI entre colchetes dentro do marcador <img src=”...”>. A imagem pode, é claro,
residir em qualquer servidor e o cliente irá baixá-la automaticamente ao renderizar a página web. O marcador <h1>...</h1> é usado
para especificar o primeiro nível de títulos. O marcador <ul> indica uma lista não numerada enquanto o marcador <li> indica um
item da lista. O <a href=”URI”>texto</a> indica um hiperlink. O texto será sublinhado na página web renderizada e o cliente irá
buscar o URI especificado quando o usuário clicar no link.

Figura 3.18: Uma página HTML simples

Detalhes adicionais sobre as diversas extensões para HTML podem ser encontrados nas especificações oficiais mantido pelo W3C.

O terceiro componente da rede mundial de computadores é o Protocolo de Transporte de Hipertexto (HTTP). HTTP é um protocolo
baseado em texto, no qual o cliente envia uma solicitação e o servidor retorna uma resposta. O HTTP é executado acima do serviço
bytestream e os servidores HTTP escutam por padrão na porta 80. O design do HTTP foi amplamente inspirado nos protocolos de
e-mail da Internet. Cada solicitação HTTP contém três partes:

• um método , que indica o tipo de solicitação, um URI e a versão do protocolo HTTP usado pelo cliente

3.2. Protocolos em nível de aplicativo 49

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• um , que é usado pelo cliente para especificar parâmetros opcionais para a solicitação. Uma linha vazia é usada para
cabeçalho marca o final do cabeçalho

• um documento MIME opcional anexado à solicitação

A resposta enviada pelo servidor também contém três partes:

• uma linha de status , que indica se a solicitação foi bem-sucedida ou não

• uma linha de , que contém informações adicionais sobre a resposta. O cabeçalho da resposta termina com um vazio
cabeçalho.

• um documento MIME

Figura 3.19: Solicitações e respostas HTTP

Vários tipos de métodos podem ser usados em solicitações HTTP. Os três mais importantes são:

• o método GET é o mais popular. É usado para recuperar um documento de um servidor. O


O método GET é codificado como GET seguido pelo caminho do URI do documento solicitado e
a versão do HTTP usada pelo cliente. Por exemplo, para recuperar o http://www.w3.org/MarkUp/
URI, um cliente deve abrir um TCP na porta 80 com o host www.w3.org e enviar uma solicitação HTTP
contendo a seguinte linha

OBTER /Marcação/HTTP/1.0
• – o método HEAD é uma variante do método GET que permite a recuperação do cabeçalho
linhas para um determinado URI sem recuperar o documento inteiro. Ele pode ser usado por um cliente para
verificar se existe um documento, por exemplo.

• o método POST pode ser usado por um cliente para enviar um documento a um servidor. O documento enviado é
anexado à solicitação HTTP como um documento MIME.

Clientes e servidores HTTP podem incluir muitos cabeçalhos HTTP diferentes em solicitações e respostas HTTP. Cada HTTP
O cabeçalho é codificado como uma única linha ASCII terminada por CR e LF. Vários desses cabeçalhos são brevemente descritos
abaixo. Uma discussão detalhada de todos os cabeçalhos padrão pode ser encontrada na RFC 1945. Os cabeçalhos MIME podem aparecer
em solicitações HTTP e respostas HTTP.

• o cabeçalho Content-Length: é o cabeçalho MIME que indica o comprimento do documento MIME em bytes.

• o cabeçalho Content-Type: é o cabeçalho MIME que indica o tipo do documento MIME anexado.
As páginas HTML usam o tipo text/html.

• o cabeçalho Content-Encoding: indica como o documento MIME foi codificado. Por exemplo, este
o cabeçalho seria definido como x-gzip para um documento compactado usando o gzip Programas.

RFC 1945 e RFC 2616 defina cabeçalhos específicos para respostas HTTP. Esses cabeçalhos de servidor incluem:

50 Capítulo 3. A Camada de Aplicação

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• o cabeçalho Servidor: indica a versão do servidor web que gerou a resposta HTTP. Alguns servidores fornecem informações
sobre a versão do software e os módulos opcionais que utilizam. Por motivos de segurança, alguns administradores de
sistema desativam esses cabeçalhos para evitar revelar muitas informações sobre seu servidor a possíveis invasores.

• o cabeçalho Date: indica quando a resposta HTTP foi produzida pelo servidor.

• o cabeçalho Last-Modified: indica a data e hora da última modificação do documento anexado ao


a resposta HTTP.

Da mesma forma, as seguintes linhas de cabeçalho só podem aparecer dentro de solicitações HTTP enviadas por um cliente:

• o cabeçalho User-Agent: fornece informações sobre o cliente que gerou a solicitação HTTP. Alguns servidores analisam esta
linha de cabeçalho e retornam cabeçalhos diferentes e, às vezes, documentos diferentes para diferentes agentes de usuário.

• o cabeçalho If-Modified-Since: é seguido por uma data. Ele permite que os clientes armazenem em cache na memória ou no
disco os documentos recentes ou usados com mais frequência. Quando um cliente precisa solicitar um URI de um servidor,
ele primeiro verifica se o documento já está em seu cache. Se for, o cliente envia uma solicitação HTTP com o cabeçalho If-
Modified-Since: indicando a data do documento em cache. O servidor só retornará o documento anexado à resposta HTTP
se for mais recente que a versão armazenada no cache do cliente.

• o cabeçalho Referrer: é seguido por um URI. Indica o URI do documento que o cliente visitou antes de enviar esta solicitação
HTTP. Graças a este cabeçalho, o servidor pode conhecer o URI do documento que contém o hiperlink seguido pelo cliente,
se houver. Esta informação é muito útil para medir o impacto dos anúncios que contêm hiperlinks colocados em websites.

• o cabeçalho Host: contém o nome de domínio totalmente qualificado do URI que está sendo solicitado.

Nota: A importância da linha de cabeçalho Host:

A primeira versão do HTTP não incluía a linha de cabeçalho Host:. Esta foi uma limitação severa para empresas de hospedagem na
web. Por exemplo, considere uma empresa de hospedagem na web que deseja servir web.example.com e www.example.net no
mesmo servidor físico. Ambos os sites contêm um documento /index.html. Quando um cliente envia uma solicitação para http://
web.example.com/index.html ou http://www.example.net/index.html, a solicitação HTTP 1.0 contém a seguinte linha:

OBTER /index.html HTTP/1.0

Ao analisar esta linha, um servidor não pode determinar qual arquivo index.html é solicitado. Graças à linha de cabeçalho Host:, o
servidor sabe se a solicitação é para http://web.example.com/index.html ou http://www.dummy.net/index.html. Sem o cabeçalho Host:
isso é impossível. A linha de cabeçalho Host: permitiu que as empresas de hospedagem web desenvolvessem seus negócios,
suportando um grande número de servidores web independentes no mesmo servidor físico.

A linha de status da resposta HTTP começa com a versão do HTTP usada pelo servidor (geralmente HTTP/1.0 definida na RFC 1945
ou HTTP/1.1 definido na RFC 2616) seguido por um código de status de três dígitos e informações adicionais em inglês. Os códigos
de status HTTP têm uma estrutura semelhante aos códigos de resposta usados pelo SMTP.

• Todos os códigos de status começando com o dígito 2 indicam uma resposta válida. 200 Ok indica que a solicitação HTTP foi
processado com sucesso pelo servidor e que a resposta é válida.

• Todos os códigos de status começando com o dígito 3 indicam que o documento solicitado não está mais disponível no
servidor. 301 Movido Permanentemente indica que o documento solicitado não está mais disponível neste servidor.
Um cabeçalho Location: contendo o novo URI do documento solicitado é inserido na resposta HTTP.
304 Not Modified é usado em resposta a uma solicitação HTTP contendo o cabeçalho If-Modified-Since:. Esta linha de status
é usada pelo servidor se o documento armazenado no servidor não for mais recente que a data indicada no cabeçalho If-
Modified-Since:.

• Todos os códigos de status começando com o dígito 4 indicam que o servidor detectou um erro na solicitação HTTP enviada
pelo cliente. 400 Bad Request indica um erro de sintaxe na solicitação HTTP. 404 Not Found indica que o documento
solicitado não existe no servidor.

3.2. Protocolos em nível de aplicativo 51

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• Todos os códigos de status começando com o dígito 5 indicam um erro no servidor. 500 Erro interno do servidor indica que
o servidor não conseguiu processar a solicitação devido a um erro no próprio servidor.

Tanto na solicitação HTTP quanto na resposta HTTP, o documento MIME refere-se a uma representação do documento com os
cabeçalhos MIME indicando o tipo de documento e seu tamanho.

Como ilustração do HTTP/1.0, a transcrição abaixo mostra uma solicitação HTTP para http://www.ietf.org e a resposta HTTP
correspondente. A solicitação HTTP foi enviada usando o curl ferramenta de linha de comando. A linha de cabeçalho User-Agent:
contém mais informações sobre este software cliente. Não há nenhum documento MIME anexado a esta solicitação HTTP e ela
termina com uma linha em branco.

Agente de usuário GET /


HTTP/1.0: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.19.4 OpenSSL/0.9.8l zlib/1.2.3 Host: www.ietf.org

A resposta HTTP indica a versão do software do servidor usado com os módulos incluídos. O cabeçalho Last-Modified: indica que
o documento solicitado foi modificado cerca de uma semana antes da solicitação. Um documento HTML (não mostrado) está
anexado à resposta. Observe a linha em branco entre o cabeçalho da resposta HTTP e o documento MIME anexado. A linha de
cabeçalho Servidor: foi truncada nesta saída.

HTTP/1.1 200 OK Data:


Seg, 15 de março de 2010 13:40:38 GMT Servidor: Apache/
2.2.4 (Linux/SUSE) mod_ssl/2.2.4 OpenSSL/0.9.8e (truncado)
Última modificação: terça, 09 de março de 2010 21:26:53 GMT Comprimento
do conteúdo: 17019 Tipo de conteúdo:
texto/html

<!DOCTYPE HTML PUBLIC .../HTML>

O HTTP foi inicialmente projetado para compartilhar documentos de texto independentes. Por esta razão, e para facilitar a
implementação de clientes e servidores, os projetistas do HTTP optaram por abrir uma conexão TCP para cada solicitação HTTP.
Isto implica que um cliente deve abrir uma conexão TCP para cada URI que deseja recuperar de um servidor conforme ilustrado
na figura abaixo. Para uma página web contendo apenas documentos de texto, esta foi uma escolha de design razoável, já que o
cliente geralmente permanece ocioso enquanto o usuário (humano) lê o documento recuperado.

Figura 3.20: HTTP 1.0 e a conexão TCP subjacente

Entretanto, à medida que a web evoluiu para suportar documentos mais ricos contendo imagens, abrir uma conexão TCP para
cada URI tornou-se um problema de desempenho [Mogul1995]. Na verdade, além da parte HTML, uma página web pode incluir
dezenas de imagens ou mais. Forçar o cliente a abrir uma conexão TCP para cada componente de uma página web tem duas
desvantagens importantes. Primeiro, o cliente e o servidor devem trocar pacotes para abrir e fechar uma conexão TCP, como
veremos mais adiante. Isso aumenta a sobrecarga da rede e o atraso total na recuperação completa de todos os componentes de
uma página da web. Segundo, um grande número de conexões TCP estabelecidas pode ser um gargalo de desempenho nos
servidores.

Este problema foi resolvido estendendo o HTTP para suportar conexões TCP persistentes RFC 2616. Uma conexão persistente é
uma conexão TCP pela qual um cliente pode enviar várias solicitações HTTP. Isto é ilustrado na figura abaixo.

52 Capítulo 3. A Camada de Aplicação The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 3.21: Conexões persistentes HTTP 1.1

Para permitir que clientes e servidores controlem a utilização dessas conexões TCP persistentes, HTTP 1.1 RFC 2616 define vários
novos cabeçalhos HTTP:

• O cabeçalho Connection: é usado com o argumento Keep-Alive pelo cliente para indicar que ele espera que a conexão TCP
subjacente seja persistente. Quando este cabeçalho é usado com o argumento Close, indica que a entidade que o enviou
fechará a conexão TCP subjacente no final da resposta HTTP.

• O cabeçalho Keep-Alive: é usado pelo servidor para informar ao cliente como ele concorda em usar a conexão persistente. Um
Keep-Alive típico: contém dois parâmetros: o número máximo de solicitações que o servidor concorda em atender na conexão
TCP subjacente e o tempo limite (em segundos) após o qual o servidor fechará uma conexão inativa.

O exemplo abaixo mostra a operação de HTTP/1.1 em uma conexão TCP persistente para recuperar três URIs armazenados no mesmo
servidor. Uma vez estabelecida a conexão, o cliente envia sua primeira solicitação com o cabeçalho Connection: keep-alive para solicitar
uma conexão persistente.

OBTER/HTTP/1.1
Anfitrião: www.kame.net
Agente do usuário: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us)
Conexão: keep-alive

O servidor responde com o cabeçalho Connection: Keep-Alive e indica que aceita no máximo 100 solicitações HTTP nesta conexão e
que fechará a conexão se permanecer inativa por 15 segundos.

HTTP/1.1 200 OK Data:


Sex, 19 de março de 2010 09:23:37 GMT Servidor:
Apache/2.0.63 (FreeBSD) PHP/5.2.12 com Suhosin-Patch Keep-Alive: timeout=15, max=100
Conexão: Comprimento do conteúdo Keep-Alive:
3462 Tipo de conteúdo: texto/html

<html>... </html>

O cliente envia uma segunda solicitação para a folha de estilos da página da web recuperada.

OBTER /style.css Host HTTP/1.1:


www.kame.net
Referer: http://www.kame.net/ User-Agent:
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us)
Conexão: keep-alive

3.2. Protocolos em nível de aplicativo 53

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O servidor responde com a folha de estilo solicitada e mantém a conexão persistente. Observe que o servidor aceita apenas
99 solicitações HTTP restantes nesta conexão persistente.

HTTP/1.1 200 OK
Data: Sexta-feira, 19 de março de 2010 09:23:37 GMT Servidor:
Apache/2.0.63 (FreeBSD) PHP/5.2.12 com Suhosin-Patch Última modificação: Seg, 10 de abril de 2006
05:06:39 GMT Content-Length : 2235 Keep-Alive: timeout=15, max=99 Conexão:
Keep-Alive Content-Type: text/css

...

Em seguida, o cliente solicita automaticamente o ícone do servidor18 , que pode ser exibido pelo navegador. Este servidor
web
não contém tal URI e, portanto, responde com um status HTTP 404. No entanto, a conexão TCP subjacente não é fechada
imediatamente.

OBTER /favicon.ico HTTP/1.1


Anfitrião: www.kame.net
Referer: http://www.kame.net/ User-Agent:
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us)
Conexão: keep-alive

HTTP/1.1 404 Data não encontrada:


Sex, 19 de março de 2010 09:23:40 GMT Servidor:
Apache/2.0.63 (FreeBSD) PHP/5.2.12 com Suhosin-Patch Content-Length: 318 Keep-Alive:
timeout=15 , max=98
Conexão: Keep-Alive Content-Type: text/html;
conjunto de caracteres=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> ...

Conforme ilustrado acima, um cliente pode enviar várias solicitações HTTP pela mesma conexão TCP persistente. Entretanto,
é importante observar que todas essas solicitações HTTP são consideradas independentes pelo servidor. Cada solicitação
HTTP deve ser independente. Isso implica que cada solicitação deve incluir todas as linhas de cabeçalho exigidas pelo servidor
para compreender a solicitação. A independência dessas solicitações é uma das escolhas importantes de design do HTTP.
Como consequência desta escolha de design, quando um servidor processa uma solicitação HTTP, ele não usa nenhuma
outra informação além daquela contida na própria solicitação. Isso explica por que o cliente adiciona seu cabeçalho User-
Agent: em todas as solicitações HTTP que envia pela conexão TCP persistente.

Porém, na prática, alguns servidores desejam fornecer conteúdo ajustado para cada usuário. Por exemplo, alguns servidores
podem fornecer informações em vários idiomas ou outros servidores desejam fornecer anúncios direcionados a diferentes
tipos de usuários. Para fazer isso, os servidores precisam manter algumas informações sobre as preferências de cada usuário
e usar essas informações para produzir conteúdo que corresponda às preferências do usuário. HTTP contém vários
mecanismos que permitem resolver este problema. Discutimos três deles abaixo.

Uma primeira solução é forçar a autenticação dos usuários. Essa foi a solução utilizada pelo FTP para controlar os arquivos
que cada usuário poderia acessar. Inicialmente, nomes de usuários e senhas poderiam ser incluídos nos URIs RFC 1738. No
entanto, colocar senhas em um URI potencialmente visível publicamente é completamente inseguro e esse uso agora foi
descontinuado RFC 3986. HTTP suporta vários cabeçalhos de extensão RFC 2617 que pode ser utilizado por um servidor
para solicitar a autenticação do cliente, fornecendo suas credenciais. No entanto, nomes de usuário e senhas não são
populares em servidores web, pois forçam os usuários humanos a lembrar um nome de usuário e uma senha por servidor.
Lembrar uma senha é aceitável quando um usuário precisa acessar conteúdo protegido, mas os usuários não aceitarão a
necessidade de um nome de usuário e senha apenas para receber anúncios direcionados dos sites que visitam.

Uma segunda solução para permitir que os servidores ajustem esse conteúdo às necessidades e capacidades do usuário é
contar com os diferentes tipos de cabeçalhos HTTP Accept-*. Por exemplo, o Accept-Language: pode ser usado pelo cliente para
18
Ícones favoritos são pequenos ícones usados para representar servidores web na barra de ferramentas dos navegadores da Internet. A Microsoft adicionou esse
recurso em seus navegadores sem levar em consideração os padrões W3C. Consulte http://www.w3.org/2005/10/howto-favicon para uma discussão sobre como
oferecer suporte limpo a esses ícones favoritos.

54 Capítulo 3. A Camada de Aplicação The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

indicar seus idiomas preferidos. Infelizmente, na prática este cabeçalho é geralmente definido com base no idioma padrão do navegador e
não é possível ao usuário indicar o idioma que prefere usar selecionando opções em cada servidor web visitado.

A terceira solução, e amplamente adotada, são os cookies HTTP. Os cookies HTTP foram inicialmente desenvolvidos como uma extensão
privada pela Netscape. Eles agora fazem parte do padrão RFC 6265. Resumindo, um cookie é uma string curta escolhida por um servidor
para representar um determinado cliente. Dois cabeçalhos HTTP são usados: Cookie: e Set-Cookie:. Quando um servidor recebe uma
solicitação HTTP de um novo cliente (ou seja, uma solicitação HTTP que não contém o cabeçalho Cookie:), ele gera um cookie para o
cliente e o inclui no cabeçalho Set-Cookie: da resposta HTTP retornada. O cabeçalho Set-Cookie: contém vários parâmetros adicionais,
incluindo os nomes de domínio para os quais o cookie é válido. O cliente armazena em disco todos os cookies recebidos e sempre que
envia uma solicitação HTTP verifica se já conhece algum cookie para este domínio. Nesse caso, ele anexa o cabeçalho Cookie: à solicitação
HTTP. Isto é ilustrado na figura abaixo com HTTP 1.1, mas os cookies também funcionam com HTTP 1.0.

Figura 3.22: Cookies HTTP

Nota: Problemas de privacidade com cookies HTTP

Os cookies HTTP introduzidos pela Netscape são essenciais para grandes sites de comércio eletrônico. No entanto, eles também levantaram
muitas discussões sobre seus possíveis usos indevidos. Considere ad.com, uma empresa que oferece muitos anúncios em sites. Um site
que deseja incluir anúncios do ad.com próximo ao seu conteúdo adicionará links para o ad.com em suas páginas HTML. Se o ad.com for
usado por muitos sites, o ad.com poderá rastrear os interesses de todos os usuários que visitam os sites de seus clientes e usar essas
informações para fornecer anúncios direcionados.
Os defensores da privacidade até processaram empresas de publicidade online para forçá-las a cumprir os regulamentos de privacidade.
Tecnologias relacionadas mais recentes também levantam preocupações com a privacidade

3.3 Escrevendo aplicações simples em rede


Os aplicativos em rede geralmente eram implementados usando a API de soquete. Esta API foi projetada quando o TCP/IP foi implementado
pela primeira vez no Unix BSD sistema operacional [Sechrest] [LFJLMT] e serviu de modelo para muitas APIs entre aplicativos e a pilha de
rede em um sistema operacional. Embora a API de soquete seja muito popular, outras APIs também foram desenvolvidas. Por exemplo, a
API STREAMS foi adicionada a diversas variantes do Unix System V [Rago1993]. A API de soquete é suportada pela maioria das linguagens
de programação e vários livros foram dedicados a ela. Os usuários da linguagem C podem consultar [DC2009], [Stevens1998], [SFR2004]
ou [Kerrisk2010]. A implementação Java da API de soquete é descrita em [CD2008] e no tutorial Java. Nesta seção, usaremos o python
implementação do soquete API para ilustrar os principais conceitos. Informações adicionais sobre esta API podem ser encontradas na
seção de soquete da documentação do python
.

3.3. Escrevendo aplicativos simples em rede Saylor URL: 55

http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

A API do soquete é de baixo nível e deve ser usada somente quando você precisar de controle completo do acesso à rede. Se o seu
aplicativo simplesmente precisa, por exemplo, recuperar dados com HTTP, existem APIs muito mais simples e de nível superior.

Uma discussão detalhada da API de soquete está fora do escopo desta seção e as referências citadas acima fornecem uma discussão
detalhada de todos os detalhes da API de soquete. Como ponto de partida, é interessante comparar a API do soquete com as
primitivas de serviço que discutimos no capítulo anterior. Consideremos primeiro o serviço sem conexão que consiste nas duas
primitivas a seguir:

• DATA.request(destination,message) é usado para enviar uma mensagem para um destino especificado. Nesta API de soquete,
isso corresponde ao método send.

• DATA.indication(message) é emitido pelo serviço de transporte para entregar uma mensagem à aplicação. Na API do soquete,
isso corresponde ao retorno do método recv que é chamado pela aplicação.

As primitivas DATA são trocadas através de um ponto de acesso de serviço. Na API de soquete, o equivalente ao ponto de acesso
de serviço é o soquete. Um soquete é uma estrutura de dados mantida pela pilha de rede e usada pelo aplicativo sempre que precisa
enviar ou receber dados por meio da pilha de rede. O método socket em python A API leva dois argumentos principais:

• uma família de endereços que especifica o tipo de família de endereços e, portanto, a pilha de rede subjacente que será usada
com o soquete. Este parâmetro pode ser socket.AF_INET ou socket.AF_INET6. socket.AF_INET, que corresponde à pilha de
protocolos TCP/IPv4 é o padrão. socket.AF_INET6 corresponde à pilha de protocolos TCP/IPv6.

• um tipo indica o tipo de serviço esperado da pilha de rede. socket.STREAM (o padrão) corresponde ao serviço confiável
orientado à conexão bytestream. socket.DGRAM corresponde ao serviço sem conexão.

Um cliente simples que envia uma solicitação a um servidor geralmente é escrito da seguinte maneira nas descrições da API do soquete.

# Um cliente simples do soquete de importação de serviço sem conexão


import sys
HOSTIP=sys.argv[1]

PORTA=int(sys.argv[2])
MSG="Olá, mundo!" s =
soquete.socket( soquete.AF_INET, soquete.SOCK_DGRAM) s.sendto(MSG, (HOSTIP,
PORTA))

Um uso típico deste aplicativo seria

cliente python.py 127.0.0.1 12345

onde 127.0.0.1 é o endereço IPv4 do host (neste caso, o localhost) onde o servidor está rodando e 12345 é a porta do servidor.

A primeira operação é a criação do soquete. Dois parâmetros devem ser especificados ao criar um soquete.
O primeiro parâmetro indica a família de endereços e o segundo o tipo de soquete. A segunda operação é a transmissão da
mensagem usando sendto para o servidor. Ressalta-se que sendto toma como argumentos a mensagem a ser transmitida e uma
tupla que contém o endereço IPv4 do servidor e seu número de porta.

O código mostrado acima oferece suporte apenas à pilha de protocolos TCP/IPv4. Para usar a pilha de protocolos TCP/IPv6, o
soquete deve ser criado usando a família de endereços socket.AF_INET6. Forçar o desenvolvedor do aplicativo a selecionar TCP/
IPv4 ou TCP/IPv6 ao criar um soquete é um grande obstáculo para a implantação e uso de TCP/IPv6 na Internet global [Cheshire2010].
Embora a maioria dos sistemas operacionais suporte TCP/IPv4 e TCP/IPv6, muitos aplicativos ainda usam apenas TCP/IPv4 por
padrão. No longo prazo, a API do soquete deve ser capaz de lidar com TCP/IPv4 e TCP/IPv6 de forma transparente e não deve
forçar o desenvolvedor do aplicativo a sempre especificar se usa TCP/IPv4 ou TCP/IPv6.

Outro problema importante com a API de soquete suportada por python é que força o aplicativo a lidar com endereços IP em vez de
lidar diretamente com nomes de domínio. Esta limitação data dos primeiros dias da API de soquete no Unix 4.2BSD. Naquela época,
o DNS não estava amplamente disponível e apenas endereços IP podiam ser usados. A maioria dos aplicativos depende de nomes
DNS para interagir com os servidores e essa utilização do DNS desempenha um papel muito importante para dimensionar servidores
web e redes de distribuição de conteúdo. Para usar nomes de domínio, o aplicativo precisa

56 Capítulo 3. A Camada de Aplicação The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

para realizar a resolução DNS usando o método getaddrinfo. Este método consulta o DNS e constrói a estrutura de dados
sockaddr que é usada por outros métodos da API de soquete. Em píton, getaddrinfo leva vários argumentos:

• um nome que seja o nome de domínio para o qual o DNS será consultado

• um número de porta opcional que é o número da porta do servidor remoto

• uma família de endereços opcional que indica a família de endereços usada para a solicitação DNS. socket.AF_INET
(resp. socket.AF_INET6) indica que um endereço IPv4 (IPv6) é esperado. Além disso, o python A API de soquete
permite que um aplicativo use socket.AF_UNSPEC para indicar que é capaz de usar endereços IPv4 ou IPv6.

• um tipo de soquete opcional que pode ser socket.SOCK_DGRAM ou socket.SOCK_STREAM

Nos hosts da Internet atuais que são capazes de suportar IPv4 e IPv6, todos os aplicativos devem ser capazes de lidar com
endereços IPv4 e IPv6. Quando utilizado com o parâmetro socket.AF_UNSPEC, o método socket.getaddrinfo retorna uma
lista de tuplas contendo todas as informações para criar um soquete.

importar soquete
socket.getaddrinfo('www.example.net',80,socket.AF_UNSPEC,socket.SOCK_STREAM) [ (30, 1, 6, '', ('2001:db8:3080:3::2', 80 ,
0, 0)),
(2, 1, 6, '', ('203.0.113.225', 80))]

No exemplo acima, socket.getaddrinfo retorna duas tuplas. O primeiro corresponde ao sockaddr contendo o endereço IPv6
do servidor remoto e o segundo corresponde à informação IPv4. Devido a algumas peculiaridades do IPv6 e IPv4, o formato
das duas tuplas não é exatamente o mesmo, mas as principais informações em ambos os casos são o endereço da camada
de rede (2001:db8:3080:3::2 e 203.0.113.225) e o número da porta (80). Os outros parâmetros raramente são usados.

socket.getaddrinfo pode ser usado para construir um cliente simples que consulta o DNS e contata o servidor usando IPv4
ou IPv6 dependendo dos endereços retornados pelo método socket.getaddrinfo. O cliente abaixo percorre a lista de
endereços retornados pelo DNS e envia sua solicitação para o primeiro endereço de destino para o qual pode criar um
soquete. É claro que outras estratégias são possíveis. Por exemplo, um host rodando em uma rede IPv6 pode preferir usar
sempre IPv6 quando o IPv6 estiver disponível 19. Outro exemplo é a abordagem dos olhos felizes que está sendo discutida
na IETF [WY2011]. Por exemplo, [WY2011] menciona que alguns navegadores tentam usar o primeiro endereço retornado
por socket.getaddrinfo. Se não houver resposta dentro de um pequeno atraso (por exemplo, 300 milissegundos), o segundo
endereço será tentado.

importar soquete
importar sys
HOSTNAME=sys.argv[1]
PORTA=int(sys.argv[2])
MSG="Olá, mundo!" para um
em socket.getaddrinfo(HOSTNAME, PORT, socket.AF_UNSPEC,socket.SOCK_DGRAM,0, socket.AI_PASSI address_family,sock_type,protocol,canonicalname,
sockaddr=a tente: s = socket.socket(address_family, sock_type) exceto soquete. erro:

s = Nenhum
print "Não foi possível criar o soquete" continuar

se s não for Nenhum:


s.sendto(MSG, sockaddr) quebra

Agora que descrevemos a utilização da API de soquete para escrever um cliente simples usando o serviço de transporte
sem conexão, vamos dar uma olhada mais de perto no serviço confiável de transporte de fluxo de bytes. Conforme explicado
acima, este serviço é invocado criando um soquete do tipo socket.SOCK_STREAM. Depois que um soquete for criado, um
cliente normalmente se conectará ao servidor remoto, enviará alguns dados, aguardará uma resposta e, eventualmente,
encerrará a conexão. Essas operações são realizadas chamando os seguintes métodos:
19
A maioria dos sistemas operacionais hoje, por padrão, prefere usar IPv6 quando o DNS retorna um endereço IPv4 e um endereço IPv6 para um nome. Ver
http://ipv6int.net/systems/ para obter informações mais detalhadas.

3.3. Escrevendo aplicativos simples em rede Saylor 57

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• socket.connect : este método usa uma estrutura de dados sockaddr, normalmente retornada por socket.getaddrinfo,
como argumento. Pode falhar e gerar uma exceção se o servidor remoto não puder ser alcançado.

• socket.send : este método recebe uma string como argumento e retorna o número de bytes que foram realmente
enviados. A string será transmitida como uma sequência de bytes consecutivos para o servidor remoto. Espera-
se que as aplicações verifiquem o valor retornado por este método e reenviem os bytes que não foram enviados.

• socket.recv : este método recebe como argumento um número inteiro que indica o tamanho do buffer que foi
alocado para receber os dados. Um ponto importante a ser observado sobre a utilização do método socket.recv é
que como ele roda acima de um serviço bytestream, ele pode retornar qualquer quantidade de bytes (até o
tamanho do buffer fornecido pela aplicação). A aplicação precisa coletar todos os dados recebidos e não há
garantia de que alguns dados enviados pelo host remoto usando uma única chamada ao método socket.send
serão recebidos pelo destino com uma única chamada ao método socket.recv.

• socket.shutdown : este método é usado para liberar a conexão subjacente. Em algumas plataformas, é possível
especificar a direção da transferência a ser liberada (por exemplo, socket.SHUT_WR para liberar a direção de
saída ou socket.SHUT_RDWR para liberar ambas as direções).

• socket.close: este método é usado para fechar o soquete. Ele chama socket.shutdown se a conexão subjacente
ainda estiver aberta.

Com esses métodos, agora é possível escrever um cliente HTTP simples. Este cliente opera em IPv6 e IPv4 e grava a
página inicial do servidor remoto na saída padrão. Ele também informa o número de chamadas socket.recv que foram
20
usadas para recuperar a página inicial .

#!/usr/bin/python # Um cliente
http simples que recupera a primeira página de um site

importar soquete, sys

se len(sys.argv)!=3 e len(sys.argv)!=2:
imprima "Uso: ",sys.argv[0]," hostname [porta]"

nome do host = sys.argv[1] se


len(sys.argv)==3 :
porta=int(sys.argv[2])
outro:
porta = 80

READBUF=16384 # tamanho dos dados lidos do servidor web


s=Nenhum

para res em socket.getaddrinfo (nome do host, porta, soquete.AF_UNSPEC, soquete.SOCK_STREAM):


af, socktype, proto, canonname, sa = res # cria soquete

tente:
s = socket.socket(of, tipo de meia, proto)
exceto soquete.error:
s = Nenhum
continuar
#conecta-se ao host remoto
try:
print "Tentando "+sa[0] s.connect(sa)

exceto socket.error, mensagem:


# soquete falhou
s.close() s =
Nenhum
continuar
se for :

20
Experimentos com o cliente indicam que o número de chamadas socket.recv pode variar a cada execução. Existem vários fatores que
influenciam o número dessas chamadas necessárias para recuperar algumas informações de um servidor. Discutiremos alguns deles depois de
explicar a operação do protocolo de transporte subjacente.

58 Capítulo 3. A Camada de Aplicação


URL de Saylor: http://www.saylor.org/courses/cs402/ The Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

print "Conectado a "+sa[0] s.send('GET / HTTP/


1.1\r\nHost:'+hostname+'\r\n\r\n') finalizado=Falso

contagem=0
enquanto não terminou:
dados = s.recv (READBUF)
contagem = contagem + 1
se len(dados)!=0: imprimir
repr(dados)
outro:
finalizado = Verdadeiro
s.shutdown(socket.SHUT_WR) s.close() print
"Dados foram
recebidos em ",count," recv calls" break

Conforme mencionado acima, a API do soquete é de nível muito baixo. Esta é a interface para o serviço de transporte. Para uma
tarefa comum e simples, como recuperar um documento da Web, existem soluções muito mais simples. Por exemplo, a biblioteca
padrão python inclui várias APIs de alto nível para implementações de vários protocolos de camada de aplicação, incluindo HTTP.
Por exemplo, o httplib O módulo pode ser usado para acessar facilmente documentos via HTTP.

#!/usr/bin/python # Um cliente
http simples que recupera a primeira página de um site, usando # a biblioteca httplib padrão

importar httplib, sys

se len(sys.argv)!=3 e len(sys.argv)!=2:
imprima "Uso: ",sys.argv[0]," nome do host [porta]" sys.exit(1)

caminho = '/' nome


do host = sys.argv[1] se len(sys.argv)==3 :

porta = int(sys.argv[2]) senão:

porta = 80

conn = httplib.HTTPConnection(hostname, porta) conn.request("GET", caminho) r =


conn.getresponse() print "A resposta é %i (%s)"
% (r.status, r.reason) print r .ler()

Outro módulo, urllib2 permite que o programador use URLs diretamente. Isso é muito mais simples do que usar soquetes
diretamente.

Mas a simplicidade não é a única vantagem de usar bibliotecas de alto nível. Eles permitem ao programador manipular conceitos
de nível superior (por exemplo, quero que o conteúdo seja apontado por esta URL), mas também incluem muitos recursos, como
suporte transparente para a utilização de TLS ou IPv6.

O segundo tipo de aplicativos que podem ser escritos usando a API de soquete são os servidores. Um servidor normalmente fica
sempre esperando para processar solicitações provenientes de clientes remotos. Um servidor que usa o connectionless normalmente
começará com a criação de um soquete com o socket.socket. Este soquete pode ser criado acima da pilha de rede TCP/IPv4
(socket.AF_INET) ou da pilha de rede TCP/IPv6 (socket.AF_INET6), mas não ambos por padrão. Se um servidor estiver disposto
a usar as duas pilhas de rede, ele deverá criar dois threads, um para lidar com o soquete TCP/IPv4 e outro para lidar com o soquete
TCP/IPv6. Infelizmente, é impossível definir um soquete que possa receber dados de ambas as pilhas de rede ao mesmo tempo
com o python API de soquete.

Um servidor que usa o serviço sem conexão normalmente usará dois métodos da API de soquete além daqueles que já discutimos.

• socket.bind é usado para vincular um soquete a um número de porta e, opcionalmente, a um endereço IP. A maioria dos
servidores vinculará seu soquete a todas as interfaces disponíveis nos servidores, mas há algumas situações em que o servidor

3.3. Escrevendo aplicativos simples em rede Saylor 59

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

pode preferir estar vinculado apenas a endereços IP específicos. Por exemplo, um servidor executado em um
smartphone pode querer estar vinculado ao endereço IP da interface WiFi, mas não à interface 3G, que é mais cara.

• socket.recvfrom é usado para receber dados da pilha de rede subjacente. Este método retorna
tanto o endereço do remetente quanto os dados recebidos.

O código abaixo ilustra um servidor muito simples rodando acima do serviço de transporte sem conexão que
simplesmente imprime na saída padrão todas as mensagens recebidas. Este servidor usa a pilha de rede TCP/IPv6.

importar soquete, sys

PORTA=int(sys.argv[1])
BUFF_LEN=8192

s=socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.bind(('',PORT,0,0))


enquanto Verdadeiro:

dados, addr = s.recvfrom(BUFF_LEN) se data=="STOP" :

print "Parando servidor" sys.exit(0)


print "recebido
de ", addr, "mensagem:", dados

Um servidor que usa o serviço confiável de fluxo de bytes também pode ser construído acima da API de soquete. Esse
servidor começa criando um soquete vinculado à porta escolhida para o servidor. Em seguida, o servidor chama o
método socket.listen. Isso informa à pilha de rede subjacente o número de tentativas de conexão de transporte que
podem ser enfileiradas na pilha de rede subjacente aguardando para serem aceitas e processadas pelo servidor. O
servidor normalmente possui um thread aguardando o método socket.accept. Este método retorna assim que uma
tentativa de conexão é recebida pela pilha subjacente. Ele retorna um soquete que está vinculado à conexão
estabelecida e ao endereço do host remoto. Com esses métodos, é possível escrever um servidor web muito simples
que sempre retorne um erro 404 para todas as solicitações GET e erros 501 para todas as outras solicitações.

# Um servidor HTTP extremamente simples

importar soquete, sys, hora

# O servidor é executado em todos os endereços IP por padrão


ANFITRIÃO=''

#8080 pode ser usado sem privilégios de root


PORTA=8080
BUFLEN=8192 #tamanho do buffer

s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) try: print "Iniciando servidor


HTTP
na porta ", PORT s.bind((HOST,PORT,0,0)) exceto socket.error : print
"Não é possível vincular a
porta :",PORTA sys.exit(-1)

s.listen(10) # máximo de 10 conexões na fila

enquanto Verdadeiro:

# um servidor real seria multithread e capturaria exceções conn, addr = s.accept() print "Connection from ", addr

dados=''
while not '\n' in data : # espera até que a primeira linha seja recebida
dados = dados+conn.recv(BUFLEN)
se data.startswith('GET'):
# GET request
conn.send('HTTP/1.0 404 Not Found\r\n') # um servidor real deve
servir arquivos , caso contrário:

60 Capítulo 3. A Camada de Aplicação


URL de Saylor: http://www.saylor.org/courses/cs402/ The Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

# outro tipo de solicitação HTTP


conn.send('HTTP/1.0 501 Não implementado\r\n')

agora = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) conn.send('Data: '


conn.send('Servidor: Dummy- + agora +'\r\n')
HTTP -Servidor\r\n') conn.send('\r\n')

conn.shutdown(socket.SHUT_RDWR) conn.close()

Este servidor está longe de ser um servidor web com qualidade de produção. Um servidor web real usaria vários threads e/ou IO sem
21
bloqueio para processar um grande número de solicitações simultâneas. Além disso, também precisaria lidar com todos os erros que
poderiam acontecer durante o recebimento de dados através de uma conexão de transporte. Estas estão fora do escopo desta seção e
informações adicionais sobre aplicações de rede mais complexas podem ser encontradas em outros lugares.
Por exemplo, [RG2010] fornece uma discussão aprofundada sobre a utilização da API de soquete com python, enquanto [SFR2004]
continua sendo uma excelente fonte de informações sobre a API de soquete em C.

3.4 Resumo
Neste capítulo, começamos descrevendo os modelos cliente-servidor e ponto a ponto. Descrevemos então, detalhadamente, três
importantes famílias de protocolos na camada de aplicação. A Internet identifica hosts usando IPv4 de 32 bits ou IPv6 de 128 bits. No
entanto, usar esses endereços diretamente dentro dos aplicativos seria difícil para os humanos que os utilizam. Explicamos como o
Sistema de Nomes de Domínio permite o mapeamento de nomes para endereços correspondentes. Descrevemos o protocolo DNS
executado acima do UDP e a hierarquia de nomenclatura. Discutimos então uma das aplicações mais antigas da Internet: o correio
eletrônico. Descrevemos o formato das mensagens de e-mail e o protocolo SMTP usado para enviar mensagens de e-mail, bem como o
protocolo POP usado pelos destinatários de e-mail para recuperar suas mensagens de e-mail do servidor. Por fim, explicamos os
protocolos usados na rede mundial de computadores e no HyperText Transfer Protocol em particular.

3.5 Exercícios

Esta seção contém vários exercícios e pequenos desafios sobre os protocolos da camada de aplicação.

3.5.1 O Sistema de Nomes de Domínio

O Sistema de Nomes de Domínio (DNS) desempenha um papel fundamental na Internet hoje, pois permite que os aplicativos usem
nomes de domínio totalmente qualificados (FQDN) em vez de endereços IPv4 ou IPv6. Muitas ferramentas permitem realizar consultas
através de servidores DNS. Para este exercício, usaremos dig que está instalado na maioria dos sistemas Unix.

Um uso típico de dig é o seguinte

dig @server -t digite fqdn

onde

• servidor é o endereço IP ou o nome de um servidor ou resolvedor DNS

• type é o tipo de registro DNS solicitado pela consulta, como NS para um servidor de nomes, A para um IPv4
endereço, AAAA para um endereço IPv6, MX para um retransmissor de correio, ...

• fqdn é o nome de domínio totalmente qualificado que está sendo consultado

1. Quais são os endereços IP dos resolvedores dos quais a implementação dig que você está usando depende 22 ?

21 Existem muitos softwares de servidores web com qualidade de produção disponível. apache é muito complexo, mas amplamente utilizado. httpd e lighttpd são

menos complexos e seu código-fonte é provavelmente mais fácil de entender.


22 Em uma máquina Linux, a seção Descrição da página de manual do dig informa onde o dig encontra a lista de servidores de nomes a serem consultados.

3.4. URL de resumo 61

de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

2. Qual é o endereço IP que corresponde a inl.info.ucl.ac.be? Que tipo de consulta DNS o dig envia para obter essas informações?

3. Que tipo de solicitação DNS você precisa enviar para obter os servidores de nomes responsáveis por um determinado
domínio?

4. Quais são os servidores de nomes responsáveis pelo domínio de nível superior? Onde eles estão localizados? É isso
é possível usar IPv6 para consultá-los?

5. Quando executado sem nenhum parâmetro, dig consulta um dos servidores DNS raiz e recupera a lista dos nomes de todos os
servidores DNS raiz. Por razões técnicas, existem apenas 13 servidores DNS raiz diferentes. Esta informação também está disponível
como um arquivo de texto em http://www.internic.net/zones/named.root Quais são os endereços IP de todos esses servidores. Eles
podem ser consultados usando IPv6 23 ?

6. Suponha agora que você reside em uma rede onde não há resolvedor de DNS e que precisa iniciar sua consulta a partir da raiz do DNS.

• Use dig para enviar uma consulta a um desses servidores raiz para encontrar o endereço IP do(s) servidor(es) DNS (registro NS)
responsáveis pelo domínio de nível superior da organização

• Use dig para enviar uma consulta a um desses servidores DNS para encontrar o endereço IP do(s) servidor(es) DNS (NS
registro) responsável por root-servers.org'

• Continue até encontrar o servidor responsável por www.root-servers.org

• Qual é o tempo de vida associado a este endereço IP?

7. Faça a mesma análise para um site popular como www.google.com. Qual é o tempo de vida associado a este endereço IP? Se você
realizar a mesma solicitação várias vezes, receberá sempre a mesma resposta? Você pode explicar por que uma vida inteira está
associada às respostas DNS?

8. Use dig para encontrar os retransmissores de e-mail usados pelos domínios uclouvain.be e gmail.com. Qual é o TTL desses registros
(use a opção +ttlid ao usar dig)? Você pode explicar as preferências usadas pelos registros MX.
Você pode encontrar mais informações sobre os registros MX na RFC 974

9. Use dig para consultar o endereço IPv6 (registro DNS AAAA) dos seguintes hosts

• www.sixxs.net

• www.google.com

• ipv6.google.com

10. Quando dig é executado, a seção do cabeçalho em sua saída indica o id do identificador DNS usado para enviar a consulta.
Sua implementação de dig gera identificadores aleatórios?

dig -t MX gmail.com

; <<>> DiG 9.4.3-P3 <<>> -t MX gmail.com ;; opções globais:


printcmd ;; Obtive resposta: ;; ->>HEADER<<-
opcode: QUERY,
status: NOERROR, id: 25718

11. Uma implementação de DNS como dig e, mais importante, um resolvedor de nomes como bind ou não vinculado, sempre verifica se a
resposta DNS recebida contém o mesmo identificador da solicitação DNS enviada. Por que isso é tão importante ?

• Imagine um invasor capaz de enviar respostas DNS forjadas para, por exemplo, associar www.bigbank.com ao seu próprio
endereço IP. Como ele poderia atacar uma implementação de DNS que

– envia solicitações DNS contendo sempre o mesmo identificador

– envia solicitações DNS contendo identificadores que são incrementados em um após cada solicitação

– envia solicitações DNS contendo identificadores aleatórios


23
Você pode obter informações adicionais sobre os servidores DNS raiz em http://www.root-servers.org

62 Capítulo 3. A Camada de Aplicação The Saylor


URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

12. O protocolo DNS pode ser executado em UDP e TCP. A maioria dos servidores DNS prefere usar UDP porque
consome menos recursos no servidor. Entretanto, o TCP é útil quando uma resposta grande é esperada ou quando
uma grande resposta deve. Você pode forçar a utilização do TCP usando dig +tcp. Use TCP e UDP para consultar um
servidor DNS raiz. É mais rápido receber uma resposta via TCP ou via UDP?

3.5.2 Protocolos de e-mail da Internet

Muitos protocolos da Internet são protocolos baseados em ASCII onde o cliente envia solicitações como uma linha de código ASCII . texto
finalizado por CRLF e o servidor responde com uma ou mais linhas de ASCII texto. Usando tal ASCII mensagens tem
diversas vantagens em comparação com protocolos que dependem de mensagens codificadas em binário

• as mensagens trocadas entre o cliente e o servidor podem ser facilmente compreendidas por um desenvolvedor ou rede
engenheiro simplesmente lendo as mensagens

• muitas vezes é fácil escrever um pequeno protótipo que implemente uma parte do protocolo

• é possível testar um servidor manualmente usando telnet Telnet é um protocolo que permite obter um terminal em
um servidor remoto. Para isso, o telnet abre uma conexão TCP com o servidor remoto na porta 23. Porém, a maioria
implementações de telnet permitem ao usuário especificar uma porta alternativa como porta de hosts telnet Quando usada com uma porta
number como parâmetro, o telnet abre uma conexão TCP com o host remoto na porta especificada. telnet pode
portanto, pode ser usado para testar qualquer servidor usando um protocolo baseado em ASCII sobre TCP. Observe que se você precisar parar
uma sessão telnet em execução, Ctrl-C não funcionará, pois será enviado por telnet para o host remoto através do TCP
conexão. Em muitas implementações de telnet você pode digitar Ctrl-] para congelar a conexão TCP e retornar
para a interface Telnet.

1. Suponha que Alice envie um e-mail de sua conta alice@yahoo.com para Bob, que usa bob@yahoo.com.
Quais protocolos estão envolvidos na transmissão deste e-mail?

2. A mesma pergunta quando Alice envia um e-mail para sua amiga Trudy, trudy@gmail.com.

3. Antes do advento do webmail e dos mailers ricos em recursos, o email era escrito e lido usando a linha de comando
ferramentas em servidores. Usando sua conta em sirius.info.ucl.ac.be, use a ferramenta de linha de comando /bin/mail para enviar
um e-mail para você mesmo neste host. Este servidor armazena e-mails locais no diretório /var/mail com um arquivo por
do utilizador. Verifique com /bin/more o conteúdo do seu arquivo de mensagens e tente entender quais linhas foram adicionadas
pelo servidor no cabeçalho do seu e-mail.

4. Use sua ferramenta de e-mail preferida para enviar uma mensagem de e-mail para você mesmo contendo uma única linha de texto. Maioria
ferramentas de e-mail têm a capacidade de mostrar a origem da mensagem, use esta função para ver a mensagem que
você enviou e a mensagem que recebeu. Você consegue encontrar uma explicação para todas as linhas que foram
adicionado ao seu e-mail de linha única 24 ?

5. A primeira versão do protocolo SMTP foi definida na RFC 821. O padrão atual para SMTP é definido
na RFC 5321 Considerando apenas RFC 821 quais são os principais comandos do protocolo SMTP 25 ?

6. Ao usar SMTP, como você reconhece uma resposta positiva de uma negativa?

7. Um servidor SMTP é um processo daemon que pode falhar devido a um bug ou falta de recursos (por exemplo, memória). Rede
26 administradores geralmente instalam ferramentas que se conectam regularmente aos seus servidores para verificar se estão funcionando
27 .
corretamente. Uma solução simples é abrir uma conexão TCP na porta 25 para o host do servidor SMTP.
conexão é estabelecida, isso implica que há um processo de escuta. Qual é a resposta enviada pelo SMTP
servidor quando você digita o seguinte comando?

telnet cnp3.info.ucl.ac.be 25

24
Desde a RFC 821, O SMTP evoluiu muito devido principalmente ao uso crescente de email e à necessidade de proteger o sistema de email contra
spammers. É improvável que você consiga explicar todas as linhas adicionais que encontrará nos cabeçalhos de e-mail, mas iremos discuti-las
junto.
25 Uma descrição mais curta do protocolo SMTP pode ser encontrada na Wikipedia em http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
26
Existem muitas ferramentas de monitoramento disponível. nagios é um sistema de monitoramento de código aberto muito popular.
27
Observe que usar o telnet para conectar-se a um host remoto na porta 25 pode não funcionar em todas as redes. Devido ao spam problema, muitos ISP redes
não permitem que seus clientes usem a porta TCP 25 diretamente e os forçam a usar o retransmissor de correio do ISP para encaminhar seus e-mails. Graças a isso, se
um software de envio de spam foi instalado no PC de um dos clientes do ISP, esse software não será capaz de enviar uma grande quantidade de
Spam. Se você se conectar a nostromo.info.ucl.ac.be a partir das estações fixas do laboratório do INGI, você não deverá ser bloqueado.

3.5. Exercícios 63

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Aviso: não tente fazer isso em um servidor SMTP aleatório. Os exercícios propostos nesta seção devem
só será executado no servidor SMTP dedicado para estes exercícios: cnp3.info.ucl.ac.be. Se você experimentá-los
em um servidor SMTP de produção, o administrador deste servidor pode ficar irritado.

1. Continue a sessão SMTP iniciada acima enviando o comando de saudações (HELO seguido de
o nome de domínio totalmente qualificado do seu host) e encerre a sessão enviando o comando QUIT.

2. A sessão SMTP mínima acima permite verificar se o SMTP está em execução. No entanto, isso não
sempre implica que a correspondência pode ser entregue. Por exemplo, grandes servidores SMTP costumam usar um banco de dados para armazenar todos
os endereços de e-mail que eles atendem. Para verificar o correto funcionamento de tal servidor, uma possibilidade é
use o comando VRFY. Abra uma sessão SMTP no servidor SMTP do laboratório (cnp3.info.ucl.ac.be) e use este
comando para verificar se sua conta está ativa.

3. Agora que você conhece os princípios básicos para abrir e fechar uma sessão SMTP, pode enviar e-mail manualmente
usando os comandos MAIL FROM:, RCPT TO: e DATA. Use estes comandos para enviar manualmente um
e-mail para INGI2141@cnp3.info.ucl.ac.be. Não se esqueça de incluir as linhas De:, Para: e Assunto: em seu
cabeçalho.

1. Utilizando SMTP, é possível enviar um email que contenha exatamente a seguinte arte ASCII?

.
..
...
1. A maioria dos agentes de e-mail permite que você envie e-mails em cópia carbono (cc :) e também em cópia oculta (cco:) para um
destinatário. Como um servidor SMTP suporta esses dois tipos de destinatários?

2. No início, o e-mail era lido usando ferramentas como /bin/mail ou leitores de e-mail mais avançados baseados em texto
como o pinheiro ou olmo . Hoje, os e-mails são armazenados em servidores dedicados e recuperados usando protocolos como
como POP_ ou IMAP. Do ponto de vista do usuário, você pode listar as vantagens e desvantagens desses dois
protocolos?

3. O protocolo TCP suporta 65.536 números de portas diferentes. Muitos desses números de porta foram reservados
para algumas aplicações. O repositório oficial dos números de porta reservados é mantido pela Internet
Autoridade de Atribuição de Números (IANA) em http://www.iana.org/assignments/port-numbers 28. Usando essas informações, qual é o
número da porta padrão para o protocolo POP3? Ele roda em cima de UDP ou TCP?
?

4. O Post Office Protocol (POP) é um protocolo bastante simples descrito na RFC 1939. O POP opera em três
fases. A primeira fase é a fase de autorização onde o cliente fornece um nome de usuário e uma senha. O
a segunda fase é a fase de transação onde o cliente pode recuperar e-mails. A última fase é a fase de atualização
onde o cliente finaliza a transação. Quais são os principais comandos POP e seus parâmetros? Quando
um servidor POP retorna uma resposta, como você pode determinar facilmente se a resposta é positiva ou negativa?

5. Em smartphones, os usuários geralmente desejam evitar o download de e-mails grandes em uma conexão sem fio lenta. Como
um cliente POP poderia baixar apenas e-mails menores que 5 KBytes?

6. Abra uma sessão POP com o servidor POP do laboratório (nostromo.info.ucl.ac.be) usando o nome de usuário e a senha que você recebeu.
Verifique se seu nome de usuário e senha são aceitos pelo servidor.

7. O servidor POP do laboratório contém um script que é executado a cada minuto e envia duas mensagens de e-mail para sua conta
se sua pasta de e-mail estiver vazia. Use POP para recuperar esses dois e-mails e fornecer a mensagem secreta ao seu
professor assistente.

3.5.3 O protocolo de transferência de hipertexto

1. Quais são os principais métodos suportados pela primeira versão do HyperText Transfer Protocol (HTTP)
29 definido na RFC 1945 ? Quais são os principais tipos de respostas enviadas por um servidor http 30 ?

2. Os administradores de sistema responsáveis por servidores web geralmente desejam monitorar esses servidores e verificar
que eles estão funcionando corretamente. Como um servidor HTTP utiliza TCP na porta 80, a solução mais simples é abrir um

28
Em hosts Unix, um subconjunto de atribuições de portas geralmente é colocado em /etc/services
29 Consulte a seção 5 da RFC 1945
30 Consulte a seção 6.1 da RFC 1945

64 Capítulo 3. A Camada de Aplicação

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Conexão TCP na porta 80 e verifique se a conexão TCP é aceita pelo host remoto. No entanto, como
HTTP é um protocolo baseado em ASCII, também é muito fácil escrever um pequeno script que baixe uma página da web em
o servidor e compara seu conteúdo com o esperado. Use telnet para verificar se um servidor web está em execução
31
no host rembrandt.info.ucl.ac.be

3. Em vez de usar telnet na porta 80, também é possível usar uma ferramenta de linha de comando como curl Usar ondulação com
a opção –trace-ascii tracefile para armazenar no tracefile todas as informações trocadas pelo curl ao acessar
o servidor.

• qual é a versão do HTTP usada pelo curl?

• você pode explicar os diferentes cabeçalhos colocados pelo curl na solicitação?

• você pode explicar os diferentes cabeçalhos encontrados na resposta?

4. HTTP 1.1, especificado na RFC 2616 força o cliente a usar o Host: em todas as suas solicitações. HTTP 1.0 não
defina o cabeçalho Host:, pela maioria das implementações o suporta. Usando telnet e curl recupere a primeira página
do http://totem.info.ucl.ac.be servidor web enviando solicitações http com e sem o cabeçalho Host:.
32 .
Explique a diferença entre os dois

5. Usando cavar e enrolar , determinar em qual host físico o http://www.info.ucl.ac.be,


http://inl.info.ucl.ac.be e http://totem.info.ucl.ac.be estão hospedados

6. Use ondulação com o nome do arquivo –trace-ascii para recuperar http://www.google.com . Explique o que é um navegador como
o firefox faria ao recuperar este URL.

7. Os cabeçalhos enviados em uma solicitação HTTP permitem que o cliente forneça informações adicionais ao servidor. Um
destes cabeçalhos é o cabeçalho Language que permite indicar o idioma preferido do cliente 33. Para
exemplo, curl -HAccept-Language:en http://www.google.be' enviará para 'http://www.google.be um HTTP
solicitação indicando inglês (en) como idioma preferencial. O Google fornece uma página diferente em francês?
(fr) e Valão (wa)? A mesma pergunta para http://www.uclouvain.be (dado o tamanho da página inicial, use
diff para comparar as diferentes páginas recuperadas de www.uclouvain.be)

8. Compare o tamanho do http://www.yahoo.com e http://www.google.com páginas da web baixando


eles com cachos

9. O que é um cookie http? Liste algumas vantagens e desvantagens do uso de cookies em servidores web.

10. Você agora é responsável pelo http://www.belgium.be. O governo construiu dois datacenters contendo 1.000 servidores cada em
Antuérpia e Namur. Este site contém informações estáticas e seu objetivo
é equilibrar a carga entre os diferentes servidores e garantir que o serviço permaneça ativo mesmo que um dos
os datacenters estão desconectados da Internet devido a inundações ou outros desastres naturais. O que são as
técnicas que você pode usar para atingir esse objetivo?

31
O comando mínimo enviado para um servidor HTTP é GET / HTTP/1.0 seguido de CRLF e uma linha em branco
32 Use cavar para encontrar o endereço IP usado por totem.info.ucl.ac.be
33
A lista de tags de idioma disponíveis pode ser encontrada em http://www.loc.gov/standards/iso639-2/php/code_list.php Informações adicionais sobre
o suporte de vários idiomas em protocolos de Internet pode ser encontrado na RFC 5646

3.5. Exercícios 65

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

66 Capítulo 3. A Camada de Aplicação


URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

CAPÍTULO 4

A camada de transporte

Como a camada de transporte é construída sobre a camada de rede, é importante conhecer os principais recursos do serviço da
camada de rede. Existem dois tipos de serviços da camada de rede: sem conexão e orientados a conexão. O serviço da camada de
rede sem conexão é o mais difundido. Suas principais características são:

• o serviço da camada de rede sem conexão só pode transferir SDUs de tamanho limitado 1

• o serviço da camada de rede sem conexão pode descartar SDUs

• o serviço da camada de rede sem conexão pode corromper SDUs

• o serviço da camada de rede sem conexão pode atrasar, reordenar ou até mesmo duplicar SDUs

Figura 4.1: A camada de transporte no modelo de referência

Essas imperfeições do serviço da camada de rede sem conexão ficarão muito mais claras quando explicarmos a camada de rede no
próximo capítulo. Neste ponto, vamos simplesmente supor que essas imperfeições ocorrem sem tentar entender por que ocorrem.

Alguns protocolos de transporte podem ser usados em cima de um serviço de rede orientado a conexão, como a classe 0 do Protocolo
de Transporte ISO (TP0) definido em [ X224] , mas eles não têm sido amplamente utilizados. Não discutiremos com mais detalhes
essa utilização de um serviço de rede orientado a conexões neste livro.

Este capítulo está organizado da seguinte forma. Explicaremos primeiro como é possível fornecer um serviço de transporte confiável
além de um serviço de rede não confiável e sem conexão. Para isso, explicamos os principais mecanismos encontrados em tais
protocolos. A seguir, estudaremos detalhadamente os dois protocolos de transporte utilizados na Internet. Começamos com o User
Datagram Protocol (UDP), que fornece um serviço de transporte simples sem conexão. Em seguida, descreveremos detalhadamente
o Protocolo de Controle de Transmissão (TCP), incluindo seu mecanismo de controle de congestionamento.

4.1 Princípios de um protocolo de transporte confiável

Nesta seção, descrevemos um protocolo de transporte confiável executado acima de um serviço de camada de rede sem conexão.
Para isso, primeiro assumimos que a camada de rede fornece um serviço perfeito, ou seja:

• o serviço da camada de rede sem conexão nunca corrompe SDUs

1 Muitos serviços da camada de rede não conseguem transportar SDUs maiores que 64 KBytes.

67

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• o serviço da camada de rede sem conexão nunca descarta SDUs

• o serviço da camada de rede sem conexão nunca atrasa, reordena ou duplica SDUs

• o serviço da camada de rede sem conexão pode suportar SDUs de qualquer tamanho

Em seguida, removeremos cada uma dessas suposições, uma após a outra, para entender melhor os mecanismos usados para resolver
cada imperfeição.

4.1.1 Transferência confiável de dados além de um serviço de rede perfeito

A entidade da camada de transporte interage tanto com um usuário na camada de aplicação quanto com uma entidade na camada de rede.
De acordo com o modelo de referência, essas interações serão realizadas utilizando as primitivas DATA.req e DATA.ind.
Porém, para simplificar a apresentação e evitar confusão entre uma primitiva DATA.req emitida pelo usuário da entidade da camada de
transporte, e um DATA.req emitido pela própria entidade da camada de transporte, utilizaremos a seguinte terminologia:

• as interações entre o usuário e a entidade da camada de transporte são representadas usando o clássico
Primitivas DATA.req, DATA.ind

• as interações entre a entidade da camada de transporte e o serviço da camada de rede são representadas usando
enviar em vez de DATA.req e recvd em vez de DATA.ind

Isto é ilustrado na figura abaixo.

Dados.req Dados.ind

Entidade de
transporte

Enviar Recebido

Figura 4.2: Interações entre a camada de transporte, seu usuário e seu provedor da camada de rede

Ao executar um serviço de rede sem conexão perfeito, uma entidade de nível de transporte pode simplesmente emitir um send(SDU) na
chegada de um DATA.req(SDU). Da mesma forma, o receptor emite um DATA.ind(SDU) ao receber um recvd(SDU). Um protocolo tão
simples é suficiente quando um único SDU é enviado.

Infelizmente, isto nem sempre é suficiente para garantir uma entrega confiável dos SDUs. Considere o caso em que um cliente envia
dezenas de SDUs para um servidor. Se o servidor for mais rápido que o cliente, ele poderá receber e processar todos os segmentos
enviados pelo cliente e entregar seu conteúdo ao seu usuário. No entanto, se o servidor for mais lento que o cliente, poderão surgir
problemas. A entidade da camada de transporte contém buffers para armazenar SDUs que foram recebidos como uma solicitação de dados
do aplicativo, mas ainda não foram enviados através do serviço de rede. Se a aplicação for mais rápida que a camada de rede, o buffer fica
cheio e o sistema operacional suspende a aplicação para permitir que a entidade de transporte esvazie sua fila de transmissão. A entidade
de transporte também utiliza um buffer para armazenar os segmentos recebidos da camada de rede que ainda não foram processados pela
aplicação. Se a aplicação demorar para processar os dados, esse buffer fica cheio e a entidade de transporte não consegue mais aceitar
os segmentos da camada de rede. Os buffers da entidade de transporte têm um tamanho limitado e se transbordarem, a entidade de
2
transporte é forçada a

2 Na camada de aplicação, a maioria dos servidores são implementados como processos. As camadas de rede e transporte, por outro lado, são

geralmente implementadas dentro do sistema operacional e a quantidade de memória que podem usar é limitada pela quantidade de memória alocada
para todo o kernel.

68 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

A B

Solicitação de dados(a)
Segmento(a)

Dados.ind(a)

Figura 4.3: O protocolo de transporte mais simples

descartar segmentos recebidos.

Para resolver este problema, nosso protocolo de transporte deve incluir um mecanismo de feedback que permita ao receptor informar ao remetente
que processou um segmento e que outro pode ser enviado. Esse feedback é necessário mesmo que a camada de rede forneça um serviço perfeito.
Para incluir tal feedback, nosso protocolo de transporte deve processar dois tipos de segmentos:

• segmentos de dados transportando uma SDU

• segmentos de controle carregando uma confirmação indicando que o segmento anterior foi processado corretamente

Esses dois tipos de segmentos podem ser distinguidos usando um segmento composto por duas partes:

• o cabeçalho que contém um bit definido como 0 em segmentos de dados e definido como 1 em segmentos de controle

• a carga útil que contém o SDU fornecido pelo aplicativo do usuário

A entidade de transporte pode então ser modelada como uma máquina de estados finitos, contendo dois estados para o receptor e dois estados para
o remetente. A figura abaixo fornece uma representação gráfica desta máquina de estados com o remetente acima e o destinatário abaixo.

Figura 4.4: Máquina de estados finitos do protocolo de transporte mais simples

4.1. Princípios de um protocolo de transporte confiável Saylor URL: 69

http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O FSM acima mostra que o remetente tem que esperar por uma confirmação do receptor antes de poder transmitir o próximo SDU. A figura
abaixo ilustra a troca de alguns segmentos entre dois hosts.

A B

Dados.req(a) D(a)

Dados.ind(a)
Dados.req(b) C(OK)

D(b)

Dados.ind(b)
C(OK)

Figura 4.5: Diagrama de sequência temporal ilustrando a operação do protocolo de transporte mais simples

4.1.2 Transferência confiável de dados em cima de um serviço de rede imperfeito

A camada de transporte deve lidar com as imperfeições do serviço da camada de rede. Existem três tipos de imperfeições que devem ser
consideradas pela camada de transporte:

1. Os segmentos podem ser corrompidos por erros de transmissão

2. Segmentos podem ser perdidos

3. Os segmentos podem ser reordenados ou duplicados

Para lidar com esses tipos de imperfeições, os protocolos de transporte contam com diferentes tipos de mecanismos. O primeiro problema são
os erros de transmissão. Os segmentos enviados por uma entidade de transporte são processados pelas camadas de rede e enlace de dados e
finalmente transmitidos pela camada física. Todas essas camadas são imperfeitas. Por exemplo, a camada física pode ser afetada por diferentes
tipos de erros:

• erros aleatórios isolados onde o valor de um único bit foi modificado devido a um erro de transmissão

• erros de rajada aleatória onde os valores de n bits consecutivos foram alterados devido a erros de transmissão

• criações aleatórias de bits e remoções aleatórias de bits onde bits foram adicionados ou removidos devido à transmissão
erros

A única solução para proteção contra erros de transmissão é adicionar redundância aos segmentos enviados. A Teoria da Informação define
dois mecanismos que podem ser usados para transmitir informações através de um canal de transmissão afetado por erros aleatórios. Estes dois
mecanismos acrescentam redundância à informação enviada, para permitir ao receptor detectar ou por vezes até corrigir erros de transmissão.
Uma discussão detalhada desses mecanismos está fora do escopo
escopo deste capítulo, mas é útil considerar um mecanismo simples para entender seu funcionamento e suas limitações.

A teoria da informação define esquemas de codificação. Existem diferentes tipos de esquemas de codificação, mas vamos nos concentrar nos
esquemas de codificação que operam em strings binárias. Um esquema de codificação é uma função que mapeia informações codificadas como
uma sequência de m bits em uma sequência de n bits. O esquema de codificação mais simples é a codificação de paridade par. Este esquema
de codificação pega uma string de origem de m bits e produz uma string codificada de m+1 bits, onde os primeiros m bits da string codificada
são os bits da string de origem e o último bit da string codificada é escolhido de tal forma que a string codificada será sempre contém um número
par de bits definido como 1. Por exemplo:

• 1001 é codificado como 10010

• 1101 é codificado como 11011

70 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Este esquema de paridade tem sido usado em algumas RAMs e também para codificar caracteres enviados por uma linha serial. É fácil mostrar
que este esquema de codificação permite ao receptor detectar um único erro de transmissão, mas não pode corrigi-lo.
No entanto, se dois ou mais bits estiverem errados, o receptor nem sempre será capaz de detectar o erro.

Alguns esquemas de codificação permitem ao receptor corrigir alguns erros de transmissão. Por exemplo, considere o esquema de codificação que
codifica cada bit de origem da seguinte forma:

• 1 é codificado como 111

• 0 é codificado como 000

Por exemplo, considere um remetente que envia 111. Se houver um bit com erro, o receptor poderá receber 011 ou 101 ou 110. Nestes três casos,
o receptor irá decodificar o padrão de bits recebido como 1, uma vez que contém a maioria dos bits definidos como 1. Se houver dois bits com erro,
o receptor não poderá mais se recuperar do erro de transmissão.

Este esquema de codificação simples força o remetente a transmitir três bits para cada bit de origem. No entanto, permite que o receptor corrija
erros de bit único. Sistemas de codificação mais avançados que permitem a recuperação de erros são utilizados em diversos tipos de camadas
físicas.

Os protocolos de transporte utilizam esquemas de detecção de erros, mas nenhum dos protocolos de transporte amplamente utilizados depende de
esquemas de correção de erros. Para detectar erros, um segmento geralmente é dividido em duas partes:

• um cabeçalho que contém os campos usados pelo protocolo de transporte para garantir uma entrega confiável. O cabeçalho contém uma
soma de verificação ou Verificação de Redundância Cíclica (CRC) [Williams1993] que é usada para detectar transmissão
erros

• uma carga útil que contém os dados do usuário passados pela camada de aplicação.

Alguns cabeçalhos de segmento também incluem um comprimento, que indica o comprimento total do segmento ou o comprimento da carga útil.

O esquema de detecção de erros mais simples é a soma de verificação. Uma soma de verificação é basicamente uma soma aritmética de todos os
bytes que compõem um segmento. Existem diferentes tipos de somas de verificação. Por exemplo, uma soma de verificação de oito bits pode ser
calculada como a soma aritmética de todos os bytes (tanto do cabeçalho quanto do trailer) do segmento. A soma de verificação é calculada pelo
remetente antes de enviar o segmento e o destinatário verifica a soma de verificação na recepção de cada segmento. O receptor descarta
segmentos recebidos com um checksum inválido. As somas de verificação podem ser facilmente implementadas em software, mas suas capacidades
de detecção de erros são limitadas. As verificações de redundância cíclica (CRC) têm melhores capacidades de detecção de erros [SGP98], mas
requerem mais CPU quando implementadas em software.

Nota: somas de verificação, CRCs, ...

A maioria dos protocolos do conjunto de protocolos TCP/IP baseia-se na simples soma de verificação da Internet para verificar se o segmento
recebido não foi afetado por erros de transmissão. Apesar de sua popularidade e facilidade de implementação, a soma de verificação da Internet
não é o único mecanismo de soma de verificação disponível. Verificações de redundância cíclica (CRC) são esquemas de detecção de erros muito
poderosos que são usados principalmente em discos, por muitos protocolos de camada de link de dados e formatos de arquivo como zip ou png.
Eles podem ser facilmente implementados de forma eficiente em hardware e possuem melhores capacidades de detecção de erros do que o
checksum da Internet [SGP98] . No entanto, quando os primeiros protocolos de transporte foram projetados, os CRCs foram considerados muito
intensivos em CPU para implementações de software e outros mecanismos de soma de verificação foram usados. A comunidade TCP/IP escolheu
o checksum da Internet, a comunidade OSI escolheu o checksum Fletcher [Sklower89] . Agora, existem técnicas eficientes para calcular rapidamente
CRCs em software [Feldmeier95]. O protocolo SCTP inicialmente escolheu a soma de verificação Adler-32, mas substituiu-a recentemente por um
, CRC (ver RFC 3309).

A segunda imperfeição da camada de rede é que os segmentos podem ser perdidos. Como veremos mais adiante, a principal causa das perdas de
pacotes na camada de rede é a falta de buffers nos roteadores intermediários. Como o receptor envia um segmento de confirmação após ter
recebido cada segmento de dados, a solução mais simples para lidar com perdas é utilizar um temporizador de retransmissão. Quando o remetente
envia um segmento, ele inicia um temporizador de retransmissão. O valor deste temporizador de retransmissão deverá ser superior ao tempo de
ida e volta, ou seja, o atraso entre a transmissão de um segmento de dados e a recepção do reconhecimento correspondente. Quando o
temporizador de retransmissão expira, o remetente assume que o segmento de dados foi perdido e o retransmite. Isto é ilustrado na figura abaixo.

Infelizmente, os temporizadores de retransmissão por si só não são suficientes para recuperar as perdas de segmento. Consideremos, como
exemplo, a situação descrita abaixo em que um reconhecimento é perdido. Neste caso, o remetente retransmite

4.1. Princípios de um protocolo de transporte confiável Saylor URL: 71

http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

A B

Dados.req(a)
iniciar temporizador D(a)

Dados.ind(a)
C(OK)
cancelar temporizador
Dados.req(b)
iniciar temporizador D(b) Segmento perdido

o cronômetro expira D(b)

Dados.ind(b)
C(OK)

Figura 4.6: Usando temporizadores de retransmissão para recuperação de perdas de segmento

o segmento de dados que não foi reconhecido. Infelizmente, conforme ilustrado na figura abaixo, o receptor considera a retransmissão como
um novo segmento cuja carga útil deve ser entregue ao seu usuário.

A B

Dados.req(a)
iniciar temporizador D(a)

C(OK) Dados.ind(a)
cancelar temporizador
Dados.req(b) D(b)
iniciar temporizador

C(OK) Dados.ind(b)

o cronômetro expira D(b)

Segmento perdido
C(OK) Dados.ind(b) !!!!!!

Figura 4.7: Limitações dos temporizadores de retransmissão

Para resolver este problema, os protocolos de transporte associam um número de sequência a cada segmento de dados. Este número de
sequência é um dos campos encontrados no cabeçalho dos segmentos de dados. Usamos a notação D(S,...) para indicar um segmento de
dados cujo campo de número de sequência está definido como S. As confirmações também contêm um número de sequência que indica os
segmentos de dados que estão reconhecendo. Usamos OKS para indicar um segmento de confirmação que confirma a recepção de D(S,...).
O número de sequência é codificado como uma sequência de bits de comprimento fixo. O protocolo de transporte mais simples é o Alternating
Bit Protocol (ABP).

O Alternating Bit Protocol usa um único bit para codificar o número de sequência. Pode ser implementado facilmente. O remetente e os
destinatários requerem apenas uma máquina de estados finitos de quatro estados.

72 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Recvd(C(NAK?)) OR
Data.req(SDU)
Recvd(C(OK1)) ou o temporizador expira
envio(D(0,SDU,CRC))
send(D(0,SDU,CRC))
start_timer()
Esperar restart_timer()
por
Aguarde D(0,...) OK0/OK

Recvd(C(OK1)) Recvd(C(OK0))
cancel_timer() cancel_timer()
Data.req(SDU)
envio(D(1,SDU,CRC))
start_timer()
Esperar Todos os
por
segmentos
OK1/OK Aguarde D(1,...) corrompidos são descartados em todos os estados

Recvd(C(NAK?)) ou recvd(C(OK0)) ou o temporizador expira


send(D(1,SDU,CRC))
restart-timer()

Figura 4.8: Protocolo de bits alternados: Remetente FSM

O estado inicial do remetente é Aguardar D(0,...). Neste estado, o remetente aguarda um Data.request. O primeiro segmento de
dados que envia utiliza o número de sequência 0. Após ter enviado este segmento, o remetente aguarda um reconhecimento
ac OK0. Um segmento é retransmitido após a expiração do temporizador de retransmissão ou se uma confirmação com um
número de sequência incorreto for recebida.

O receptor primeiro espera por D(0,...). Se o segmento contiver um CRC correto, ele passa o SDU ao seu usuário e envia OK0.
Se o segmento contiver um CRC inválido, ele será imediatamente descartado. Então, o receptor espera por D(1,...).
Neste estado, pode receber um D(0,...) duplicado ou um segmento de dados com CRC inválido. Em ambos os casos, retorna
um segmento OK0 para permitir ao remetente se recuperar da possível perda do segmento OK0 anterior.

Nota: Lidando com segmentos corrompidos

O receptor FSM do protocolo Alternating bit descarta todos os segmentos que contêm um CRC inválido. Esta é a abordagem
mais segura, pois o segmento recebido pode ser completamente diferente do segmento enviado pelo host remoto.
Um receptor não deve tentar extrair informações de um segmento corrompido porque não pode saber qual parte do segmento
foi afetada pelo erro.

A figura abaixo ilustra a operação do protocolo de bits alternados.

O Alternating Bit Protocol pode se recuperar de erros de transmissão e perdas de segmento. No entanto, tem uma desvantagem
importante. Considere dois hosts conectados diretamente por um enlace de satélite de 50 Kbits/s com atraso de propagação de
250 milissegundos. Se esses hosts enviam segmentos de 1000 bits, então a taxa de transferência máxima que pode ser
alcançada pelo protocolo de bits alternados é um segmento a cada 20 + 250 + 250 = 520 milissegundos se ignorarmos o tempo
de transmissão da confirmação. Isso é menos de 2 Kbits/s!

Go-back-n e repetição seletiva

Para superar as limitações de desempenho do protocolo de bits alternados, os protocolos de transporte dependem de pipeline.
Esta técnica permite que um remetente transmita vários segmentos consecutivos sem ser forçado a esperar por uma confirmação
após cada segmento. Cada segmento de dados contém um número de sequência codificado em um campo de n bits.

Pipelining permite que o remetente transmita segmentos a uma taxa mais alta, mas precisamos garantir que o receptor não

4.1. Princípios de um protocolo de transporte confiável 73

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Recebido(D(1,SDU,CRC)) Recebido(D(0,SDU,CRC))
E está OK (CRC,SDU) E está OK (CRC,SDU)
Enviar(C(OK1)) Recebido(D(0,SDU,CRC)) Enviar(C(OK0))
E está OK (CRC,SDU) -
Dados.ind(SDU) Enviar(C(OK0))
Processo
SDU0
Aguarde D(0,...) OK
Aguarde D(1,...)

- Recebido(D(1,SDU,CRC))
E está OK (CRC,SDU)
Enviar(C(OK1)) Dados.ind(SDU)

Todos os
segmentos Processo
corrompidos são descartados em todos os estados
SDU1
OK

Figura 4.9: Protocolo de bits alternados: Receptor FSM

A B

Dados.req(a)
D(0,uma)

C(OK0) Dados.ind(a)
Dados.req(b)

D(1, b)
Temporizador de retransmissão

D(1,b)
Dados.ind(b)
C(OK1)
Duplicata detectada

C(OK1)
Dados.req(c)

D(0, c)
Temporizador de retransmissão

D(0, c)
Dados.ind(c)

Figura 4.10: Funcionamento do protocolo de bits alternados

Figura 4.11: Pipelining para melhorar o desempenho dos protocolos de transporte

74 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

ficar sobrecarregado. Caso contrário, os segmentos enviados pelo remetente não serão recebidos corretamente pelo destino. Os protocolos de
transporte que dependem de pipeline permitem que o remetente transmita W segmentos não confirmados antes de ser forçado a aguardar uma
confirmação da entidade receptora.

Isso é implementado usando uma janela deslizante. A janela deslizante é o conjunto de números de sequência consecutivos que o remetente
pode usar ao transmitir segmentos sem ser forçado a esperar por uma confirmação. A figura abaixo mostra uma janela deslizante contendo cinco
segmentos (6,7,8,9 e 10). Dois desses números de sequência (6 e 7) foram usados para enviar segmentos e apenas três números de sequência
(8, 9 e 10) permanecem na janela deslizante. Diz-se que a janela deslizante é fechada quando todos os números de sequência contidos na janela
deslizante forem usados.

Figura 4.12: A janela deslizante

A figura abaixo ilustra o funcionamento da janela deslizante. A janela deslizante mostrada contém três segmentos. O remetente pode assim
transmitir três segmentos antes de ser forçado a esperar por uma confirmação. A janela deslizante move-se para os números de sequência mais
altos após a recepção das confirmações. Quando a primeira confirmação (OK0) é recebida, permite ao remetente mover sua janela deslizante
para a direita e o número de sequência 3 fica disponível. Este número de sequência é usado posteriormente para transmitir SDU d.

Figura 4.13: Exemplo de janela deslizante

Na prática, como o cabeçalho do segmento codifica o número de sequência em uma string de n bits, apenas os números de sequência entre 0 e
2 n
ÿ 1 pode ser usado. Isso implica que o mesmo número de sequência será usado para segmentos diferentes e que a janela
deslizante será quebrada. Isso é ilustrado na figura abaixo, assumindo que 2 bits são usados para codificar o número de sequência no cabeçalho
do segmento. Observe que ao receber OK1, o remetente desliza sua janela e pode usar o número de sequência 0 novamente.

Infelizmente, as perdas de segmento não desaparecem porque um protocolo de transporte utiliza uma janela deslizante. Para se recuperar de
perdas de segmento, um protocolo de janela deslizante deve definir:

• uma heurística para detectar perdas de segmento

• uma estratégia de retransmissão para retransmitir os segmentos perdidos.

4.1. Princípios de um protocolo de transporte confiável Saylor 75

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.14: Utilização da janela deslizante com módulo aritmético

O protocolo de janela deslizante mais simples usa recuperação go-back-n. Intuitivamente, go-back-n funciona da seguinte maneira.
Um receptor go-back-n é o mais simples possível. Aceita apenas os segmentos que chegam em sequência. Um receptor go-back-n
descarta qualquer segmento fora de sequência que recebe. Quando go-back-n recebe um segmento de dados, ele sempre retorna
uma confirmação contendo o número de sequência do último segmento em sequência que recebeu. Diz-se que esse reconhecimento
é cumulativo. Quando um receptor go-back-n envia uma confirmação para o número de sequência x, ele reconhece implicitamente a
recepção de todos os segmentos cujo número de sequência é anterior a x. Uma vantagem importante destes reconhecimentos
cumulativos é que é fácil recuperar da perda de um reconhecimento. Considere, por exemplo, um receptor go-back-n que recebeu
os segmentos 1, 2 e 3. Enviou OK1, OK2 e OK3. Infelizmente, OK1 e OK2 foram perdidos. Graças às confirmações cumulativas,
quando o receptor recebe OK3, ele sabe que todos os três segmentos foram recebidos corretamente.

A figura abaixo mostra o FSM de um receptor go-back-n simples. Este receptor usa duas variáveis: lastack e next. next é o próximo
número de sequência esperado e lastack é o número de sequência do último segmento de dados que foi reconhecido. O receptor
aceita apenas os segmentos recebidos em sequência. maxseq é o número de diferentes números de sequência (2 n).

Todos os Recebido(D(próximo,SDU,CRC))
segmentos E está OK (CRC,SDU)
corrompidos são descartados em todos os estados
Dados.ind(SDU)

Processo
Espere SDU
OK

-
enviar(C(OK,próximo,CRC));
Recebido(D(t<>próximo,SDU,CRC)) lastack = próximo
AND IsOK(CRC,SDU) próximo=(próximo+1)% maxseq;
descarte(SDU);
enviar(C(OK,última pilha,CRC));

Figura 4.15: Go-back-n: receptor FSM

Um remetente go-back-n também é muito simples. Ele usa um buffer de envio que pode armazenar uma janela deslizante inteira de
segmentos 3 . Os segmentos são enviados com número de sequência crescente (módulo maxseq). O remetente deve esperar pelos
3
O tamanho da janela deslizante pode ser fixo para um determinado protocolo ou negociado durante a fase de estabelecimento da conexão. Bem
veja mais adiante que também é possível alterar o tamanho da janela deslizante durante a vida útil da conexão.

76 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

uma confirmação quando seu buffer de envio estiver cheio. Quando um remetente go-back-n recebe uma confirmação, ele remove
do buffer de envio todos os segmentos reconhecidos e usa um temporizador de retransmissão para detectar perdas de segmento.
Um remetente go-back-n simples mantém um temporizador de retransmissão por conexão. Este temporizador é iniciado quando o
primeiro segmento é enviado. Quando o remetente go-back-n recebe uma confirmação, ele reinicia o temporizador de retransmissão
somente se ainda houver segmentos não confirmados em seu buffer de envio. Quando o temporizador de retransmissão expira, o
remetente go-back-n assume que todos os segmentos não confirmados atualmente armazenados em seu buffer de envio foram
perdidos. Assim, ele retransmite todos os segmentos não reconhecidos no buffer e reinicia seu temporizador de retransmissão.

Todos os
segmentos Data.req(SDU)
corrompidos são descartados em todos os estados tamanho(buffer) < w if
(seq==unack) { start_timer ; }
insert_in_buffer(seq,SDU);
enviar(D(seq,SDU,CRC));
seq=(seq+1) % maxseq;
Recvd(C(OK,t,CRC)) e
CRCOK(C(OK,t,CRC)) removem o temporizador
sequências confirmadas do buffer; expira para todos (i, SDU) no
descompactar = (t+1)% maxseq; if buffer { send(D(i,SDU,CRC)); }
(descompactar==seq) restart_timer();
{ cancel_timer(); } else
{ restart_timer(); }

Figura 4.16: Go-back-n: remetente FSM

A operação de go-back-n é ilustrada na figura abaixo. Nesta figura, observe que após a recepção do segmento fora de sequência
D(2,c), o receptor retorna uma confirmação cumulativa C(OK,0) que reconhece todos os segmentos que foram recebidos em
sequência. O segmento perdido é retransmitido após a expiração do temporizador de retransmissão.

Figura 4.17: Voltar-n: exemplo

A principal vantagem do go-back-n é que ele pode ser facilmente implementado e também pode fornecer bom desempenho
quando apenas alguns segmentos são perdidos. Porém, quando há muitas perdas, o desempenho do go-back-n cai rapidamente
por dois motivos:

• o receptor go-back-n não aceita segmentos fora de sequência

• o remetente go-back-n retransmite todos os segmentos não confirmados assim que detecta uma perda

A repetição seletiva é a melhor estratégia para se recuperar de perdas de segmento. Intuitivamente, a repetição seletiva permite
ao receptor aceitar segmentos fora de sequência. Além disso, quando um remetente repetidor seletivo detecta perdas, ele
retransmite apenas os segmentos que foram perdidos e não os segmentos que já foram recebidos corretamente.

4.1. Princípios de um protocolo de transporte confiável 77

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Um receptor de repetição seletiva mantém uma janela deslizante de W segmentos e armazena em um buffer os segmentos fora
de sequência que recebe. A figura abaixo mostra uma janela de recepção de cinco segmentos em um receptor que já recebeu os
segmentos 7 e 9.

Figura 4.18: A janela de recepção com repetição seletiva

Um receptor de repetição seletiva descarta todos os segmentos que possuem um CRC inválido e mantém a variável lastack como
o número de sequência do último segmento em sequência que recebeu. O receptor sempre inclui o valor de lastack nas
confirmações que envia. Alguns protocolos também permitem que o receptor de repetição seletiva reconheça os segmentos fora
de sequência que recebeu. Isto pode ser feito, por exemplo, colocando a lista dos números de sequência dos segmentos
corretamente recebidos, mas fora de sequência, nas confirmações, juntamente com o valor lastack.

Quando um receptor de repetição seletiva recebe um segmento de dados, ele primeiro verifica se o segmento está dentro da
janela de recepção. Se sim, o segmento é colocado no buffer de recebimento. Caso contrário, o segmento recebido é descartado
e uma confirmação contendo lastack é enviada ao remetente. O receptor então remove todos os segmentos consecutivos
começando no lastack (se houver) do buffer de recepção. As cargas desses segmentos são entregues ao usuário, o lastack e a
janela de recebimento são atualizados e uma confirmação confirmando o último segmento recebido na sequência é enviada.

O remetente repetidor seletivo mantém um buffer de envio que pode armazenar até W segmentos não confirmados. Esses
segmentos são enviados enquanto o buffer de envio não estiver cheio. São possíveis diversas implementações de um remetente
repetidor seletivo. Uma implementação simples é associar um temporizador de retransmissão a cada segmento. O cronômetro é
iniciado quando o segmento é enviado e cancelado após a recepção de uma confirmação que abrange este segmento. Quando
um temporizador de retransmissão expira, o segmento correspondente é retransmitido e este temporizador de retransmissão é reiniciado.
Quando uma confirmação é recebida, todos os segmentos cobertos por esta confirmação são removidos do buffer de envio e a
janela deslizante é atualizada.

A figura abaixo ilustra a operação de repetição seletiva quando segmentos são perdidos. Nesta figura, C(OK,x) é usado para
indicar que todos os segmentos, até e incluindo o número de sequência x, foram recebidos corretamente.

Figura 4.19: Repetição seletiva: exemplo

Reconhecimentos cumulativos puros funcionam bem com a estratégia go-back-n. No entanto, apenas com reconhecimentos
cumulativos, um remetente repetidor seletivo não pode determinar facilmente quais segmentos de dados foram recebidos
corretamente após a perda de um segmento de dados. Por exemplo, na figura acima, o segundo C(OK,0) não informa

78 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

explicitamente o remetente da recepção de D(2,c) e o remetente poderia retransmitir este segmento embora já tenha sido recebido.
Uma possível solução para melhorar o desempenho da repetição seletiva é fornecer informações adicionais sobre os segmentos
recebidos nas confirmações retornadas pelo receptor. Por exemplo, o receptor poderia adicionar na confirmação retornada a lista dos
números de sequência de todos os segmentos que já foram recebidos. Tais reconhecimentos são às vezes chamados de reconhecimentos
seletivos. Isto é ilustrado na figura abaixo.

Na figura acima, quando o remetente recebe C(OK,0,[2]), ele sabe que todos os segmentos até D(0,...) inclusive foram recebidos
corretamente. Ele também sabe que o segmento D(2,...) foi recebido e pode cancelar o temporizador de retransmissão associado a
este segmento. Contudo, este segmento não deve ser removido do buffer de envio antes da recepção de uma confirmação cumulativa
(C(OK,2) na figura acima) que cobre este segmento.

Nota: Tamanho máximo da janela com retrocesso n e repetição seletiva

Um protocolo de transporte que usa n bits para codificar seu número de sequência pode enviar até 2 n segmentos diferentes. Contudo,
n
para garantir uma entrega confiável dos segmentos, o go-back-n e a repetição seletiva não podem usar uma janela de envio de 2
n
segmentos. Considere primeiro go-back-n e suponha que um remetente envie 2 segmentos. Esses segmentos são recebidos em
sequência pelo destino, mas todas as confirmações retornadas são perdidas. O remetente retransmitirá todos os segmentos e todos
serão aceitos pelo destinatário e entregues uma segunda vez ao usuário. É fácil ver que este problema pode ser evitado se o tamanho
n
máximo da janela de envio for de 2 ÿ 1 segmentos. Um problema semelhante ocorre com a repetição seletiva. Entretanto, como o
receptor aceita segmentos fora de sequência, uma janela de envio de 2 ÿ 1 segmentos não é suficiente para garantir uma entrega
n
confiável de todos os segmentos. Pode ser facilmente demonstrado que, para evitar este problema, um remetente repetidor seletivo não
n
2
pode usar uma janela maior que 2
segmentos.

Go-back-n ou repetição seletiva são usados por protocolos de transporte para fornecer uma transferência confiável de dados acima de
um serviço não confiável da camada de rede. Até agora, assumimos que o tamanho da janela deslizante era fixo durante toda a vida útil
da conexão. Na prática, uma entidade da camada de transporte é geralmente implementada no sistema operacional e compartilha
memória com outras partes do sistema. Além disso, uma entidade da camada de transporte deve suportar diversas (possivelmente
centenas ou milhares) de conexões de transporte ao mesmo tempo. Isto implica que a memória que pode ser usada para suportar o
buffer de envio ou recebimento de uma conexão de transporte pode mudar durante o tempo de vida da conexão . Assim, um protocolo
de transporte deve permitir que o remetente e o destinatário ajustem o tamanho das janelas.

Para lidar com esse problema, os protocolos de transporte permitem que o receptor anuncie o tamanho atual da sua janela de
recebimento em todas as confirmações que envia. A janela de recebimento anunciada pelo destinatário limita o tamanho do buffer de
envio usado pelo remetente. Na prática, o remetente mantém duas variáveis de estado: swin, o tamanho da sua janela de envio (que
pode ser ajustada pelo sistema) e rwin, o tamanho da janela de recebimento anunciada pelo destinatário. Em nenhum momento, o
5 . A
número de segmentos não reconhecidos não pode ser maior que min(swin,rwin)
utilização de janelas dinâmicas é ilustrada na figura abaixo.

O receptor pode ajustar a janela de recepção anunciada com base no consumo atual de memória, mas também para limitar a largura de
banda usada pelo remetente. Na prática, o buffer de recebimento também pode diminuir, pois o aplicativo pode não conseguir processar
os dados recebidos com rapidez suficiente. Nesse caso, o buffer de recebimento pode estar completamente cheio e a janela de
recebimento anunciada pode diminuir para 0. Quando o remetente recebe uma confirmação com uma janela de recebimento definida
como 0, ele é bloqueado até receber uma confirmação com uma janela de recebimento positiva. Infelizmente, conforme mostrado na
figura abaixo, a perda desta confirmação pode causar um impasse, pois o remetente espera por uma confirmação enquanto o destinatário
espera por um segmento de dados.

Para resolver este problema, os protocolos de transporte contam com um temporizador especial: o temporizador de persistência. Este
temporizador é iniciado pelo remetente sempre que recebe uma confirmação anunciando uma janela de recebimento definida como 0.
Quando o temporizador expira, o remetente retransmite um segmento antigo para forçar o destinatário a enviar uma nova confirmação
e, portanto, enviar a janela de recebimento atual. tamanho.

Para concluir a nossa descrição dos mecanismos básicos encontrados nos protocolos de transporte, ainda precisamos discutir o impacto
dos segmentos que chegam na ordem errada. Se dois segmentos consecutivos forem reordenados, o receptor dependerá de seus
números de sequência para reordená-los em seu buffer de recepção. Infelizmente, como os protocolos de transporte reutilizam o mesmo
número de sequência para segmentos diferentes, se um segmento for atrasado por um período prolongado de tempo, ele ainda poderá
ser aceito pelo receptor. Isso é ilustrado na figura abaixo, onde o segmento D(1,b) está atrasado.
4 Para uma discussão sobre como o buffer de envio pode mudar, veja, por exemplo,

[SMM1998] 5 Observe que se a janela de recebimento diminuir, pode acontecer que o remetente já tenha enviado um segmento que não está mais dentro de sua janela.
Este segmento será descartado pelo receptor e o remetente o retransmitirá posteriormente.

4.1. Princípios de um protocolo de transporte confiável Saylor 79

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

A B

Swin=3, rwin=1 Ruína=1

Dados.req(a)
0123

D(0,uma)
0123

Dados.ind(a) 0123

Swin=3, rwin=1

0123 C(OK,0, w=1)


Dados.req(b)
2 novos buffers se tornam
C(OK,0,w=3)
disponível
0123
Dados.req(c) D(1,b)
Swin=3, rwin=3
0123 D(2,c) Dados.ind(b)
Dados.req(d) C(OK,2,w=3)
D(3,d)
0123

Figura 4.20: Janela de recebimento dinâmico

Figura 4.21: Risco de impasse com janelas dinâmicas

80 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.22: Ambiguidades causadas por atrasos excessivos

Para lidar com este problema, os protocolos de transporte combinam duas soluções. Primeiro, eles usam 32 bits ou mais para
codificar o número de sequência no cabeçalho do segmento. Isto aumenta o overhead, mas também aumenta o atraso entre a
transmissão de dois segmentos diferentes tendo o mesmo número de sequência. Em segundo lugar, os protocolos de transporte
exigem que a camada de rede imponha um Tempo de Vida Máximo do Segmento (MSL). A camada de rede deve garantir que
nenhum pacote 6 permaneça na rede por mais de segundos MSL. Na Internet, presume-se que o MSL seja de 2 minutos RFC
793. Observe que isso limita a largura de banda máxima de um protocolo de transporte. Se usar n bits para codificar seus números
n
de sequência, então não poderá enviar mais de 2 segmentos a cada MSL segundos.

Os protocolos de transporte geralmente precisam enviar dados em ambas as direções. Para reduzir a sobrecarga causada pelas
confirmações, a maioria dos protocolos de transporte utiliza piggybacking. Graças a esta técnica, uma entidade de transporte
pode colocar dentro do cabeçalho os segmentos de dados que envia, as confirmações e a janela de recepção que anuncia para
a direção oposta do fluxo de dados. A principal vantagem do piggybacking é que ele reduz o overhead, pois não é necessário
enviar um segmento completo para transmitir uma confirmação. Isto é ilustrado na figura abaixo, onde o número de confirmação
está sublinhado nos segmentos de dados. O piggybacking só é usado quando os dados fluem em ambas as direções. Um receptor
gerará uma confirmação pura quando não enviar dados na direção oposta, conforme mostrado na parte inferior da figura.

Figura 4.23: Pegando carona

6
Como veremos no próximo capítulo, a Internet não aplica estritamente este MSL. Entretanto, é razoável esperar que a maioria dos
pacotes na Internet não permaneça na rede por mais de 2 minutos. Existem algumas exceções a esta regra, como RFC 1149 cuja
implementação está descrita em http://www.blug.linux.no/rfc1149/ mas existem poucos links reais que suportam RFC 1149 na internet.

4.1. Princípios de um protocolo de transporte confiável 81

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O último ponto a ser discutido sobre os mecanismos de transferência de dados utilizados pelos protocolos de transporte é a prestação de um
serviço de fluxo de bytes. Conforme indicado no primeiro capítulo, o serviço de fluxo de bytes é amplamente utilizado na camada de transporte.
Os protocolos de transporte que fornecem um serviço de fluxo de bytes associam um número de sequência a todos os bytes que são enviados
e colocam o número de sequência do primeiro byte do segmento no cabeçalho do segmento. Isto é ilustrado na figura abaixo. Neste exemplo,
o remetente opta por colocar dois bytes em cada um dos três primeiros segmentos. Isto se deve a razões gráficas; na prática, um protocolo
de transporte real usaria segmentos maiores. Contudo, a divisão do fluxo de bytes em segmentos combinada com as perdas e retransmissões
explicam porque o serviço de fluxo de bytes não preserva os limites do SDU.

Figura 4.24: Prestação do serviço de fluxo de bytes

Estabelecimento e liberação de conexão

Os últimos pontos a serem discutidos sobre o protocolo de transporte são os mecanismos utilizados para estabelecer e liberar uma conexão
de transporte.

Explicamos nos primeiros capítulos as primitivas de serviço usadas para estabelecer uma conexão. A abordagem mais simples para
estabelecer uma ligação de transporte seria definir dois segmentos de controlo especiais: CR e CA. O segmento CR é enviado pela entidade
de transporte que deseja iniciar uma conexão. Se a entidade remota desejar aceitar a conexão, ela responde enviando um segmento CA. A
conexão de transporte é considerada estabelecida assim que o segmento CA for recebido e os segmentos de dados puderem ser enviados
em ambas as direções.

Figura 4.25: Estabelecimento ingênuo de conexão de transporte

Infelizmente, este esquema não é suficiente por diversas razões. Primeiro, uma entidade de transporte normalmente precisa manter diversas
conexões de transporte com entidades remotas. Às vezes, diferentes usuários (isto é, processos) executados acima de uma determinada
entidade de transporte solicitam o estabelecimento de diversas conexões de transporte para diferentes usuários vinculados à mesma entidade
de transporte remota. Estas diferentes conexões de transporte devem ser claramente separadas para garantir que os dados de uma conexão
não sejam passados para as outras conexões. Isto pode ser conseguido através da utilização de um identificador de ligação, escolhido pelas
entidades de transporte e colocado dentro de cada segmento para permitir à entidade que recebe um segmento associá-lo facilmente a uma
ligação estabelecida.

82 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Segundo, como a camada de rede é imperfeita, o segmento CR ou CA pode ser perdido, atrasado ou sofrer erros de transmissão. Para
lidar com estes problemas, os segmentos de controle devem ser protegidos usando um CRC ou checksum para detectar erros de
transmissão. Além disso, uma vez que o segmento CA reconhece a recepção do segmento CR, o segmento CR pode ser protegido
utilizando um temporizador de retransmissão.

Infelizmente, este regime não é suficiente para garantir a fiabilidade do serviço de transporte. Consideremos, por exemplo, uma ligação
de transporte de curta duração onde é enviada uma transferência única, mas importante (por exemplo, transferência de dinheiro de uma
conta bancária). Essa conexão de curta duração começa com um segmento CR reconhecido por um segmento CA, depois o segmento
de dados é enviado, confirmado e a conexão termina. Infelizmente, como o serviço da camada de rede não é confiável, os atrasos
combinados com as retransmissões podem levar à situação ilustrada na figura abaixo, onde um CR atrasado e segmentos de dados de
uma conexão anterior são aceitos pela entidade receptora como segmentos válidos, e os dados correspondentes é entregue ao usuário.
A duplicação de SDUs não é aceitável e o protocolo de transporte deve resolver este problema.

Figura 4.26: Conexões de transporte duplicadas?

Para evitar essas duplicatas, os protocolos de transporte exigem que a camada de rede limite o Tempo de Vida Máximo do Segmento
(MSL). A organização da rede deve garantir que nenhum segmento permaneça na rede por mais de segundos MSL. Na Internet de hoje,
espera-se que o MSL dure 2 minutos. Para evitar ligações de transporte duplicadas, as entidades do protocolo de transporte devem ser
capazes de distinguir com segurança entre um segmento CR duplicado e um novo segmento CR, sem forçar cada entidade de transporte
a lembrar-se de todas as ligações de transporte que estabeleceu no passado.

Uma solução clássica para evitar lembrar as conexões de transporte anteriores para detectar duplicatas é usar um relógio dentro de cada
entidade de transporte. Este relógio de transporte possui as seguintes características:

• o clock de transporte é implementado como um contador de bits k e seu ciclo de clock é tal que 2 k × ciclo >> MSL.

Além disso, o contador do relógio de transporte é incrementado a cada ciclo de relógio e após cada estabelecimento de conexão.
Este relógio está ilustrado na figura abaixo.

• o relógio de transporte deve continuar a ser incrementado mesmo se a entidade de transporte parar ou reinicializar

Figura 4.27: Relógio de transporte

Deve-se notar que os relógios de transporte não precisam e geralmente não são sincronizados com o relógio de tempo real.
A sincronização precisa dos relógios em tempo real é um problema interessante, mas está fora do escopo deste documento.
Veja [Mills2006] para uma discussão detalhada sobre a sincronização do relógio em tempo real.

4.1. Princípios de um protocolo de transporte confiável Saylor 83

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O relógio de transporte é combinado com uma troca de três segmentos, chamada handshake de três vias, para detectar
duplicatas. Este handshake de três vias ocorre da seguinte maneira:

1. A entidade de transporte inicial envia um segmento CR. Este segmento solicita o estabelecimento de uma
ligação de transporte. Contém um identificador de conexão (não mostrado na figura) e um número de
sequência (seq=x na figura abaixo) cujo valor é extraído do clock de transporte. A transmissão do segmento
. CR é protegida por um temporizador de retransmissão.

2. A entidade de transporte remota processa o segmento CR e cria o estado para a tentativa de conexão.
Nesta fase, a entidade remota ainda não sabe se se trata de uma nova tentativa de ligação ou de um
segmento duplicado. Ele retorna um segmento CA que contém um número de confirmação para confirmar
a recepção do segmento CR (ack=x na figura abaixo) e um número de sequência (seq=y na figura abaixo)
cujo valor é extraído do seu clock de transporte. Nesta fase, a ligação ainda não está estabelecida.

3. A entidade iniciadora recebe o segmento CA. O número de confirmação deste segmento confirma que a
entidade remota recebeu corretamente o segmento CA. A ligação de transporte é considerada estabelecida
pela entidade iniciadora e a numeração dos segmentos de dados começa no número de sequência x.
Antes de enviar segmentos de dados, a entidade iniciadora deve confirmar os segmentos de CA recebidos
enviando outro segmento de CA.

4. A entidade remota considera que a ligação de transporte foi estabelecida após ter recebido o segmento que
reconhece o seu segmento CA. A numeração dos segmentos de dados enviados pela entidade remota
começa no número de sequência y.

O handshake de três vias é ilustrado na figura abaixo.

Figura 4.28: Aperto de mão de três vias

Graças ao handshake triplo, as entidades de transporte evitam conexões de transporte duplicadas. Isto é ilustrado pelos três
cenários abaixo.

O primeiro cenário é quando a entidade remota recebe um segmento CR antigo. Ele considera este segmento CR como uma
tentativa de estabelecimento de conexão e responde enviando um segmento CA. Entretanto, o host inicial não pode
corresponder o segmento CA recebido com uma tentativa de conexão anterior. Ele envia um segmento de controle (REJECT
na figura abaixo) para cancelar a tentativa de conexão espúria. A entidade remota cancela a tentativa de conexão após a
recepção deste segmento de controle.

Um segundo cenário é quando a entidade iniciadora envia um segmento CR que não alcança a entidade remota e recebe um
segmento CA duplicado de uma tentativa de conexão anterior. Este segmento CA duplicado não pode conter uma confirmação
válida para o segmento CR, pois o número de sequência do segmento CR foi extraído do relógio de transporte da entidade
iniciadora. O segmento CA é assim rejeitado e o segmento CR é retransmitido após a expiração do temporizador de
retransmissão.

O último cenário é menos provável, mas é importante considerá-lo também. A entidade remota recebe um segmento CR antigo.
Ele anota a tentativa de conexão e a confirma enviando um segmento CA. A entidade iniciadora

84 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.29: Handshake de três vias: recuperação de um CR duplicado

Figura 4.30: Handshake triplo: recuperação de uma CA duplicada

4.1. Princípios de um protocolo de transporte confiável 85


Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

não tem uma tentativa de conexão correspondente e responde enviando um REJECT. Infelizmente, este segmento nunca chega à
entidade remota. Em vez disso, a entidade remota recebe uma retransmissão de um segmento CA mais antigo que contém o mesmo
número de sequência que o primeiro segmento CR. Este segmento CA não pode ser aceite pela entidade remota como uma
confirmação da ligação de transporte, uma vez que o seu número de confirmação não pode ter o mesmo valor que o número de
sequência do primeiro segmento CA.

Figura 4.31: Handshake triplo: recuperação de duplicatas CR e CA

Quando discutimos o serviço orientado à conexão, mencionamos que existem dois tipos de liberação de conexão: liberação abrupta
e liberação graciosa.

A primeira solução para liberar uma conexão de transporte é definir um novo segmento de controle (por exemplo, o segmento DR) e
considerar a conexão liberada assim que esse segmento for enviado ou recebido. Isto é ilustrado na figura abaixo.

Figura 4.32: Liberação abrupta da conexão

Como a entidade que envia o segmento DR não pode saber se a outra entidade já enviou todos os seus dados na conexão, os SDUs
podem ser perdidos durante uma liberação tão abrupta da conexão.

O segundo método para liberar uma conexão de transporte é liberar independentemente as duas direções de transferência de dados.
Depois que um usuário do serviço de transporte envia todos os seus SDUs, ele executa um DISCONNECT.req para a direção da
transferência de dados. A entidade de transporte envia um segmento de controle para solicitar a liberação da conexão após a entrega
de todos os SDUs anteriores ao usuário remoto. Isso geralmente é feito colocando no DR o próximo número de sequência e
entregando o DISCONNECT.ind somente após todos os DATA.ind anteriores. A entidade remota confirma a recepção do segmento
DR e a liberação da direção correspondente de transferência de dados retornando uma confirmação.
Isto é ilustrado na figura abaixo.

86 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.33: Liberação graciosa da conexão

4.2 O Protocolo de Datagrama do Usuário

O User Datagram Protocol (UDP) é definido na RFC 768. Ele fornece um serviço de transporte sem conexão não confiável além do serviço
sem conexão da camada de rede não confiável. As principais características do serviço UDP
são :

7
• o serviço UDP não pode entregar SDUs maiores que 65.507 bytes

• o serviço UDP não garante a entrega de SDUs (podem ocorrer perdas e desquencing)

• o serviço UDP não entregará um SDU corrompido ao destino

Comparado ao serviço da camada de rede sem conexão, a principal vantagem do serviço UDP é que ele permite que vários aplicativos
executados em um host troquem SDUs com vários outros aplicativos executados em hosts remotos.
Consideremos dois hosts, por exemplo, um cliente e um servidor. O serviço da camada de rede permite que o cliente envie informações
ao servidor, mas se um aplicativo em execução no cliente quiser entrar em contato com um aplicativo específico em execução no servidor,
será necessário um mecanismo de endereçamento adicional além do endereço IP que identifica um host, para diferenciar o aplicativo em
execução em um host. Este endereçamento adicional é fornecido por números de porta. Quando um servidor que usa UDP está habilitado
em um host, esse servidor registra um número de porta. Este número de porta será utilizado pelos clientes para contatar o processo do
servidor via UDP.

A figura abaixo mostra um uso típico dos números de porta UDP. O processo do cliente usa a porta número 1234 enquanto o processo do
servidor usa a porta número 5678. Quando o cliente envia uma solicitação, ela é identificada como originária da porta número 1234 no host
do cliente e destinada à porta número 5678 no host do servidor. Quando o processo do servidor responder a esta solicitação, a
implementação UDP do servidor enviará a resposta como originada da porta 5678 no host do servidor e destinada à porta 1234 no host do
cliente.

O UDP usa um formato de segmento único mostrado na figura abaixo.

O cabeçalho UDP contém quatro campos:

• uma porta de origem de 16 bits

• uma porta de destino de 16 bits

• um campo de comprimento de 16 bits

• uma soma de verificação de 16 bits

Como os números das portas são codificados como um campo de 16 bits, pode haver até 65.535 processos de servidor diferentes
vinculados a uma porta UDP diferente ao mesmo tempo em um determinado servidor. Na prática, esse limite nunca é atingido. No entanto,
vale a pena notar que a maioria das implementações divide o intervalo de números de portas UDP permitidos em três intervalos diferentes:

7
Essa limitação se deve ao fato da camada de rede (IPv4 e IPv6) não poder transportar pacotes maiores que 64 KBytes. Como o UDP não
inclui nenhum mecanismo de segmentação/remontagem, ele não pode dividir um SDU antes de enviá-lo.

4.2. URL Saylor do protocolo de datagrama 87

do usuário : http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.34: Uso dos números de porta UDP

Figura 4.35: Formato do cabeçalho UDP

• os números de porta privilegiada (1 < porta < 1024 )


8
• os números de porta efêmeros (oficialmente 49152 <= porta <= 65535 )

• os números de porta registrados (oficialmente 1024 <= porta <49152)

Na maioria das variantes Unix, apenas processos com privilégios de administrador de sistema podem ser vinculados a números de
porta menores que 1024. Servidores conhecidos como DNS, NTP ou RPC usam números de porta privilegiados. Quando um cliente
precisa usar UDP, geralmente não é necessário um número de porta específico. Neste caso, a implementação do UDP alocará o
primeiro número de porta disponível no intervalo efêmero. O intervalo de números de porta registrados deve ser usado pelos servidores.
Em teoria, os desenvolvedores de servidores de rede deveriam registrar oficialmente seu número de porta por meio da IANA, mas
poucos desenvolvedores fazem isso.

Nota: Cálculo da soma de verificação UDP

A soma de verificação do segmento UDP é calculada em:

• um pseudocabeçalho contendo o endereço IP de origem, o endereço IP de destino e um campo de bits de 32 bits contendo o
byte mais significativo definido como 0, o segundo definido como 17 e o comprimento do segmento UDP nos dois bytes inferiores

• todo o segmento UDP, incluindo seu cabeçalho

Este pseudocabeçalho permite ao receptor detectar erros que afetam os endereços IP de origem ou destino colocados na camada IP
abaixo. Isto é uma violação do princípio de camadas que data da época em que UDP e IP eram elementos de um único protocolo.
Deve-se notar que se o algoritmo de checksum calcular o valor '0x0000', então o valor '0xffff' será transmitido. Um segmento UDP cuja
soma de verificação está definida como '0x0000' é um segmento para o qual o transmissor não calculou uma soma de verificação na
transmissão. Alguns servidores NFS optaram por desativar as somas de verificação UDP por motivos de desempenho, mas isso
causou problemas que eram difíceis de diagnosticar. Na prática, raramente há bons motivos para desabilitar as somas de verificação
UDP. Uma discussão detalhada sobre a implementação da soma de verificação da Internet pode ser encontrada na RFC 1071

Vários tipos de aplicativos dependem de UDP. Como regra geral, o UDP é usado para aplicações onde o atraso deve ser minimizado
ou as perdas podem ser recuperadas pela própria aplicação. Uma primeira classe de aplicativos baseados em UDP são aplicativos
onde o cliente envia uma solicitação curta e espera uma resposta rápida e curta. O DNS é um exemplo de

8
Uma discussão sobre os intervalos de portas efêmeras usadas por diferentes implementações TCP/UDP pode ser encontrada em
http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html

88 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

um aplicativo UDP que é frequentemente usado em áreas amplas. No entanto, em redes locais, muitos sistemas distribuídos dependem de
Chamada de Procedimento Remoto (RPC) , que é frequentemente usada em cima do UDP. Em ambientes Unix, o Network File System
(NFS) é construído sobre RPC e é executado frequentemente sobre UDP. Uma segunda classe de aplicações baseadas em UDP são os
jogos de computador interativos que precisam trocar frequentemente pequenas mensagens, como a localização do jogador ou suas ações
recentes. Muitos desses jogos usam UDP para minimizar o atraso e podem se recuperar de perdas. Uma terceira classe de aplicações são
as aplicações multimídia, como Voz sobre IP interativa ou Vídeo sobre IP interativo. Esses aplicativos interativos esperam um atraso menor
que cerca de 200 milissegundos entre o remetente e o destinatário e podem se recuperar de perdas diretamente dentro do aplicativo.

4.3 O Protocolo de Controle de Transmissão

O Transmission Control Protocol (TCP) foi inicialmente definido na RFC 793. Várias partes do protocolo foram melhoradas desde a
9
publicação da especificação original do protocolo. No entanto, os princípios básicos do protocolo permanecem e uma implementação que
suporta apenas RFC 793 devem interoperar com a implementação atual.

O TCP fornece um serviço de transporte confiável orientado à conexão e fluxo de bytes, além do serviço de rede não confiável e sem
conexão fornecido pelo IP. O TCP é usado por um grande número de aplicativos, incluindo:

• E-mail (SMTP, POP, IMAP)

• Rede mundial de computadores ( HTTP, ...)

• A maioria dos protocolos de transferência de arquivos ( ftp, aplicativos de compartilhamento de arquivos ponto a ponto, ...)

• acesso remoto a computadores: telnet, ssh, X11, VNC, ...

• aplicações multimídia não interativas: flash


10
Na Internet global, a maioria das aplicações utilizadas em áreas amplas dependem do TCP. Muitos estudos afirmam tem reportado
que o TCP foi responsável por mais de 90% dos dados trocados na Internet global.

Para fornecer este serviço, o TCP depende de um formato de segmento simples mostrado na figura abaixo. Cada segmento TCP contém
um cabeçalho descrito abaixo e, opcionalmente, uma carga útil. O comprimento padrão do cabeçalho TCP é de vinte bytes, mas alguns
cabeçalhos TCP contêm opções.

Figura 4.36: Formato do cabeçalho TCP

Um cabeçalho TCP contém os seguintes campos:

• Portas de origem e destino. As portas de origem e destino desempenham um papel importante no TCP, pois permitem a identificação
da conexão à qual pertence um segmento TCP. Quando um cliente abre uma conexão TCP, ele normalmente seleciona um número
de porta TCP efêmero como sua porta de origem e entra em contato com o servidor usando o número da porta do servidor. Todos
os segmentos enviados pelo cliente nesta conexão possuem as mesmas portas de origem e destino. O servidor envia segmentos
que contêm como fonte (resp. porta de destino, o

9
Uma apresentação detalhada de todos os documentos de padronização relativos ao TCP pode ser encontrada na RFC 4614
10 A maioria desses estudos
Vários pesquisadores analisaram a utilização de TCP e UDP na Internet global.
As tentativas foram realizadas coletando todos os pacotes transmitidos por um determinado enlace durante um período de algumas horas ou dias e depois
analisando seus cabeçalhos para inferir o protocolo de transporte utilizado, o tipo de aplicação, ...
Estudos recentes incluem http://www.caida.org/research/traffic-análise/tcpudpratio/, https://research.sprintlabs.com/packstat/
packetoverview.php ou http://www.nanog.org/meetings/nanog43/presentations/Labovitz_internetstats_N43.pdf

4.3. O Protocolo de Controle de Transmissão 89

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

porta de destino (resp. origem) dos segmentos enviados pelo cliente (ver figura Utilização das portas TCP origem e destino). Uma
conexão TCP é sempre identificada por cinco informações:

– o endereço IP do cliente

– o endereço IP do servidor

– a porta escolhida pelo cliente

– a porta escolhida pelo servidor

–TCP _

• os campos de número de sequência (32 bits), número de confirmação (32 bits) e janela (16 bits) são usados para fornecer uma
transferência de dados confiável, usando um protocolo baseado em janela. Em um bytestream TCP, cada byte do fluxo consome
um número de sequência. Sua utilização será descrita com mais detalhes na seção Transferência confiável de dados TCP.

• o ponteiro Urgente é usado para indicar que alguns dados devem ser considerados urgentes em um fluxo de bytes TCP.
No entanto, raramente é utilizado na prática e não será descrito aqui. Detalhes adicionais sobre a utilização deste ponteiro podem
ser encontrados na RFC 793, RFC 1122 ou [Stevens1994]

• o campo flags contém um conjunto de flags de bits que indicam como um segmento deve ser interpretado pela entidade TCP
recebendo:

– o sinalizador SYN é usado durante o estabelecimento da conexão

– o sinalizador FIN é usado durante a liberação da conexão

– o RST é utilizado em caso de problemas ou quando um segmento inválido foi recebido

– quando o sinalizador ACK está definido, indica que o campo de confirmação contém um número válido. Outro-
Neste sentido, o conteúdo do campo de confirmação deve ser ignorado pelo receptor

– o sinalizador URG é usado junto com o ponteiro Urgente

– o flag PSH é usado como uma notificação do remetente para indicar ao destinatário que ele deve passar todos os dados
recebidos para o processo receptor. Entretanto, na prática, as implementações do TCP não permitem que os usuários do
TCP indiquem quando o sinalizador PSH deve ser definido e, portanto, há poucas utilizações reais deste sinalizador.

• o campo checksum contém o valor da soma de verificação da Internet computada em todo o segmento TCP e
um pseudo-cabeçalho como no UDP

• o campo Reservado foi inicialmente reservado para utilização futura. Agora é usado pela RFC 3168.

• o campo TCP Header Length (THL) ou Data Offset é um campo de quatro bits que indica o tamanho do cabeçalho TCP em palavras
de 32 bits. O tamanho máximo do cabeçalho TCP é, portanto, 64 bytes.

• a extensão do cabeçalho Opcional é usada para adicionar informações opcionais ao cabeçalho TCP. Graças a esta extensão de
cabeçalho, é possível adicionar novos campos ao cabeçalho TCP que não foram planejados na especificação original. Isso permitiu
que o TCP evoluísse desde o início dos anos oitenta. Os detalhes da extensão do cabeçalho TCP são explicados nas seções
Estabelecimento de conexão TCP e Transferência confiável de dados TCP.

O restante desta seção está organizado da seguinte forma. Primeiro explicamos o estabelecimento e a liberação de uma conexão TCP e
depois discutimos os mecanismos que são usados pelo TCP para fornecer um serviço confiável de fluxo de bytes. Terminamos a seção
com uma discussão sobre o congestionamento da rede e explicamos os mecanismos que o TCP utiliza para evitar o colapso do
congestionamento.

4.3.1 Estabelecimento de conexão TCP

Uma conexão TCP é estabelecida usando um handshake de três vias. A fase de estabelecimento da conexão utiliza o número de sequência,
o número de confirmação e o sinalizador SYN. Quando uma conexão TCP é estabelecida, os dois hosts em comunicação negociam o
número de sequência inicial a ser usado em ambas as direções da conexão. Para isso, cada entidade TCP mantém um contador de 32 bits,
que deve ser incrementado em um pelo menos a cada 4 bits.

90 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.37: Utilização das portas TCP de origem e destino

microssegundos e após cada estabelecimento de conexão 11. Quando um host cliente deseja abrir uma conexão TCP com um
host servidor, ele cria um segmento TCP com:

• o sinalizador SYN definido

• o número de sequência definido como o valor atual do contador de 32 bits da entidade TCP do host cliente

Após a recepção deste segmento (que geralmente é chamado de segmento SYN), o host do servidor responde com um
segmento contendo:

• o sinalizador SYN definido

• o número de sequência definido como o valor atual do contador de 32 bits da entidade TCP do host do servidor

• o sinalizador ACK definido

• o número de confirmação definido como o número de sequência do segmento SYN recebido incrementado em 1 (mod 2
32). Quando uma entidade TCP envia um segmento tendo x+1 como número de confirmação, isso indica que ela recebeu
todos os dados até e incluindo o número de sequência x e que está esperando dados com o número de sequência x+1.
Como o sinalizador SYN foi definido em um segmento com número de sequência x, isso implica que definir o sinalizador
SYN em um segmento consome um número de sequência.

Este segmento é frequentemente chamado de segmento SYN+ACK. A confirmação confirma ao cliente que o servidor recebeu
corretamente o segmento SYN. O número de sequência do segmento SYN+ACK é usado pelo host do servidor para verificar se
o cliente recebeu o segmento. Após a recepção do segmento SYN+ACK, o host cliente responde com um segmento contendo:

• o sinalizador ACK definido

• o número de confirmação definido como o número de sequência do segmento SYN+ACK recebido incrementado
por 1 ( mod 2 32)

Neste ponto, a conexão TCP está aberta e tanto o cliente quanto o servidor podem enviar segmentos TCP contendo dados. Isto
é ilustrado na figura abaixo.

Na figura acima, a conexão é considerada estabelecida pelo cliente ao receber o segmento SYN+ACK, enquanto o servidor
considera a conexão estabelecida ao receber o segmento ACK. O primeiro segmento de dados enviado pelo cliente (servidor)
tem seu número de sequência definido como x+1 (resp. y+1).

Nota: Calculando o número de sequência inicial do TCP

Na especificação TCP original RFC 793, cada entidade TCP manteve um relógio para calcular o número de sequência inicial
(ISN) colocado nos segmentos SYN e SYN+ACK. Isto tornou o ISN previsível e causou um problema de segurança. O problema
de segurança típico era o seguinte. Considere um servidor que confia em um host com base em seu endereço IP
11 Este contador de 32 bits foi especificado na RFC 793. Um contador de 32 bits que é incrementado a cada 4 microssegundos dura cerca de 4,5 horas.

Este período é muito maior do que o Tempo de Vida Máximo do Segmento que é fixado em 2 minutos na Internet ( RFC 791, RFC 1122).

4.3. O Protocolo de Controle de Transmissão 91


URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.38: Estabelecimento de uma conexão TCP

e permite que o administrador do sistema faça login neste host sem fornecer uma senha 12. Considere agora um invasor que
conhece esta configuração específica e é capaz de enviar pacotes IP tendo o endereço do cliente como origem. Ele pode enviar
segmentos TCP falsos ao servidor, mas não recebe as respostas do servidor. Se ele conseguir prever o ISN que é escolhido
pelo servidor, ele poderá enviar um segmento SYN falso e logo após o segmento ACK falso confirmando a recepção do segmento
SYN+ACK enviado pelo servidor. Assim que a conexão TCP estiver aberta, ele poderá usá-la para enviar qualquer comando ao
servidor. Para combater esse ataque, as implementações atuais do TCP adicionam aleatoriedade ao ISN. Uma das soluções,
proposta na RFC 1948 é calcular o ISN como

ISN = M + H(localhost, porta local, host remoto, porta remota, segredo).

onde M é o valor atual do clock TCP e H'é uma função hash criptográfica. 'localhost e remotehost (resp. localport e remoteport)
são os endereços IP (números de porta) do host local e remoto e secret é um número aleatório conhecido apenas pelo servidor.
Este método permite que o servidor use ISNs diferentes para clientes diferentes ao mesmo tempo. Medidas realizados com as
primeiras implementações desta técnica mostraram que era difícil implementá-la corretamente, mas a implementação atual do
TCP agora gera bons ISNs.

Um servidor poderia, é claro, recusar-se a abrir uma conexão TCP ao receber um segmento SYN. Esta recusa pode dever-se a
vários motivos. Pode não haver nenhum processo do servidor escutando na porta de destino do segmento SYN.
O servidor pode sempre recusar o estabelecimento de conexão deste cliente específico (por exemplo, por razões de segurança)
ou o servidor pode não ter recursos suficientes para aceitar uma nova conexão TCP naquele momento. Neste caso, o servidor
responderia com um segmento TCP tendo seu sinalizador RST definido e contendo o número de sequência do segmento SYN
recebido como seu número de confirmação. Isto é ilustrado na figura abaixo. Discutiremos as outras utilizações do sinalizador
TCP RST posteriormente (consulte Liberação da conexão TCP).

Figura 4.39: Estabelecimento de conexão TCP rejeitado pelo peer

O estabelecimento da conexão TCP pode ser descrito como a Máquina de Estados Finitos de quatro estados mostrada abaixo.
Neste FSM, !X (resp. ?Y) indica a transmissão do segmento X (resp. recepção do segmento Y) durante a transição correspondente.
Init é o estado inicial.

Um host cliente inicia no estado Init. Em seguida, ele envia um segmento SYN e entra no estado SYN Enviado, onde aguarda
um segmento SYN+ACK. Em seguida, ele responde com um segmento ACK e entra no estado Estabelecido, onde os dados podem
12
Em muitas redes departamentais contendo estações de trabalho Unix, era comum permitir que usuários em um dos hosts usassem rlogin RFC 1258
executar comandos em qualquer uma das estações de trabalho da rede sem fornecer nenhuma senha. Neste caso, a estação de trabalho remota “autenticou”
o host cliente com base em seu endereço IP. Esta foi uma má prática do ponto de vista da segurança.

92 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.40: TCP FSM para estabelecimento de conexão

ser trocado. Por outro lado, um host de servidor inicia no estado Init. Quando um processo do servidor começa a escutar
uma porta de destino, a entidade TCP subjacente cria um bloco de controle TCP e uma fila para processar os segmentos
SYN recebidos. Após a recepção de um segmento SYN, a entidade TCP do servidor responde com um SYN+ACK e entra
no estado SYN RCVD. Ele permanece neste estado até receber um segmento ACK que reconhece seu segmento
SYN+ACK, com isso entra no estado Estabelecido.

Além desses dois caminhos no FSM de estabelecimento de conexão TCP, existe um terceiro caminho que corresponde
ao caso em que tanto o cliente quanto o servidor enviam um segmento SYN para abrir uma conexão TCP 13. Neste caso,
o cliente e o servidor enviam um segmento SYN e entre no estado SYN Enviado. Ao receber o segmento SYN enviado
pelo outro host, eles respondem enviando um segmento SYN+ACK e entram no estado SYN RCVD. O SYN+ACK que
chega do outro host permite a transição para o estado Estabelecido. A figura abaixo ilustra esse estabelecimento
simultâneo de uma conexão TCP.

Figura 4.41: Estabelecimento simultâneo de uma conexão TCP

13
É claro que tal estabelecimento simultâneo de TCP só pode ocorrer se a porta de origem escolhida pelo cliente for igual à porta de destino escolhida pelo
servidor. Isso pode acontecer quando um host pode servir tanto como cliente quanto como servidor ou em aplicações peer-to-peer quando os hosts em comunicação
não usam números de porta efêmeros.

4.3. O Protocolo de Controle de Transmissão 93

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Ataques de negação de serviço

Quando uma entidade TCP abre uma conexão TCP, ela cria um Bloco de Controle de Transmissão (TCB). O TCB contém
todo o estado mantido pela entidade TCP para cada conexão TCP. Durante o estabelecimento da conexão, o TCB contém o
endereço IP local, o endereço IP remoto, o número da porta local, o número da porta remota, o número de sequência local
atual, o último número de sequência recebido da entidade remota. Até meados da década de 1990, as implementações de
TCP tinham um limite no número de conexões TCP que poderiam estar no estado SYN RCVD em um determinado momento.
Muitas implementações definem esse limite para cerca de 100 TCBs. Este limite foi considerado suficiente mesmo para
servidores http com carga pesada dado o pequeno atraso entre a recepção de um segmento SYN e a recepção do segmento
ACK que finaliza o estabelecimento da conexão TCP.
Quando o limite de 100 TCBs no estado SYN Rcvd é atingido, a entidade TCP descarta todos os segmentos TCP SYN
recebidos que não correspondem a um TCB existente.
Este limite de 100 TCBs no estado SYN Rcvd foi escolhido para proteger a entidade TCP do risco de sobrecarregar sua
memória com muitos TCBs no estado SYN Rcvd. No entanto, também foi o motivo de um novo tipo de ataque de negação de
serviço (DoS) RFC 4987. Um ataque DoS é definido como um ataque em que um invasor pode tornar um recurso indisponível
na rede. Por exemplo, um invasor pode causar um ataque DoS em um link de 2 Mbps usado por uma empresa, enviando
mais de 2 Mbps de pacotes através desse link. Neste caso, o ataque DoS foi mais sutil. Como uma entidade TCP descarta
todos os segmentos SYN recebidos assim que tem 100 TCBs no estado SYN Rcvd, um invasor simplesmente precisa enviar
alguns 100 segmentos SYN a cada segundo para um servidor e nunca responder aos segmentos SYN+ACK recebidos. Para
evitar serem pegos, os invasores estavam enviando esses segmentos SYN com um endereço diferente do seu próprio
endereço IP a . Na maioria das implementações TCP, uma vez que um TCB entra no estado SYN Rcvd, ele permanece
nesse estado por vários segundos, aguardando uma retransmissão do segmento SYN inicial. Este ataque foi mais tarde
chamado de ataque de inundação SYN e os servidores do ISP chamado Panix foram os primeiros a serem afetados. por este
ataque.
Para evitar ataques de inundação SYN, implementações recentes de TCP não entram mais no estado SYN Rcvd após a
recepção de um segmento SYN. Em vez disso, eles respondem diretamente com um segmento SYN+ACK e aguardam até a
recepção de um ACK válido. Este truque de implementação só é possível se a implementação TCP for capaz de verificar se
o segmento ACK recebido reconhece o segmento SYN+ACK enviado anteriormente sem armazenar o número de sequência
inicial deste segmento SYN+ACK em um TCB. A solução para resolver este problema, que é conhecida como cookies SYN é
calcular os 32 bits do ISN da seguinte forma: • os bits de ordem superior
contêm os bits de ordem inferior de um contador que é incrementado lentamente • os bits de ordem
inferior contêm um valor hash calculado sobre os endereços IP e portas locais e remotos e
um segredo aleatório conhecido apenas pelo
servidor A vantagem dos cookies SYN é que ao utilizá-los, o servidor não precisa criar um TCB ao receber o segmento SYN
e ainda pode verificar o segmento ACK retornado recomputando o cookie SYN.
a
O envio de um pacote com um endereço IP de origem diferente do endereço alocado ao host é chamado de envio de pacote falsificado.

Retransmitindo o primeiro segmento SYN

Como o IP fornece um serviço sem conexão não confiável, os segmentos SYN e SYN+ACK enviados para abrir uma conexão
TCP podem ser perdidos. As implementações TCP atuais iniciam um temporizador de retransmissão quando enviam o
primeiro segmento SYN. Este temporizador é frequentemente definido para três segundos para a primeira retransmissão e
depois dobra após cada retransmissão RFC 2988. As implementações TCP também impõem um número máximo de
retransmissões para o segmento SYN inicial.

Conforme explicado anteriormente, os segmentos TCP podem conter uma extensão de cabeçalho opcional. Nos segmentos SYN
e SYN+ACK, essas opções são utilizadas para negociar alguns parâmetros e a utilização de extensões à especificação TCP básica.

O primeiro parâmetro negociado durante o estabelecimento de uma conexão TCP é o Tamanho Máximo do Segmento (MSS). O
MSS é o tamanho do maior segmento que uma entidade TCP é capaz de processar. De acordo com a RFC 879, todas as
implementações TCP devem ser capazes de receber segmentos TCP contendo 536 bytes de carga útil. Entretanto, a maioria das
implementações TCP são capazes de processar segmentos maiores. Essas implementações TCP usam a opção TCP MSS no
segmento SYN/SYN+ACK para indicar o maior segmento que são capazes de processar. O valor MSS indica o tamanho máximo da
carga útil dos segmentos TCP. O cliente (resp. servidor) armazena em seu TCB o valor MSS anunciado pelo servidor (resp. cliente).

94 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Outra utilização das opções TCP durante o estabelecimento da conexão é habilitar extensões TCP. Por exemplo, considere RFC 1323
(que é discutido em Transferência confiável de dados TCP). RFC 1323 define extensões TCP para suportar carimbos de data e hora e
janelas maiores. Se o cliente suportar RFC 1323, adiciona um RFC 1323 opção para seu segmento SYN. Se o servidor entender este
RFC 1323 opção e deseja usá-la, ele responde com uma RFC 1323 opção no segmento SYN+ACK e a extensão definida na RFC 1323 é
usado em toda a conexão TCP.
Caso contrário, se o SYN+ACK do servidor não contiver o RFC 1323 opção, o cliente não tem permissão para usar esta extensão e as
opções de cabeçalho TCP correspondentes em toda a conexão TCP. O mecanismo de opções do TCP é flexível e permite a extensão do
TCP enquanto mantém a compatibilidade com implementações mais antigas.

As opções TCP são codificadas usando um formato Type Length Value onde:

• o primeiro byte indica o tipo da opção.

• o segundo byte indica o comprimento total da opção (incluindo os dois primeiros bytes) em bytes

• os últimos bytes são específicos para cada tipo de opção

RFC 793 define a opção TCP de tamanho máximo de segmento (MSS) que deve ser compreendida por todas as implementações de
TCP. Esta opção (tipo 2) tem comprimento de 4 bytes e contém uma palavra de 16 bits que indica o MSS suportado pelo remetente do
segmento SYN. A opção MSS só pode ser usada em segmentos TCP que tenham o sinalizador SYN definido.

RFC 793 também define duas opções especiais que devem ser suportadas por todas as implementações TCP. A primeira opção é Fim da
opção. Ele é codificado como um único byte com valor 0x00 e pode ser usado para garantir que a extensão do cabeçalho TCP termine
em um limite de 32 bits. A opção No-Operation, codificada como um único byte com valor 0x01, pode ser usada quando a extensão do
cabeçalho TCP contém várias opções TCP que devem ser alinhadas em limites de 32 bits.
14
Todas as outras opções são codificados usando o formato TLV.

Nota: O princípio da robustez

O tratamento das opções TCP por implementações TCP é uma das muitas aplicações do princípio da robustez que normalmente é
atribuída a Jon Postel e é frequentemente citado como “Seja liberal no que você aceita e conservador no que você envia” RFC 1122

No que diz respeito às opções TCP, o princípio da robustez implica que uma implementação TCP deve ser capaz de aceitar opções TCP
que não compreende, em particular em segmentos SYN recebidos, e que deve ser capaz de analisar qualquer segmento recebido sem
falhar, mesmo que o segmento contém uma opção TCP desconhecida. Além disso, um servidor não deve enviar no segmento SYN+ACK
ou posterior, opções que não tenham sido propostas pelo cliente no segmento SYN.

4.3.2 Liberação da conexão TCP

O TCP, como a maioria dos protocolos de transporte orientados à conexão, suporta dois tipos de liberação de conexão:

• liberação de conexão graciosa, onde cada usuário TCP pode liberar sua própria direção de transferência de dados

• liberação abrupta da conexão, onde um usuário fecha ambas as direções de transferência de dados ou uma entidade TCP é
forçada a fechar a conexão (por exemplo, porque o host remoto não responde mais ou devido à falta de recursos)

O mecanismo de liberação abrupta da conexão é muito simples e depende de um único segmento com o bit RST definido. Um segmento
TCP contendo o bit RST pode ser enviado pelos seguintes motivos:

• um segmento não-SYN foi recebido para uma conexão TCP inexistente RFC 793

• por extensão, algumas implementações respondem com um segmento RST a um segmento que é recebido em uma conexão
existente, mas com um cabeçalho RFC 3360 inválido. Isso faz com que a conexão correspondente seja fechada e causou ataques
de segurança RFC 4953

• por extensão, algumas implementações enviam um segmento RST quando precisam fechar uma conexão TCP existente (por
exemplo, porque não há recursos suficientes para suportar esta conexão ou porque o host remoto é considerado inacessível). As
medições mostraram que este uso do TCP RST foi generalizado [AW05]

14 A lista completa de todas as opções de TCP pode ser encontrada em http://www.iana.org/assignments/tcp-parameters/

4.3. O Protocolo de Controle de Transmissão 95

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Quando um segmento RST é enviado por uma entidade TCP, ele deve conter o valor atual do número de sequência da conexão
(ou 0 se não pertencer a nenhuma conexão existente) e o número de confirmação deve ser definido para a próxima entrada
esperada. número de sequência de sequência nesta conexão.

Nota: guerras TCP RST

Os implementadores de TCP devem garantir que duas entidades TCP nunca entrem em uma guerra TCP RST onde o host A
está enviando um segmento RST em resposta a um segmento RST anterior que foi enviado pelo host B em resposta a um
... TCP RST enviado pelo host A. troca infinita de segmentos RST que não transportam dados, uma entidade TCP
segmento
nunca pode enviar um segmento RST em resposta a outro segmento RST.

A maneira normal de encerrar uma conexão TCP é usando a liberação de conexão TCP graciosa. Este mecanismo utiliza o
sinalizador FIN do cabeçalho TCP e permite que cada host libere sua própria direção de transferência de dados. Quanto ao
sinalizador SYN, a utilização do sinalizador FIN no cabeçalho TCP consome um número de sequência. A figura FSM para
liberação de conexão TCP mostra a parte do FSM TCP usada quando uma conexão TCP é liberada.

Figura 4.42: FSM para liberação de conexão TCP

A partir do estado Estabelecido, existem dois caminhos principais através deste FSM.

O primeiro caminho é quando o host recebe um segmento com número de sequência x e o sinalizador FIN definido. A utilização
do sinalizador FIN indica que o byte anterior ao número de sequência x foi o último byte do fluxo de bytes enviado pelo host
remoto. Depois que todos os dados forem entregues ao usuário, a entidade TCP envia um segmento ACK cujo campo ack está
32
definido como (x + 1) mod 2 para reconhecer o segmento FIN. O segmento FIN está sujeito aos mesmos mecanismos de
retransmissão que um segmento TCP normal. Em particular, a sua transmissão é protegida pelo temporizador de retransmissão.
Neste ponto, a conexão TCP entra no estado CLOSE_WAIT. Neste estado, o host ainda pode enviar dados ao host remoto.
Depois que todos os seus dados forem enviados, ele envia um segmento FIN e entra no estado LAST_ACK. Neste estado, a
entidade TCP aguarda o reconhecimento do seu segmento FIN. Ele ainda poderá retransmitir segmentos de dados não
confirmados, por exemplo, se o temporizador de retransmissão expirar. Ao receber o reconhecimento do segmento FIN, a
conexão TCP é completamente fechada e seu TCB pode ser descartado.

O segundo caminho é quando o host decide primeiro enviar um segmento FIN. Neste caso, entra no estado FIN_WAIT1. Neste
estado, ele pode retransmitir segmentos não reconhecidos, mas não pode enviar novos segmentos de dados. Aguarda uma
confirmação do seu segmento FIN, mas pode receber um segmento FIN enviado pelo host remoto. No primeiro caso, a conexão
TCP entra no estado FIN_WAIT2. Neste estado, novos segmentos de dados do host remoto ainda são aceitos até a recepção
do segmento FIN. A confirmação para este segmento FIN é enviada assim que todos os dados recebidos antes do segmento
FIN forem entregues ao usuário e a conexão entrar no estado TIME_WAIT.
No segundo caso, um segmento FIN é recebido e a conexão entra no estado Closing assim que todos os dados recebidos do
host remoto forem entregues ao usuário. Neste estado, nenhum novo segmento de dados pode ser enviado e o host aguarda
uma confirmação do seu segmento FIN antes de entrar no estado TIME_WAIT.

O estado TIME_WAIT é diferente dos outros estados do TCP FSM. Uma entidade TCP entra neste estado após ter enviado o
último segmento ACK em uma conexão TCP. Este segmento indica ao host remoto que todos os dados que ele enviou foram
recebidos corretamente e que ele pode liberar com segurança a conexão TCP e descartar

96 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

o TCB correspondente . Após ter enviado o último segmento ACK, uma conexão TCP entra no TIME_WAIT e permanece neste
estado por 2 ÿ MSL segundos. Durante este período, o TCB da conexão é mantido. Isso garante que a entidade TCP que enviou
o último ACK mantenha estado suficiente para poder retransmitir este segmento caso este segmento ACK seja perdido e o host
remoto retransmita seu último segmento FIN ou outro. O atraso de 2 ÿ segundos MSL garante que quaisquer segmentos duplicados
na conexão sejam tratados corretamente sem causar a transmissão de um segmento RST. Sem o estado TIME_WAIT e o atraso
de 2 ÿ MSL segundos, a liberação da conexão não seria normal quando o último segmento ACK fosse perdido.

Nota: TIME_WAIT em servidores TCP ocupados

O atraso de 2 ÿ MSL segundos no estado TIME_WAIT é um problema operacional importante em servidores que possuem
milhares de conexões TCP abertas simultaneamente [FTY99]. Considere, por exemplo, um servidor web ocupado que processa
10.000 conexões TCP por segundo. Se cada uma dessas conexões permanecer no estado TIME_WAIT por 4 minutos, isso
implica que o servidor teria que manter mais de 2 milhões de TCBs a qualquer momento. Por esta razão, algumas implementações
TCP preferem realizar uma liberação abrupta da conexão enviando um segmento RST para fechar a conexão [AW05] e descartar
imediatamente o TCB correspondente . Contudo, se o segmento RST for perdido, o host remoto continua a manter um TCB para
uma conexão que não existe mais. Esta otimização reduz o número de TCBs mantidos pelo host que envia o segmento RST, mas
com o custo potencial de aumento de processamento no host remoto quando o segmento RST é perdido.

4.3.3 Transferência confiável de dados TCP

Os mecanismos originais de transferência de dados TCP foram definidos na RFC 793. Com base na experiência de utilização do
TCP na crescente Internet global, esta parte da especificação TCP foi atualizada e melhorada diversas vezes, sempre preservando
a compatibilidade retroativa com implementações TCP mais antigas. Nesta seção, revisamos os principais mecanismos de
transferência de dados utilizados pelo TCP.

TCP é um protocolo de transporte baseado em janela que fornece um serviço de fluxo de bytes bidirecional. Isto tem diversas
implicações nos campos do cabeçalho TCP e nos mecanismos utilizados pelo TCP. Os três campos do cabeçalho TCP
são :


número sequencial. O TCP usa um número de sequência de 32 bits. O número de sequência colocado no cabeçalho de
um segmento TCP contendo dados é o número de sequência do primeiro byte da carga útil do segmento TCP.

• número de confirmação. O TCP usa reconhecimentos positivos cumulativos. Cada segmento TCP contém o número de
sequência do próximo byte que o remetente da confirmação espera receber do host remoto. Em teoria, o número de
confirmação só é válido se o sinalizador ACK do cabeçalho TCP estiver definido.
15
Na prática, quase todos os segmentos TCP têm seu sinalizador ACK definido.

• janela. um receptor TCP usa este campo de 16 bits para indicar o tamanho atual de sua janela de recepção expressa
em bytes.

Nota: O Bloco de Controle de Transmissão

Para cada conexão TCP estabelecida, uma implementação TCP deve manter um Bloco de Controle de Transmissão (TCB).
Um TCB contém todas as informações necessárias para enviar e receber segmentos nesta conexão RFC 793. Este 16 inclui
:

• o endereço IP local

• o endereço IP remoto

• o número da porta TCP local

• o número da porta TCP remota

• o estado atual do TCP FSM

• o tamanho máximo do segmento (MSS)


15
Na prática, apenas o segmento SYN não possui seu flag ACK definido.
16
Uma implementação TCP completa contém informações adicionais em seu TCB, principalmente para apoiar o ponteiro urgente. No entanto, esta parte
O TCP não é discutido neste livro. Consulte RFC 793 e RFC 2140 para mais detalhes sobre o TCB.

4.3. O Protocolo de Controle de Transmissão 97

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• snd.nxt : o número de sequência do próximo byte no fluxo de bytes (o primeiro byte de um novo segmento de dados que
você envia usa este número de sequência)

• snd.una: o número de sequência mais antigo que foi enviado, mas ainda não foi reconhecido

• snd.wnd : o tamanho atual da janela de envio (em bytes)

• rcv.nxt: o número de sequência do próximo byte que se espera ser recebido do host remoto

• rcv.wnd : o tamanho atual da janela de recebimento anunciada pelo host remoto

• buffer de envio: um buffer usado para armazenar todos os dados não confirmados

• buffer de recebimento: um buffer para armazenar todos os dados recebidos do host remoto que ainda não foram entregues ao usuário. Os
dados podem ser armazenados no buffer de recebimento porque não foram recebidos em sequência ou porque o usuário é muito lento
para processá-los.

A especificação TCP original pode ser categorizada como um protocolo de transporte que fornece um serviço de fluxo de bytes e usa go-back-n.

Para enviar novos dados em uma conexão estabelecida, uma entidade TCP realiza as seguintes operações no TCB correspondente. Primeiro
verifica se o buffer de envio não contém mais dados do que a janela de recebimento anunciada pelo host remoto (rcv.wnd). Se a janela não
estiver cheia, até bytes MSS de dados serão colocados na carga útil de um segmento TCP. O número de sequência deste segmento é o número
de sequência do primeiro byte da carga útil. Ele é definido como o primeiro número de sequência disponível: snd.nxt e snd.nxt é incrementado
pelo comprimento da carga útil do segmento TCP. O número de confirmação deste segmento é definido como o valor atual de rcv.nxt e o campo
da janela do segmento TCP é calculado com base na ocupação atual do buffer de recebimento. Os dados são mantidos no buffer de envio caso
precisem ser retransmitidos posteriormente.

Quando um segmento TCP com o sinalizador ACK definido é recebido, as seguintes operações são executadas. rcv.wnd é definido como o valor
do campo da janela do segmento recebido. O número de confirmação é comparado ao snd.una. Os dados recém-reconhecidos são removidos
do buffer de envio e snd.una é atualizado. Se o segmento TCP contiver dados, o número de sequência será comparado a rcv.nxt. Se forem iguais,
o segmento foi recebido em sequência e os dados podem ser entregues ao usuário e o rcv.nxt é atualizado. O conteúdo do buffer de recebimento
é verificado para ver se outros dados já presentes neste buffer podem ser entregues em sequência ao usuário. Nesse caso, rcv.nxt será atualizado
novamente. Caso contrário, a carga útil do segmento é colocada no buffer de recebimento.

Estratégias de transmissão de segmento

Em um protocolo de transporte como o TCP que oferece bytestream, uma questão prática que foi deixada como opção de implementação na
RFC 793 é decidir quando um novo segmento TCP contendo dados deve ser enviado. Existem duas opções de implementação simples e
extremas. A primeira opção de implementação é enviar um segmento TCP assim que o usuário solicitar a transmissão de alguns dados. Isso
permite que o TCP forneça um serviço de baixo atraso. Entretanto, se o usuário estiver enviando dados um byte por vez, o TCP colocaria cada
byte do usuário em um segmento contendo 20 bytes do cabeçalho TCP 17. Esta é uma sobrecarga enorme que não é aceitável em redes de
longa distância. Uma segunda solução simples seria transmitir um novo segmento TCP somente depois que o usuário produzisse bytes de dados
MSS. Esta solução reduz a sobrecarga, mas ao custo de um atraso potencialmente muito elevado.

Uma solução elegante para este problema foi proposta por John Nagle na RFC 896. John Nagle observou que a sobrecarga causada pelo
cabeçalho TCP era um problema em conexões de longa distância, mas menor em conexões de área local, onde a largura de banda disponível é
geralmente maior. Ele propôs as seguintes regras para decidir enviar um novo segmento de dados quando um novo dado for produzido pelo
usuário ou um novo segmento de confirmação for recebido

se rcv.wnd>= MSS e len(dados) >= MSS :


envie um segmento de tamanho MSS, caso
contrário
se houver dados não confirmados: coloque os dados
no buffer até que a confirmação seja recebida, caso contrário

envie um segmento TCP contendo todos os dados em buffer

17
Este segmento TCP é então colocado em um cabeçalho IP. Descrevemos IPv4 e IPv6 no próximo capítulo. O tamanho mínimo do IPv4 (resp.
IPv6) tem 20 bytes (resp. 40 bytes).

98 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

A primeira regra garante que uma conexão TCP usada para transferência de dados em massa sempre envie segmentos TCP completos. O
a segunda regra envia um segmento TCP parcialmente preenchido a cada ida e volta.

Esse algoritmo, chamado algoritmo de Nagle, ocupa algumas linhas de código em todas as implementações TCP. Estas linhas de
O código tem um enorme impacto nos pacotes que são trocados em redes TCP/IP. Os pesquisadores analisaram o
distribuição dos tamanhos dos pacotes capturando e analisando todos os pacotes que passam por um determinado link. Esses
estudos mostraram vários resultados importantes:

• em redes TCP/IPv4, uma grande fração dos pacotes são segmentos TCP que contêm apenas uma confirmação. Esses pacotes
geralmente representam 40-50% dos pacotes que passam pelo enlace estudado.

• em redes TCP/IPv4, a maioria dos bytes é trocada em pacotes longos, geralmente pacotes contendo até
1460 bytes de carga útil, que é o MSS padrão para hosts conectados a uma rede Ethernet, o mais popular
tipo de LAN

A figura abaixo fornece uma distribuição dos tamanhos de pacotes medidos em um link. Ele mostra uma distribuição trimodal
do tamanho do pacote. 50% dos pacotes contêm confirmações TCP puras e ocupam 40 bytes. Cerca de 20%
18
dos pacotes contêm cerca de 500 bytes de dados do usuário e 12% dos pacotes contêm 1.460 bytes de dados do usuário.
No entanto, a maior parte dos dados do usuário é transportada em pacotes grandes. Esta distribuição de tamanho de pacote tem implicações
o projeto de roteadores conforme discutiremos no próximo capítulo.

Figura 4.43: Distribuição do tamanho dos pacotes na Internet

Medições recentes indicam que essas distribuições de tamanho de pacote ainda são válidas na Internet de hoje, embora o
a distribuição de pacotes tende a se tornar bimodal com pacotes pequenos correspondendo a acks puros TCP (40-64 bytes
dependendo da utilização das opções TCP) e grandes pacotes de 1460 bytes transportando a maior parte dos dados do usuário.

Janelas TCP

Do ponto de vista do desempenho, uma das principais limitações da especificação TCP original são os 16 bits
campo de janela no cabeçalho TCP. Como este campo indica o tamanho atual da janela de recebimento em bytes, ele limita o
Janela de recepção TCP em 65535 bytes. Esta limitação não foi um problema grave quando o TCP foi projetado, pois pelo menos
naquela época, as redes de longa distância de alta velocidade ofereciam uma largura de banda máxima de 56 kbps. No entanto, na rede de hoje,
19
esta limitação não é mais aceitável. A tabela abaixo fornece o esboço obtido por uma conexão rendimento máximo que pode ser
TCP com janela de 64 KBytes em função do tempo de ida e volta da conexão

Taxa de transferência máxima RTT


1 ms 524 Mbps

10 mseg 52,4 Mbps


100 mseg 5,24 Mbps
500 mseg 1,05 Mbps

Para resolver este problema, uma extensão compatível com versões anteriores que permite ao TCP usar janelas de recepção maiores foi
proposto na RFC 1323. Hoje, a maioria das implementações TCP suporta esta opção. A ideia básica é que em vez de

18
Quando essas medições foram feitas, alguns hosts tinham um MSS padrão de 552 bytes (por exemplo, derivados BSD Unix) ou 536 bytes (o padrão
MSS especificado na RFC 793). Hoje, a maioria das implementações de TCP derivam o MSS do tamanho máximo do pacote da interface LAN que usam.
(Ethernet na maioria dos casos).
19
Uma estimativa precisa da largura de banda máxima que pode ser alcançada por uma conexão TCP deve levar em conta o overhead da rede.
Cabeçalhos TCP e IP também.

4.3. O Protocolo de Controle de Transmissão 99

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

armazenando snd.wnd e rcv.wnd como inteiros de 16 bits no TCB, eles devem ser armazenados como inteiros de 32 bits. Como o
cabeçalho do segmento TCP contém apenas 16 bits para colocar o campo da janela, é impossível copiar o valor de snd.wnd em cada
segmento TCP enviado. Em vez disso, o cabeçalho contém snd.wnd >> S onde S é o fator de escala ( 0 ÿ S ÿ 14) negociado durante o
estabelecimento da conexão. O cliente adiciona seu fator de escala proposto como uma opção TCP no segmento SYN. Se o servidor
suportar RFC 1323, ele coloca no segmento SYN+ACK o fator de escala que utiliza ao anunciar sua própria janela de recebimento. Os
fatores de escala local e remoto estão incluídos no TCB. Se o servidor não suportar RFC 1323, ignora a opção recebida e nenhuma escala
é aplicada.

Ao usar as extensões de escala de janela definidas na RFC 1323, As implementações TCP podem usar um buffer de recebimento de até
1 GByte. Com esse buffer de recebimento, o rendimento máximo que pode ser alcançado por uma única conexão TCP torna-se:

RTT Taxa de transferência máxima


1 ms 8590 Gbps
10 mseg 859 Gbps 100
mseg 86 Gbps 500 mseg
17 Gbps

Essas taxas de transferência são aceitáveis nas redes atuais. No entanto, já existem servidores com interfaces de 10 Gbps... As primeiras
implementações de TCP tinham buffers fixos de recebimento e envio 20. As implementações atuais de alto desempenho são capazes de
ajustar automaticamente o tamanho do buffer de envio e recebimento para melhor suportar fluxos de alta largura de banda [ SMM1998]

Tempo limite de retransmissão do TCP

Em um protocolo de transporte go-back-n como o TCP, o tempo limite de retransmissão deve ser definido corretamente para obter um
bom desempenho. Se o tempo limite de retransmissão expirar muito cedo, a largura de banda será desperdiçada pela retransmissão de
segmentos que já foram recebidos corretamente; ao passo que, se o tempo limite de retransmissão expirar muito tarde, a largura de banda
será desperdiçada porque o remetente ficará ocioso aguardando a expiração de seu tempo limite de retransmissão.

Uma boa configuração do tempo limite de retransmissão depende claramente de uma estimativa precisa do tempo de ida e volta de cada
conexão TCP. O tempo de ida e volta difere entre conexões TCP, mas também pode mudar durante o tempo de vida de uma única
conexão. Por exemplo, a figura abaixo mostra a evolução do tempo de ida e volta entre dois hosts durante um período de 45 segundos.

Figura 4.44: Evolução do tempo de ida e volta entre dois hosts

A solução mais fácil para medir o tempo de ida e volta em uma conexão TCP é medir o atraso entre a transmissão de um segmento de
dados e a recepção de uma confirmação correspondente 21. Conforme ilustrado na

20 Consulte http://fasterdata.es.net/tuning.html para obter mais informações sobre como ajustar uma
21
implementação TCP Em teoria, uma implementação TCP poderia armazenar o carimbo de data/hora de cada segmento de dados transmitido e
calcular uma nova estimativa para o tempo de ida e volta após a recepção da confirmação correspondente. No entanto, o uso de tais medições frequentes
introduz muito ruído na prática e muitas implementações ainda medem o tempo de ida e volta uma vez por tempo de ida e volta, registrando o tempo de
transmissão de um segmento por vez RFC 2988

100 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

figura abaixo, esta medição funciona bem quando não há perdas de segmento.

Figura 4.45: Como medir o tempo de ida e volta?

No entanto, quando um segmento de dados é perdido, como ilustrado na parte inferior da figura, a medição é ambígua, pois o
remetente não pode determinar se a confirmação recebida foi desencadeada pela primeira transmissão do segmento 123 ou pela
sua retransmissão. O uso de estimativas incorretas do tempo de ida e volta pode levar a valores incorretos do tempo limite de
retransmissão. Por esta razão, Phil Karn e Craig Partridge propuseram, em [KP91], ignorar as medições de tempo de ida e volta
realizadas durante as retransmissões.

Para evitar esta ambiguidade na estimativa do tempo de ida e volta quando os segmentos são retransmitidos, implementações
recentes de TCP contam com a opção timestamp definida na RFC 1323. Esta opção permite que um remetente TCP coloque dois
carimbos de data/hora de 32 bits em cada segmento TCP que envia. O primeiro timestamp, TS Value (TSval) é escolhido pelo
remetente do segmento. Poderia, por exemplo, ser o valor atual do seu relógio de tempo real 22. O segundo valor, TS Echo Reply
(TSecr), é o último TSval que foi recebido do host remoto e armazenado no TCB. A figura abaixo mostra como a utilização desta
opção de timestamp permite a desambiguação da medição do tempo de ida e volta quando há retransmissões.

Figura 4.46: Desambiguando medições de tempo de ida e volta com a RFC 1323 opção de carimbo de data/hora

Uma vez coletadas as medidas de tempo de ida e volta para uma determinada conexão TCP, a entidade TCP deve calcular o
tempo limite de retransmissão. Como as medições do tempo de ida e volta podem mudar durante o tempo de vida de uma
23 ,
conexão, o tempo limite de retransmissão também pode mudar. No início de uma conexão, a entidade TCP que envia um
segmento SYN não sabe o tempo de ida e volta para chegar ao host remoto e o tempo limite de retransmissão inicial geralmente
é definido como 3 segundos RFC 2988 .

A especificação TCP original proposta na RFC 793 incluir duas variáveis adicionais no TCB:

• srtt : o tempo de ida e volta suavizado calculado como srrt = (ÿ × srtt) + ((1 ÿ ÿ) × rtt) onde rtt é o tempo de ida e volta
medido de acordo com o procedimento acima e ÿ um fator de suavização ( por exemplo, 0,8 ou 0,9)
22
Alguns especialistas em segurança levantaram preocupações de que o uso do relógio em tempo real para definir o TSval na opção de carimbo de data/hora pode vazar informações
como o tempo de atividade do sistema. As soluções propostas para resolver este problema podem ser encontradas em [CNPI09]
23 Como um cliente TCP frequentemente estabelece diversas conexões paralelas ou sucessivas com o mesmo servidor, a RFC 2140 propôs reutilizar para uma nova conexão algumas

informações que foram coletadas no TCB de uma conexão anterior, como o rtt medido. No entanto, esta solução não foi amplamente implementada.

4.3. O Protocolo de Controle de Transmissão 101

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• rto : o tempo limite de retransmissão é calculado como rto = min(60, max(1, ÿ × srtt)) onde ÿ é usado para levar em conta
a variação do atraso (valor: 1,3 a 2,0). As constantes 60 e 1 são usadas para garantir que o rto não seja maior que um
minuto nem menor que 1 segundo.

Contudo, na prática, este cálculo para o tempo limite de retransmissão não funcionou bem. O principal problema foi que o rto
calculado não levou em conta corretamente as variações no tempo de ida e volta medido. Van Ja-cobson propôs em seu artigo
seminal [Jacobson1988] um algoritmo aprimorado para calcular o rto e o implementou na distribuição BSD Unix. Este algoritmo
agora faz parte do padrão TCP RFC 2988.

O algoritmo de Jacobson usa duas variáveis de estado, srtt o rtt suavizado e rttvar a estimativa da variância do rtt e dois
parâmetros: ÿ e ÿ. Quando uma conexão TCP é iniciada, o primeiro rto é definido como 3 segundos. Quando uma primeira
estimativa do rtt está disponível, o srtt, o rttvar e o rto são calculados como

srtt=rtt
rttvar=rtt/2
rto=srtt+4*rttvar

Então, quando outras medições de rtt são coletadas, srtt e rttvar são atualizados da seguinte forma:

rttvar = (1 ÿ ÿ) × rttvar + ÿ × |srtt ÿ rtt| srtt = (1 ÿ ÿ) ×

srtt + ÿ × rtt

rto = srtt + 4 × rttvar

18
e ÿ =que uma
Os valores propostos para os parâmetros são ÿ = Isso permite 1 4 . implementação TCP, implementada no kernel, execute

o cálculo de rtt usando operações de deslocamento em vez das operações de ponto flutuante mais caras [Jacobson1988] . A
figura abaixo ilustra o cálculo do rto após alterações de rtt.

Figura 4.47: Exemplo de cálculo do rto

Estratégias avançadas de retransmissão

A estratégia padrão de retransmissão go-back-n foi definida na RFC 793. Quando o temporizador de retransmissão expira, o
TCP retransmite o primeiro segmento não reconhecido (ou seja, aquele que possui o número de sequência snd.una). Após
cada expiração do tempo limite de retransmissão, RFC 2988 recomenda dobrar o valor do timeout de retransmissão. Isso é
chamado de backoff exponencial. Essa duplicação do tempo limite de retransmissão após uma retransmissão foi incluída no
TCP para lidar com problemas como sobrecarga de rede/receptor e estimativas iniciais incorretas do tempo limite de
retransmissão. Se o mesmo segmento for retransmitido diversas vezes, o tempo limite de retransmissão é duplicado após cada
retransmissão até atingir um máximo configurado. RFC 2988 sugere um tempo limite máximo de retransmissão de pelo menos
60 segundos. Quando o tempo limite de retransmissão atingir esse máximo configurado, o host remoto será considerado
inacessível e a conexão TCP será fechada.

Esta estratégia de retransmissão foi refinada com base na experiência de utilização do TCP na Internet. O primeiro refinamento
foi o esclarecimento da estratégia utilizada para envio de agradecimentos. Como o TCP usa piggybacking, o

102 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O método mais fácil e menos dispendioso de enviar confirmações é colocá-las nos segmentos de dados enviados na outra direção.
Entretanto, poucos protocolos da camada de aplicação trocam dados em ambas as direções ao mesmo tempo e, portanto, esse
método raramente funciona. Para uma aplicação que envia segmentos de dados apenas em uma direção, a entidade TCP remota
retorna segmentos TCP vazios cuja única informação útil é seu número de confirmação. Isto pode causar uma grande sobrecarga na
rede de longa distância se um segmento ACK puro for enviado em resposta a cada segmento de dados recebido.
A maioria das implementações de TCP usa uma estratégia de confirmação atrasada. Essa estratégia garante que o piggybacking seja
usado sempre que possível, caso contrário, segmentos ACK puros serão enviados para cada segundo segmento de dados recebido
quando não houver perdas. Quando há perdas ou reordenamentos, os segmentos ACK são mais importantes para o remetente e são
enviados imediatamente RFC 813 RFC 1122. Esta estratégia depende de um novo temporizador com um pequeno atraso (por
exemplo, 50 milissegundos) e um sinalizador adicional no TCB. Pode ser implementado da seguinte forma

recepção de um segmento de dados:


if pkt.seq==rcv.nxt: # segmento recebido em sequência if delayack: envia segmento
de confirmação puro
cancela acktimer

delayack=Falso
outro:
delayack=True início do
temporizador de confirmação
outro: # segmento fora de sequência
enviar segmento de confirmação
puro se atrasado:
atrasado = falso cancelar
acktimer

transmissão de um segmento de dados: # piggyback ack


if atrasadoack:
atrasadoack=Falso cancela
o temporizador de confirmação

expiração do acktimer:
enviar segmento de confirmação
puro atrasado=Falso

Devido a esta estratégia de reconhecimento atrasado, durante uma transferência em massa, uma implementação TCP geralmente
reconhece cada segundo segmento TCP recebido.

A estratégia de retransmissão go-back-n padrão usada pelo TCP tem a vantagem de ser simples de implementar, principalmente no
lado do receptor, mas quando há perdas, uma estratégia go-back-n fornece um desempenho inferior a uma estratégia de repetição
seletiva. . Os desenvolvedores do TCP projetaram diversas extensões para o TCP para permitir que ele use uma estratégia de
repetição seletiva, mantendo a compatibilidade retroativa com implementações TCP mais antigas. Essas extensões TCP assumem
que o receptor é capaz de armazenar em buffer os segmentos que recebe fora de sequência.

A primeira extensão proposta é a heurística de retransmissão rápida. Esta extensão pode ser implementada em remetentes TCP e,
portanto, não requer nenhuma alteração no protocolo. Ele apenas assume que o receptor TCP é capaz de armazenar em buffer
segmentos fora de sequência.

Do ponto de vista do desempenho, um problema com o tempo limite de retransmissão do TCP é que, quando há perdas isoladas de
segmentos, o remetente TCP geralmente permanece ocioso aguardando a expiração de seus tempos limite de retransmissão. Essas
perdas isoladas são frequentes na Internet global [Paxson99]. Uma heurística para lidar com perdas isoladas sem esperar pela
expiração do tempo limite de retransmissão foi incluída em muitas implementações de TCP desde o início da década de 1990. Para
entender essa heurística, consideremos a figura abaixo que mostra os segmentos trocados em uma conexão TCP quando um
segmento isolado é perdido.

Conforme mostrado acima, quando um segmento isolado é perdido, o remetente recebe várias confirmações duplicadas, pois o
receptor TCP envia imediatamente uma confirmação pura quando recebe um segmento fora de sequência. Uma confirmação duplicada
é uma confirmação que contém o mesmo número de confirmação de um segmento anterior. Uma única confirmação duplicada não
implica necessariamente que um segmento foi perdido, pois uma simples reordenação dos segmentos também pode causar
confirmações duplicadas. Medições [Paxson99] mostraram que a reordenação de segmentos é frequente na Internet. Com base
nessas observações, a heurística de retransmissão rápida foi incluída na maioria das implementações TCP. Pode ser implementado
da seguinte forma

4.3. O Protocolo de Controle de Transmissão 103

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.48: Detectando perdas de segmentos isolados

confirmação de chegada:

if tcp.ack==snd.una: dupacks+ # confirmação duplicada


+ if
dupacks==3:
retransmitir segmento(snd.una)
outro:
dupacks=0 #
reconhecimento do processo

Esta heurística requer uma variável adicional no TCB (dupacks). A maioria das implementações define o número padrão de confirmações
duplicadas que acionam uma retransmissão como 3. Agora faz parte da especificação TCP padrão RFC 2581. A heurística de retransmissão
rápida melhora o desempenho do TCP desde que segmentos isolados sejam perdidos e a janela atual seja grande o suficiente para permitir
ao remetente enviar três confirmações duplicadas.

A figura abaixo ilustra o funcionamento da heurística de retransmissão rápida.

Figura 4.49: Heurística de retransmissão rápida TCP

Quando as perdas não são isoladas ou quando as janelas são pequenas, o desempenho da heurística de retransmissão rápida diminui.
Nesses ambientes, é necessário permitir que um remetente TCP use uma estratégia de repetição seletiva em vez da estratégia go-back-n
padrão. A implementação da repetição seletiva requer uma mudança no protocolo TCP, pois o receptor precisa ser capaz de informar o
remetente sobre os segmentos fora de ordem que já recebeu. Isso pode ser feito usando a opção Selective Acknowledgments (SACK)
definida na RFC 2018. Esta opção TCP é

104 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

negociado durante o estabelecimento de uma conexão TCP. Se ambos os hosts TCP suportarem a opção, os blocos SACK poderão ser
anexados pelo receptor aos segmentos que ele envia. Os blocos SACK permitem que um receptor TCP indique os blocos de dados que recebeu
corretamente, mas fora de sequência. A figura abaixo ilustra a utilização dos blocos SACK.

Figura 4.50: Reconhecimentos seletivos de TCP

Uma opção SACK contém um ou mais blocos. Um bloco corresponde a todos os números de sequência entre a borda esquerda e a borda direita
do bloco. As duas bordas do bloco são codificadas como números de 32 bits (o mesmo tamanho do número de sequência TCP) em uma opção
SACK. Como a opção SACK contém um byte para codificar seu tipo e um byte para seu comprimento, uma opção SACK contendo b blocos é
codificada como uma sequência de 2 + 8 × b bytes. Na prática, o tamanho da opção SACK pode ser problemático, pois a extensão opcional do
cabeçalho TCP não pode ter mais de 44 bytes. Como a opção SACK geralmente é combinada com a RFC 1323 extensão de timestamp, isso
implica que um segmento TCP geralmente não pode conter mais de três blocos SACK. Esta limitação implica que um receptor TCP nem sempre
pode colocar na opção SACK que envia informações sobre todos os blocos recebidos.

Para lidar com o tamanho limitado da opção SACK, um receptor TCP que atualmente possui mais de 3 blocos dentro de seu buffer de
recebimento deve selecionar os blocos a serem colocados na opção SACK. Uma boa heurística é colocar na opção SACK os blocos que foram
alterados mais recentemente, pois é provável que o remetente já esteja ciente dos blocos mais antigos.

Quando um remetente recebe uma opção SACK indicando um novo bloco e, portanto, uma nova possível perda de segmento, ele geralmente
não retransmite o(s) segmento(s) ausente(s) imediatamente. Para lidar com a reordenação, um remetente TCP pode usar uma heurística
semelhante à retransmissão rápida, retransmitindo um gap apenas depois de receber três opções de SACK indicando esta lacuna.
Deve-se observar que a opção SACK não substitui o número de confirmação do cabeçalho TCP. Um remetente TCP só pode remover dados de
seu buffer de envio depois que eles forem reconhecidos pelas confirmações cumulativas do TCP. Este desenho foi escolhido por dois motivos.
Primeiro, permite que o receptor descarte partes de seu buffer de recepção quando estiver ficando sem memória, sem perder dados. Em
segundo lugar, como a opção SACK não é transmitida de forma confiável, as confirmações cumulativas ainda são necessárias para lidar com
perdas de segmentos ACK que transportam apenas informação SACK. Assim, a opção SACK serve apenas como uma dica para permitir ao
remetente otimizar suas retransmissões.

Controle de congestionamento TCP

Nas seções anteriores, explicamos os mecanismos que o TCP utiliza para lidar com erros de transmissão e perdas de segmento. Em uma rede
heterogênea como a Internet ou redes IP empresariais, os sistemas finais têm níveis de desempenho muito diferentes. Alguns sistemas finais
são servidores de ponta conectados a links de 10 Gbps, enquanto outros são dispositivos móveis conectados a um link sem fio de largura de
banda muito baixa. Apesar dessas enormes diferenças de desempenho, um dispositivo móvel deve ser capaz de trocar segmentos de forma
eficiente com um servidor de última geração.

Para entender melhor este problema, consideremos o cenário mostrado na figura abaixo, onde um servidor (A)

4.3. O Protocolo de Controle de Transmissão 105

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

conectado a um link de 10 Mbps está enviando segmentos TCP para outro computador (C) através de um caminho que contém um
link de 2 Mbps.

Figura 4.51: TCP em links heterogêneos

Nesta rede, os segmentos TCP enviados pelo servidor chegam ao roteador R1. R1 encaminha os segmentos para o roteador R2.
O roteador R2 pode potencialmente receber segmentos a 10 Mbps, mas só pode encaminhá-los a 2 Mbps para o roteador R2 e depois
para o host C. O roteador R2 contém buffers que permitem armazenar os pacotes que não podem ser encaminhados imediatamente
ao seu destino. Para entender o funcionamento do TCP neste ambiente, consideremos um modelo simplificado desta rede onde o host
A está conectado a um link de 10 Mbps a uma fila que representa os buffers do roteador R2. Esta fila é esvaziada a uma taxa de 2
Mbps.

Figura 4.52: Auto-relógio TCP

Consideremos que o host A utiliza uma janela de três segmentos. Assim, ele envia três segmentos consecutivos a 10 Mbps e depois
aguarda uma confirmação. O Host A para de enviar segmentos quando sua janela está cheia. Esses segmentos alcançam os buffers
do roteador R2. O primeiro segmento armazenado neste buffer é enviado pelo roteador R2 a uma taxa de 2 Mbps para o host de
destino. Após a recepção deste segmento, o destino envia uma confirmação. Esta confirmação permite que o host A transmita um
novo segmento. Este segmento é armazenado nos buffers do roteador R2 enquanto ele transmite o segundo segmento que foi enviado
pelo host A... Assim, após a transmissão da primeira janela de segmentos, o TCP envia um segmento de dados após a recepção de
cada reconhecimento retornado pelo destino Na prática, as confirmações enviadas pelo destino servem como uma espécie de relógio
que permite ao24host
. remetente adaptar sua taxa de transmissão à taxa na qual os segmentos são recebidos pelo destino. Este auto-
clocking do TCP é o primeiro mecanismo que permite ao TCP se adaptar a redes heterogêneas [Jacobson1988]. Depende da
disponibilidade de buffers para armazenar os segmentos que foram enviados pelo remetente, mas ainda não foram transmitidos ao
destino.

No entanto, o TCP nem sempre é usado neste ambiente. Na Internet global, o TCP é usado em redes onde um grande número de
hosts envia segmentos para um grande número de receptores. Por exemplo, consideremos a rede

24
Se o destino estiver usando confirmações atrasadas, o host remetente enviará dois segmentos de dados após cada confirmação.

106 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

descrito abaixo, que é semelhante ao discutido em [Jacobson1988] e RFC 896. Nesta rede, assumimos
que os buffers do roteador sejam infinitos para garantir que nenhum pacote seja perdido.

Figura 4.53: O problema do colapso do congestionamento

Se muitos remetentes TCP estiverem conectados à parte esquerda da rede acima, todos eles enviarão uma janela cheia de segmentos.
Esses segmentos são armazenados nos buffers do roteador antes de serem transmitidos ao seu destino. Se lá
Se houver muitos remetentes na parte esquerda da rede, a ocupação dos buffers aumentará rapidamente. Uma consequência de
a ocupação do buffer é que o tempo de ida e volta, medido pelo TCP, entre o remetente e o destinatário aumenta.
Considere uma rede onde são enviados segmentos de 10.000 bits. Quando o buffer está vazio, tal segmento requer 1
milissegundos para serem transmitidos no link de 10 Mbps e 5 milissegundos para serem transmitidos no link de 2 Mbps.
Assim, o tempo de ida e volta medido pelo TCP é de aproximadamente 6 milissegundos se ignorarmos o atraso de propagação no
links. A maioria dos roteadores gerencia seus buffers como uma fila FIFO 25. Se o buffer contiver 100 segmentos, o tempo de ida e volta será de 1 + 100
× 5 + 5 milissegundos, pois novos segmentos serão transmitidos apenas no link de 2 Mbps quando todos
segmentos anteriores foram transmitidos. Infelizmente, o TCP usa um temporizador de retransmissão e executa go-back-n
para se recuperar de erros de transmissão. Se a ocupação do buffer for alta, o TCP assume que alguns segmentos foram
perdido e retransmite uma janela completa de segmentos. Isso aumenta a ocupação do buffer e o atraso através
o buffer... Além disso, o buffer pode armazenar e enviar nos links de baixa largura de banda diversas retransmissões de
o mesmo segmento. Este problema é chamado de colapso de congestionamento. Ocorreu diversas vezes no final da década de 1980. Para
Por exemplo, [Jacobson1988] observa que em 1986, a largura de banda utilizável de um link de 32 Kbits caiu para 40 bits por segundo
26 !
devido ao colapso do congestionamento

O colapso do congestionamento é um problema que todas as redes heterogêneas enfrentam. Diferentes mecanismos foram
proposto na literatura científica para evitar ou controlar o congestionamento da rede. Algumas delas foram implementadas
e implantado em redes reais. Para entender esse problema com mais detalhes, consideremos primeiro uma rede simples
com dois hosts conectados a um link de alta largura de banda que está enviando segmentos para o destino C conectado a um link de baixa largura de banda
link de largura de banda conforme mostrado abaixo.

Figura 4.54: O problema do congestionamento

27
Para evitar o colapso do congestionamento, os hosts devem regular a sua taxa de transmissão usando um sistema de controle de congestionamento.
mecanismo. Tal mecanismo pode ser implementado na camada de transporte ou na camada de rede. Em TCP/IP
redes, é implementado na camada de transporte, mas outras tecnologias, como modo de transferência assíncrona
(ATM) ou Frame Relay incluem mecanismos de controle de congestionamento em camadas inferiores.

Vamos primeiro considerar o problema simples de um conjunto de i hosts que compartilham um único enlace gargalo, como mostrado na
exemplo acima. Nesta rede, o esquema de controle de congestionamento deve atingir os seguintes objetivos [CJ1989] :

25
Discutiremos em outro capítulo outras possíveis organizações dos buffers do roteador.
26
Neste momento, as implementações do TCP seguiam principalmente a RFC 791. As estimativas de tempo de ida e volta e os mecanismos de retransmissão
eram muito simples. O TCP foi melhorado após a publicação de [Jacobson1988]
27
Nesta seção, nos concentramos nos mecanismos de controle de congestionamento que regulam a taxa de transmissão dos hosts. Outros tipos de
mecanismos foram propostos na literatura. Por exemplo, o controle de fluxo baseado em crédito foi proposto para evitar congestionamento em redes ATM
[KR1995]. Com um mecanismo baseado em crédito, os hosts só podem enviar pacotes depois de terem recebido créditos dos roteadores e os créditos dependem
na ocupação dos buffers do roteador.

4.3. O Protocolo de Controle de Transmissão 107

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

1. O esquema de controle de congestionamento deve evitar congestionamentos. Na prática, isso significa que o elo
gargalo não pode ser sobrecarregado. Se ri(t) é a taxa de transmissão alocada ao host i no tempo t e R é a largura
de banda do enlace gargalo, então o esquema de controle de congestionamento deve garantir que, em média, ÿt
ri(t) ÿ R.

2. O esquema de controle de congestionamento deve ser eficiente. O link gargalo geralmente é um recurso compartilhado
e caro. Normalmente, os links de gargalo são links de longa distância cuja atualização é muito mais cara do que as
redes locais. O esquema de controle de congestionamento deverá garantir que tais links sejam utilizados de forma
eficiente. Matematicamente, o esquema de controle deve garantir que ÿt ri(t) ÿ R.

3. O esquema de controle de congestionamento deve ser justo. A maioria dos esquemas de congestionamento visa
alcançar a justiça máxima-mínima. Uma alocação de taxas de transmissão às fontes é considerada max-min justa se:

• nenhum link na rede está congestionado

• a taxa alocada à fonte j não pode ser aumentada sem diminuir a taxa alocada a uma fonte i cuja alocação é menor
que a taxa alocada à fonte j [Leboudec2008] .

Dependendo da rede, nem sempre pode existir uma alocação justa max-min. Na prática, a justiça max-min é um objectivo ideal que não
pode necessariamente ser alcançado. Quando há um único link de gargalo, como no exemplo acima, a imparcialidade max-min implica
que cada fonte deve receber a mesma taxa de transmissão.

Para visualizar as diferentes alocações de taxas, é útil considerar o gráfico abaixo. Neste gráfico, plotamos no eixo x (resp. eixo y) a taxa
alocada ao host B (resp. A). Um ponto no gráfico (rB, rA) corresponde a uma possível alocação das taxas de transmissão. Como existe
um gargalo de link de 2 Mbps nesta rede, o gráfico pode ser dividido em duas regiões. A parte inferior esquerda do gráfico contém todas
as alocações (rB, rA) de forma que o link gargalo não fique congestionado (rA + rB <2). A borda direita desta região é a linha de eficiência,
ou seja, o conjunto de alocações que utilizam completamente o link gargalo (rA + rB = 2). Finalmente, a linha de justiça é o conjunto de
alocações justas.

Figura 4.55: Possíveis taxas de transmissão alocadas

Conforme mostrado no gráfico acima, uma alocação de taxa pode ser justa, mas não eficiente (por exemplo, rA = 0,7, rB = 0,7), justa e
eficiente (por exemplo, rA = 1, rB = 1) ou eficiente, mas não justa (por exemplo, rA = 1,5 , rB = 0,5). Idealmente, a alocação deveria ser
justa e eficiente. Infelizmente, manter tal alocação com flutuações no número de fluxos que utilizam a rede é um problema desafiador.
Além disso, pode haver milhares de conexões TCP ou mais que passam pelo mesmo enlace.
28 .

Para lidar com essas flutuações na demanda, que resultam em flutuações na largura de banda disponível, as redes de computadores
utilizam um esquema de controle de congestionamento. Este esquema de controlo de congestionamento deverá atingir os três objectivos
acima enumerados. Alguns esquemas de controle de congestionamento dependem de uma estreita cooperação entre os hosts finais e os
roteadores, enquanto outros são implementados principalmente nos hosts finais com suporte limitado dos roteadores.

28
Por exemplo, as medições realizadas na rede Sprint em 2004 relataram mais de 10 mil conexões TCP ativas em um link, consulte https://
research.sprintlabs.com/packstat/packetoverview.php. Informações mais recentes sobre links de backbone podem ser obtidas em caida medições
em tempo real, consulte, por exemplo, http://www.caida.org/data/realtime/passive/

108 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Um esquema de controle de congestionamento pode ser modelado como um algoritmo que adapta a taxa de transmissão (ri(t)) do host
i com base no feedback recebido da rede. Diferentes tipos de feedback são possíveis. O esquema mais simples é um feedback binário
[CJ1989] [Jacobson1988] onde os hosts simplesmente aprendem se a rede está congestionada ou não. Alguns esquemas de controle
de congestionamento permitem que a rede envie regularmente uma taxa de transmissão alocada em Mbps para cada host [BF1995].

Vamos nos concentrar no esquema de feedback binário que é o mais utilizado atualmente. Intuitivamente, o esquema de controle de
congestionamento deve diminuir a taxa de transmissão de um host quando um congestionamento for detectado na rede, a fim de evitar
o colapso do congestionamento. Além disso, os hosts devem aumentar a sua taxa de transmissão quando a rede não estiver
congestionada. Caso contrário, os hosts não seriam capazes de utilizar a rede com eficiência. A taxa alocada para cada host flutua
com o tempo, dependendo do feedback recebido da rede. A figura abaixo ilustra a evolução das taxas de transmissão alocadas para
dois hosts em nossa rede simples. Inicialmente, dois hosts possuem uma alocação baixa, mas isso não é eficiente. As alocações
aumentam até que a rede fique congestionada.
Neste ponto, os hosts diminuem sua taxa de transmissão para evitar o colapso do congestionamento. Se o esquema de controle de
congestionamento funcionar bem, depois de algum tempo as alocações deverão tornar-se justas e eficientes.

Figura 4.56: Evolução das taxas de transmissão

Vários tipos de algoritmos de adaptação de taxa são possíveis. Dah Ming Chiu e Raj Jain analisaram, em [CJ1989], diferentes tipos de
algoritmos que podem ser usados por uma fonte para adaptar sua taxa de transmissão ao feedback recebido da rede. Intuitivamente,
tal algoritmo de adaptação de taxa aumenta a taxa de transmissão quando a rede não está congestionada (garantindo que a rede seja
usada de forma eficiente) e diminui a taxa de transmissão quando a rede está congestionada (para evitar o colapso do congestionamento).

A forma mais simples de feedback que a rede pode enviar a uma fonte é um feedback binário (a rede está congestionada ou não).
Neste caso, um algoritmo de adaptação de taxa linear pode ser expresso como:

• taxa(t + 1) = ÿC + ÿC taxa(t) quando a rede está congestionada • taxa(t + 1)

= ÿN + ÿN taxa(t) quando a rede não está congestionada

Com um algoritmo de adaptação linear, ÿC é , ÿN , ÿC e ÿN são constantes. A análise de [CJ1989] mostra que para
justo e eficiente, tal mecanismo de adaptação de taxa binária deve contar com Aumento Aditivo e Diminuição Multiplicativa. Quando a
rede não está congestionada, os hosts devem aumentar lentamente sua taxa de transmissão (ÿN = 1 e ÿN > 0). Quando a rede está
congestionada, os hosts devem diminuir multiplicativamente sua taxa de transmissão (ÿC < 1 e ÿC = 0). Tal algoritmo de adaptação de
taxa AIMD pode ser implementado pelo pseudocódigo abaixo

# Aumento Aditivo Diminuição Multiplicativa em caso de


congestionamento:
rate=rate*betaC # diminuição multiplicativa, betaC<1
outro
taxa = taxa + alfaN # aumento aditivo, v0>0

Nota: Qual feedback binário?

Dois tipos de feedback binário são possíveis em redes de computadores. Uma primeira solução é confiar no feedback implícito.
Esta é a solução escolhida para TCP. O esquema de controle de congestionamento do TCP [Jacobson1988] não requer nenhuma
cooperação do roteador. Ele apenas assume que eles usam buffers e descartam pacotes quando há congestionamento.

4.3. O Protocolo de Controle de Transmissão 109

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

O TCP usa as perdas de segmento como uma indicação de congestionamento. Quando não há perdas, presume-se que a rede não esteja
congestionada. Isto implica que o congestionamento é a principal causa das perdas de pacotes. Isto é verdade em redes com fio, mas
infelizmente nem sempre é verdade em redes sem fio. Outra solução é confiar no feedback explícito. Esta é a solução proposta no
esquema de controle de congestionamento DECBit [RJ1995] e utilizada em redes Frame Relay e ATM. Este feedback explícito pode ser
implementado de duas maneiras. Uma primeira solução seria definir uma mensagem especial que pudesse ser enviada pelos roteadores
aos hosts quando estes estivessem congestionados. Infelizmente, a geração de tais mensagens pode aumentar a quantidade de
congestionamento na rede. Tal pacote de indicação de congestionamento é, portanto, desencorajado pela RFC 1812. Uma abordagem
melhor é permitir que os roteadores intermediários indiquem, nos pacotes que encaminham, seu status atual de congestionamento. O
feedback binário pode ser codificado usando um bit no cabeçalho do pacote. Com esse esquema, os roteadores congestionados definem
um bit especial nos pacotes que encaminham, enquanto os roteadores não congestionados deixam esse bit inalterado. O host de destino
retorna o status de congestionamento da rede nas confirmações que envia. Detalhes sobre tal solução em redes IP podem ser encontrados
na RFC 3168. Infelizmente, no momento em que este livro foi escrito, esta solução ainda não estava implementada, apesar dos seus
potenciais benefícios.

O esquema de controle de congestionamento TCP foi inicialmente proposto por Van Jacobson em [Jacobson1988]. A especificação atual
pode ser encontrada na RFC 5681. O TCP depende de Aumento Aditivo e Diminuição Multiplicativa (AIMD).
Para implementar o AIMD, um host TCP deve ser capaz de controlar sua taxa de transmissão. Uma primeira abordagem seria utilizar
temporizadores e ajustar os seus tempos de expiração em função da taxa imposta pela AIMD. Infelizmente, pode ser difícil manter esses
temporizadores para um grande número de conexões TCP. Em vez disso, Van Jacobson observou que a taxa de congestionamento do
TCP pode ser controlada artificialmente restringindo sua janela de envio. Uma conexão TCP não pode enviar janela de dados onde a
janela é
o máximo entre a janela de envio do host e a janela anunciada mais rápido que rtt
pelo receptor.

O esquema de controle de congestionamento do TCP é baseado em uma janela de congestionamento. O valor atual da janela de
congestionamento (cwnd) é armazenado no TCB de cada conexão TCP e a janela que pode ser usada pelo remetente é restringida por
min(cwnd, rwin, swin) onde swin é a janela de envio atual e rwin é a janela de envio atual. última janela de recebimento recebida. A parte
de aumento aditivo do controle de congestionamento TCP incrementa a janela de congestionamento em bytes MSS a cada tempo de ida
e volta. Na literatura TCP, esta fase é frequentemente chamada de fase de prevenção de congestionamento. A parte de redução
multiplicativa do controle de congestionamento TCP divide o valor atual da janela de congestionamento assim que o congestionamento
for detectado.

Quando uma conexão TCP começa, o host remetente não sabe se a parte da rede que utiliza para chegar ao destino está congestionada
ou não. Para evitar causar muito congestionamento, deve-se começar com uma pequena janela de congestionamento. [Jacobson1988]
recomenda uma janela inicial de bytes MSS. Como a parte de aumento aditivo do esquema de controle de congestionamento TCP
incrementa a janela de congestionamento em bytes MSS a cada tempo de ida e volta, a conexão TCP pode ter que esperar muitos
tempos de ida e volta antes de poder usar eficientemente a largura de banda disponível. Isto é especialmente importante em ambientes
onde o produto largura de banda × rtt é alto. Para evitar esperar muitos tempos de ida e volta antes de atingir uma janela de
congestionamento que seja grande o suficiente para utilizar a rede de forma eficiente, o esquema de controle de congestionamento TCP
inclui o algoritmo de início lento. O objetivo do início lento do TCP é atingir rapidamente um valor aceitável para o cwnd. Durante a partida
lenta, a janela de congestionamento é duplicada a cada tempo de ida e volta. O algoritmo de início lento usa uma variável adicional no
TCB: sshtresh (limiar de início lento). O ssthresh é uma estimativa do último valor do cwnd que não causou congestionamento. Ele é
inicializado na janela de envio e atualizado após cada evento de congestionamento.

Na prática, uma implementação TCP considera a rede congestionada uma vez que necessita retransmitir um segmento.
O esquema de controle de congestionamento TCP distingue entre dois tipos de congestionamento:

• congestão leve. O TCP considera que a rede está levemente congestionada se receber três confirmações duplicadas e realizar
uma retransmissão rápida. Se a retransmissão rápida for bem sucedida, isto implica que apenas um segmento foi perdido. Neste
caso, o TCP realiza uma diminuição multiplicativa e a janela de congestionamento é dividida por 2. O limite de início lento é
definido para o novo valor da janela de congestionamento.

• congestionamento grave. O TCP considera que a rede está severamente congestionada quando o seu temporizador de
retransmissão expira. Neste caso, o TCP retransmite o primeiro segmento, define o limite de início lento para 50% da janela de
congestionamento. A janela de congestionamento é redefinida para seu valor inicial e o TCP executa uma inicialização lenta.

A figura abaixo ilustra a evolução da janela de congestionamento quando há congestionamentos graves. No início da conexão, o remetente
realiza uma inicialização lenta até que os primeiros segmentos sejam perdidos e o temporizador de retransmissão expire. Neste momento,
o ssthresh é definido para metade da janela de congestionamento atual e a janela de congestionamento é redefinida em um segmento.
Os segmentos perdidos são retransmitidos enquanto o remetente executa novamente a inicialização lenta até que o

110 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

janela de congestionamento atinge o sshtresh. Em seguida, ele muda para evitar congestionamento e a janela de congestionamento aumenta
linearmente até que os segmentos sejam perdidos e o temporizador de retransmissão expire...

Figura 4.57: Avaliação da janela de congestionamento TCP com congestionamento severo

A figura abaixo ilustra a evolução da janela de congestionamento quando a rede está levemente congestionada e todos os segmentos perdidos
podem ser retransmitidos usando retransmissão rápida. O remetente começa com um início lento. Um segmento é perdido, mas retransmitido
com sucesso por uma retransmissão rápida. A janela de congestionamento é dividida por 2 e o remetente entra imediatamente em prevenção
de congestionamento, pois se trata de um congestionamento leve.

Figura 4.58: Avaliação da janela de congestionamento do TCP quando a rede está levemente congestionada

A maioria das implementações TCP atualiza a janela de congestionamento quando recebe uma confirmação. Se assumirmos que o receptor
reconhece cada segmento recebido e o remetente envia apenas segmentos de tamanho MSS, o esquema de controle de congestionamento
TCP pode ser implementado usando o pseudocódigo simplificado 29 abaixo

# Inicialização
cwnd = MSS;
ssthresh=swin;

# Ack chegada se
tcp.ack > snd.una: # novo ack, sem congestionamento
se cwnd <ssthresh:
# início lento: aumenta rapidamente cwnd # duplica cwnd a cada
rtt
cwnd = cwnd + MSS
outro:
# evitar congestionamento: aumentar lentamente cwnd # aumentar cwnd em um
mss a cada rtt cwnd = cwnd+ mss*(mss/cwnd)

else: # confirmação duplicada ou antiga if


tcp.ack==snd.una: # confirmação duplicada dupacks++ if dupacks==3:

29
Neste pseudocódigo, assumimos que o TCP usa números de sequência e de confirmação ilimitados. Além disso, não detalhamos como
o cwnd é ajustado após a retransmissão do segmento perdido por retransmissão rápida. Detalhes adicionais podem ser encontrados na RFC 5681.

4.3. O Protocolo de Controle de Transmissão 111

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

segmento de retransmissão(snd.una)
ssthresh=max(cwnd/2,2*MSS)
cwnd=ssthresh
outro:
dupacks=0 #
confirmação para segmento antigo, ignorado

Expiração do temporizador de retransmissão: send(snd.una) #


retransmite o primeiro segmento perdido sshtresh=max(cwnd/2,2*MSS)

cwnd=MSS

Além disso, quando uma conexão TCP estiver ociosa por mais tempo do que seu temporizador de retransmissão atual, ela deverá
redefinir sua janela de congestionamento para o tamanho da janela de congestionamento que usa quando a conexão começa, pois não
conhece mais o estado atual de congestionamento da rede.

Nota: janela inicial de congestionamento

O mecanismo original de controle de congestionamento TCP proposto em [Jacobson1988] recomendava que cada conexão TCP
começasse configurando cwnd = MSS. Entretanto, nas redes atuais com maior largura de banda, o uso de uma janela inicial de
congestionamento tão pequena afeta severamente o desempenho de conexões TCP curtas, como aquelas usadas por servidores web.
Desde a publicação da RFC 3390, Os hosts TCP podem usar uma janela de congestionamento inicial de cerca de 4 KBytes, o que
corresponde a 3 segmentos em muitos ambientes.

Graças ao seu esquema de controle de congestionamento, o TCP adapta sua taxa de transmissão às perdas que ocorrem na rede.
Intuitivamente, a taxa de transmissão do TCP diminui quando a porcentagem de perdas aumenta. Pesquisadores propuseram modelos
detalhados que permitem prever o rendimento de uma conexão TCP quando ocorrem perdas [MSMO1997] .
Para ter alguma intuição sobre os fatores que afetam o desempenho do TCP, consideremos um modelo muito
simples. Suas suposições não são completamente realistas, mas nos dão uma boa intuição sem exigir matemática complexa.

Este modelo considera uma conexão TCP hipotética que sofre perdas de segmentos igualmente espaçados. Se p for a taxa de perda de
1
segmento, então a conexão TCP transfere com sucesso ÿ1 segmentos e o próximop segmento é perdido.
Se ignorarmos o início lento no início da conexão, o TCP neste ambiente estará sempre evitando congestionamentos, pois há apenas
perdas isoladas que podem ser recuperadas usando a retransmissão rápida. A evolução da janela de congestionamento é assim
mostrada na figura abaixo. Observe que o eixo x desta figura representa o tempo medido em unidades de um tempo de ida e volta, que
deve ser constante no modelo, e o eixo y representa o tamanho da janela de congestionamento medida em segmentos do tamanho de
MSS .

Figura 4.59: Evolução da janela de congestionamento com perdas regulares

Como as perdas são igualmente espaçadas, a janela de congestionamento sempre começa em algum valor
2 (W ), e é incrementada em
um MSS a cada tempo de ida e volta até atingir o dobro deste valor (W). Neste ponto, um segmento é retransmitido e o ciclo recomeça.
Em
Se a janela de congestionamento for medida em segmentos do tamanho de MSS, um ciclo dura tempos de ida e volta. A 2largura de
banda da conexão TCP é o número de bytes que foram transmitidos durante um determinado período de tempo. Durante um ciclo, o
número de segmentos enviados na conexão TCP é igual à área do trapézio amarelo da figura. Sua área é assim:

2+
Em 2 = 3×W2 8
área = (W ) 2 12 ×( 2 )

112 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

No entanto, dadas as perdas regulares que consideramos, o número de segmentos que são enviados entre duas perdas (ou seja,
1
. Assim,
durante um ciclo) é, por definição, igual a A taxa de W = (em bytes=por ksegundo)
transferência . da conexão TCP é igual ao número de
p 8 3×p ÿ p
segmentos transmitido dividido pela duração do ciclo:
3×W2
Taxa de transferência =
área×tempo MSS = ou, depois de eliminar W, T hroughput =
3 × MSS
Em
8 ×rtt 2 rtt× ÿp
2

Modelos mais detalhados e a análise de simulações mostraram que um modelo de primeira ordem do throughput do TCP quando
k×MSS
ocorrem perdas foi Throughput ÿ Este é um resultado importante que mostra que: rtt× ÿp .

• Conexões TCP com um tempo de ida e volta pequeno podem atingir um rendimento mais alto do que conexões TCP com um
tempo de ida e volta mais longo quando ocorrem perdas. Isto implica que o esquema de controle de congestionamento TCP não
é completamente justo, uma vez que favorece as conexões que possuem menor tempo de ida e volta.

• Conexões TCP que usam um MSS grande podem atingir um rendimento mais alto que as conexões TCP que usam um MSS
mais curto. Isto cria outra fonte de injustiça entre conexões TCP. No entanto, deve-se notar que hoje a maioria dos hosts usa
quase o mesmo MSS, aproximadamente 1.460 bytes.

Em geral, o rendimento máximo que pode ser alcançado por uma conexão TCP depende do tamanho máximo da janela e do tempo de
ida e volta se não houver perdas. Se houver perdas, depende do MSS, do tempo de ida e volta e do índice de perdas.

janela rtt , k×MSS


Taxa de transferência <min( )
rtt× ÿp

Nota: O zoológico de controle de congestionamento TCP

O primeiro esquema de controle de congestionamento TCP foi proposto por Van Jacobson em [Jacobson1988]. Além de escrever o
artigo científico, Van Jacobson também implementou os esquemas de início lento e prevenção de congestionamento na versão 4.3
Tahoe do BSD Unix distribuído pela Universidade de Berkeley. Mais tarde, ele melhorou o controle de congestionamento adicionando a
retransmissão rápida e os mecanismos de recuperação rápida na versão Reno do 4.3 BSD Unix. Desde então, muitos pesquisadores
propuseram, simularam e implementaram modificações no esquema de controle de congestionamento do TCP. Algumas dessas
modificações ainda são usadas hoje, por exemplo:

• NewReno ( RFC 3782), que foi proposto como uma melhoria do mecanismo de recuperação rápida no Reno
implementação

• TCP Vegas, que utiliza alterações no tempo de ida e volta para estimar o congestionamento a fim de evitá-lo [BOP1994]

• CUBIC, que foi projetado para links de alta largura de banda e é o esquema de controle de congestionamento padrão no kernel
Linux 2.6.19 [HRX2008]

• O TCP composto, que foi projetado para links de alta largura de banda, é o esquema de controle de congestionamento padrão
em vários sistemas operacionais Microsoft [STBT2009]

Uma pesquisa na literatura científica provavelmente revelará mais de 100 variantes diferentes do esquema de controle de
congestionamento TCP. A maioria deles foi avaliada apenas por simulações. Entretanto, a implementação do TCP nos kernels Linux
recentes suporta vários esquemas de controle de congestionamento e novos podem ser facilmente adicionados. Podemos esperar que
novos esquemas de controle de congestionamento TCP sempre continuem a aparecer.

4.4 Resumo
Neste capítulo, estudamos a camada de transporte. Esta camada fornece dois tipos de serviços para a camada de aplicação. O serviço
não confiável e sem conexão é o serviço mais simples oferecido aos aplicativos. Na Internet, este é o serviço oferecido pelo UDP.
Entretanto, a maioria das aplicações prefere usar um serviço de transporte confiável e orientado à conexão. Mostramos que fornecer
este serviço era muito mais complexo do que fornecer um serviço não confiável, pois a camada de transporte precisa se recuperar dos
erros que ocorrem na camada de rede. Para isso, os protocolos da camada de transporte contam com diversos mecanismos. Primeiro,
eles usam um mecanismo de handshake, como o mecanismo de handshake de três vias, para estabelecer corretamente uma conexão
de transporte. Uma vez estabelecida a ligação, as entidades de transporte trocam segmentos. Cada segmento contém um número de
sequência e a camada de transporte utiliza confirmações para confirmar os segmentos que foram recebidos corretamente. Além disso,
são utilizados temporizadores para recuperação de perdas de segmento e janelas deslizantes para evitar o transbordamento dos buffers
das entidades de transporte. Finalmente,

4.4. URL de resumo 113

de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

explicamos como uma conexão de transporte pode ser liberada com segurança. Discutimos então os mecanismos usados no TCP, o protocolo de
transporte confiável, usado pela maioria das aplicações na Internet. Mais notavelmente, descrevemos o mecanismo de controle de congestionamento
que foi incluído no TCP desde o final da década de 1980 e explicamos como os mecanismos de confiabilidade usados pelo TCP foram ajustados
ao longo dos anos.

4.5 Exercícios
Esta seção está dividida em duas partes. A primeira parte contém exercícios sobre os princípios dos protocolos de transporte, incluindo o TCP. A
segunda parte contém desafios de programação, ferramentas de análise de pacotes para observar o comportamento dos protocolos de transporte.

4.5.1 Princípios
1. Considere o protocolo de bits alternados conforme descrito neste capítulo

• Como o protocolo se recupera da perda de um segmento de dados?

• Como o protocolo se recupera da perda de uma confirmação?

2. Um aluno propôs otimizar o protocolo de bits alternados adicionando uma confirmação negativa, ou seja, o receptor envia um segmento de
controle NAK quando recebe um segmento de dados corrompido. Que tipo de informação deve ser colocada neste segmento de controle e
como o remetente deve reagir ao receber tal NAK?

3. Os protocolos de transporte dependem de diferentes tipos de somas de verificação para verificar se os segmentos foram afetados por
erros de transmissão. As somas de verificação usadas com mais frequência são:

• a soma de verificação da Internet usada pelo UDP, TCP e outros protocolos da Internet, definida na RFC 1071 e implementado
em vários módulos, por exemplo http://ilab.cs.byu.edu/cs460/code/ftp/ichecksum.py para uma píton implementação

• as verificações de redundância cíclica (CRC) de 16 ou 32 bits que são frequentemente usadas em discos, em arquivos zip e
em protocolos da camada de enlace de dados. Consulte http://docs.python.org/library/binascii.html para uma píton módulo
que contém o CRC de 32 bits

• a soma de verificação Alder definida na RFC 2920 para o protocolo SCTP, mas substituído por um CRC posteriormente
RFC 3309

• a soma de verificação Fletcher [Fletcher1982], consulte http://drdobbs.com/database/184408761 para implementar


detalhes de mentoria

Usando seu conhecimento da soma de verificação da Internet, você consegue encontrar um erro de transmissão que não será
detectado pela soma de verificação da Internet?

4. Os CRC são códigos eficientes de detecção de erros, capazes de detectar:

• todos os erros que afetam um número ímpar de bits

• todos os erros que afetam uma sequência de bits menor que o comprimento do CRC

Faça experimentos com uma implementação do CRC-32 para verificar se este é realmente o caso.

5. Checksums e CRCs não devem ser confundidos com funções hash seguras, como MD5 definidas na RFC 1321 ou SHA-1 descrito na RFC
4634. Funções hash seguras são usadas para garantir que arquivos ou, às vezes, pacotes/segmentos não foram modificados. As funções

hash seguras visam detectar alterações maliciosas, enquanto somas de verificação e CRCs detectam apenas erros de transmissão
aleatórios. Realize alguns experimentos com funções hash, como aquelas definidas em http://docs.python.org/library/hashlib.html módulo
python hashlib para verificar se este é realmente o caso.

6. Uma versão do Alternating Bit Protocol que suporta segmentos de comprimento variável usa um cabeçalho que contém
os seguintes campos:

• um número (0 ou 1)

• um campo de comprimento que indica o comprimento dos dados

114 Capítulo 4. A camada de transporte Fundação

URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• um CRC

Para acelerar a transmissão dos segmentos, um aluno propõe calcular o CRC sobre a parte de dados do segmento,
mas não sobre o cabeçalho. O que você acha dessa otimização?

7. Em hosts Unix, o comando ping(8) pode ser usado para medir o tempo de ida e volta para enviar e receber pacotes de um host
remoto. Use ping(8) para medir o percurso de ida e volta até um host remoto. Escolha um destino remoto que esteja longe da
sua localização atual, por exemplo, um pequeno servidor web em um país distante. Existem implementações de ping em vários
idiomas, consulte, por exemplo, http://pypi.python.org/pypi/ping/0.2 para uma píton implementação de ''ping''

8. Como você configuraria o temporizador de retransmissão se estivesse implementando o Alternating Bit Protocol para trocar
arquivos com um servidor como o que você mediu acima?

9. Quais são os fatores que afetam o desempenho do Alternating Bit Protocol?

10. Os links são frequentemente considerados simétricos, ou seja, oferecem a mesma largura de banda em ambas as direções.
Links simétricos são amplamente utilizados em redes locais e no núcleo da Internet, mas existem muitas tecnologias de links
assimétricos. O exemplo mais comum são os vários tipos de tecnologias ADSL e CATV. Considere uma implementação do
Alternating Bit Protocol usado entre dois hosts conectados diretamente por meio de um link assimétrico. Suponha que um host
esteja enviando segmentos contendo 10 bytes de informações de controle e 90 bytes de dados e que as confirmações tenham
10 bytes de comprimento. Se o tempo de ida e volta for insignificante, qual é a largura de banda mínima necessária no link de
retorno para garantir que a transmissão de confirmações não seja um gargalo?

11. Derive uma expressão matemática que forneça o goodput alcançado pelo Alternating Bit Protocol como-
resumindo que:

• Cada segmento contém D bytes de dados e c bytes de informações de controle

• Cada confirmação contém c bytes de informações de controle

• A largura de banda das duas direções do link é definida como B bits por segundo

• O atraso entre os dois hosts é de segundos em ambas as direções

O goodput é definido como a quantidade de SDUs (medidos em bytes) que são transferidos com sucesso durante um
período de tempo

12. Considere um protocolo de bits alternados usado em um link que apresenta erros determinísticos. Quando a taxa de erro é
definida como bit está corrompido.
1 , isso significa que p ÿ 1 bits são transmitidos corretamente e o p º
p
Discuta os fatores que afetam o desempenho do Alternating Bit Protocol em tal link.

13. Amazon fornece o serviço de armazenamento S3 onde empresas e pesquisadores podem armazenar muitas informações e
realizar cálculos nas informações armazenadas. A Amazon permite aos usuários enviar arquivos pela Internet, mas também
enviando discos rígidos. Suponha que um disco rígido de 1 Terabyte possa ser entregue à Amazon em 24 horas por serviço de
correio. Qual é a largura de banda mínima necessária para corresponder à largura de banda deste serviço de correio?

14. Vários grandes operadores de centros de dados (por exemplo, Microsoft e Google) anunciaram que instalam servidores como
contêineres, com cada contêiner hospedando até 2.000 servidores. Supondo um contêiner com 2.000 servidores e cada um
armazenando 500 GBytes de dados, qual é o tempo necessário para mover todos os dados armazenados em um contêiner por
um link de 10 Gbps? Qual é a largura de banda de um caminhão que precisa de 10 horas para transportar um contêiner de um
data center para outro.

15. Quais são as técnicas usadas por um remetente de retorno para se recuperar de:

• erros de transmissão

• perdas de segmentos de dados

• perdas de reconhecimentos

16. Considere um enlace de ab bits por segundo entre dois hosts que tem um atraso de propagação de t segundos. Derive uma
fórmula que calcule o tempo decorrido entre a transmissão do primeiro bit do segmento de bytes de anúncio de um host
remetente e a recepção do último bit deste segmento no host receptor.

4.5. Exercícios 115

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

17. Considere um remetente go-back-n e um receptor go-back que estão diretamente conectados a um link de 10 Mbps que tem um
atraso de propagação de 100 milissegundos. Suponha que o temporizador de retransmissão esteja definido para três segundos.
Se a janela tiver 4 segmentos, desenhe um diagrama de sequência de tempo mostrando a transmissão de 10 segmentos (cada
segmento contém 10.000 bits):

• quando não há perdas

• quando o terceiro e o sétimo segmentos são perdidos

• quando o segundo, quarto, sexto, oitavo, ... reconhecimentos são perdidos

• quando o terceiro e quarto segmentos de dados são reordenados (ou seja, o quarto chega antes do terceiro)

18. A mesma pergunta ao usar repetição seletiva em vez de voltar-n. Observe que a resposta não é necessariamente a
mesmo.

19. Considere dois servidores de última geração conectados costas com costas usando uma interface de 10 Gbps. Se o atraso entre
os dois servidores for de um milissegundo, qual é o rendimento que pode ser alcançado por um protocolo de transporte que usa
segmentos de 10.000 bits e uma janela de

• um segmento

• dez segmentos

• cem segmentos

20. Considere que dois servidores estão conectados diretamente usando um link de ab bits por segundo com um tempo de ida e volta
de r segundos. Os dois servidores estão utilizando um protocolo de transporte que envia segmentos contendo s bytes e
confirmações compostas por bytes. Você pode derivar uma fórmula que calcule a menor janela (medida em segmentos) necessária
para garantir que os servidores serão capazes de utilizar completamente o link?

21. Mesma pergunta acima se os dois servidores estiverem conectados através de um link assimétrico que transmite bu bits por
segundo na direção usada para enviar segmentos de dados e bd bits por segundo na direção usada para enviar confirmações.

22. O Trivial File Transfer Protocol é um protocolo de transferência de arquivos muito simples, frequentemente usado por hosts sem
disco ao inicializar a partir de um servidor. Leia a especificação TFTP na RFC 1350 e explicar como o TFTP se recupera de erros
e perdas de transmissão.

23. É possível que um receptor go-back-n interopere com um remetente de repetição seletiva? Justifique sua resposta.

24. É possível que um receptor de repetição seletiva interopere com um remetente go-back-n? Justifique sua resposta.

25. Os mecanismos de retorno e repetição seletiva descritos no livro baseiam-se exclusivamente em reconhecimentos cumulativos.
Isto implica que um receptor sempre retorna ao remetente informações sobre o último segmento recebido em sequência. Se
houver perdas ou reordenamentos frequentes, um receptor de repetição seletiva poderá retornar várias vezes a mesma
confirmação cumulativa. Você consegue pensar em outros tipos de confirmações que poderiam ser usadas por um receptor de
repetição seletiva para fornecer informações adicionais sobre os segmentos fora de sequência que ele recebeu? Elabore tais
confirmações e explique como o remetente deve reagir ao receber essas informações.

26. O goodput alcançado por um protocolo de transporte é geralmente definido como o número de bytes da camada de aplicação que
são trocados por unidade de tempo. Quais são os fatores que podem influenciar o goodput alcançado por um determinado
protocolo de transporte?

27. Quando usado com IPv4, o Transmission Control Protocol (TCP) anexa 40 bytes de informações de controle a cada segmento
enviado. Assumindo uma janela infinita e sem perdas nem erros de transmissão, derive uma fórmula que calcule o goodput
máximo do TCP em função do tamanho dos segmentos que são enviados.

28. Um remetente go-back-n usa um tamanho de janela codificado em um campo de bits. Quantos segmentos ele pode enviar sem
receber uma confirmação?

29. Considere a seguinte situação. Um receptor go-back-n enviou uma janela completa de segmentos de dados. Todos os segmentos
foram recebidos corretamente e em ordem pelo receptor, mas todas as confirmações retornadas foram perdidas. Mostre, utilizando
um diagrama de sequência temporal (por exemplo, considerando uma janela de quatro segmentos), o que acontece neste caso.
Você pode corrigir o problema no remetente go-back-n?

116 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

30. Mesma pergunta acima, mas suponha agora que tanto o remetente quanto o destinatário implementem a repetição seletiva.
Observe que a resposta será diferente da pergunta acima.

31. Considere um transporte que suporta janelas de cem segmentos de 1250 bytes. Qual é a largura de banda máxima que este
protocolo pode atingir se o tempo de ida e volta for definido como um segundo? O que acontece se, em vez de anunciar uma
janela de cem segmentos, o receptor decidir anunciar uma janela de 10 segmentos?

32. Explique em que circunstâncias uma entidade de transporte poderia anunciar uma janela de 0 segmentos?

33. Para compreender a operação do mecanismo de controle de congestionamento do TCP, é útil desenhar alguns diagramas de
sequência temporal. Vamos considerar um cenário simples de um cliente web conectado à Internet que deseja recuperar uma
página web simples de um servidor web remoto. Para simplificar, assumiremos que o atraso entre o cliente e o servidor é de 0,5
segundos e que os tempos de transmissão de pacotes no cliente e nos servidores são insignificantes (por exemplo, ambos estão
conectados a uma rede de 1 Gbps). Também assumiremos que o cliente e o servidor usam segmentos de 1 KBytes.

1. Calcule o tempo necessário para abrir uma conexão TCP, enviar uma solicitação HTTP e recuperar uma página da web de 16
KBytes. Este tamanho de página é típico dos resultados retornados por mecanismos de pesquisa como google_ ou bing. Um fator
importante nesse atraso é o tamanho inicial da janela de congestionamento TCP no servidor. Suponha primeiro que a janela inicial
esteja definida como 1 segmento conforme definido na RFC 2001, 4 KBytes (ou seja, 4 segmentos neste caso) conforme proposto
na RFC 3390 ou 16 KBytes conforme proposto em um artigo recente.

2. Faça a mesma análise com uma janela inicial de um segmento se o terceiro segmento enviado pelo servidor for
perdido e o tempo limite de retransmissão é fixo e definido para 2 segundos.

3. Mesma pergunta acima, mas suponha agora que o 6º segmento foi perdido.

4. Mesma pergunta acima, mas considere agora a perda do segundo e sétimo agradecimentos enviados pelo
cliente.

5. A análise acima muda se a janela inicial for definida para 16 KBytes em vez de um segmento?

34. Vários MBytes foram enviados em uma conexão TCP e ela ficou inativa por vários minutos. Discuta quais valores devem ser usados
para a janela de congestionamento, limite de início lento e temporizadores de retransmissão.

35. Para operar de forma confiável, um protocolo de transporte que usa Go-back-n (resp. repetição seletiva) não pode usar uma janela
n n-1
isso é maior que 2 ÿ 1 (resp. 2 ) segmentos. Essa limitação afeta o TCP? Explique sua resposta.

36. Considere a rede simples mostrada na figura abaixo. Nesta rede, o roteador entre o cliente e o servidor só pode armazenar em
cada interface de saída um pacote além do pacote que está transmitindo no momento. Ele descarta todos os pacotes que chegam
enquanto seu buffer está cheio. Supondo que você pode desprezar o tempo de transmissão das confirmações e que o servidor
utiliza uma janela inicial de um segmento e possui um temporizador de retransmissão configurado para 500 milissegundos, qual é
o tempo necessário para transmitir 10 segmentos do cliente para o servidor. O desempenho aumenta se o servidor usar uma
janela inicial de 16 segmentos?

Figura 4.60: Rede simples

37. A figura abaixo descreve a evolução da janela de congestionamento de uma conexão TCP. Você pode encontrar o
razões para os três eventos marcados na figura?

38. A figura abaixo descreve a evolução da janela de congestionamento de uma conexão TCP. Você pode encontrar o
razões para os três eventos marcados na figura?

4.5. Exercícios 117

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.61: Evolução da janela de congestionamento

Figura 4.62: Evolução da janela de congestionamento

39. Um servidor web serve principalmente páginas HTML que cabem em 10 segmentos TCP. Assumindo que o tempo de transmissão
de cada segmento pode ser desprezado, calcule o tempo total de transferência de tal página (em tempos de ida e volta)
assumindo que:

• a pilha TCP usa um tamanho de janela inicial de 1 segmento

• a pilha TCP usa um tamanho de janela inicial de três segmentos

40. RFC 3168 define o mecanismo que permite aos roteadores marcar pacotes definindo um bit no cabeçalho do pacote quando
eles estão congestionados. Quando um destino TCP recebe tal marcação em um pacote, ele retorna a marcação de
congestionamento para a fonte que reage reduzindo pela metade sua janela de congestionamento e evitando o congestionamento.
Considere uma conexão TCP onde o quarto segmento de dados sofre congestionamento. Compare o atraso para transmitir 8
segmentos em uma rede onde os roteadores descartam pacotes durante o congestionamento e uma rede onde os roteadores
marcam os pacotes durante o congestionamento.

4.5.2 Prática

1. A tomada interface permite que você use o protocolo UDP em um host Unix. O UDP fornece um serviço não confiável e sem
conexão que, em teoria, permite enviar SDUs de até 64 KBytes.

• Implemente um pequeno cliente UDP e um pequeno servidor UDP (em python, você pode começar pelo exemplo fornecido
em http://docs.python.org/library/socket.html mas você também pode usar C ou java)

• execute o cliente e os servidores em diferentes estações de trabalho para determinar experimentalmente o maior SDU compatível
com sua linguagem e sistema operacional. Se possível, use idiomas e sistemas operacionais diferentes em cada grupo.

2. Usando a interface de soquete, implemente o serviço não confiável sem conexão fornecido pelo UDP
um cliente simples que envia a seguinte mensagem mostrada na figura abaixo.

Nesta mensagem, os sinalizadores de bits devem ser definidos como 01010011b, o valor do campo de 16 bits deve ser
a raiz quadrada do valor contido no campo de 32 bits, a sequência de caracteres deve ser uma representação ASCII
(sem nenhum 0 à direita) de o número contido no campo de caracteres de 32 bits. Os últimos 16 bits da mensagem
contêm uma soma de verificação da Internet que foi calculada em toda a mensagem.

Ao receber uma mensagem, o servidor verifica se:

118 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

• a bandeira tem o valor correto

• o número inteiro de 32 bits é o quadrado do número inteiro de 16 bits

• a sequência de caracteres é uma representação ASCII do número inteiro de 32 bits

• a soma de verificação da Internet está correta

Se a verificação for bem-sucedida, o servidor retornará um SDU contendo 11111111b. Caso contrário, retorna 01010101b

Sua implementação deve ser capaz de rodar em máquinas low endian e big endian. Se você tiver acesso a diferentes tipos de
máquinas (por exemplo, x86 laptops e SPARC servidores), tente executar sua implementação em ambos os tipos de máquinas.

Figura 4.63: Formato SDU simples

3. A tomada A biblioteca também é usada para desenvolver aplicativos acima do serviço confiável de fluxo de bytes fornecido pelo TCP.
Instalamos no servidor cnp3.info.ucl.ac.be um servidor simples que fornece um serviço cliente-servidor simples. O serviço funciona da
seguinte forma:

• o servidor escuta na porta 62141 uma conexão TCP



após o estabelecimento de uma conexão TCP, o servidor envia um número inteiro usando o seguinte
Formato TLV:

– os dois primeiros bits indicam o tipo de informação (01 para ASCII, 10 para booleano)

– os próximos seis bits indicam o comprimento da informação (em bytes)

– Um TLV ASCII tem comprimento variável e os próximos bytes contêm um caractere ASCII por byte. Um TLV booleano
tem comprimento de um byte. O byte é definido como 00000000b para verdadeiro e 00000001b para falso.

• o cliente responde enviando o inteiro recebido codificado como um inteiro de 32 bits em bytes de rede
ordem

• o servidor retorna um TLV contendo verdadeiro se o número inteiro estiver correto e um TLV contendo falso
caso contrário, e fecha a conexão TCP

Implemente um cliente para interagir com este servidor em C, Java ou python.

4. Chegou a hora de implementar um pequeno protocolo de transporte. O protocolo utiliza uma janela deslizante para transmitir mais de um
segmento sem ser forçado a esperar por uma confirmação. Sua implementação deve oferecer suporte a janelas deslizantes de tamanho
variável, pois a outra extremidade do fluxo pode enviar seu tamanho máximo de janela. O tamanho da janela é codificado como um
número inteiro sem sinal de três bits.

O protocolo identifica os segmentos DATA usando números de sequência. O número de sequência do primeiro segmento deve
ser 0. Ele é incrementado em um para cada novo segmento. O receptor deve confirmar os segmentos entregues enviando um
segmento ACK. O campo de número de sequência no segmento ACK sempre contém o número de sequência do próximo
segmento de sequência esperado no receptor. O fluxo de dados é unidirecional, o que significa que o remetente envia apenas
segmentos DATA e o destinatário envia apenas segmentos ACK.

Para lidar com perdas de segmentos, o protocolo deve implementar uma técnica de recuperação como go-back-n ou repetição
seletiva e usar temporizadores de retransmissão. Você pode selecionar a técnica que melhor atende às suas necessidades e
partir de uma técnica simples que você aprimora posteriormente.

4.5. Exercícios 119

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.64: Formato do segmento

Este formato de segmento contém os seguintes campos:

• Tipo: tipo de segmento

– Segmento de DADOS 0x1.

– segmento ACK 0x2

• WIN: o tamanho da janela atual (um número inteiro codificado como um campo de 3 bits). Nos segmentos DATA, este
campo indica o tamanho da janela de envio do remetente. Nos segmentos ACK, este campo indica o valor atual da
janela de recebimento.

• Sequência: Número de sequência (número inteiro sem sinal de 8 bits), começa em 0. O número de sequência é
incrementado em 1 para cada novo segmento de DADOS enviado pelo remetente. Dentro de um segmento ACK, o
campo de sequência carrega o número de sequência do próximo segmento na sequência esperado pelo receptor.

• Comprimento: comprimento do payload em múltiplos de um byte. Todos os segmentos DATA contêm uma carga útil com
512 bytes de dados, exceto o último segmento DATA de uma transferência que pode ser mais curto. A recepção de um
segmento DATA cujo comprimento seja diferente de 512 indica o fim do trânsito de dados.

• Carga útil: os dados a serem enviados

O cliente e o servidor trocam datagramas UDP que contêm os segmentos DATA e ACK. Eles devem fornecer uma interface de
linha de comando que permita transmitir um arquivo binário e suportar os seguintes parâmetros:

remetente <nome_DNS_de_destino> <número_da_porta_de_destino> <tamanho_da_janela> <arquivo_de_entrada> receptor


<número_da_porta_de_escuta> <tamanho_da_janela> <arquivo_de_saída>

Para testar as reações do seu protocolo contra erros e perdas, você pode usar um gerador de números aleatórios para descartar
probabilisticamente segmentos recebidos e introduzir atrasos aleatórios na chegada de um segmento.

Análise de rastreamento de pacotes

Ao depurar problemas de rede ou analisar problemas de desempenho, às vezes é útil capturar os segmentos que são trocados entre dois hosts
e analisá-los.

Várias ferramentas de análise de rastreamento de pacotes estão disponíveis, tanto como ferramentas comerciais quanto de código aberto.
Essas ferramentas são capazes de capturar todos os pacotes trocados em um link. Obviamente, a captura de pacotes requer privilégios de
administrador. Eles também podem analisar o conteúdo dos pacotes capturados e exibir informações sobre eles. Os pacotes capturados podem
ser armazenados em um arquivo para análise offline.

tcpdump é provavelmente um dos softwares de captura de pacotes mais conhecidos. É capaz de capturar pacotes e exibir seu conteúdo.
tcpdump é uma ferramenta baseada em texto que pode exibir o valor dos campos mais importantes dos pacotes capturados. Informações
adicionais sobre tcpdump pode ser encontrado em tcpdump(1). O texto abaixo é um exemplo da saída do tcpdump para os primeiros segmentos
TCP trocados em uma transferência scp entre dois hosts.

21:05:56.230737 IP 192.168.1.101.54150 > 130.104.78.8.22: S 1385328972:1385328972(0) vitória 65535 <m


21:05:56.251468 IP 130.104.78.8.22 > 192.168.1.101.54150: S 3627767479:3627767479(0) ack 13853289 21:05:56.251560 IP 192.168.1.10 1.54150 >
130.104.78.8.22: . ack 1 vitória 65535 <nop,nop,timestamp 27 21:05:56.279137 IP 130.104.78.8.22 > 192.168.1.101.54150: P 1:21(20) ack 1 vitória 49248
<nop,nop,tim

120 Capítulo 4. A camada de transporte

URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

21:05:56.279241 IP 192.168.1.101.54150 > 130.104.78.8.22: . ack 21 vitória 65535 <nop,nop,timestamp 2 21:05:56.279534 IP 192.168.1.101.54150 >
130.104.78.8.22: P 1:22(21) ack 21 vitória 65535 <nop,nop,t 21:05: 56.303527 IP 130.104.78.8.22 > 192.168.1.101.54150: . ack 22 vitória 49248
<nop,nop,timestamp 1 21:05:56.303623 IP 192.168.1.101.54150 > 130.104.78.8.22: P 22:814(792) ack 21 vitória 65535 <nop,nop

Você pode reconhecer facilmente na saída acima o segmento SYN contendo as opções MSS, escala de janela, carimbo de data /
hora e sackOK, o segmento SYN + ACK cuja opção wscale indica que o servidor usa escala de janela para esta conexão e então os
primeiros segmentos trocados no conexão.

wirehark é mais recente que o tcpdump. Ele evoluiu do software de análise de rastreamento de pacotes etéreos. Ele pode ser usado
como uma ferramenta de texto como o tcpdump. Para uma conexão TCP, wireshark forneceria quase a mesma saída que o tcpdump.
A principal vantagem do wireshark é que também inclui uma interface gráfica de usuário que permite realizar vários tipos de análise
em um rastreamento de pacote.

Figura 4.65: Wireshark: janela padrão

A janela do wireshark é dividida em três partes. A parte superior da janela é um resumo dos primeiros pacotes do rastreamento. Ao
clicar em uma das linhas, você pode mostrar o conteúdo detalhado deste pacote no meio da janela. O meio da janela permite
inspecionar todos os campos do pacote capturado. A parte inferior da janela é a representação hexadecimal do pacote, com o campo
selecionado na janela do meio sendo destacado.

wirehark é muito bom para exibir pacotes, mas também contém diversas ferramentas de análise que podem ser muito úteis.
A primeira ferramenta é Seguir fluxo TCP. Faz parte do menu Analisar e permite remontar e exibir toda a carga trocada durante uma
conexão TCP. Esta ferramenta pode ser útil se você precisar analisar, por exemplo, os comandos trocados durante uma sessão
SMTP.

A segunda ferramenta é o gráfico de fluxo que faz parte do menu Estatísticas. Ele fornece um diagrama de seqüência temporal dos
pacotes trocados com alguns comentários sobre o conteúdo do pacote. Veja o golpe, por exemplo.

Figura 4.66: Wireshark: gráfico de fluxo

O terceiro conjunto de ferramentas são as ferramentas gráficas de fluxo TCP que fazem parte do menu Estatísticas. Essas
ferramentas permitem plotar diversos tipos de informações extraídas dos segmentos trocados durante uma conexão TCP. Um
primeiro gráfico interessante é o gráfico de números de sequência que mostra a evolução do campo de números de sequência dos
segmentos capturados ao longo do tempo. Este gráfico pode ser usado para detectar retransmissões graficamente.

4.5. Exercícios 121

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 4.67: Wireshark: gráfico de número de sequência

Um segundo gráfico interessante é o gráfico do tempo de ida e volta que mostra a evolução do tempo de ida e volta em função
de tempo. Este gráfico pode ser usado para verificar se o tempo de ida e volta permanece estável ou não. Observe que de um
rastreamento de pacotes, wireshark pode traçar dois gráficos de tempo de ida e volta, um para o fluxo do cliente para o servidor e
o outro. wirehark irá traçar o gráfico de tempo de ida e volta que corresponde ao pacote selecionado no topo
wirehark janela.

Figura 4.68: Wireshark: gráfico de tempo de ida e volta

Emulando uma rede com netkit

Kit de rede é um emulador de rede baseado no User Mode Linux. Permite configurar facilmente uma rede emulada de Linux
máquinas, que podem atuar como host final ou roteadores.

Nota: Onde posso encontrar o Netkit?

é
Netkit http://www.netkit.org.
disponível no Os arquivos podem ser baixados em
http://wiki.netkit.org/index.php/Download_Official, e instruções para as instalações estão disponíveis aqui:
http://wiki.netkit.org/download/netkit/INSTALL .

Existem duas maneiras de usar o Netkit: a maneira manual e usando laboratórios pré-configurados. No primeiro caso, você
inicialize e controle cada máquina individualmente, usando os comandos que começam com “v” (para máquina virtual). No
no segundo caso, você pode iniciar uma rede inteira em uma única operação. Os comandos para controlar o laboratório começam com
um “eu”. As páginas de manual desses comandos estão disponíveis em http://wiki.netkit.org/man/man7/netkit.7.html

122 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Você deve ter cuidado para não esquecer de parar suas máquinas virtuais e laboratórios, usando vhalt ou lhalt.

Um netkit lab é simplesmente um diretório contendo pelo menos um arquivo de configuração chamado lab.conf e um diretório para cada máquina
virtual. No caso do laboratório disponível no iCampus, a rede é composta por dois pcs, pc1 e pc2, ambos conectados a um roteador r1. O arquivo
lab.conf contém as seguintes linhas:

pc1[0]=A
pc2[0]=B
r1[0]=A
r1[1]=B

Isso significa que pc1 e r1 estão conectados a uma “LAN virtual” chamada A através de sua interface eth0, enquanto pc2 e r1 estão conectados à
“LAN virtual” B através, respectivamente, de suas interfaces eth0 e eth1.

O diretório de cada dispositivo está inicialmente vazio, mas será utilizado pelo Netkit para armazenar seu sistema de arquivos.

O diretório lab pode conter arquivos opcionais. No laboratório fornecido a você, o arquivo “pc1.startup” contém as instruções do shell a serem
executadas na inicialização da máquina virtual. Neste caso específico, o script configura a interface eth0 para permitir trocas de tráfego entre pc1
e r1, bem como a entrada da tabela de roteamento para ingressar no pc2.

Iniciar um laboratório consiste simplesmente em descompactar o arquivo fornecido, entrar no diretório lab e digitar lstart para iniciar a rede.

Nota: Compartilhamento de arquivos entre máquinas virtuais e host

As máquinas virtuais podem acessar o diretório do laboratório ao qual pertencem. Este repertório é montado em seu sistema de arquivos no
caminho /hostlab.

No laboratório netkit (exercícios/netkit/netkit_lab_2hosts_1rtr_ipv4.tar.tar.gz, você pode encontrar um python simples aplicação cliente/servidor
que estabelece conexões TCP. Sinta-se à vontade para reutilizar este código para realizar sua análise.

Nota: ferramentas netkit

Como as máquinas virtuais executam Linux, ferramentas de rede padrão, como hping, tcpdump, netstat etc. estão disponíveis normalmente.

Observe que a captura de rastreamentos de rede pode ser facilitada usando a extensão uml_dump disponível em http://kartoch.msi.unilim.fr/blog/?
p=19 . Esta extensão já está instalada na instalação do Netkit no laboratório do aluno. Para
capturar o tráfego trocado em uma determinada 'LAN virtual', basta emitir o comando vdump <nome da LAN> no host. Se você deseja canalizar o
rastreamento para o wireshark, você pode usar vdump A | wirehark -i - -k

1. Uma pilha TCP/IP recebe um segmento SYN com o número de sequência definido como 1234. Qual será o valor do número de confirmação
no segmento SYN+ACK retornado?

2. É possível que uma pilha TCP/IP retorne um segmento SYN+ACK com o número de confirmação definido como 0? Se não, explique por
quê. Se sim, qual foi o conteúdo do segmento SYN recebido.

3. Abra o tcpdump exercícios de rastreamento de pacotes/traces/trace.5connections_opening_closing.pcap e identifique o número de diferentes


conexões TCP que são estabelecidas e fechadas. Para cada conexão, explique por qual mecanismo elas são fechadas. Analise os
números de sequência iniciais usados nos segmentos SYN e SYN+ACK. Como esses números de sequência iniciais evoluem? Eles
aumentam a cada 4 microssegundos?

4. O tcpdump exercícios de rastreamento de pacotes/traces/trace.5connections.pcap contém vários


tentativas de conexão. Você pode explicar o que está acontecendo com essas tentativas de conexão?

5. O tcpdump exercícios de rastreamento de pacotes/traces/trace.ipv6.google.com.pcap foram coletados de um site popular que pode ser
acessado usando IPv6. Explique as opções de TCP suportadas pelo cliente e pelo servidor.

4.5. Exercícios 123

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

6. O tcpdump exercícios de rastreamento de pacotes/traces/trace.sirius.info.ucl.ac.be.pcap Was


coletados no servidor departamental. Quais são as opções de TCP suportadas por este servidor?

7. Uma implementação TCP mantém um Bloco de Controle de Transmissão (TCB) para cada conexão TCP. Este TCB é
uma estrutura de dados que contém o “estado” completo de cada conexão TCP. O TCB é descrito na RFC 793. Contém
primeiro a identificação da conexão TCP:

• localip: o endereço IP do host local

• remoteip: o endereço IP do host remoto

• remoteport: a porta TCP usada para esta conexão no host remoto

• localport : a porta TCP usada para esta conexão no host local. Observe que quando um cliente abre uma
conexão TCP, a porta local geralmente será escolhida no intervalo de portas efêmeras ( 49152 <= localport
<= 65535 ).

• sndnxt : o número de sequência do próximo byte no fluxo de bytes (o primeiro byte de um novo
segmento que você enviar usará esse número de sequência)

• snduna: o número de sequência mais antigo que foi enviado, mas ainda não foi reconhecido

• rcvnxt : o número de sequência do próximo byte que sua implementação espera receber do host remoto.
Para este exercício, você não precisa manter um buffer de recebimento e sua implementação pode descartar
os segmentos fora de sequência que ela recebe

• sndwnd : a janela de envio atual

• rcvwnd : a janela atual anunciada pelo receptor

Usando o rastreamento de pacote de exercícios/traces/trace.sirius.info.ucl.ac.be.pcap, qual é o TCB da conexão


no host 130.104.78.8 quando ele envia o terceiro segmento do rastreamento?

8. O tcpdump Os exercícios de rastreamento de pacotes/traces/trace.maps.google.com foram coletados contendo um site


popular que fornece informações de mapeamento. Quantas conexões TCP foram usadas para recuperar as informações
deste servidor?

9. Algumas ferramentas de monitoramento de rede, como ntop colete todos os segmentos TCP enviados e recebidos por um
host ou grupo de hosts e forneça estatísticas interessantes, como o número de conexões TCP, o número de bytes
trocados em cada conexão TCP, ... Supondo que você possa capturar todos os segmentos TCP enviado por um host,
proponha o pseudocódigo de uma aplicação que listaria todas as conexões TCP estabelecidas e aceitas por esse host e
a quantidade de bytes trocados em cada conexão. Você precisa contar o número de bytes contidos em cada segmento
para relatar o número de bytes trocados em cada conexão TCP?

30
10. Existem dois tipos de firewalls : dispositivos especiais colocados na fronteira de campus ou redes corporativas
e software executado em hosts finais. Os firewalls de software normalmente analisam todos os pacotes recebidos por um
host e decidem, com base no cabeçalho e no conteúdo do pacote, se ele pode ser processado pela pilha de rede do host
ou se deve ser descartado. Os administradores de sistema geralmente configuram firewalls em laptops ou máquinas de
alunos para evitar que os alunos instalem servidores em suas máquinas. Como você projetaria um firewall simples que
bloqueie todas as conexões TCP de entrada, mas ainda permita que o host estabeleça conexões TCP com qualquer
servidor remoto?

11. Usando o netkit laboratório explicado acima, realize alguns testes usando hping3(8). hping3(8) é uma ferramenta de linha
de comando que permite que qualquer pessoa (com privilégios de administrador do sistema) envie pacotes IP especiais
33
e segmentos TCP. hping3(8) pode ser usado para verificar a configuração de firewalls ou diagnosticar problemas.
Iremos usá-lo para testar a operação da pilha TCP do Linux em execução dentro do netkit.

1. No host do servidor, execute tcpdump(1) com -vv como parâmetro para coletar todos os pacotes recebidos do cliente e
exibi-los. Usando hping3(8) no host do cliente, envie um segmento SYN válido para uma porta não utilizada no host do
servidor (por exemplo, 12345). Qual é o conteúdo do segmento retornado pelo servidor?
30
Um firewall é um dispositivo de software ou hardware que analisa pacotes TCP/IP e decide, com base em um conjunto de regras, aceitar ou descartar os
pacotes recebidos ou enviados. As regras utilizadas por um firewall geralmente dependem do valor de alguns campos dos pacotes (ex. tipo de protocolos de
transporte, portas, ...). Discutiremos com mais detalhes a operação de firewalls no capítulo sobre camada de rede.

124 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

2. Execute o mesmo experimento, mas agora envie um segmento SYN para a porta 7. Esta porta é a porta padrão para o serviço de
descarte (veja services(5)) lançado por xinetd(8)). Qual segmento o servidor envia em resposta? O que acontece na recepção
deste segmento? Explique sua resposta.

12. A pilha TCP/IP do Linux pode ser facilmente configurada usando sysctl(8) para alterar as variáveis de configuração do kernel.
Consulte http://fasterdata.es.net/TCP-tuning/ip-sysctl-2.6.txt para obter uma lista recente das variáveis sysctl na pilha TCP/IP do
Linux. Tente desabilitar as confirmações seletivas e o carimbo de data e hora RFC1323 e as opções de janela grande e abra uma
conexão TCP na porta 7 do servidor usando :manpage:telnet'(1)'.
Verifique usando tcpdump(1) o efeito dessas variáveis do kernel nos segmentos enviados pela pilha do Linux no netkit.

13. Às vezes, os administradores de rede precisam verificar quais daemons de rede estão ativos em um servidor. Quando logado no
servidor, diversas ferramentas podem ser utilizadas para verificar isso. Uma primeira solução é usar o comando netstat(8). Este
comando permite extrair várias estatísticas da pilha de rede no kernel Linux. Para TCP, o netstat pode listar todas as conexões
TCP ativas com o estado de seu FSM. netstat suporta as seguintes opções que podem ser úteis durante estes exercícios:

• -t solicita informações sobre as conexões TCP

• -n solicita saída numérica (por padrão, o netstat envia consultas DNS para resolver endereços IP em hosts e usa /etc/
services para converter o número da porta em nomes de serviço, -n é recomendado no netkit máquinas)

• -e fornece mais informações sobre o estado das conexões TCP

• -o fornece informações sobre os temporizadores

• -a fornece informações sobre todas as conexões TCP, não apenas aquelas no estado Estabelecido

No netkit lab, inicie um daemon e inicie uma conexão TCP usando telnet(1) e use netstat(8) para verificar o estado dessas
conexões.

Uma segunda solução para determinar quais daemons de rede estão sendo executados em um servidor é usar uma
ferramenta como o nmap(1). O nmap(1) pode ser executado remotamente e, portanto, pode fornecer informações sobre
um host no qual o administrador do sistema não pode efetuar login. Use tcpdump(1) para coletar os segmentos enviados
pelo nmap(1) em execução no cliente e explicar como o nmap(1) funciona.

14. Conexões TCP de longa duração são suscetíveis aos chamados ataques RST. Tente encontrar informações adicionais
sobre esse ataque e explique como uma pilha TCP poderia mitigar tais ataques.
31 rede semelhante à
15. Para os exercícios abaixo, realizamos medições em um formato emulado
mostrado abaixo.

Figura 4.69: Rede emulada

A rede emulada é composta por três máquinas UML 32: um cliente, um servidor e um roteador. O
o cliente e o servidor estão conectados através do roteador. O cliente envia dados para o servidor. O link entre o roteador
e o cliente é controlado usando o netem Módulo do kernel Linux. Este módulo permite inserir atrasos adicionais, reduzir a
largura de banda do link e inserir perdas aleatórias de pacotes.

31 Com uma rede emulada é mais difícil obter resultados quantitativos do que com uma rede real, pois todas as máquinas emuladas precisam compartilhar a mesma CPU e memória.
Isto cria interações entre as diferentes máquinas emuladas que não acontecem no mundo real. Entretanto, como o objetivo deste exercício é apenas permitir que os alunos compreendam
o comportamento do mecanismo de controle de congestionamento TCP, este não é um problema grave.

32
Para obter mais informações sobre os esquemas de controle de congestionamento TCP implementados no kernel Linux, consulte
http://linuxgazette.net/135/pfeiffer.html e http://www.cs.helsinki.fi/research/iwtcp/papers/linuxtcp.pdf ou o código-fonte de um Linux recente.
Uma descrição de algumas das variáveis sysctl que permitem ajustar a implementação do TCP no kernel Linux pode ser encontrada em
http://fasterdata.es.net/TCP-tuning/linux.html. Para este exercício, configuramos o kernel Linux para usar o esquema NewReno RFC 3782
isso está muito próximo do padrão oficial definido na RFC 5681

4.5. Exercícios 125

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Usamos netem para coletar vários vestígios:

• exercícios/traços/trace0.pcap

• exercícios/traços/trace1.pcap

• exercícios/traços/trace2.pcap

• exercícios/traços/trace3.pcap

Usando wirehark ou tcpdump, faça as seguintes análises:

1. Identifique as opções TCP que foram usadas na conexão TCP

2. Tente encontrar explicações para a evolução do tempo de ida e volta em cada uma dessas conexões
TCP. Para isso, você pode usar o gráfico de tempo de ida e volta do Wireshark, mas tenha cuidado
com a estimativa deles, pois algumas versões do wireshark estão cheios de erros

3. Verifique se a implementação TCP utilizada implementou reconhecimento atrasado


comentários

4. Dentro de cada rastreamento de pacote, encontre:

1. um segmento que foi retransmitido usando retransmissão rápida. Explique esta retransmissão em
detalhes.

2. um segmento que foi retransmitido graças ao término do tempo limite de retransmissão do TCP.
Explique por que esse segmento não poderia ter sido retransmitido usando a retransmissão rápida.

5. wirehark contém vários dois gráficos úteis: o gráfico de tempo de ida e volta e o gráfico de sequência
de tempo. Explique como você calcularia o mesmo gráfico a partir de tal traço .

6. Ao exibir segmentos TCP, versões recentes do wireshark contêm heurísticas de análise especializada
que indicam se o segmento foi retransmitido, se é uma confirmação duplicada ou se o tempo limite
de retransmissão expirou. Explique como você implementaria a mesma heurística do wireshark.

7. Você consegue descobrir qual arquivo foi trocado durante a transferência?

16. Você foi contratado como especialista em networking por uma empresa. Nesta empresa, os usuários de uma aplicação em
rede reclamam que a rede está muito lenta. Os desenvolvedores do aplicativo argumentam que quaisquer atrasos são
causados por perdas de pacotes e falhas na rede. O administrador da rede argumenta que a rede funciona perfeitamente e
que os atrasos percebidos pelos usuários são causados pelas aplicações ou pelos servidores onde a aplicação está rodando.
Para resolver o caso e determinar se o problema se deve à rede ou ao servidor no qual o aplicativo está sendo executado. O
administrador da rede coletou um rastreio de pacote representativo que você pode baixar em exerces/traces/trace9.pcap.
Observando o rastreamento, você pode resolver esse caso e indicar se a rede ou o aplicativo é o culpado?

126 Capítulo 4. A camada de transporte


URL de Saylor: http://www.saylor.org/courses/cs402/ Fundação Saylor
Machine Translated by Google

CAPÍTULO 5

A camada de rede

A camada de transporte permite que os aplicativos troquem dados de maneira eficiente e confiável. As entidades da camada de
transporte esperam poder enviar segmentos para qualquer destino sem precisar entender nada sobre as tecnologias de sub-rede
subjacentes. Existem muitas tecnologias de sub-rede. A maioria deles difere em detalhes sutis (tamanho do quadro,
endereçamento, ...). A camada de rede é a ligação entre essas sub-redes e a camada de transporte. Ele oculta para a camada de
transporte toda a complexidade das sub-redes subjacentes e garante que as informações possam ser trocadas entre hosts
conectados a diferentes tipos de sub-redes.

Neste capítulo, primeiro explicamos os princípios da camada de rede. Esses princípios incluem os modos de datagrama e circuito
virtual, a separação entre o plano de dados e o plano de controle e os algoritmos usados pelos protocolos de roteamento. Em
seguida, explicamos, com mais detalhes, a camada de rede na Internet, começando pelo IPv4 e IPv6 e depois passando para os
protocolos de roteamento (RIP, OSPF e BGP).

5.1 Princípios
O principal objetivo da camada de rede é permitir que sistemas finais, conectados a diferentes redes, troquem informações através
de sistemas intermediários denominados roteadores. A unidade de informação na camada de rede é chamada de pacote.

Figura 5.1: A camada de rede no modelo de referência

Antes de explicar detalhadamente a camada de rede, é útil começar analisando o serviço fornecido pela camada de enlace de dados.
Existem muitas variantes da camada de datalink. Alguns fornecem um serviço orientado à conexão, enquanto outros fornecem um
serviço sem conexão. Nesta seção, nos concentramos nos serviços da camada de enlace de dados sem conexão, pois são os mais
amplamente utilizados. Usar uma camada de enlace de dados orientada a conexão causa alguns problemas que estão além do
escopo deste capítulo. Veja RFC 3819 para uma discussão sobre este tema.

Existem três tipos principais de camadas de datalink. A camada de enlace de dados mais simples ocorre quando há apenas dois
sistemas de comunicação diretamente conectados através da camada física. Essa camada de enlace de dados é usada quando há
um enlace ponto a ponto entre os dois sistemas de comunicação. Os dois sistemas podem ser sistemas finais ou roteadores. PPP
(Protocolo Ponto a Ponto), definido na RFC 1661, é um exemplo de tal camada de link de dados ponto a ponto. As camadas de
enlace trocam quadros e um quadro de enlace enviado por uma entidade da camada de enlace à esquerda é transmitido através da
camada física, para que possa alcançar a entidade da camada de enlace à direita. Camadas de datalink ponto a ponto podem

127

URL de Saylor: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 5.2: A camada de link de dados ponto a ponto

fornecer um serviço não confiável (os quadros podem ser corrompidos ou perdidos) ou um serviço confiável (neste caso, a camada de enlace
de dados inclui mecanismos de retransmissão semelhantes aos usados na camada de transporte). O serviço não confiável é frequentemente
usado acima das camadas físicas (por exemplo, fibra óptica, pares trançados) com uma taxa de erro de bit baixa, enquanto mecanismos de
confiabilidade são frequentemente usados em redes sem fio para recuperação local de erros de transmissão.

O segundo tipo de camada de link de dados é aquele usado em redes locais (LAN). Conceitualmente, uma LAN é um conjunto de dispositivos
de comunicação de modo que quaisquer dois dispositivos possam trocar quadros diretamente através da camada de enlace de dados. Tanto
os sistemas finais quanto os roteadores podem ser conectados a uma LAN. Algumas LANs conectam apenas alguns dispositivos, mas existem
LANs que podem conectar centenas ou até milhares de dispositivos.

Figura 5.3: Uma rede local

No próximo capítulo, descrevemos a organização e o funcionamento das Redes Locais. Uma diferença importante entre as camadas de
enlace de dados ponto a ponto e as camadas de enlace de dados usadas em LANs é que em uma LAN, cada dispositivo de comunicação é
identificado por um endereço exclusivo da camada de enlace de dados. Este endereço geralmente está incorporado no hardware do dispositivo
e diferentes tipos de LANs usam diferentes tipos de endereços da camada de enlace de dados. Um dispositivo de comunicação conectado a
uma LAN pode enviar um quadro de link de dados para qualquer outro dispositivo de comunicação conectado à mesma LAN. A maioria das
LANs também suporta endereços especiais de camada de enlace de dados de transmissão e multicast. Um quadro enviado para o endereço
de broadcast da LAN é entregue a todos os dispositivos de comunicação conectados à LAN. Os endereços multicast são usados para
identificar grupos de dispositivos em comunicação. Quando um quadro é enviado para um endereço da camada de enlace de dados multicast,
ele é entregue pela LAN a todos os dispositivos de comunicação que pertencem ao grupo correspondente.

O terceiro tipo de camadas de link de dados é usado em redes Non-Broadcast Multi-Access (NBMA). Essas redes são usadas para
interconectar dispositivos como uma LAN. Todos os dispositivos conectados a uma rede NBMA são identificados por um endereço exclusivo
da camada de enlace de dados. Porém, e esta é a principal diferença entre uma rede NBMA e uma LAN tradicional, o serviço NBMA suporta
apenas unicast. O serviço da camada de enlace fornecido por uma rede NBMA não suporta nem broadcast nem multicast.

Infelizmente nenhuma camada de datalink é capaz de enviar quadros de lado ilimitado. Cada camada de datalink é caracterizada por um
tamanho máximo de quadro. Existem mais de uma dúzia de camadas de datalink diferentes e, infelizmente, a maioria delas usa um tamanho
máximo de quadro diferente. A camada de rede deve lidar com a heterogeneidade da camada de enlace de dados.

A própria camada de rede depende dos seguintes princípios:

1. Cada entidade da camada de rede é identificada por um endereço da camada de rede. Este endereço é independente do
endereços da camada de enlace de dados que ela pode usar.

128 Capítulo 5. A camada de rede The Saylor

URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

2. O serviço prestado pela camada de rede não depende do serviço ou da organização interna da
camadas de link de dados subjacentes.

3. A camada de rede é conceitualmente dividida em dois planos: o plano de dados e o plano de controle. O plano de dados contém os
protocolos e mecanismos que permitem que hosts e roteadores troquem pacotes que transportam dados do usuário. O plano de
controle contém os protocolos e mecanismos que permitem aos roteadores aprender com eficiência como encaminhar pacotes para
seu destino final.

A independência da camada de rede da camada de enlace de dados subjacente é um princípio fundamental da camada de rede. Ele garante
que a camada de rede possa ser usada para permitir que hosts conectados a diferentes tipos de camadas de enlace de dados troquem pacotes
através de roteadores intermediários. Além disso, isso permite que as camadas de enlace de dados e a camada de rede evoluam
independentemente uma da outra. Isso permite que a camada de rede seja facilmente adaptada a uma nova camada de enlace de dados
sempre que uma nova camada de enlace de dados for inventada.

Existem dois tipos de serviços que podem ser fornecidos pela camada de rede:

• um serviço sem conexão não confiável

• um serviço orientado à conexão, confiável ou não confiável

Os serviços orientados à conexão têm sido populares com tecnologias como X.25 e ATM ou frame-relay, mas hoje em dia a maioria das redes
usa um serviço sem conexão não confiável. Este é o nosso foco principal neste capítulo.

5.1.1 Organização da camada de rede

Existem duas possíveis organizações internas da camada de rede:

• datagrama

• circuitos virtuais

A organização interna da rede é ortogonal ao serviço que ela fornece, mas na maioria das vezes uma organização de datagrama é usada para
fornecer um serviço sem conexão, enquanto uma organização de circuito virtual é usada em redes que fornecem um serviço orientado a
conexão.

Organização de datagrama

A primeira e mais popular organização da camada de rede é a organização de datagramas. Esta organização é inspirada na organização dos
correios. Cada host é identificado por um endereço da camada de rede. Para enviar informações a um host remoto, um host cria um pacote
que contém:

• o endereço da camada de rede do host de destino

• seu próprio endereço de camada de rede

• as informações a serem enviadas

A camada de rede limita o tamanho máximo do pacote. Assim, as informações devem ter sido divididas em pacotes pela camada de transporte
antes de serem passadas para a camada de rede.

Para entender a organização do datagrama, consideremos a figura abaixo. Um endereço da camada de rede, representado por uma letra, foi
atribuído a cada host e roteador. Para enviar alguma informação ao host J, o host A cria um pacote contendo seu próprio endereço, o endereço
de destino e as informações a serem trocadas.

Com a organização do datagrama, os roteadores usam o encaminhamento salto a salto. Isto significa que quando um roteador recebe um
pacote que não é destinado a ele mesmo, ele procura o endereço de destino do pacote em sua tabela de roteamento. Uma tabela de
roteamento é uma estrutura de dados que mapeia cada endereço de destino (ou conjunto de endereços de destino) para a interface de saída
através da qual um pacote destinado a esse endereço deve ser encaminhado para chegar ao seu destino final.

A principal restrição imposta às tabelas de roteamento é que elas devem permitir que qualquer host da rede alcance qualquer outro host. Isto
implica que cada roteador deve conhecer uma rota para cada destino, mas também que os caminhos compostos a partir das informações
armazenadas nas tabelas de roteamento não devem conter loops. Caso contrário, alguns destinos seriam inacessíveis.

5.1. Princípios Saylor 129

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 5.4: Uma interligação de redes simples

No exemplo acima, o host A envia seu pacote para o roteador R1. R1 consulta sua tabela de roteamento e encaminha o pacote para
R2. Com base em sua própria tabela de roteamento, R2 decide encaminhar o pacote para R5, que pode entregá-lo ao seu destino.

Para permitir que os hosts troquem pacotes, uma rede depende de dois tipos diferentes de protocolos e mecanismos. Primeiro, deve
haver uma definição precisa do formato dos pacotes que são enviados pelos hosts e processados pelos roteadores.
Segundo, o algoritmo usado pelos roteadores para encaminhar esses pacotes deve ser definido. Este protocolo e este algoritmo
fazem parte do plano de dados da camada de rede. O plano de dados contém todos os protocolos e algoritmos usados por hosts e
roteadores para criar e processar os pacotes que contêm dados do usuário.

O plano de dados e, em particular, o algoritmo de encaminhamento usado pelos roteadores, depende das tabelas de roteamento
mantidas no roteador de alcance. Essas tabelas de roteamento podem ser mantidas usando diversas técnicas (configuração manual,
protocolos distribuídos, computação centralizada, etc.). Essas técnicas fazem parte do plano de controle da camada de rede. O plano
de controle contém todos os protocolos e mecanismos usados para calcular e instalar tabelas de roteamento nos roteadores.

A organização de datagramas tem sido muito popular em redes de computadores. As camadas de rede baseadas em datagramas
incluem IPv4 e IPv6 na Internet global, CLNP definido pela ISO, IPX definido pela Novell ou XNS definido pela Xerox [Perlman2000].

Organização de circuito virtual

A principal vantagem da organização do datagrama é a sua simplicidade. Os princípios desta organização podem ser facilmente
compreendidos. Além disso, permite que um host envie facilmente um pacote para qualquer destino a qualquer momento. Entretanto,
como cada pacote é encaminhado independentemente por roteadores intermediários, os pacotes enviados por um host podem não
seguir o mesmo caminho para chegar a um determinado destino. Isto pode causar reordenação de pacotes, o que pode ser irritante
para protocolos de transporte. Além disso, como um roteador que usa encaminhamento hop-by-hop sempre encaminha pacotes
enviados para o mesmo destino pela mesma interface de saída, isso pode causar congestionamento em alguns links.

A segunda organização da camada de rede, denominada circuitos virtuais, foi inspirada na organização das redes telefônicas. As
redes telefônicas foram projetadas para transmitir chamadas que geralmente duram alguns minutos.
Cada telefone é identificado por um número de telefone e está conectado a uma central telefônica. Para iniciar uma chamada
telefônica, primeiro o telefone precisa enviar o número de telefone do destino ao seu switch local. O switch coopera com os outros
switches da rede para criar um canal bidirecional entre os dois telefones através da rede.
Este canal será utilizado pelos dois telefones durante a duração da chamada e será liberado ao final da chamada. Até a década de
1960, a maioria desses canais era criada manualmente, pelas operadoras de telefonia, a pedido do chamador. As redes telefónicas
actuais utilizam comutadores automatizados e permitem que vários canais sejam transmitidos através da mesma ligação física, mas
os princípios permanecem praticamente os mesmos.

130 Capítulo 5. A camada de rede The


URL de Saylor: http://www.saylor.org/courses/cs402/ Saylor Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Numa rede que utiliza circuitos virtuais, todos os hosts são identificados com um endereço da camada de rede. Entretanto, um host deve
solicitar explicitamente o estabelecimento de um circuito virtual antes de poder enviar pacotes a um host de destino.
A solicitação para estabelecer um circuito virtual é processada pelo plano de controle, que instala o estado para criar o circuito virtual entre a
origem e o destino através de roteadores intermediários. Todos os pacotes enviados no circuito virtual contêm um identificador de circuito virtual
que permite aos roteadores determinar a qual circuito virtual cada pacote pertence. Isso é ilustrado na figura abaixo com um circuito virtual
entre o host A e o host I e outro entre o host A e o host J.

Figura 5.5: Uma interligação de redes simples usando circuitos virtuais

O estabelecimento de um circuito virtual é realizado utilizando um protocolo de sinalização no plano de controle. Normalmente, o host de origem
envia uma mensagem de sinalização para indicar ao seu roteador o endereço de destino e possivelmente algumas características de
desempenho do circuito virtual a ser estabelecido. O primeiro roteador pode processar a mensagem de sinalização de duas maneiras diferentes.

Uma primeira solução é o roteador consultar sua tabela de roteamento, lembrar as características do circuito virtual solicitado e encaminhá-lo
pela interface de saída até o destino. A mensagem de sinalização é então encaminhada salto a salto até chegar ao destino e o circuito virtual
é aberto ao longo do caminho seguido pela mensagem de sinalização. Isso é ilustrado com o circuito virtual vermelho na figura abaixo.

Figura 5.6: Estabelecimento de circuito virtual

Uma segunda solução pode ser utilizada se os roteadores conhecerem toda a topologia da rede. Neste caso, o primeiro roteador pode usar
uma técnica chamada roteamento de origem. Ao receber a mensagem de sinalização, o primeiro roteador escolhe o caminho do circuito virtual
na rede. Este caminho é codificado como a lista de endereços de todos os roteadores intermediários para chegar ao destino. Ele está incluído
na mensagem de sinalização e os roteadores intermediários podem remover seu endereço da mensagem de sinalização antes de encaminhá-
la. Essa técnica permite que os roteadores distribuam melhor os circuitos virtuais pela rede. Se os roteadores conhecerem a carga dos links
remotos, eles também poderão selecionar o caminho menos carregado ao estabelecer um circuito virtual. Esta solução é ilustrada com o circuito
azul na figura acima.

O último ponto a ser discutido sobre a organização do circuito virtual é o seu plano de dados. O plano de dados define principalmente o formato
dos pacotes de dados e o algoritmo usado pelos roteadores para encaminhar pacotes. Os pacotes de dados contêm um identificador de circuito
virtual, codificado como um número fixo de bits. Esses identificadores de circuitos virtuais são geralmente chamados de rótulos.

5.1. Princípios Saylor 131

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Cada host mantém uma tabela de fluxo que associa um rótulo a cada circuito virtual estabelecido. Quando um roteador recebe um pacote contendo

um rótulo, ele extrai o rótulo e consulta sua tabela de encaminhamento de rótulos. Esta tabela é uma estrutura de dados que mapeia cada par
(interface de entrada, rótulo) para a interface de saída a ser usada para encaminhar o pacote, bem como o rótulo que deve ser colocado nos
pacotes de saída. Na prática, a tabela de encaminhamento de rótulos pode ser implementada como um vetor e o par (interface de entrada, rótulo)
é o índice da entrada no vetor que contém a interface de saída e o rótulo de saída. Assim, um único acesso à memória é suficiente para consultar
a tabela de encaminhamento de etiquetas. A utilização da tabela de encaminhamento de etiquetas é ilustrada na figura abaixo.

Figura 5.7: Tabelas de encaminhamento de rótulos em uma rede usando circuitos virtuais

A organização de circuitos virtuais tem sido utilizada principalmente em redes públicas, a partir de X.25 e depois em redes Frame Relay e Modo de
Transferência Assíncrona (ATM).

Tanto as organizações de datagramas quanto de circuitos virtuais têm vantagens e desvantagens. A principal vantagem da organização de
datagramas é que os hosts podem facilmente enviar pacotes para qualquer número de destinos, enquanto a organização de circuitos virtuais requer
o estabelecimento de um circuito virtual antes da transmissão de um pacote de dados. Esta solução pode ser dispendiosa para hosts que trocam
pequenas quantidades de dados. Por outro lado, a principal vantagem da organização de circuitos virtuais é que o algoritmo de encaminhamento
utilizado pelos roteadores é mais simples do que quando se utiliza a organização de datagramas. Além disso, a utilização de circuitos virtuais pode
permitir que a carga seja melhor distribuída pela rede graças à utilização de múltiplos circuitos virtuais. A técnica MultiProtocol Label Switching
(MPLS) que discutiremos em outra revisão deste livro pode ser considerada um bom compromisso entre datagramas e circuitos virtuais. MPLS
utiliza circuitos virtuais entre roteadores, mas não os estende aos hosts finais. Informações adicionais sobre MPLS podem ser encontradas em
[ML2011].

5.1.2 O plano de controle

Um dos objetivos do plano de controle na camada de rede é manter as tabelas de roteamento usadas em todos os roteadores. Conforme indicado
anteriormente, uma tabela de roteamento é uma estrutura de dados que contém, para cada endereço de destino (ou bloco de endereços) conhecido
pelo roteador, a interface de saída pela qual o roteador deve encaminhar um pacote destinado a esse endereço. A tabela de roteamento também
pode conter informações adicionais, como o endereço do próximo roteador no caminho em direção ao destino ou uma estimativa do custo desse
caminho.

Nesta seção, discutimos as três principais técnicas que podem ser usadas para manter as tabelas de roteamento em uma rede.

Roteamento Estático

A solução mais simples é pré-calcular todas as tabelas de roteamento de todos os roteadores e instalá-las em cada roteador.
Vários algoritmos podem ser usados para calcular essas tabelas.

132 Capítulo 5. A camada de rede The Saylor


URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation
Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Uma solução simples é usar o roteamento pelo caminho mais curto e minimizar o número de roteadores intermediários para chegar a cada destino.
Algoritmos mais complexos podem levar em conta a carga esperada nos links para garantir que não ocorra congestionamento para uma determinada
demanda de tráfego. Todos esses algoritmos devem garantir que:

• todos os roteadores são configurados com uma rota para chegar a cada destino

• nenhum dos caminhos compostos com as entradas encontradas nas tabelas de roteamento contém ciclo. Tal ciclo levaria a um loop de
encaminhamento.

A figura abaixo mostra exemplos de tabelas de roteamento em uma rede de cinco roteadores.

Figura 5.8: Tabelas de roteamento em uma rede simples

A principal desvantagem do roteamento estático é que ele não se adapta à evolução da rede. Quando um novo roteador ou link é adicionado, todas
as tabelas de roteamento devem ser recalculadas. Além disso, quando um link ou roteador falha, as tabelas de roteamento também devem ser
atualizadas.

Roteamento vetorial de distância

O roteamento de vetor de distância é um protocolo de roteamento distribuído simples. O roteamento vetorial de distância permite que os roteadores
descubram automaticamente os destinos acessíveis dentro da rede, bem como o caminho mais curto para chegar a cada um desses destinos. O
caminho mais curto é calculado com base nas métricas ou custos associados a cada link. Usamos l.cost para representar a métrica que foi
configurada para o link l em um roteador.

Cada roteador mantém uma tabela de roteamento. A tabela de roteamento R pode ser modelada como uma estrutura de dados que armazena, para
cada endereço de destino conhecido d, os seguintes atributos:

• R[d].link é o link de saída que o roteador usa para encaminhar pacotes para o destino d

• R[d].cost é a soma das métricas dos links que compõem o caminho mais curto para chegar ao destino d

• R[d].time é o carimbo de data/hora do último vetor de distância contendo o destino d

Um roteador que usa roteamento de vetor de distância envia regularmente seu vetor de distância por todas as suas interfaces. O vetor de distância
é um resumo da tabela de roteamento do roteador que indica a distância até cada destino conhecido. Este vetor de distância pode ser calculado a
partir da tabela de roteamento usando o pseudocódigo abaixo.

A cada N segundos: v=Vector()

para d em R[]: # adicione


o destino d ao vetor v.add(Pair(d,R[d].cost))

para eu em interfaces
# envia o vetor v nesta interface send(v,interface)

Quando um roteador é inicializado, ele não conhece nenhum destino na rede e sua tabela de roteamento contém apenas a si mesmo. Assim, ele
envia a todos os seus vizinhos um vetor de distância que contém apenas seu endereço a uma distância 0. Quando um roteador recebe um vetor de
distância no enlace l, ele o processa da seguinte maneira.

# V: vetor recebido # l: link através do


qual o vetor é recebido
def recebido(V,l): # vetor recebido
do link l para d em V[]

5.1. Princípios Saylor 133

URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

se não (d em R[]): # nova rota

R[d].cost=V[d].cost+l.cost R[d].link=l
R[d].time=agora
mais:

# rota existente, a nova é melhor? if ( ((V[d].cost+l.cost) <


R[d].cost) ou ( R[d].link == l) ) :
# Melhor rota ou mudança para rota atual R[d].cost=V[d].cost+l.cost

R[d].link=l
R[d].time=agora

O roteador itera sobre todos os endereços incluídos no vetor de distância. Se o vetor de distância contém um endereço que o roteador não
conhece, ele insere o destino dentro de sua tabela de roteamento via enlace l e a uma distância que é a soma entre a distância indicada no
vetor de distância e o custo associado ao enlace l. Se o destino já for conhecido pelo roteador, ele somente atualizará a entrada
correspondente em sua tabela de roteamento se:

• o custo da nova rota é menor que o custo da rota já conhecida ( (V[d].cost+l.cost) < R[d].cost)

• a nova rota foi aprendida através do mesmo link que a melhor rota atual para este destino ( R[d].link
== eu)

A primeira condição garante que o roteador descubra o caminho mais curto para cada destino. A segunda condição é usada para levar
em conta as mudanças de rotas que podem ocorrer após uma falha no link ou uma mudança na métrica associada a um link.

Para entender a operação de um protocolo de vetor de distância, consideremos a rede de cinco roteadores mostrada abaixo.

Figura 5.9: Operação do roteamento vetorial de distância em uma rede simples

Suponha que A seja o primeiro a enviar seu vetor distância [A=0].

• B e D processam o vetor de distância recebido e atualizam sua tabela de roteamento com uma rota em direção a A.

• D envia seu vetor de distância [D=0,A=1] para A e E. E agora pode alcançar A e D.

• C envia seu vetor de distância [C=0] para B e E

• E envia seu vetor de distância [E=0,D=1,A=2,C=2] para D, B e C. B agora pode alcançar A, C, D e E

• B envia seu vetor de distância [B=0,A=1,C=1,D=2,E=1] para A, C e E. A, B, C e E agora podem alcançar todos
destinos.

• A envia seu vetor de distância [A=0,B=1,C=2,D=1,E=2] para B e D.

Neste ponto, todos os roteadores podem alcançar todos os outros roteadores da rede graças às tabelas de roteamento mostradas na figura
abaixo.

Para lidar com falhas de links e roteadores, os roteadores usam o carimbo de data/hora armazenado em sua tabela de roteamento. Como
todos os roteadores enviam seu vetor de distância a cada N segundos, o carimbo de data/hora de cada rota deve ser atualizado
regularmente. Portanto, nenhuma rota deve ter um carimbo de data/hora anterior a N segundos, a menos que a rota não esteja mais
acessível. Na prática, para lidar com a possível perda de um vetor de distância devido a erros de transmissão, os roteadores verificam o
carimbo de data/hora das rotas armazenadas em sua tabela de roteamento a cada N segundos e removem as rotas com mais de 3 × N
segundos. Quando um roteador percebe que uma rota em direção a um destino expirou, ele deve primeiro associar um custo ÿ a essa rota e enviar

134 Capítulo 5. A camada de rede The Saylor

URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

Figura 5.10: Tabelas de roteamento calculadas por vetor de distância em uma rede simples

seu vetor de distância para seus vizinhos para informá-los. A rota pode então ser removida da tabela de roteamento após algum tempo
(por exemplo, 3 × N segundos), para garantir que os roteadores vizinhos tenham recebido as más notícias, mesmo que alguns vetores
de distância não os alcancem devido a erros de transmissão.

Considere o exemplo acima e suponha que o link entre os roteadores A e B falhe. Antes da falha, A usava B para alcançar os destinos B,
C e E, enquanto B usava apenas o link AB para chegar a A. As entradas afetadas atingem o tempo limite nos roteadores A e B e ambos
enviam seu vetor de distância.

• A envia seu vetor distância [A = 0, D = ÿ, C = ÿ, D = 1, E = ÿ]. D sabe que não pode alcançar B
mais via A

• D envia seu vetor distância [D = 0, B = ÿ, A = 1, C = 2, E = 1] para A e E. A recupera rotas para


C e E via D.

• B envia seu vetor de distância [B = 0, A = ÿ, C = 1, D = 2, E = 1] para E e C. D descobre que não há mais rota para chegar a A via
B.

• E envia seu vetor de distância [E = 0, A = 2, C = 1, D = 1, B = 1] para D, B e C. D aprende uma rota em direção


B. C e B aprendem uma rota em direção a A.

Neste ponto, todos os roteadores possuem uma tabela de roteamento que lhes permite alcançar todos os outros roteadores, exceto o
roteador A, que ainda não pode alcançar o roteador B. A recupera a rota em direção a B assim que o roteador D envia seu vetor de distância
atualizado [A = 1, B = 2, C = 2, D = 1, E = 1]. Esta última etapa é ilustrada na figura Tabelas de roteamento calculadas pelo vetor de distância
após uma falha, que mostra as tabelas de roteamento em todos os roteadores.

Figura 5.11: Tabelas de roteamento calculadas pelo vetor de distância após uma falha

Considere agora que a ligação entre D e E falha. A rede agora está particionada em duas partes disjuntas: (A, D) e (B, E, C). As rotas
para B, C e E expiram primeiro no roteador D. Neste momento, o roteador D atualiza sua tabela de roteamento.

Se D enviar [D = 0, A = 1, B = ÿ, C = ÿ, E = ÿ], A aprende que B, C e E estão inacessíveis e atualiza sua tabela de roteamento.

Infelizmente, se o vetor de distância enviado para A for perdido ou se A enviar seu próprio vetor de distância ( [A = 0, D = 1, B =
3, C = 3, E = 2]) ao mesmo tempo que D envia seu vetor de distância, D atualiza sua tabela de roteamento para usar o

5.1. Princípios 135

Saylor URL: http://www.saylor.org/courses/cs402/ A Fundação Saylor


Machine Translated by Google

Redes de Computadores: Princípios, Protocolos e Práticas, Versão 0.25

rotas mais curtas anunciadas por A em direção a B, C e E. Depois de algum tempo, D envia um novo vetor de distância: [D = 0, A = 1, E = 3,
C = 4, B = 4]. A atualiza sua tabela de roteamento e depois de algum tempo envia seu próprio vetor de distância [A = 0, D = 1, B = 5, C = 5, E
= 4], etc. Este problema é conhecido como problema de contagem até o infinito em redes literatura. Os roteadores A e D trocam vetores de
distância com custos crescentes até que esses custos atinjam ÿ. Esse problema pode ocorrer em outros cenários além daquele representado
na figura acima. Na verdade, o roteamento do vetor de distância pode sofrer problemas de contagem até o infinito assim que houver um ciclo
na rede. Os ciclos são necessários para que haja redundância suficiente para lidar com falhas de links e roteadores. Para mitigar o impacto da
contagem até o infinito, alguns protocolos de vetores de distância consideram que 16 = ÿ. Infelizmente, isto limita as métricas que os
operadores de rede podem utilizar e o diâmetro das redes que utilizam vetores de distância.

Esse problema de contagem até o infinito ocorre porque o roteador A anuncia ao roteador D uma rota que ele aprendeu por meio do roteador
D. Uma possível solução para evitar esse problema poderia ser alterar a forma como um roteador cria seu vetor de distância. Em vez de
calcular um vetor de distância e enviá-lo a todos os seus vizinhos, um roteador poderia criar um vetor de distância específico para cada vizinho
e conter apenas as rotas que não foram aprendidas através deste vizinho. Isso pode ser implementado pelo seguinte pseudocódigo.

A cada N segundos: # um
vetor para cada interface para l em interfaces:

v=Vetor() para d
em R[]: if (R[d].link !=
i) :
v=v+Pair(d,R[d.cost]) send(v) # fim
para d em
R[] #fim para l em interfaces

Essa técnica é chamada de horizonte dividido. Com esta técnica, o problema da contagem até o infinito não teria acontecido no cenário acima,
pois o roteador A teria anunciado [A = 0], uma vez que aprendeu todas as suas outras rotas via roteador D. Outra variante chamada split-
horizon com veneno reverso também é possível. Os roteadores que usam esta variante anunciam um custo de ÿ para os destinos que
alcançam através do roteador para o qual enviam o vetor de distância. Isso pode ser implementado usando o pseudocódigo abaixo.

A cada N segundos: para l


em interfaces:
# um vetor para cada interface
v=Vetor() para d
em R[]: if (R[d].link !=
i) :
v=v+Pair(d,R[d.cost]) senão:

v=v+Par(d,infinito); send(v) # fim


para d em
R[] #fim para l em interfaces

Infelizmente, o horizonte dividido não é suficiente para evitar todos os problemas de contagem até o infinito com roteamento de vetor de distância.
Considere a falha do link AB na rede dos quatro roteadores abaixo.

Figura 5.12: Problema de contagem até o infinito

136 Capítulo 5. A camada de rede The Saylor

URL de Saylor: http://www.saylor.org/courses/cs402/ Foundation

Você também pode gostar