POST de MTU + ~ 798 bytes se perde

5

Eu tenho um problema muito estranho com certos pacotes que não chegam no host de destino. Isso acontece quando transmitimos um POST que é um pouco maior que o MTU. Podemos reproduzi-lo com este script:

#!/usr/bin/python

import urllib2

magic_length = 2297
logurl = 'http://www.example.nl/'
data = (magic_length - len(logurl)) * 'X'
headers = {'content-type': 'application/x-www-form-urlencoded', 'User-Agent': 'Fake'}
request = urllib2.Request(logurl, data, headers)                                        
handler = urllib2.build_opener(urllib2.HTTPHandler())                                   
answer = handler.open(request, timeout=5)

A parte de envio não recebe ACKs e retransmite. A parte receptora nunca a vê.

Depende de onde você executa o script e para onde você faz o POST. Minha conexão de casa é uma que falha (e, aliás, eu tive problemas com AJAX POSTs não consegui passar desde alguns meses, já que eu tenho um novo modem).

Se eu reduzir o MTU da máquina de envio em 100, ele funcionará novamente. Mas, se eu reduzir magic_length por 100 também, ele falhará novamente. Uma primeira teoria foi que uma camada do meu ADSL (como o PPPoA) adiciona cabeçalhos e faz com que os pacotes sejam divididos erroneamente, mas isso não parece ser o caso.

Talvez algo dê errado com a descoberta da MTU. Alguns pulam a linha bloqueando todo o ICMP talvez? Esta é a primeira parte de um traceroute para o google da minha casa:

traceroute to google.com (74.125.133.102), 30 hops max, 60 byte packets
 1  dsldevice.lan (192.168.2.254)  0.453 ms  0.547 ms  0.636 ms
 2  195.190.243.7 (195.190.243.7)  29.836 ms  29.947 ms  29.986 ms
 3  nl-zl-dc2-git-cr02.kpn.net (213.75.64.237)  37.004 ms  37.153 ms  37.204 ms
 4  nl-rt-dc2-ice-ir02.kpn.net (213.75.64.236)  37.261 ms  37.300 ms  37.339 ms
 5  72.14.198.161 (72.14.198.161)  38.351 ms  38.395 ms  38.405 ms
 6  209.85.254.92 (209.85.254.92)  37.976 ms  38.103 ms  37.972 ms
 7  209.85.253.247 (209.85.253.247)  38.612 ms 72.14.238.153 (72.14.238.153)  33.709 ms 209.85.253.249 (209.85.253.249)  36.890 ms
 8  209.85.240.158 (209.85.240.158)  41.052 ms  41.104 ms 209.85.244.102 (209.85.244.102)  41.164 ms
 9  209.85.249.12 (209.85.249.12)  38.392 ms 209.85.249.14 (209.85.249.14)  38.247 ms  38.851 ms^C

Se eu pingar 213.75.64.237, recebo (nunca vi 'filtrado por pacote' como uma resposta no STDOUT ...):

PING 213.75.64.237 (213.75.64.237) 56(84) bytes of data.
From 213.75.64.237 icmp_seq=1 Packet filtered

O resto eu posso pingar.

Esta resposta parece semelhante. No entanto, meu script não define o sinalizador DF (não fragmentar) (edit: correction, o tcpdmp mostra que o sinalizador está configurado na solicitação POST), nem posso ver solicitações ICMP voltando para mim quando executo o comando script em um host que faz funcionar. Além disso, os pacotes já estão divididos pelo remetente e o envio do segundo pacote falha.

Como procedo? ISPs Os NOCs são difíceis o suficiente para chegar como estão, então eu preciso ter uma prova do que está acontecendo. Eles não vão me ajudar a descobrir ...

Editar: para confirmar ou negar as hipóteses do ICMP tipo 4 (fragmentação necessária), eu fiz isso:

$ ping -c 1 -M do -s 1472 host
PING host (1.2.3.4) 1472(1500) bytes of data.
1480 bytes from host (1.2.3.4): icmp_req=1 ttl=50 time=33.8 ms

Isso funciona, mas estou um pouco confuso. O "(1500)" significa o tamanho total do fragmento? Eu suponho que sim, porque o cabeçalho IP de 1480 bytes + 20 bytes é de 1500 bytes.

Se eu aumentar o tamanho do ping em um:

$ ping -c 1 -M do -s 1473 host
PING host (1.2.3.4) 1473(1501) bytes of data.
From pannekoek.lan (192.168.2.5) icmp_seq=1 Frag needed and DF set (mtu = 1500)

Portanto, isso significaria que o caminho entre os dois hosts permite pacotes de 1500 bytes e nenhum problema de fragmentação ocorre. Parece que estou de volta à estaca zero.

Edite novamente: encontrei algo significativo. O problema é simplesmente que pacotes de determinados tamanhos não chegam. Isso acontece entre o meu modem e o primeiro gateway do provedor:

$ for i in 'seq 1025 1030'; do ping -c 1 -M do -s $i 195.190.243.7; done
PING 195.190.243.7 (195.190.243.7) 1025(1053) bytes of data.
1033 bytes from 195.190.243.7: icmp_req=1 ttl=254 time=31.2 ms  <- works

--- 195.190.243.7 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 31.273/31.273/31.273/0.000 ms
==========================
PING 195.190.243.7 (195.190.243.7) 1026(1054) bytes of data.

--- 195.190.243.7 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss   
==========================
PING 195.190.243.7 (195.190.243.7) 1027(1055) bytes of data.

--- 195.190.243.7 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss
==========================
PING 195.190.243.7 (195.190.243.7) 1028(1056) bytes of data.

--- 195.190.243.7 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss
==========================
PING 195.190.243.7 (195.190.243.7) 1029(1057) bytes of data.

--- 195.190.243.7 ping statistics --- 
1 packets transmitted, 0 received, 100% packet loss, time 0ms <- packet loss
==========================
PING 195.190.243.7 (195.190.243.7) 1030(1058) bytes of data.
1038 bytes from 195.190.243.7: icmp_req=1 ttl=254 time=31.1 ms <- works

--- 195.190.243.7 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 31.177/31.177/31.177/0.000 ms

Acho que preciso convencê-los de que é problema deles.

    
por Halfgaar 27.10.2014 / 11:59

1 resposta

1

Em algum lugar ao longo da linha, do ponto A ao ponto B, um roteador foi configurado com um MTU inferior e é isso que está quebrando as coisas. Você já tentou fazer um rastreamento para ver exatamente onde os pacotes ICMP estão sendo perdidos?

    
por 31.01.2015 / 08:43