Teoria de rede e segurança
 
 
TCP
(Transmission Control Protocol)

O TCP é um protocolo de rede que fica na camada de transporte do modelo OSI. Ele é orientado à conexão e confiável, significando que todas as comunicações, antes de iniciar a troca de dados, precisam estabelecer uma conexão. Esse estabelecimento ocorre pelo three-way handshake. Esse protocolo, também, corrige erros como perda, duplicação ou falta de integridade de segmentos, envia segmentos confirmando o recebimento dos dados, faz controle de congestionamento e de fluxo. Além disso tudo, faz a sincronização dos segmentos e finalização das conexões.

O segmento TCP é composto por um cabeçalho que pode variar de 20 à 60 bytes. Essa variação ocorre devido ao campo options, onde dependendo das opções usadas, o tamanho do cabeçalho TCP pode mudar. A seguir é apresentado o segmento TCP e em seguida o conceito de cada campo, sendo realizada uma síntese de acordo com Soares, Lemos e Colcher (1995); Tanenbaum (1997); Diógenes (2004); Comer (1998); Firewall.cx [200-?]; Postel (1981c):

Figura 1: Segmento TCP.
Fonte: Postel (1981c, p. 15) adaptado.

As especificações do TCP foram atualizadas em setembro de 2001 de acordo com a RFC (Request for Comments) 3168. Esta atualização teve o intuito de melhorar o desempenho do protocolo em relação ao descarte de pacotes quando a rede está congestionada. Um congestionamento de rede ocorre quando o desempenho dos roteadores, que estão entre os hosts finais, é prejudicado pelo excesso de pacotes na rede. Muitas são as causas de congestionamento nos roteadores, como por exemplo: processador lento, pouca memória, muita memória, muitas interfaces de rede de entrada e uma única de saída, largura de banda mal dimensionada, imposição do transmissor etc. Na figura a seguir é mostrado o que mudou no cabeçalho TCP:

Figura 2: Novo segmento TCP.
Fonte: Ramakrishnan, Floyd e Black (2001, p. 13) adaptado.

Como pode ser visto na figura 2, o campo Reserved diminuiu e duas novas flags foram acrescentadas no cabeçalho TCP que são as CWR e ECE:

Quando ocorre um congestionamento, é indício que pacotes estão sendo descartados. Stevens (1997, p. 2) complementa, descrevendo que este descarte é devido a capacidade de algum ponto da Internet ter sido alcançado. Os hosts finais podem saber que isto está acontecendo por três fatores: timeout de segmento sem confirmação (TCP-ACK), recebimento de três segmentos TCP-ACKs duplicados ou notificação explícita de congestionamento (TCP-ECN-Echo). No momento em que um congestionamento é detectado, o transmissor reduz a taxa de transmissão e reenvia o(s) segmento(s) que foram descartados.

Para um melhor entendimento sobre controle de congestionamento com o TCP, se faz necessário abordar assuntos que envolvem o próprio TCP. Assim, nos três tópicos a seguir são expostos assuntos como: estabelecimento de conexão, troca de dados, janelamento, retransmissão, controle de fluxo, controle de congestionamento etc.



TCP
(Notificação Implícita de Congestionamento)

Ao se usar o TCP é necessário estabelecer uma conexão antes da troca de dados. Esse estabelecimento de conexão se chama Three-way Handshake e são utilizados três segmentos para isto. Assim, para estabelecer uma conexão o receptor deve enviar um TCP-SYN para o transmissor, o transmissor responde com um TCP-SYN-ACK e o receptor envia um TCP-ACK. Diógenes (2004, p. 84) evidência que o Three-way Handshake consiste de três trocas de informações que são um SYN, SYN/ACK e ACK. Esses segmentos são usados para que os hosts finais saibam da existência um do outro e para que troquem informações como: porta de origem e de destino pretendidas, números de seqüência inicias, janelas iniciais, tamanho máximo de um segmento, tipo de implementação para controle de congestionamento etc. Com isso, é estabelecido uma conexão entre o transmissor e o receptor. Devido as essas características apresentadas, o TCP é chamado de orientado à conexão.

A partir deste momento, o transmissor pode trocar dados com o receptor. Para cada segmento enviado, tanto pelo transmissor, quanto pelo receptor, se faz necessário uma confirmação com um segmento TCP com a flag ACK ligada. No entanto, enquanto essa confirmação não chegar, o destino não pode enviar os segmentos seguintes. Comer (1998, p. 214) assinala que o transmissor espera uma confirmação antes de enviar o próximo segmento. Essa confirmação vem para garantir que o segmento transmitido chegou ao seu destino de forma correta. É interessante frisar que o único segmento TCP que não tem a flag ACK ligada é o primeiro (TCP-SYN) enviado pelo receptor durante o estabelecimento de uma conexão. Devido as características acima, o TCP é chamado de confiável.

