Um handshake TCP "normal" se parece com isto:
MachineA → SYN → MachineB
Machine B → SYN,ACK → MachineA
MachineA → ACK → MachineB
Isso significa que para cada etapa, espera-se que um sinalizador (ou conjunto de sinalizadores) seja definido no pacote.
Os sinalizadores extras são descartados quando o sinalizador esperado está presente ou um pacote com sinalizadores extras é tratado como incorreto? Em outras palavras, a sequência a seguir seria tratada MachineB
como um aperto de mão completo e correto?
MachineA → SYN → MachineB
Machine B → SYN,ACK → MachineA
MachineA → ACK,RST,FIN → MachineB
ACK
está presente no último pacote (portanto, o handshake pode ser visto como finalizado), mas também há um sinalizador RST
and FIN
(este é apenas um exemplo de sinalizadores estranhos).
Minha pergunta é geral - o aperto de mão inicial é apenas um exemplo, estou interessado no caso geral de descartar ou não sinalizadores extras em outras sequências também.
Nenhum deles é estranho por si só, tecnicamente, mesmo que a combinação completa no seu exemplo seja realmente excessiva.
"o terceiro pacote do handshake espera um ACK" é uma simplificação exagerada - o handshake TCP nunca foi realmente especificado como tendo esta forma
SYN
→SYN,ACK
→ rígidaACK
. Em vez disso, cada sinalizador tem uma função específica e transições de estado específicas, o que leva a um aperto de mão típico com esta forma.De forma mais geral, a função do aperto de mão é:
SYN
, que máquina BACK
s.SYN
, que máquina AACK
s.Mesmo que a
ACK
máquina B seja mesclada com aSYN
, essas ainda são apenas operações separadas e até mesmo a especificação a descreve como um handshake lógico de quatro vias, onde algumas etapas " podem ser combinadas " em uma operação de três vias - e geralmente são, mas isso não está gravado em pedra.Por exemplo, é legal que ambos os hosts enviem seus
SYN
s ao mesmo tempo, cruzando caminhos (não que isso aconteça na prática, presumo), levando a uma trocaSYN
⇄SYN
/SYN,ACK
⇄SYN,ACK
– chamada de " abertura simultânea " no TCP.Por outro lado, embora a especificação diga que um SYN recebido deve ser seguido pelo envio de um SYN,ACK em troca, ainda não é um erro se apenas um
ACK
semSYN
for recebido na etapa dois – é um ACK válido, embora tenha nenhum efeito no avanço do aperto de mão.Da mesma forma, a sequência
FIN
→FIN,ACK
→ consiste em duas sequências → distintas onde cada máquina ACK é o FIN recebido, e é legal - e comum - ter uma conexão " semifechada " onde um lado emitiu um FIN, mas o outro apenas o ACK, mas continua enviando dados.ACK
FIN
ACK
Então, em relação ao seu exemplo:
A Máquina-B está no estado SYN-RECEIVED quando recebe o terceiro pacote.
É permitido definir
RST
neste ponto o que fecharia a conexão sem estabelecê-la totalmente – não como um pacote de handshake inválido, mas como um RST válido.A especificação não indica nada sobre a verificação do FIN neste momento – isso só é feito se não houver RST.
Também é permitido ter
FIN
set neste ponto, o que – se o RST não estivesse presente – teria o mesmo efeito como se a conexão estivesse no estado ESTABLISHED.(Observe que a mesma seção diz apenas "enviar uma confirmação para o FIN"; não diz nada sobre o envio de outro FIN em troca - isso deve ser feito explicitamente pelo software fechando o soquete.)
Ter FIN e RST no mesmo pacote é realmente estranho, mas neste caso o RST entrará em vigor primeiro e (seguindo o algoritmo detalhado na especificação) o FIN nunca será verificado.
Não existe um caso geral de “sinalizações extras”; a especificação lista quais sinalizadores o receptor deve verificar em cada estado , e a resposta depende do sinalizador e do estado. Por exemplo, o sinalizador URG no estado CLOSING é especificado como "Ignorar o URG", enquanto no estado SYN-SENT ele é processado normalmente (já que o pacote SYN pode conter dados regulares).