Exatamente quando o PMTUD é realizado? (Descoberta do caminho MTU)


21

Nas discussões que estimularam a partir de outras perguntas sobre este site , eu percebi que eu não tenho uma sólida compreensão de quando Path MTU Discovery (PMTUD) é realizada.

Eu sei o que ele faz - descubra o MTU mais baixo no caminho do cliente para o servidor).
Eu sei como ele faz isso - envie pacotes progressivamente maiores com o conjunto de bits "Não fragmentar" e veja o tamanho de um pacote que você pode obter sem obter o erro "Necessidade de fragmentação do ICMP".

Minha pergunta é especificamente então, quando um host executará o PMTUD?

Estou procurando casos específicos. Não é apenas algo genérico como "quando um host deseja descobrir o caminho MTU". Pontos de bônus se você puder fornecer uma captura de pacote de um host fazendo isso ou fornecer instruções para gerar essa captura de pacote.

Além disso, estou me referindo especificamente ao IPv4. Eu sei que os roteadores transitórios IPv6 não são responsáveis ​​pela fragmentação e posso imaginar que o PMTUD acontece com muito mais frequência. Mas, por enquanto, estou procurando exemplos específicos de PMTUD no IPv4. (embora se a única captura de pacote que você pode montar do PMTUD estiver no IPv6, eu ainda adoraria vê-lo)


O PMTUD é feito do MTU suportado mais baixo para o mais alto? Ou o dispositivo que executa o PMTUD tenta primeiro a MTU maior e depois diminui um grande incremento até que o pacote passe e depois aumenta em incrementos menores, alternando entre si até que uma determinação final seja feita?
Ct_fink

@ cpt_fink, existem algumas estratégias. As implementações modernas da mensagem ICMP Fragmentation Needed incluem na própria carga útil do ICMP o MTU do link para o qual a fragmentação foi necessária. Isso facilita, pois o host inicial sabe imediatamente qual é o caminho da MTU. Implementações mais antigas precisam usar várias estratégias para 'procurar' o MTU correto a ser usado. Essas estratégias estão descritas na RFC1191 na Seção 5. Elas variam do padrão automaticamente ao Mínimo de IP (576), até o uso de uma tabela de MTU 'comuns' para pesquisar com mais eficiência (consulte a Seção 7.1 da RFC1191).
Eddie

2
Esta é uma pergunta interessante. Eu estava pesquisando sobre o PMTUD e encontrei isso. Mesmo sendo velho, decidi responder porque tinha exatamente a mesma pergunta e, após algumas horas de pesquisa, consegui encontrar uma resposta bastante decente (eu acho). Tentarei atualizar e dar suporte à minha resposta com uma captura de pacotes amanhã, se possível.
Filipe Gonçalves

Respostas:


15

A resposta é simples: sempre que o host quiser. Sério. É simples assim.

A explicação abaixo pressupõe um ambiente somente IPv4, pois o IPv6 elimina a fragmentação nos roteadores (forçando o host a sempre lidar com a fragmentação e a descoberta de MTU).

Não existe uma regra estrita que governa quando (ou mesmo se) um host realiza a descoberta do Path MTU. A razão pela qual o PMTUD apareceu é que a fragmentação é considerada prejudicial por vários motivos. Para evitar a fragmentação de pacotes, o conceito de PMTUD foi trazido à vida como uma solução alternativa. Obviamente, um bom sistema operacional deve usar o PMTUD para minimizar a fragmentação.

Portanto, naturalmente, a semântica exata de quando o PMTUD é usado depende do sistema operacional do remetente - em particular, da implementação do soquete. Só posso falar pelo caso específico do Linux, mas outras variantes do UNIX provavelmente não são muito diferentes.

No Linux, o PMTUD é controlado pela IP_MTU_DISCOVERopção de soquete. Você pode recuperar seu status atual getsockopt(2)especificando o nível IPPROTO_IPe a IP_MTU_DISCOVERopção. Essa opção é válida SOCK_STREAMapenas para soquetes (um SOCK_STREAMsoquete é um soquete confiável bidirecional, orientado à conexão; na prática é um soquete TCP, embora outros protocolos sejam possíveis) e, quando definido, o Linux executará o PMTUD exatamente como definido no RFC 1191

Observe que, na prática, o PMTUD é um processo contínuo; os pacotes são enviados com o conjunto de bits DF - incluindo os pacotes de handshake de três vias - você pode considerá-lo uma propriedade de conexão (embora uma implementação possa estar disposta a aceitar um certo grau de fragmentação em algum momento e parar de enviar pacotes com o DF conjunto de bits). Portanto, o PMTUD é apenas uma conseqüência do fato de que tudo nessa conexão está sendo enviado com o DF.