Quando os hosts finais trocam dados, o TCP utiliza o conceito de janela deslizante que tem o intuito de aproveitar ao máximo a capacidade dos recursos oferecidos tanto pela rede, quanto pelo receptor. Como já foi dito, para cada segmento TCP enviado, se faz necessário uma confirmação (TCP-ACK). Isso, em termos de confiabilidade é interessante, mas de desempenho não. Pensando nisto, o TCP traz o recurso da janela deslizante, onde as confirmações só serão enviadas depois de certa quantidade de bytes transferidos. Em outras palavras, isso significa que uma confirmação só será enviada depois que um ou vários segmentos forem transmitidos. Comer (1998, p. 216) escreveu que a janela deslizante permite que múltiplos segmentos sejam transmitidos antes de esperar uma confirmação. Com isso, o desempenho geral do protocolo aumenta, pois ele não tem que esperar por uma confirmação para enviar vários segmentos consecutivos. Vale ressaltar que o número de segmentos que pode ser enviado de uma única vez é limitado pela quantidade de bytes definida pela janela de transmissão. Para saber o valor dessa janela de transmissão, o TCP verifica dois parâmetros: a AWND (Advertised Window ou Announced Window) e a CWND (Congestion Window).

A AWND é uma propaganda ou janela, enviada pelo receptor ao transmissor, da quantidade de bytes que aquele pode receber em seu buffer de uma única vez. Esse parâmetro é definido no campo window do cabeçalho TCP. Ele tem o intuito de aproveitar ao máximo a capacidade do receptor sem que o transmissor envie mais bytes que aquele é capaz de suportar e que, também, a capacidade dele não seja subutilizada. Os valores da AWND são especificados desde o estabelecimento, até a finalização de uma conexão. A AWND, também, é conhecida como RWND (Receiver Window) de acordo com a RFC 2581. As características apresentadas acima da AWND, são conhecidas como controle de fluxo.

Já a CWND pode ser entendida como uma variável cujo conteúdo é capacidade passageira de transferência de bytes pela rede. Algoritmos de controle congestionamento adicionam a CWND como uma nova janela para o transmissor, sendo o concorrente direto da AWND (campo window do cabeçalho TCP). Na prática, a CWND pode ser entendida como a quantidade de bytes que os roteadores podem suportar sem que haja congestionamento, evitando assim o descarte de datagramas. Para uma melhor compreensão, Stevens (1997, p. 2) considera que a AWND é o controle de fluxo imposto pelo receptor e a CWND é o controle de fluxo imposto pela rede através do transmissor. Nada adiantaria, por exemplo, se o buffer de um receptor (AWND) fosse de 10 bytes, o da rede (CWND) fosse 4 bytes e o transmissor enviasse um segmento compondo 10 bytes. A rede não suportaria e o descartaria. O inverso também é verdadeiro, se a rede suporta 10 bytes, o receptor somente 4 bytes e se o transmissor enviasse 10 bytes, o receptor não teria buffer para armazenar o segmento. Devido a esse problema, o transmissor sempre escolhe o mínimo entre a AWND e a CWND que no exemplo exposto seria uma janela de 4 bytes.

Para saber o valor da AWND é fácil, pois quem o anuncia é o próprio receptor que sabe de sua capacidade atual, mas para calcular a CWND não é tão simples. Isso, porque o transmissor precisa conhecer a capacidade da rede que são equipamentos que estão remotamente conectados. Para dificultar um pouco mais, a capacidade desses equipamentos pode variar no decorrer do tempo, sendo que essa variável deve ser atualizada freqüentemente. Para realizar a descoberta da janela de congestionamento são utilizados vários algoritmos como: Slow-Start, Congestion Avoidance, Fast Retransmit e Fast Recovery. Além desses algoritmos, também, são utilizadas várias versões do TCP como: Tahoe, Reno, New Reno e SACK.

Durante o estabelecimento de uma conexão, são especificados os valores iniciais para a AWND e a CWND. O valor de AWND é anunciado pelo transmissor e pelo receptor no campo window do cabeçalho TCP. A CWND não tem campo, devido a isso, é criada essa variável pelo algoritmo chamado Slow-Start com o valor inicial a de um MSS (Maximum Segment Size) que, em outras palavras, é similar (equivalente) a um segmento. De acordo com Tanenbaum (1997, p. 612) quando uma conexão é estabelecida, o transmissor ajusta a janela de transmissão ao tamanho de um MSS. O MSS é especificado durante o estabelecimento da conexão nas opções do cabeçalho TCP. Depois do estabelecimento da conexão, ou seja, durante a troca de dados, a AWND ainda continua sendo fornecida dinamicamente pelo hosts finais. Já no caso da CWND, são usados vários algoritmos para a sua regulação.

Durante a troca de dados, o algoritmo Slow-Start aumenta exponencialmente a janela de congestionamento (CWND). Ao enviar um segmento e receber uma confirmação, a CWND passa de um segmento para dois. Quando esses dois segmentos são enviados e confirmados, a CWND passa para 4 segmentos e assim sucessivamente até alcançar o valor de AWND que é o limite. Vale relembrar que a janela de transmissão é o mínimo entre a AWND e a CWND. Essa situação demonstrada de crescimento exponencial seria o ideal, pois a rede estaria suportando a quantidade de bytes da janela do receptor. Mas na prática, isso poderia ser diferente caso a CWND não pudesse alcançar tal valor. Nesse caso, usam-se outros algoritmos que evitam congestionamento da rede. Um congestionamento de rede ocorre pela incapacidade de equipamentos entre os hosts finais de processar todos os pacotes que passam por eles. Existem duas maneiras implícitas para saber se está havendo congestionamento na rede.

A primeira é pela expiração do RTT (Round Trip Time). O RTT é uma estimativa de tempo gasta para que um segmento seja enviado e confirmado, ou seja, tempo de ida e de volta. Para cada segmento enviado, esse temporizador é iniciado. Comer (1998, p. 230) explica que se esse temporizador terminar antes da confirmação do segmento, o TCP retransmite o segmento não confirmado. Mas antes de fazer essa retransmissão, entra em ação um outro algoritmo chamado de Congention Avoidance o qual encara a expiração do RTT como perda de pacote. Esse algoritmo utiliza uma outra variável chamada de SSTHRESH (Slow-Start Threshold Size) que no momento da detecção de congestionamento é atribuído a ela o valor da metade da quantidade de bytes da janela de transmissão atual [SSTHRESH = mínimo(AWND,CWMD) / 2]. Depois de definido o valor para o SSTHRESH, o algoritmo diminui a CWND para um segmento (CWND = 1 segm). Então, é executado o Slow-Start para reiniciar a transmissão, retransmitir o segmento descartado e os subseqüentes. Agora, o crescimento exponencial da CWND tem um limite que é o valor do SSTHRESH. Ao alcançar esse limite, o crescimento exponencial passa para linear, significando que é aumentada de um segmento a cada RTT.

A segunda maneira para saber se está havendo congestionamento implicitamente na rede é pela recepção de três TCP-ACKs duplicados. No receptor é executado o algoritmo chamado Fast Retransmit que ao receber três TCP-ACKs duplicados, é encarado como perda de segmento. Três ACKs duplicados querem dizer, três confirmações de segmentos já enviados com o valor do campo acknowledgement number iguais. Stevens (1997, p. 4) detalha que um ou dois ACKs duplicados são considerados segmentos fora de ordem, mas três ou mais é um forte indício de descarte. Devido a isso, depois dessas três confirmações duplicadas, o algoritmo Fast Retransmit imediatamente retransmite o segmento solicitado no campo duplicado, não esperando a expiração do RTT. Caso não haja mais descarte, essa confirmação do recebimento da retransmissão deve confirmar a recepção de todos os outros segmentos anteriormente enviados. Em seguida, entra em ação o algoritmo Fast Recovery que atribui ao SSTHRESH a metade da janela de congestionamento (SSTHRESH = CWMD / 2) que não pode ser menos que dois segmentos. Já a janela congestionamento é SSTHRESH mais três vezes o valor de um segmento (CWND = SSTHRESH + 3 segm). Esta multiplicação por três é devido ao congestionamento não ser severo, pois foram recebidos três reconhecimentos duplicados que afirmam que o receptor recebeu três segmentos com sucesso. Após todos esses procedimentos, o algoritmo Congestion Avoidance é executado para reiniciar a transmissão normal dos segmentos.



TCP
(Notificação Explícita de Congestionamento)

