se um pacote TCP foi parcialmente reconhecido, como o mecanismo de retransmissão reagirá?

12

se um cliente tcp enviar um pacote, com número de sequência de 10000 a 20000, para um servidor tcp. o tcp responderá com um ACK com seq_ack 20001.

se eu interceptar o pacote TCP do cliente e dividir o pacote em segmentos de 2 tcp, um com seq de 10000 a 15000 e o outro com seq de 15001 a 20000. E então esses 2 segmentos TCP são enviados para o Servidor TCP. Suponha que o segundo segmento seja perdido no caminho. O servidor TCP responderá um ACK com seq_ack 15001.

Agora, já que o cliente TCP envia um pacote integral com o seq 10000 a 20000, mas obtém um ACK com 15001, do ponto de vista do cliente, isso é estranho. Como vai reagir? Em teoria, o cliente deve retransmitir os bytes de seq 15001 a 20000, ou seja, o cliente transmitirá novos pacotes a partir do seq 15001. Mas, quanto à prática, na implementação da pilha TCP, é a mesma que na teoria?

Eu acho que no buffer de envio TCP, quando um segmento tcp é enviado, o segmento ainda permanece lá até o ACK. Quando o ACK vem, esses bytes para o segmento são limpos do buffer. Há um ponteiro no buffer de envio, quando um ACK chega, o ponteiro aponta para o local onde o ack_seq corresponde. Os bytes que estão abaixo do ack_seq são limpos. Desta forma, todo o segmento não precisa ser retransmitido?

    
por misteryes 22.05.2013 / 14:57

2 respostas

8

Isso é chamado de reconhecimento seletivo e já está incluído na especificação TCP definida em RFC 2018 . Isso permitiria que o cliente reenviasse apenas os bytes 15001 a 20000 (já que eles estão em pacotes / segmentos diferentes se você os dividiu como você diz), mas o mais interessante é que ele permite até mesmo o out-of- pedir confirmações.

da RFC 2018:

When receiving an ACK containing a SACK option, the data sender SHOULD record the selective acknowledgment for future reference. The data sender is assumed to have a retransmission queue that contains the segments that have been transmitted but not yet acknowledged, in sequence-number order.

O suporte a SACK não é não exigido pela especificação TCP. Se o cliente ou o servidor não suportasse a confirmação seletiva, de fato, todos os bytes 10000 a 20000 teriam que ser retransmitidos.

In TCP stack implementation, is it the same as in the theory?

Normalmente, o SACK é suportado, pois os ganhos de desempenho, eficiência e latência são significativos - especialmente em uma rede como a internet.

Na verdade, no entanto, essas suposições devem ser verdadeiras mesmo se você manipular manualmente os pacotes conforme declarou. De acordo com a RFC 793 , no mínimo, toda a janela de dados terá que ser retransmitida, mas o receptor faz sabe que os dados recebidos são pelo menos válidos . Para detalhes de implementação, Seção 3.3 - Números de Sequência da RFC 793.

Para obter uma descrição geral de todo o processo, com e sem suporte de reconhecimento seletivo, consulte este artigo (que inclui alguns diagramas muito úteis).

    
por 22.05.2013 / 15:04
3

Os tamanhos dos segmentos podem (e mudam) durante a vida útil de uma conexão. Felizmente, o TCP não precisa registrar o tamanho do segmento com o qual os pacotes individuais foram enviados anteriormente. Portanto, ele fará o seguinte:

  1. Sempre que um ACK chegar, avance o ponteiro para o primeiro byte não reconhecido e descarte qualquer buffer desnecessário.
  2. Quando surgir a necessidade de retransmissão (Fast Retransmit ou Timeout; NOT imediatamente após o recebimento do primeiro ACK!), ele será reenviado no tamanho do segmento atualmente válido a partir do ponteiro para o primeiro byte não reconhecido.

Ambas as operações são feitas independentemente do tamanho do segmento em que esses bytes foram originalmente enviados. Portanto, a teoria deve corresponder à maioria das implementações.

Deixe-me dar algumas informações para explicar:

O TCP usa bytes ou segmentos? Para o aplicativo, o TCP expõe uma interface de fluxo de bytes. Além disso, todos os campos de cabeçalho e variáveis internas estão em bytes. No entanto, para transmitir informações, o TCP as fragmenta em segmentos, já que enviar bytes um por um seria um grande desperdício :-). O uso de contadores de bytes em todos os lugares tem a vantagem de que o tamanho do segmento não precisa permanecer constante durante a vida útil da conexão:

  • Opções estão sendo introduzidas, por exemplo pegando carona em um SACK em uma retransmissão (implementações reais irão encontrar isso raramente, se forem)
  • A MTU do caminho muda, por exemplo um link ao longo do caminho muda para um MTU mais baixo ou o link do MTU gargalo é gerado. Isso acontece quando os túneis são estabelecidos (VPN, PPPoE) ou o protocolo de roteamento seleciona um link MTU diferente. Isso acontece no IPv4 com o conjunto Don't Fragment (verdadeiro para a maioria dos TCPs modernos); sempre em TCPv6).

BTW: SACK não é a resposta aqui, já que o receptor (normalmente) só usa o SACK se reconhecer um buraco no fluxo de byte (ou seja, se um pacote se perdeu mas um pacote seguinte chegou).

    
por 05.06.2013 / 14:01