草庐IT

networking - 关于ICMP“需要分片,DF位设置”或ICMP包太大的消息

coder 2023-09-18 原文

我正在向服务器中注入ICMP“需要碎片,df位集”,理想情况下,服务器应该开始发送数据包,其大小如ICMP中“下一个跃点MTU”字段中所述。但这不起作用。
这是服务器代码:

#!/usr/bin/env python 
import socket               # Import socket module
import time
import os

range= [1,2,3,4,5,6,7,8,9]
s = socket.socket()         # Create a socket object
host = '192.168.0.17'                   # Get local machine name
port = 12349               # Reserve a port for your service.
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))        # Bind to the port
rand_string = os.urandom(1600)

s.listen(5)                 # Now wait for client connection.
while True:
   c, addr = s.accept()     # Establish connection with client.
   print 'Got connection from', addr
   for i in range:
    c.sendall(rand_string)
        time.sleep(5)
   c.close()

客户代码如下:
#!/usr/bin/python           # This is client.py file

import socket               # Import socket module

s = socket.socket()         # Create a socket object
host = '192.168.0.17' # Get local machine name
port = 12348              # Reserve a port for your service.
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((host, port))
while 1:
    print s.recv(1024)
s.close()

scapy注入ICMP:
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags= DF
  frag= 0
  ttl= 64
  proto= ip
  chksum= None
  src= 192.168.0.45
  dst= 192.168.0.17
  \options\
###[ ICMP ]###
  type= dest-unreach
  code= fragmentation-needed
  chksum= None
  unused= 1300

Send(ip/icmp)

未使用的字段显示为wireshark中的下一跳mtu。服务器是否足够智能,以检查在与客户机通信时未设置df位,并且仍在接收icp“需要碎片,df位设置”消息?如果不是,那么为什么服务器不将其数据包大小从1500减小到1300?

最佳答案

首先,让我们回答您的第一个问题(ICMP是通过TCP发送的吗?).
ICMP直接通过IP运行,如RFC 792中所述:
ICMP消息使用基本IP头发送。
这可能有点让人困惑,因为ICMP is classified as a network layer protocol rather than a transport layer protocol但考虑到它只是IP的一个附加部分,用于携带错误、路由和控制消息和数据,这是有意义的。因此,它不能依赖于tcp层来传输自己,因为tcp层依赖于icmp帮助管理和解决问题的ip层。
现在,让我们来处理您的第二个问题(如果ICMP不是通过TCP发送的,TCP如何了解MTU?).我试着尽我所能地回答这个问题,并依赖官方规范,但最好的方法可能是分析一些开放源代码网络堆栈的实现,以了解到底发生了什么……
TCP层可能知道路径的MTU值,即使ICMP消息不在TCP上分层。这取决于网络堆栈操作系统的实现来通知MTU的TCP层,这样它就可以使用这个值来更新其mss值。
RFC 1122要求icmp消息包括ip报头以及触发该icmp消息的有问题数据报的前8个字节:
每个icmp错误消息都包括internet报头和触发错误的数据报的至少前8个数据八位字节;可以发送8个以上的八位字节;该报头和数据必须与接收的数据报保持不变。
在需要Internet层向传输层传递ICMP错误消息的情况下,必须从原始头提取IP协议号,并用于选择适当的传输协议实体来处理错误。
这说明操作系统如何精确定位其MSS应更新的TCP连接,因为这8个字节包括源端口和目标端口。
RFC1122还指出,传输层必须有一种机制,通过这种机制,可以了解给定源、目的地、TOS三元组可能发送的最大传输层消息大小。因此,我假设一旦收到ICMP Fragmentation needed and DF set错误消息,MTU值就会以某种方式提供给TCP层,该层可以使用它来更新其mss值。
此外,我认为实例化TCP连接并使用它的应用程序层也可以处理此类消息,并在更高的级别上分割数据包。应用程序可以打开期望icmp消息的套接字,并在接收到此类消息时相应地采取行动。但是,在应用程序层分割数据包对tcp&ip层是完全透明的。注意,大多数应用程序都允许TCP&IP层自己处理这种情况。
但是,一旦主机接收到一条ICMP Fragmentation needed and DF set错误消息,它的行为就不具有决定性了。
RFC 5927, section 2.2指的是RFC 1122,第4.2.3.9节,该节规定,当IP层向上传递ICMP Fragmentation needed and DF set错误消息时,TCP应中止连接,因为它表示硬错误条件。RFC声明主机应该实现这种行为,但这不是必须的(第4.2.5节)。此RFC还在第3.2.2.1节中声明,接收到的目标不可到达消息必须报告给TCP层。当在连接上接收到ICMP Fragmentation needed and DF set错误消息时,实现这两种方法都将导致TCP连接的破坏,这没有任何意义,而且显然不是所需的行为。
另一方面,RFC 1191说明了所需行为:
RFC 1191没有概述发送过程中预期的特定行为
主机,因为不同的应用程序可能有不同的要求,以及
不同的实现架构可能有利于不同的策略[这
给这种方法留下了空间。
唯一需要的行为是主机必须尝试避免发送更多
在不久的将来具有相同pmtu值的消息。主机可以
停止设置IP头中的“不分段”位(并允许
通过路由器分段)或减小数据报大小。这个
更好的策略是降低消息大小,因为碎片化
会造成更多的流量和消耗更多的互联网资源。
最后,我认为在接收到ICMP Fragmentation needed and DF set错误消息时,规范对于来自主机的所需行为并不确定。我的猜测是,这两个层(ip和tcp)都会收到消息通知,以便分别更新它们的mtu和mss值,其中一个层负责将有问题的包以较小的块重新传输。
最后,关于您的实现,我认为为了完全符合RFC 1122,您应该更新ICMP消息以包括有问题的包的IP头,以及它的下8个字节(尽管您可能包括的不仅仅是前8个字节)。此外,您应该验证是否在该ICMP消息所指的数据包的相应ACK之前接收到该ICMP消息。事实上,为了安全起见,我会彻底废除ACK。
this是如何构建ICMP消息的示例实现。如果将icmp消息作为对其中一个tcp包的响应发送失败,我建议您甚至在第一次接收到它所关联的tcp包之前尝试发送icmp消息,以确保在ack之前接收到它。只有在同样失败的情况下,试着完全废除ack。

关于networking - 关于ICMP“需要分片,DF位设置”或ICMP包太大的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26942820/

有关networking - 关于ICMP“需要分片,DF位设置”或ICMP包太大的消息的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  3. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  4. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  5. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  6. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  7. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  8. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  9. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  10. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

随机推荐