O estabelecimento de conexão descrita no tópico anterior é para uma situação normal onde os hosts controlam o congestionamento implicitamente. Mas se os hosts tiverem a intenção de fazê-lo explicitamente devem utilizar tanto a flag ECE (ECN-Echo), quanto a CWR (Congestion Window Reduced). Ramakrishnan, Floyd e Black (2001, p. 13) explanam que a notificação explícita de congestionamento utilizam duas novas flags dentro do campo Reserved do cabeçalho do segmento TCP. Durante o estabelecimento de uma conexão com controle de congestionamento explícito, o receptor envia um TCP-SYN-ECN-CWR para o transmissor, o transmissor deve responder com um TCP-SYN-ACK-ECN e o receptor envia um TCP-ACK. Estes segmentos, além de serem usados para a troca normal de informações, também especificam que o transmissor e receptor estão hábitos a realizarem o controle de congestionamento explícito.

Além dessas duas novas flags no cabeçalho TCP, também são utilizados 2 bits no cabeçalho do datagrama IP. No campo Differentiated Services Field são utilizadas duas flags: o ECT (ECN-Capable Transport) e o ECN-CE (ECN-Congestion Experienced). Ramakrishnan, Floyd e Black (2001, p. 14) mostram que a notificação de congestionamento explícita usa o ECT e o ECN-CE no cabeçalho IP. Durante a troca de dados, o transmissor emite segmentos com o flag ECT no cabeçalho IP ligada. Assim, os roteadores, que estão no meio da transmissão, têm condições de saber se os equipamentos finais estão utilizando controle de congestionamento explicitamente na camada de transporte. Ao descartar datagramas com esta flag ECT ligada, o roteador, que possui esse recurso, envia um datagrama IP para o receptor com a flag ECE ligada. Com isso, mostra ao receptor que houve congestionamento. Os TCP-ACKs seguintes, o receptor manda com a flag ECN-Echo setada para que o transmissor tome as providências para resolver o problema. O transmissor ao receber esses reconhecimentos (confirmações) com ECN-Echo. reduz os valores de CWND e SSTHRESH, passando a enviar os segmentos seguintes com o bit CWR ligado para que o receptor saiba que providências estão sendo tomadas e para que ele pare de enviar TCP-ACKs com ECN-Echo. Para um melhor ententimento sobre o ECT e ECN-CE, leia a parte do Differentiated Services Field no artigo chamado IP ou IPv4 (Internet Protocol ou Internet Protocol versão 4).



Versões do TCP

Umas das versões do protocolo TCP é o Reno que utiliza os algoritmos Slow-Start, Congestion Avoidance, Fast Retransmit e Fast Recovery. O Reno tenta prevenir o congestionamento através de TCP-ACKs duplicados. Caso receba 3 ACKs duplicados é transmitido novamente o segmento descartado e reduzida a janela de transmissão, conforme já exposto nos tópicos anteriores. O receptor ao receber a retransmissão, deve confirmar sua chegada ao transmissor, transmitindo um TCP-ACK, o qual pode confirmar, também, todos os outros segmentos anteriormente enviados. Mas o Reno de acordo com Costa (2004, p. 1) não trabalha bem com a perda de segmentos consecutivos, reduzindo abruptamente a vazão. O problema nesta versão ocorre quando mais de um segmento é descartado na mesma janela de transmissão. O transmissor vendo isso, irá reduzir a janela sucessivas vezes a cada detecção de segmento descartado, até que todos os segmentos sejam confirmados.

Para resolver esse problema, um nova versão do TCP Reno surgiu: o New Reno. Ao detectar que mais de um segmento em uma mesma janela de transmissão foram descartados, ele deve permanecer no Fast Retransmit e transmitir novamente um segmento descartado a cada solicitação (TCP-ACK duplicado). Isso irá acontecer até que o transmissor receba um TCP-ACK que confirme todos os segmentos enviados até o momento. Assim, evita-se as seguidas reduções na janela de transmissão. Depois, ele sai do algoritmo Fast Retransmit e segue o caminho normal de uma transmissão com o Fast Recovery.

Para melhorar ainda mais o desempenho nas retransmissões é usado atualmente a versão SACK (Selective ACK) do TCP. Que conforme já foi exposto, é utilizado o campo Options do cabeçalho TCP para informar qual ou quais segmentos precisam ser retransmitidos. Mathis, Mahdavi, Floyd e Romanow (1996, p. 2) acrescentam que sem o uso do SACK o transmissor tem que esperar o tempo de ida e volta dos segmentos para saber quais foram perdidos. Somente para termos de conhecimento, a primeira versão do TCP era chamada de Tahoe e utilizava somente os algoritmos Slow-Start e Congestion Avoidance para controle de congestionamento.

 
 




ETI - Especialista em Tecnologia
da Informação