E se você não definir IP_MTU_DISCOVER?

Há um valor padrão. Por padrão, IP_MTU_DISCOVERestá ativado nos SOCK_STREAMsoquetes. Isso pode ser lido ou alterado lendo /proc/sys/net/ipv4/ip_no_pmtu_disc. Um valor zero significa que IP_MTU_DISCOVERé ativado por padrão em novos soquetes; um diferente de zero significa o oposto.

E as tomadas sem conexão?

Isso é complicado porque soquetes não confiáveis ​​e sem conexão não retransmitem segmentos perdidos. Torna-se responsabilidade do usuário empacotar os dados em pedaços do tamanho da MTU. Além disso, o usuário deve fazer as retransmissões necessárias no caso de um erro muito grande da mensagem. Portanto, essencialmente o código do usuário deve reimplementar o PMTUD. No entanto, se você estiver pronto para o desafio, poderá forçar o bit DF passando a IP_PMTUDISC_DObandeira para setsockopt(2).

A linha inferior

  • O host decide quando (e se) usar o PMTUD
  • Quando ele usa o PMTUD, é como um atributo de conexão, acontece continuamente (mas a qualquer momento a implementação é livre para deixar de fazê-lo)
  • Sistemas operacionais diferentes usam abordagens diferentes, mas, geralmente, os soquetes confiáveis ​​e orientados à conexão executam o PMTUD por padrão, enquanto os soquetes não confiáveis ​​e sem conexão não

4

Normalmente, o PMTUD (Path Maximum Discovery Unit Discovery) acontece sempre que um host pensa que um pacote foi descartado devido a ser muito grande.

Isso pode estar em resposta à resposta necessária à fragmentação do ICMP (tipo 3, código 4), indicando explicitamente que o pacote foi descartado. Na prática típica, todos os pacotes IPv4 são configurados com o sinalizador "não fragmentar" (DF), portanto, qualquer pacote que exceda o MTU provocará essa resposta. O IPv6 não suporta fragmentação.

Alguns roteadores ou firewalls de host descartam todo o ICMP com frequência porque um administrador ingênuo acredita que o ICMP é um risco à segurança . Ou, alguns esquemas de agregação de link podem interromper a entrega do ICMP . Um mecanismo alternativo para descobrir o MTU foi excedido e não depende do ICMP é proposto na RFC4821 .

tracepathé a minha ferramenta Linux favorita para pesquisar MTU. Aqui está um exemplo de um host com uma MTU 9001 na LAN, mas que deve atravessar uma VPN IPsec para alcançar 10.33.32.157:

$ tracepath -n 10.33.32.157
 1?: [LOCALHOST]                                         pmtu 9001
 1:  10.1.22.1                                             0.122ms pmtu 1500
 1:  169.254.3.1                                           1.343ms pmtu 1422
 1:  10.255.254.61                                        23.790ms 
 2:  no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]

Os erros do ICMP podem ser observados com tcpdump:

$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556

As descobertas da MTU são armazenadas em cache. No Linux, isso pode ser observado e liberado ip(cuidado com as mudanças desde o Linux 3.6 ):

$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache  expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache

Para o TCP, exceder a MTU pode ser evitado como parte da configuração da conexão. Incluído no SYN enviado por cada extremidade está um tamanho máximo de segmento (MSS). O cabeçalho TCP (20 bytes excluindo opções ) e o cabeçalho IP (20 bytes) significam que o MSS e o MTU estão relacionados por uma diferença de 40 bytes.

Aqui está um exemplo de uma configuração de conexão entre esses dois hosts ao transferir um arquivo grande com scp:

$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0

No primeiro pacote, o host local propõe um MSS de 8961. Este é o 9001 MTU configurado, menos 40 bytes. O SYN / ACK retornado possui um MSS de 1379, implicando uma MTU de 1419. Por acaso sei nesta rede que o host remoto também enviou 8961, mas o valor foi modificado por um roteador, pois sabe que o caminho inclui um caminho da Internet ( MTU 1500) uma sobrecarga de um túnel IPsec. Este roteador também modificou nosso MSS enviado de 8961 para aparecer como 1419 no outro host. Isso é chamado de fixação MSS .

Então, de certa forma, o PMTUD está acontecendo o tempo todo. Na prática, isso pode realmente nunca acontecer, se a fixação do MSS estiver em vigor e todo o tráfego estiver ocorrendo através do TCP ou se nenhum dos roteadores tiver uma MTU menor do que a configurada nos pontos de extremidade. Mesmo sem a fixação do MSS, isso pode acontecer apenas raramente, quando o cache expira.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.