UDP, bad length 1496 > 496


 

 

 

1496是總個報文的長度
[root@localhost ~]# tcpdump -i enp125s0f0 udp and host 10.10.16.81  -env 
tcpdump: listening on enp125s0f0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:17:19.222749 48:57:02:64:ea:1b > b0:08:75:5f:b7:d9, ethertype IPv4 (0x0800), length 538: (tos 0x0, ttl 64, id 12345, offset 0, flags [+], proto UDP (17), length 524)
    10.10.16.81.vlsi-lm > 10.10.16.229.krb524: UDP, bad length 1496 > 496
21:17:19.294418 48:57:02:64:ea:1b > b0:08:75:5f:b7:d9, ethertype IPv4 (0x0800), length 538: (tos 0x0, ttl 64, id 12345, offset 504, flags [+], proto UDP (17), length 524)
    10.10.16.81 > 10.10.16.229: ip-proto-17
21:17:19.364260 48:57:02:64:ea:1b > b0:08:75:5f:b7:d9, ethertype IPv4 (0x0800), length 530: (tos 0x0, ttl 64, id 12345, offset 1008, flags [none], proto UDP (17), length 516)
    10.10.16.81 > 10.10.16.229: ip-proto-17
21:17:47.252277 48:57:02:64:ea:1b > 01:00:5e:01:01:01, ethertype IPv4 (0x0800), length 120: (tos 0x0, ttl 1, id 43958, offset 0, flags [none], proto UDP (17), length 106)
    10.10.16.81.57013 > 239.1.1.1.4789: VXLAN, flags [I] (0x08), vni 100
ba:d8:f4:bf:4f:f5 > 33:33:00:00:00:02, ethertype IPv6 (0x86dd), length 70: (hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::b8d8:f4ff:febf:4ff5 > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 16
          source link-address option (1), length 8 (1): ba:d8:f4:bf:4f:f5
21:20:14.652961 48:57:02:64:ea:1b > b0:08:75:5f:b7:d9, ethertype IPv4 (0x0800), length 538: (tos 0x0, ttl 64, id 12345, offset 0, flags [+], proto UDP (17), length 524)
    10.10.16.81.vlsi-lm > 10.10.16.229.krb524: UDP, bad length 1496 > 496
21:20:14.694614 48:57:02:64:ea:1b > b0:08:75:5f:b7:d9, ethertype IPv4 (0x0800), length 538: (tos 0x0, ttl 64, id 12345, offset 504, flags [+], proto UDP (17), length 524)
    10.10.16.81 > 10.10.16.229: ip-proto-17
21:20:14.764480 48:57:02:64:ea:1b > b0:08:75:5f:b7:d9, ethertype IPv4 (0x0800), length 530: (tos 0x0, ttl 64, id 12345, offset 1008, flags [none], proto UDP (17), length 516)
    10.10.16.81 > 10.10.16.229: ip-proto-17

 

二 問題分析

2.1 基本分析

程序同時發送到本地應用和遠程應用的,雖然是不同的IP和端口,但是是同一個邏輯,所以程序的本身的問題可能性比較小,先測試下是否為網絡問題:

  • 先用ping測試下,由於ping被禁止了,所以沒有測試出什么來.
  • 利用nc -ul xxx 在遠程機器新建一個udp監聽端口,應用程序所在機器,通過nc -u x.x.x.x xxx 連接后,通過輸入一些字符,來看看遠程機器是否有屏顯,結果本次測試正常,說明網絡是通的.
  • 繼續在遠程的機器抓包,發現不是沒有收到,而是收到的包相對來說比較小,大小為400多個字節左右,均是這種小於1千個字節的.
  • 在發送告警的機器通過tcpdump抓包: tcpdump -i eth1 udp port xxxx -A -nn 發現有類似於以下內容的告警:
21:01:39.000550 IP (tos 0x0, ttl 64, id 63736, offset 0, flags [+], proto UDP (17), length 1500) xxx.xxx.xxx.xxx.59019 > xxx.xxx.xxx.xxx.documentum: UDP, bad length 6902 > 1472 

首先,我們來看下這個1472是怎么來的,在以太網環境中,以太網的幀的body大小為46字節到1500字節之間,本次是處於IPV4的環境,IP包頭大小為20個字節,所以還剩下1480字節;UDP的協議的報文頭長度為8個字節,所以剩下的udp的包體長度為1480-8 = 1472個字節,具體展示如下圖:
格式如下:


 
協議格式
 
UDP報文格式

上述告警意思是因為我們環境下網卡的MTU設置為1500個字節,如下:

[root@localhost ~]# ifconfig em1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 

因為發送的UDP報文長度大於可以傳輸的安全長度1472個字節,這不代表不能發送,只是因為大於了幀的最大傳輸長度,所以在IP層需要進行分包,一旦網絡環境不好,分包產生了丟失問題,會造成IP的組包失敗,從而導致UDP的報文丟失.

不過鑒於Internet上的標准MTU值為576字節,所以建議在進行Internet的UDP編程時,最好將UDP的數據長度控制在 (576-8-20)548字節以內

還可以通過netstat -su進行監控:

[root@localhost ~]# netstat -su IcmpMsg: InType0: 141039 InType3: 72945 InType8: 1616 InType13: 1 OutType0: 1616 OutType3: 777474 OutType8: 141039 OutType14: 1 Udp: 4039279 packets received 123325 packets to unknown port received. 67020 packet receive errors 4229636 packets sent 67020 receive buffer errors 0 send buffer errors UdpLite: IpExt: InNoRoutes: 2 InMcastPkts: 26 InBcastPkts: 723113 InOctets: 27500413848629 OutOctets: 27491308862298 InMcastOctets: 832 InBcastOctets: 287040162 InNoECTPkts: 126755848707 InECT0Pkts: 16 

2.2 嘗試解決

既然MTU太小了,那么嘗試修改下兩端的MTU最大值,MTU是取整個路由的MTU最小值,我們嘗試把兩端的MTU增大下:

ifconfig eth1 mtu 9000 up

兩端MTU增加后,仍然會報錯,那么可能的原因是中間路由設備設置的MTU比較小,查看下,由於主機上沒有traceroute命令來跟蹤,嘗試使用另外一個命令:

tracepath xxx.xxx.xx.xx.xx

類似於traceroute,可以追蹤路由,結束后打印MTU值.
還可以帶個端口,測試這個UDP端口.

[root@localhost ~]# tracepath 1xx.xx.xx.2xx/10001 1?: [LOCALHOST] pmtu 1500 1: xx.xx.xx.xx 0.502ms reached 1: xx.xx.xx.xx 0.323ms reached Resume: pmtu 1500 hops 1 back 1 

在實際環境中,由於中間很多路由都看不到,而且讓中間的所有路由都改MTU值不是太現實.

在MTU為1500字節的情況下,如果發送的UDP報文大於MTU,比如發送8000個字節,如果包緩存足夠,且分包按照正確的順序到來,通過recvfrom(9000) 還是可以收到一個完整的UDP包的. 如果IP分片丟失,校驗失敗,包就會丟棄.recvfrom(9000)將阻塞.

2.3 更改socket緩沖區大小

為防止socket緩沖區溢出造成的問題,特意增加了socket的緩沖區.
cat /proc/sys/net/core/rmem_defaultcat /proc/sys/net/core/rmem_max可以查看socket緩沖區的缺省值和最大值。
可以通過echo xxx >/proc/sys/net/core/rmem_default的方法來臨時修改,也通過更改/etc/sysctl.conf文件添加以下配置來修改:

net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144

修改完成后記得運行以下命令來生效:

sysctl -p

 


 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM