Alex Vaz Mendes (discussão | contribs)
Sem resumo de edição
Alex Vaz Mendes (discussão | contribs)
 
(25 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 48: Linha 48:


= Especificação Funcional =
= Especificação Funcional =
* O TCP fornece a informação do campom "protocolo" do IP.
* Segue o cabeçalho:
[[Arquivo: cabecalhoTCP.png|center|frame|]]
* Porta fonte e destino (16 bits)
* Número de Sequência (32 bits): número do primeiro byte do segmento, quando tem SYN, é o número inicial da sequência (ISN) e o primeiro byte está em ISN+1.
* Número de reconhecimento (32 bits): se o bit ACK está setado, este é o valor do próximo número de sequência esperado.
* Comprimento do cabeçalho (Data offset - 4 bits)
* Não utilizado (6 bits)
* Bits de Controle (6 bits)
** URG: ponteiro de urgência
** ACK
** PSH: ponteiro do PUSH
** RST: resetar conexão
** SYN: sincronização dos números de sequência
** FIN: fim da transmissão
* Window (16 bits): número de bytes, quando ACK está setado, que o destinatário ainda pode receber.
* Checksum (16 bits): complemento de 1 da soma de todas as palavras de 16 bits. Ele abrange um pseudo cabeçalho de 96 bits (endereços de fonte e destino, o protocolo e o TCP Length(tamanho do cabeçalho TCP mais os dados - em octetos, sem contar o pseudo cabeçalho).
[[Arquivo:cabecalhopseudo.png|center|frame|Pseudo Cabeçalho do TCP]]
* Ponteiro para urgência (16 bits): Indica a localização para dados urgentes (flag URG ativada).
* Opções (variável): múltiplos de 8 bits, são incluídas no checksum. São 2 casos:
** Um único byte para o tipo de opção.
** Um byte para o tipo, um para o tamanho e um para os dados.
*** 00000000: fim da lista de opções
*** 00000001: usado entre opções.
*** [00000010][00000100][max seg size] - usado para determinar o maior tamanho do segmento, são 16 bits.
== Terminologia ==
* As variáveis necessárias são armazenadas no TCB:
** SND.___: enviando algo
** ISS: Inicial Sequence Number
** RCV.___: recebendo algo
** SEG.___: informações sobre o segmento (tamanho, janela, número,...)
* Alguns estados durante a conexão:
** LISTEN: espera por uma conexão.
** SYN-SENT: esperando confirmação
** SYN-RECEIVED
** ESTABLISHED
** FIN-WAIT-1: espera por um fim de conexão, ou pelo ACK como resposta por um fim (TCP remoto)
** FIN-WAIT-2: espera apenas pelo fim de conexão (TCP remoto).
** CLOSE-WAIT: espera por uma requisição de fim de conexão do usuário local.
** CLOSING: esperando pelo ACK de resposta por um fim.
** LAST-ACK: ACK de fim enviado ao TCP remoto.
** TIME-WAIT: Representa o tempo de espera até que se tenha certeza de que o TCP remoto recebeu o ACK de fim.
** CLOSED
== Números de Sequência ==
* São armazenados para serem consecutivos.
* São limitados pelos 32 bits, ou seja 2^32 - 1.
* Um segmento recebido deve ter um número de sequência esperado.
* SEG.SEQ + SEG.LEN - 1 = último número de sequência de um segmento.
* SND.UNA < SEG.ACK <= SND.NXT, o UNA é o último que não recebeu ACK.
* RCV.NXT =< SEG.SEQ < RCV.NXT + RCV.WND
* Quando a janela de recepção é zero, só recebe ACKs.
* O ISN (primeiro número de sequência) é gerado de acordo com um relógio, e a cada 4 microsegundos incrementa em 1, isso quer dizer que para fechar o ciclo são 4.55 horas.
* Para sincronizar a conexão tem-se o three way handshake.
**A --> B (SYN)
**A <-- B (ACK,SYN)
**A --> B (ACK)
* O TCP espera um MSL(maximum segment lifetime), que segundo a RFC eram 2 minutos, para abrir uma conexão igual (com os mesmos sockets), desde que não seja reiniciado.
* Quando um host dá um "crash", ele pode esperar esse MSL pra não correr o risco de problemas com uma conexão repetida.
== Estabelecimento/Fechamento da Conexão ==
* Handshake normal
[[Arquivo: handshake1.png|center|frame|]]
* Handshake Sincronizado
[[Arquivo: handshake2.png|center|frame|]]
* O TCP é capaz de se recuperar de uma duplicata resetando a conexão.
* É possível uma conexão aberta pela metade, quando um dos lados encerra a conexão e o outro não fica sabendo. Os métodos para sair das anomalias podem ser visualizados abaixo.
** Caso 1: Descoberta de conexão aberta pela metade
[[Arquivo: errotcp1.png|center|frame|]]
** Caso 2: Lado ativo causa a descoberta
[[Arquivo: errotcp2.png|center|frame|]]
** Caso 3: SYN antigo duplicado causa um reset
[[Arquivo: errotcp3.png|center|frame|]]
* Um reset é sempre válido de acordo com seu número de sequência (dentro da janela), apenas no estado SYN-SENT é que reseta se ACK reconheceu o SYN.
* Apenas o estado LISTEN ignora o RST.
* Fechar a conexão acontece quando os dados já foram enviados, e sempre é esperada a resposta para o fechamento do outro lado.
* Para o fechamento da conexão são 3 casos:
** O usuário diz para o TCP fechar a conexão
*** O primeiro TCP manda um FIN, o segundo responde esse FIN(ACK depois FIN) e o primeiro envia um ACK confirmando.
** O TCP remoto fecha a conexão (FIN)
*** O TCP responde esse FIN, e espera um ACK, se não receber, encerra a conexão por timeout. Nesse caso a conexão pode ser encerrada mesmo no meio da transmissão.
** Ambos fecham simultaneamente
*** Quando todos os segmentos já forem enviados/recebidos e reconhecidos, os FINs são reconhecidos encerrando a conexão.
* Fechamento Normal:
[[Arquivo: fechatcp1.png|center|frame|]]
* Fechamento Simultâneo:
[[Arquivo: fechatcp2.png|center|frame|]]
== Precedência e Segurança ==
* São usados os mesmos parâmetros de segurança do IP, sendo que é enviado um reset quando o nível de segurança é abaixo do esperado para a conexão.
== Comunicação de Dados ==
* O Timeout é dinamicamente calculado
* RTT(Round Trip Time) - Tempo de "viagem" do segmento
* Pela RFC 793:
**RTTestimado = (Alpha * RTTestimado) + ((1 - Alpha) * RTT)
**Timeout = min[UBOUND,max[LBOUND,(BETA*SRTT)]]
**Ubound = 1 minuto
**Lbound = 1 segundo
**Alpha = 0.8 até 0.9
**Beta = 1.3 até 2.0
* Pelo Kurose:
**RTTest = (1 - Alpha)*RTTest + Alpha*RTT
**RTTdesvio = (1 - Beta)*RTTdesvio + Beta*(RTT-RTTest)
**Timeout = RTTest + 4*RTTdesvio
**Alpha = 0,125
**Beta = 0,25
* Na comunicação de urgência, o ponteiro de urgência permite saber o início/fim dos dados urgentes.
* A janela, indica geralmente o espeço em buffer disponível no receptor. Um janela igual a zero faz com que a fonte dos dados espere para enviar algo. Um receptor quando recebe um segmento e sua janela é zero, ele envia um ack com o próximo segmento que ele espera, mas avisa que a janela é zero.
* É desencorajado diminuir bruscamente o tamanho da janela sem ter recebido dados suficientes para isso (chamado de shrinking the window).
* A janela deve ser enviada nos ACKs de maior número de sequência. Janelas pequenas são piores do que as grandes e podem causar segmentos pequenos demais.
== Interfaces ==
* Interface TCP/Usuário
** É importante destacar que podem existir implementações diferentes.
** Informações podem ser retornados por comandos de usuários, sendo informações gerais até informação de sucesso/falha.
** Seguem os comandos:
** OPEN: OPEN (local port, foreign socket, active/passive [, timeout] [, precedence] [,security/compartment] [,options])-> local connection name
*** Se for passiva, é uma chamada para LISTEN, esperando uma conexão, se for ativa, é iniciado o processo de sincronização.
*** O timeout é um tempo para encerrar a conexão se não houver nenhuma resposta.
*** O SO verifica a autoridade para segurança/precedência.
*** Lembrete: o TCP só aceita a conexão se segurança/compartimento forem iguais e a precedência por igual ou maior do que a definida.
** SEND: SEND (local connection name, buffer address, byte count, PUSH flag, URGENT flag [,timeout])
*** Se a conexão não estiver aberta SEND é considerada um erro (as vezes um OPEN automático pode ser chamado).
*** O PUSH setado faz com que o último segmento criado recebe a flag PUSH, se não esses dados são acoplados com os próximos.
*** URGENT é setada para ativar a flag e o ponteiro.
*** Uma conexão que não conhece o socket estrangeiro pode usar SEND sem conhecê-lo, mas caso contrário, isso retorna erro.
*** O timeout pode mudar o timeout anterior.
*** Múltiplos SENDs podem ser feitos ao mesmo tempo.
*** Podem ser usados reconhecimentos locais para o segmento como retorno do SEND. (não é desconsiderado o reconhecimento a distância)
** RECEIVE: RECEIVE (local connection name, buffer address, byte count) -> byte count, urgent flag, push flag
*** Este comando reserva um buffer para a conexão.
*** Podem ser executados multiplos deste ao mesmo tempo.
*** Um PUSH pode ser visto com um buffer parcialmente preenchido.
*** A flag URGENT ativa um sinal do TCP para o usuário, entrando no modo de urgência.
*** Existe um ponteiro e um contador para não ocorrer problemas com buffers parcialmente preenchidos.
** CLOSE: CLOSE (local connection name)
*** Significa "eu não tenho mais dados para enviar!, e pode ser chamada após vários SEND. Implica no PUSH...
** STATUS: STATUS (local connection name) -> status data
*** Retorna uma série de informações do TCB: local socket, estrangeiro, nome da conexão local, janela, estado da conexão, estado de urgência, timeout, etc...
** ABORT: ABORT (local connection name)
*** Cancela todos RECEIVE e SEND e envia um RESET.
** Informações cedidas em forma de mensagens pelo TCP para a aplicação: Nome da conexão(sempre), string de resposta(sempre), endereço do buffer(send e receive), byte count(receive), push flag(receive), urgent flag(receive).
*Interface TCP/Baixo-Nível
** Usa informações de camadas abaixo, se o protocolo de rede for o IP, o TCP "recebe" os seguintes argumentos:
*** Tipo de Serviço: Precedência, rotina, vazão, delay...
*** TTL
** Também são obtidas informações do roteamento.
** O protocolo abaixo deve providenciar os endereços e os campos de protocolo, até para que sejam usados no checksum do TCP.
== Processamento de Eventos ==
* Os eventos ocorrem em três categorias: chamadas do usuário, segmentos que chegam e timeouts.
** Chamadas de Usuário: OPEN, SEND, RECEIVE, CLOSE, ABORT, STATUS
** Segmentos que chegam (arriving segments): SEGMENT ARRIVES
** Timeouts: USER TIMEOUT, RETRANSMISSION TIMEOUT, TIME-WAIT TIMEOUT
* Respostas para comandos do usuário podem ser imediantas ou não, até em forma de strings no caso dos erros. Respostas com delay são chamadas de signal.
=== OPEN Call ===
* CLOSED STATE
** Cria um novo TCB, ou seja, TCB não existia anteriormente. Então verifica se é passivo/ativo, no passivo passa para LISTEN, no ativo verifica se existe o socket estrangeiro, e se existe envia o SYN, se não existe é erro!
* LISTEN STATE
** Se é passivo, passa para ativo se conhecer o socket estrangeiro. Quando passa para o ativo envia o SYN, no qual ele pode enviar dados ou não, e se for requisitado o bit de urgência.
* Para todos os outros estados são retornados erros. ("error: conection already exists")
=== SEND Call ===
* CLOSED STATE
** Retorna erro
* LISTEN STATE
** Se existe um socket estrangeiro especificado, passa de passivo pra ativo e seleciona um ISS.
* SYN-SENT/SYN-RECEIVED STATE
** Espera a conexão ficar estabelecida e envia os dados, inicialmente eles ficam em uma fila, na qual se não houver espaço da erro.
* ESTABLISHED/CLOSE-WAIT STATE
** Envia o pacote normalmente.
* Para todos os outros estados retorna erro ("error: conection closing")
=== RECEIVE Call ===
* CLOSED STATE
** Retorna erro
* LISTEN/SYN-SENT/SYN-RECEIVED STATE
** Chamada processada
* ESTABLISHED/FIN-WAIT-1/FIN-WAIT-2 STATE
** Enfileira a requisição se os segmentos para satisfazê-la forem insuficientes. Se estiver tudo certo, marca o PUSH. Em caso de dados urgentes, avisa o sistema. Quando o dado é recebido com sucesso deve-se fabricar o ACK para responder o remetente do segmento.
* CLOSE-WAIT STATE
** Se o remoto já enviou o FIN, o RECEIVE só pode ser satisfeito com dados já em mãos. Se não existe mais texto para chegar, retorna erro ("error:  connection closing"), caso contrário, os textos remanescentes podem satisfazer a chamada.
* Para todos os outros estados retorna erro ("error: conection closing")
=== CLOSE Call ===
* CLOSED STATE
** Retorna erro
* LISTEN STATE
** Todos RECEIVEs pendentes são retornados com erros, o TCB é excluído e passa ao CLOSED STATE.
* SYN-SENT STATE
** Delete TCB e retorna erro para todos RECEIVEs e SENDs.
* SYN-RECEIVED STATE
** Se não tiver o que mandar envia um FIN e vai para o estado FIN-WAIT-1.
* ESTABLISHED STATE
** Enfileira todos os SENDs e envia o FIN. Vai para o FIN-WAIT-1.
* FIN-WAIT-1/FIN-WAIT-2 STATE
** Retorna um erro
* CLOSED-WAIT STATE
** Enfileira a requisição até todos os SENDs serem realizados. Aí manda o FIN entrando no estado CLOSING.
* Para todos os outros estados retorna erro ("error: conection closing")
=== ABORT Call ===
* CLOSED STATE
** Retorna erro
* LISTEN STATE
** Todos RECEIVEs pendentes são retornados com erros, o TCB é excluído e passa ao CLOSED STATE.
* SYN-SENT STATE
** Todos SENDs e RECEIVEs em fila recebem "conection reset", o TCB é deletado e entra para o CLOSED STATE.
* SYN-RECEIVED/ESTABLISHED/FIN-WAIT-1/FIN-WAIT-2/CLOSE-WAIT STATE
** Envia um segmento de "reset", avisa todos RECEIVEs e SENDs, deleta o TCB e entre para o CLOSED.
* CLOSING/LAST-ACK/TIME-WAIT STATE
** Responde com "ok", deleta TCB e vai para o estado CLOSED.
=== STATUS Call ===
* CLOSED STATE
** Retorna erro
* Para todos os outros estados retorna "state = NOMEDOSTATUS" e o ponteiro para TCB.
=== CHEGADA DE UM SEGMENTO ===
* CLOSED STATE
** Todos os dados são ignorados. Se o RST não estiver setado, responde uma mensagem com RST. Se o bit ACK está desativado, é usado o número de sequência zero.
* LISTEN STATE
** Primeiro checa pelo RST, o qual deve ser ignorado.
** Depois checa pelo ACK, que é respondido por um RST.
** Terceiro checa se é SYN, se sim, verifica a segurança, que se não for atendida é respondido com um RST (valores de SEG.PRC e TCB.PRC), se estiver tudo ok muda para o estado SUN-RECEIVED. Depois checa o restante de opções.
* SYN-SENT
** Primeiro checa o bit ACK, o qual se estiver ativo, pode ser descartado e respondido com RST (Caso não corresponda ao ACK esperado), ou aceitado normalmente.
** Segundo lugar, checa o RST, no qual se o ACK for aceitável fecha a conexão, se não apenas ignora o segmento.
** Terceiro lugar checa segurança/precedência. Se não compatibilizar com o valor da TCB, manda um RST. Sendo a precedência do segmento menor do que a do TCB, tudo ok.
** Quarto lugar checa o SYN, se estiver ok muda a conexão pra ESTABLISHED, ou pra SYN-RECEIVED, se não ouver o ACK, respondendo com um <SYN,ACK>. Se nenhum estiver setado descarta o segmento. É importante observar que o número de sequência deve ser observado.
* SYN-RECEIVED/ESTABLISHED/FIN-WAIT-1/FIN-WAIT-2/CLOSE-WAIT/CLOSING/LATS-ACK/TIME-WAIT STATE
** Nestes casos os segmentos são processados em sequência. Se a janela é zero os segmentos não podem ser aceitados (com excessão para ACK, URG e RST). Se um segmento não é aceitável, manda-se um ACK com RST. Para ser aceitável: RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
** Em segundo lugar checa o RST. No caso do SYN-RECEIVED, se o OPEN foi passivo volta para o estado de LISTEN, se foi ativo passa ao estado CLOSED e deleta o TCB. Para os FIN-WAIT, ESTABLISHED e CLOSE-WAIT, todos SENDs e RECEIVEs passam a ter respostas com RST, vai para o estado CLOSED e deleta o TCB. Para os outros estados deleta o TCB e vai para CLOSED.
** Em terceiro lugar checa segurança e precedência. No caso do SYN-RECEIVED, se não estiver ok responde com um RST. No caso do ESTABLISHED, causa um ABORT, a conexão vai para closed e a TCB é encerrada, os próximos SENDs e RECEIVEs são respondidos com RST.
** Quarto lugar checa o SYN, que se estiver na janela gera erro.
** Quinto lugar checa o ACK, que se estiver desativado faz com que o segmento seja descartado. No caso do SYN-RECEIVED, se estiver ok vai para ESTABLISHED, se não manda um RST. No estado ESTABLISHED, um ACK correto exige a mudança de várias variáveis, inclusive atualização de janela, um duplicado é ignorado. No caso do FIN-WAIT-1, passa-se para o FIN-WAIT-2. No FIN-WAIT-2, se a fila de transmissão estiver vazia, o CLOSE pode ser confirmado, mas sem deletar a TCB. O CLOSE-WAIT funciona como o ESTABLISHED. CLOSING-WAIT entra para o TIME-WAIT. LAST-ACK deleta a TCB e vai para o CLOSED. No TIME-WAIT a única coisa que pode acontecer é a retransmissão do FIN.
** Sexto lugar, checa o bit URG. Se estiver setado dá um "signal" e entra em modo de urgência, se já estiver em modo de urgência não envia o signal. Isto só vale para os estados ESTABLISHED e FIN-WAITs, para os outros o bit é ignorado.
** Sétimo lugar, processa o texto do segmento. Apenas no estado ESTABLISHED é que os dados são enviados para os buffers. É enviado um ACK e ajustados os valores de RCV.NXT e RCV.WND. Paraa os outros estados (exceto FIN-WAITs) o texto é ignorado.
** Oitavo lugar, checa o bit FIN. Este envia um signal avisando que a conexão está fechando e seta nos segmentos que não foram processados o PUSH. Além disso é enviado um ACK respondendo ao FIN. Nos estados SYN-RECEIVED e ESTABLISHED passa-se para o estado CLOSE-WAIT. No estado FIN-WAIT-1, sendo o FIN confirmado (via ACK) entra para o estado TIME-WAIT, se não for confirmado entra para o CLOSING. No FIN-WAIT-2 passa-se para o estado TIME-WAIT e inicia o timer. Nos estados restantes não há mudança de estado, o único efeito acontece no TIME-WAIT, onde o timeout é reiniciado.
=== TIMEOUTS ===
* User Timeout
** Se o timeout expirar em qualquer estado, limpa as filas, avisa o usuário, deleta o TCB e entra para o estado CLOSED.
* Retransmission Timeout
** Se este timeout expirar reenvia o primeiro segmento da fila de retransmissão e reinicializa o timeout.
* TIME-WAIT Timeout
** Se este timeout expirar, deleta o TCB e entra para o estado CLOSED.

Edição atual tal como às 16h01min de 7 de outubro de 2013

Link

http://tools.ietf.org/html/rfc793

Introdução

  • O TCP é um protocolo host-to-host altamente confiável.
  • Comunicação inter-processos, orientado a conexão, com suporte a muitas aplicações, e já assume a simplicidade do protocolo da camada abaixo (IP).
  • A interface TCP consiste de um conjunto de chamadas, como em um SO, como exemplo para abrir e fechar conexões. A comunicação com a aplicação pode ser assíncrona.
  • A Operação do TCP está nas seguintes áreas:
    • Transferência básica de dados
      • O TCP é capaz de tranferir dados em um fluxo em cada direção. Uma função "push" garante que esses dados são passados adiante no receptor.
    • Confiabilidade
      • O TCP é capaz de "recuperar" dados comprometidos, perdidos, duplicados ou entregues fora de ordem. Mensagens como o "ACK" são usadas para confirmação de recepção ccorreta.
    • Controle de fluxo
      • O TCP permite um controle da quantidade de dados transmitidos, através de uma janela e da quantidade de ACKs.
    • Multiplexação
      • A partir do IP mais a porta é formado um socket, que permite conexões múltiplas. Existem sockets fixos para certas aplicações.
    • Conexão
      • Os mecanismos descritos anteriormente exigem a inicialização e manutenção dos fluxos de dados, daí vem a conexão, feita por um mecanismo de "handshake", baseado em números de sequência baseados no clock.
    • Precedência e segurança
      • Podem ser indicados precedência e segurança da comunicação pelos usuários.

Filosofia

  • Os ambientes de rede podem ser locais, ou de grande abrangência, mas assumem uma tecnologia de comutação de pacotes. Toda esta estrutura é para a comunicação entre processos de hosts (através das portas), daí a importância do TCP.
  • O TCP recebe uma chamada de um processo com um buffer de dados como argumento. Na recepção ele notifica o usuário e passa esses dados para a aplicação de destino.
  • Fragmentação e remontagem é responsabilidade do módulo da internet (camada de rede - IP). O segmento (TCP) é retirado da parte dos dados do datagrama (IP).
  • O TCP é como um módulo do SO, controlado por um driver.
  • A interface tem chamadas como: SEND, RECEIVE, OPEN, CLOSE, STATUS. Essas chamadas podem ter parâmetros como: tipo de serviço, endereço, precedência, segurança, etc.

Transferência

  • A transferência confiável é baseada em números de sequência e ACKs, sendo que se um segmento com um certo número de sequência não receber o ACK correspondente ele é retransmitido, se não, deletado da fila. A janela citada anteriormente possui um número, que designa a quantidade de segmentos enviados sem receber ACK.
  • Para uma identificação TCP ser única, deve-se acoplar o IP (endereço+porta -> socket).
  • Dois sockets definem uma conexão, full-duplex (nos dois sentidos)
  • Existe uma estrutura, a TCB (Transmission Control Block), para guardar as informações das conexões.

Chamadas de funções

  • Chamadas passivas da função OPEN, acontecem quando existe uma solicitação de conexão "estrangeira". Neste caso um socket estrangeiro de zeros é utilizado para denotar um socket não especificado.
  • Dois processos que requisitam OPEN ao mesmo tempo, obtém sucesso pela forma assícrona.
  • Para estabelecer a conexão existe a mensagem SYN (tree-way handshake), para fechar a conexão existe a flag FIN.
  • Para enviar, usa-se a chamada SEND, e quando um receptor vê a flag PUSH, ele não espera mais dados e passa os recebidos para a camada superior. Se o buffer estiver cheio e não for visto o PUSH os dados são passados para o usuário.

Segurança e Robustez

  • O TCP não define uma atitude na presença de dados urgentes por parte do usuário, mas a noção geral é que o processo receptor toma a a ação de processar dados urgentes primeiro.
  • O TCP pode usar o tipo de serviço e opções do IP para tratar segurança, mas nem todos os módulos tem essa capacidade multicamada. Alguns módulos permitem a aplicações, como Telnet, especificar certos níveis de segurança, precedência, conexão...
  • O TCP tem um princípio enquanto à robustez: Ser liberal no que aceita e conservador no que faz.

Especificação Funcional

  • O TCP fornece a informação do campom "protocolo" do IP.
  • Segue o cabeçalho:
  • Porta fonte e destino (16 bits)
  • Número de Sequência (32 bits): número do primeiro byte do segmento, quando tem SYN, é o número inicial da sequência (ISN) e o primeiro byte está em ISN+1.
  • Número de reconhecimento (32 bits): se o bit ACK está setado, este é o valor do próximo número de sequência esperado.
  • Comprimento do cabeçalho (Data offset - 4 bits)
  • Não utilizado (6 bits)
  • Bits de Controle (6 bits)
    • URG: ponteiro de urgência
    • ACK
    • PSH: ponteiro do PUSH
    • RST: resetar conexão
    • SYN: sincronização dos números de sequência
    • FIN: fim da transmissão
  • Window (16 bits): número de bytes, quando ACK está setado, que o destinatário ainda pode receber.
  • Checksum (16 bits): complemento de 1 da soma de todas as palavras de 16 bits. Ele abrange um pseudo cabeçalho de 96 bits (endereços de fonte e destino, o protocolo e o TCP Length(tamanho do cabeçalho TCP mais os dados - em octetos, sem contar o pseudo cabeçalho).
Pseudo Cabeçalho do TCP
  • Ponteiro para urgência (16 bits): Indica a localização para dados urgentes (flag URG ativada).
  • Opções (variável): múltiplos de 8 bits, são incluídas no checksum. São 2 casos:
    • Um único byte para o tipo de opção.
    • Um byte para o tipo, um para o tamanho e um para os dados.
      • 00000000: fim da lista de opções
      • 00000001: usado entre opções.
      • [00000010][00000100][max seg size] - usado para determinar o maior tamanho do segmento, são 16 bits.

Terminologia

  • As variáveis necessárias são armazenadas no TCB:
    • SND.___: enviando algo
    • ISS: Inicial Sequence Number
    • RCV.___: recebendo algo
    • SEG.___: informações sobre o segmento (tamanho, janela, número,...)
  • Alguns estados durante a conexão:
    • LISTEN: espera por uma conexão.
    • SYN-SENT: esperando confirmação
    • SYN-RECEIVED
    • ESTABLISHED
    • FIN-WAIT-1: espera por um fim de conexão, ou pelo ACK como resposta por um fim (TCP remoto)
    • FIN-WAIT-2: espera apenas pelo fim de conexão (TCP remoto).
    • CLOSE-WAIT: espera por uma requisição de fim de conexão do usuário local.
    • CLOSING: esperando pelo ACK de resposta por um fim.
    • LAST-ACK: ACK de fim enviado ao TCP remoto.
    • TIME-WAIT: Representa o tempo de espera até que se tenha certeza de que o TCP remoto recebeu o ACK de fim.
    • CLOSED

Números de Sequência

  • São armazenados para serem consecutivos.
  • São limitados pelos 32 bits, ou seja 2^32 - 1.
  • Um segmento recebido deve ter um número de sequência esperado.
  • SEG.SEQ + SEG.LEN - 1 = último número de sequência de um segmento.
  • SND.UNA < SEG.ACK <= SND.NXT, o UNA é o último que não recebeu ACK.
  • RCV.NXT =< SEG.SEQ < RCV.NXT + RCV.WND
  • Quando a janela de recepção é zero, só recebe ACKs.
  • O ISN (primeiro número de sequência) é gerado de acordo com um relógio, e a cada 4 microsegundos incrementa em 1, isso quer dizer que para fechar o ciclo são 4.55 horas.
  • Para sincronizar a conexão tem-se o three way handshake.
    • A --> B (SYN)
    • A <-- B (ACK,SYN)
    • A --> B (ACK)
  • O TCP espera um MSL(maximum segment lifetime), que segundo a RFC eram 2 minutos, para abrir uma conexão igual (com os mesmos sockets), desde que não seja reiniciado.
  • Quando um host dá um "crash", ele pode esperar esse MSL pra não correr o risco de problemas com uma conexão repetida.

Estabelecimento/Fechamento da Conexão

  • Handshake normal
  • Handshake Sincronizado
  • O TCP é capaz de se recuperar de uma duplicata resetando a conexão.
  • É possível uma conexão aberta pela metade, quando um dos lados encerra a conexão e o outro não fica sabendo. Os métodos para sair das anomalias podem ser visualizados abaixo.
    • Caso 1: Descoberta de conexão aberta pela metade
    • Caso 2: Lado ativo causa a descoberta
    • Caso 3: SYN antigo duplicado causa um reset
  • Um reset é sempre válido de acordo com seu número de sequência (dentro da janela), apenas no estado SYN-SENT é que reseta se ACK reconheceu o SYN.
  • Apenas o estado LISTEN ignora o RST.
  • Fechar a conexão acontece quando os dados já foram enviados, e sempre é esperada a resposta para o fechamento do outro lado.
  • Para o fechamento da conexão são 3 casos:
    • O usuário diz para o TCP fechar a conexão
      • O primeiro TCP manda um FIN, o segundo responde esse FIN(ACK depois FIN) e o primeiro envia um ACK confirmando.
    • O TCP remoto fecha a conexão (FIN)
      • O TCP responde esse FIN, e espera um ACK, se não receber, encerra a conexão por timeout. Nesse caso a conexão pode ser encerrada mesmo no meio da transmissão.
    • Ambos fecham simultaneamente
      • Quando todos os segmentos já forem enviados/recebidos e reconhecidos, os FINs são reconhecidos encerrando a conexão.
  • Fechamento Normal:
  • Fechamento Simultâneo:

Precedência e Segurança

  • São usados os mesmos parâmetros de segurança do IP, sendo que é enviado um reset quando o nível de segurança é abaixo do esperado para a conexão.

Comunicação de Dados

  • O Timeout é dinamicamente calculado
  • RTT(Round Trip Time) - Tempo de "viagem" do segmento
  • Pela RFC 793:
    • RTTestimado = (Alpha * RTTestimado) + ((1 - Alpha) * RTT)
    • Timeout = min[UBOUND,max[LBOUND,(BETA*SRTT)]]
    • Ubound = 1 minuto
    • Lbound = 1 segundo
    • Alpha = 0.8 até 0.9
    • Beta = 1.3 até 2.0
  • Pelo Kurose:
    • RTTest = (1 - Alpha)*RTTest + Alpha*RTT
    • RTTdesvio = (1 - Beta)*RTTdesvio + Beta*(RTT-RTTest)
    • Timeout = RTTest + 4*RTTdesvio
    • Alpha = 0,125
    • Beta = 0,25
  • Na comunicação de urgência, o ponteiro de urgência permite saber o início/fim dos dados urgentes.
  • A janela, indica geralmente o espeço em buffer disponível no receptor. Um janela igual a zero faz com que a fonte dos dados espere para enviar algo. Um receptor quando recebe um segmento e sua janela é zero, ele envia um ack com o próximo segmento que ele espera, mas avisa que a janela é zero.
  • É desencorajado diminuir bruscamente o tamanho da janela sem ter recebido dados suficientes para isso (chamado de shrinking the window).
  • A janela deve ser enviada nos ACKs de maior número de sequência. Janelas pequenas são piores do que as grandes e podem causar segmentos pequenos demais.

Interfaces

  • Interface TCP/Usuário
    • É importante destacar que podem existir implementações diferentes.
    • Informações podem ser retornados por comandos de usuários, sendo informações gerais até informação de sucesso/falha.
    • Seguem os comandos:
    • OPEN: OPEN (local port, foreign socket, active/passive [, timeout] [, precedence] [,security/compartment] [,options])-> local connection name
      • Se for passiva, é uma chamada para LISTEN, esperando uma conexão, se for ativa, é iniciado o processo de sincronização.
      • O timeout é um tempo para encerrar a conexão se não houver nenhuma resposta.
      • O SO verifica a autoridade para segurança/precedência.
      • Lembrete: o TCP só aceita a conexão se segurança/compartimento forem iguais e a precedência por igual ou maior do que a definida.
    • SEND: SEND (local connection name, buffer address, byte count, PUSH flag, URGENT flag [,timeout])
      • Se a conexão não estiver aberta SEND é considerada um erro (as vezes um OPEN automático pode ser chamado).
      • O PUSH setado faz com que o último segmento criado recebe a flag PUSH, se não esses dados são acoplados com os próximos.
      • URGENT é setada para ativar a flag e o ponteiro.
      • Uma conexão que não conhece o socket estrangeiro pode usar SEND sem conhecê-lo, mas caso contrário, isso retorna erro.
      • O timeout pode mudar o timeout anterior.
      • Múltiplos SENDs podem ser feitos ao mesmo tempo.
      • Podem ser usados reconhecimentos locais para o segmento como retorno do SEND. (não é desconsiderado o reconhecimento a distância)
    • RECEIVE: RECEIVE (local connection name, buffer address, byte count) -> byte count, urgent flag, push flag
      • Este comando reserva um buffer para a conexão.
      • Podem ser executados multiplos deste ao mesmo tempo.
      • Um PUSH pode ser visto com um buffer parcialmente preenchido.
      • A flag URGENT ativa um sinal do TCP para o usuário, entrando no modo de urgência.
      • Existe um ponteiro e um contador para não ocorrer problemas com buffers parcialmente preenchidos.
    • CLOSE: CLOSE (local connection name)
      • Significa "eu não tenho mais dados para enviar!, e pode ser chamada após vários SEND. Implica no PUSH...
    • STATUS: STATUS (local connection name) -> status data
      • Retorna uma série de informações do TCB: local socket, estrangeiro, nome da conexão local, janela, estado da conexão, estado de urgência, timeout, etc...
    • ABORT: ABORT (local connection name)
      • Cancela todos RECEIVE e SEND e envia um RESET.
    • Informações cedidas em forma de mensagens pelo TCP para a aplicação: Nome da conexão(sempre), string de resposta(sempre), endereço do buffer(send e receive), byte count(receive), push flag(receive), urgent flag(receive).
  • Interface TCP/Baixo-Nível
    • Usa informações de camadas abaixo, se o protocolo de rede for o IP, o TCP "recebe" os seguintes argumentos:
      • Tipo de Serviço: Precedência, rotina, vazão, delay...
      • TTL
    • Também são obtidas informações do roteamento.
    • O protocolo abaixo deve providenciar os endereços e os campos de protocolo, até para que sejam usados no checksum do TCP.

Processamento de Eventos

  • Os eventos ocorrem em três categorias: chamadas do usuário, segmentos que chegam e timeouts.
    • Chamadas de Usuário: OPEN, SEND, RECEIVE, CLOSE, ABORT, STATUS
    • Segmentos que chegam (arriving segments): SEGMENT ARRIVES
    • Timeouts: USER TIMEOUT, RETRANSMISSION TIMEOUT, TIME-WAIT TIMEOUT
  • Respostas para comandos do usuário podem ser imediantas ou não, até em forma de strings no caso dos erros. Respostas com delay são chamadas de signal.

OPEN Call

  • CLOSED STATE
    • Cria um novo TCB, ou seja, TCB não existia anteriormente. Então verifica se é passivo/ativo, no passivo passa para LISTEN, no ativo verifica se existe o socket estrangeiro, e se existe envia o SYN, se não existe é erro!
  • LISTEN STATE
    • Se é passivo, passa para ativo se conhecer o socket estrangeiro. Quando passa para o ativo envia o SYN, no qual ele pode enviar dados ou não, e se for requisitado o bit de urgência.
  • Para todos os outros estados são retornados erros. ("error: conection already exists")

SEND Call

  • CLOSED STATE
    • Retorna erro
  • LISTEN STATE
    • Se existe um socket estrangeiro especificado, passa de passivo pra ativo e seleciona um ISS.
  • SYN-SENT/SYN-RECEIVED STATE
    • Espera a conexão ficar estabelecida e envia os dados, inicialmente eles ficam em uma fila, na qual se não houver espaço da erro.
  • ESTABLISHED/CLOSE-WAIT STATE
    • Envia o pacote normalmente.
  • Para todos os outros estados retorna erro ("error: conection closing")

RECEIVE Call

  • CLOSED STATE
    • Retorna erro
  • LISTEN/SYN-SENT/SYN-RECEIVED STATE
    • Chamada processada
  • ESTABLISHED/FIN-WAIT-1/FIN-WAIT-2 STATE
    • Enfileira a requisição se os segmentos para satisfazê-la forem insuficientes. Se estiver tudo certo, marca o PUSH. Em caso de dados urgentes, avisa o sistema. Quando o dado é recebido com sucesso deve-se fabricar o ACK para responder o remetente do segmento.
  • CLOSE-WAIT STATE
    • Se o remoto já enviou o FIN, o RECEIVE só pode ser satisfeito com dados já em mãos. Se não existe mais texto para chegar, retorna erro ("error: connection closing"), caso contrário, os textos remanescentes podem satisfazer a chamada.
  • Para todos os outros estados retorna erro ("error: conection closing")

CLOSE Call

  • CLOSED STATE
    • Retorna erro
  • LISTEN STATE
    • Todos RECEIVEs pendentes são retornados com erros, o TCB é excluído e passa ao CLOSED STATE.
  • SYN-SENT STATE
    • Delete TCB e retorna erro para todos RECEIVEs e SENDs.
  • SYN-RECEIVED STATE
    • Se não tiver o que mandar envia um FIN e vai para o estado FIN-WAIT-1.
  • ESTABLISHED STATE
    • Enfileira todos os SENDs e envia o FIN. Vai para o FIN-WAIT-1.
  • FIN-WAIT-1/FIN-WAIT-2 STATE
    • Retorna um erro
  • CLOSED-WAIT STATE
    • Enfileira a requisição até todos os SENDs serem realizados. Aí manda o FIN entrando no estado CLOSING.
  • Para todos os outros estados retorna erro ("error: conection closing")

ABORT Call

  • CLOSED STATE
    • Retorna erro
  • LISTEN STATE
    • Todos RECEIVEs pendentes são retornados com erros, o TCB é excluído e passa ao CLOSED STATE.
  • SYN-SENT STATE
    • Todos SENDs e RECEIVEs em fila recebem "conection reset", o TCB é deletado e entra para o CLOSED STATE.
  • SYN-RECEIVED/ESTABLISHED/FIN-WAIT-1/FIN-WAIT-2/CLOSE-WAIT STATE
    • Envia um segmento de "reset", avisa todos RECEIVEs e SENDs, deleta o TCB e entre para o CLOSED.
  • CLOSING/LAST-ACK/TIME-WAIT STATE
    • Responde com "ok", deleta TCB e vai para o estado CLOSED.

STATUS Call

  • CLOSED STATE
    • Retorna erro
  • Para todos os outros estados retorna "state = NOMEDOSTATUS" e o ponteiro para TCB.

CHEGADA DE UM SEGMENTO

  • CLOSED STATE
    • Todos os dados são ignorados. Se o RST não estiver setado, responde uma mensagem com RST. Se o bit ACK está desativado, é usado o número de sequência zero.
  • LISTEN STATE
    • Primeiro checa pelo RST, o qual deve ser ignorado.
    • Depois checa pelo ACK, que é respondido por um RST.
    • Terceiro checa se é SYN, se sim, verifica a segurança, que se não for atendida é respondido com um RST (valores de SEG.PRC e TCB.PRC), se estiver tudo ok muda para o estado SUN-RECEIVED. Depois checa o restante de opções.
  • SYN-SENT
    • Primeiro checa o bit ACK, o qual se estiver ativo, pode ser descartado e respondido com RST (Caso não corresponda ao ACK esperado), ou aceitado normalmente.
    • Segundo lugar, checa o RST, no qual se o ACK for aceitável fecha a conexão, se não apenas ignora o segmento.
    • Terceiro lugar checa segurança/precedência. Se não compatibilizar com o valor da TCB, manda um RST. Sendo a precedência do segmento menor do que a do TCB, tudo ok.
    • Quarto lugar checa o SYN, se estiver ok muda a conexão pra ESTABLISHED, ou pra SYN-RECEIVED, se não ouver o ACK, respondendo com um <SYN,ACK>. Se nenhum estiver setado descarta o segmento. É importante observar que o número de sequência deve ser observado.
  • SYN-RECEIVED/ESTABLISHED/FIN-WAIT-1/FIN-WAIT-2/CLOSE-WAIT/CLOSING/LATS-ACK/TIME-WAIT STATE
    • Nestes casos os segmentos são processados em sequência. Se a janela é zero os segmentos não podem ser aceitados (com excessão para ACK, URG e RST). Se um segmento não é aceitável, manda-se um ACK com RST. Para ser aceitável: RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
    • Em segundo lugar checa o RST. No caso do SYN-RECEIVED, se o OPEN foi passivo volta para o estado de LISTEN, se foi ativo passa ao estado CLOSED e deleta o TCB. Para os FIN-WAIT, ESTABLISHED e CLOSE-WAIT, todos SENDs e RECEIVEs passam a ter respostas com RST, vai para o estado CLOSED e deleta o TCB. Para os outros estados deleta o TCB e vai para CLOSED.
    • Em terceiro lugar checa segurança e precedência. No caso do SYN-RECEIVED, se não estiver ok responde com um RST. No caso do ESTABLISHED, causa um ABORT, a conexão vai para closed e a TCB é encerrada, os próximos SENDs e RECEIVEs são respondidos com RST.
    • Quarto lugar checa o SYN, que se estiver na janela gera erro.
    • Quinto lugar checa o ACK, que se estiver desativado faz com que o segmento seja descartado. No caso do SYN-RECEIVED, se estiver ok vai para ESTABLISHED, se não manda um RST. No estado ESTABLISHED, um ACK correto exige a mudança de várias variáveis, inclusive atualização de janela, um duplicado é ignorado. No caso do FIN-WAIT-1, passa-se para o FIN-WAIT-2. No FIN-WAIT-2, se a fila de transmissão estiver vazia, o CLOSE pode ser confirmado, mas sem deletar a TCB. O CLOSE-WAIT funciona como o ESTABLISHED. CLOSING-WAIT entra para o TIME-WAIT. LAST-ACK deleta a TCB e vai para o CLOSED. No TIME-WAIT a única coisa que pode acontecer é a retransmissão do FIN.
    • Sexto lugar, checa o bit URG. Se estiver setado dá um "signal" e entra em modo de urgência, se já estiver em modo de urgência não envia o signal. Isto só vale para os estados ESTABLISHED e FIN-WAITs, para os outros o bit é ignorado.
    • Sétimo lugar, processa o texto do segmento. Apenas no estado ESTABLISHED é que os dados são enviados para os buffers. É enviado um ACK e ajustados os valores de RCV.NXT e RCV.WND. Paraa os outros estados (exceto FIN-WAITs) o texto é ignorado.
    • Oitavo lugar, checa o bit FIN. Este envia um signal avisando que a conexão está fechando e seta nos segmentos que não foram processados o PUSH. Além disso é enviado um ACK respondendo ao FIN. Nos estados SYN-RECEIVED e ESTABLISHED passa-se para o estado CLOSE-WAIT. No estado FIN-WAIT-1, sendo o FIN confirmado (via ACK) entra para o estado TIME-WAIT, se não for confirmado entra para o CLOSING. No FIN-WAIT-2 passa-se para o estado TIME-WAIT e inicia o timer. Nos estados restantes não há mudança de estado, o único efeito acontece no TIME-WAIT, onde o timeout é reiniciado.

TIMEOUTS

  • User Timeout
    • Se o timeout expirar em qualquer estado, limpa as filas, avisa o usuário, deleta o TCB e entra para o estado CLOSED.
  • Retransmission Timeout
    • Se este timeout expirar reenvia o primeiro segmento da fila de retransmissão e reinicializa o timeout.
  • TIME-WAIT Timeout
    • Se este timeout expirar, deleta o TCB e entra para o estado CLOSED.