我正在向服务器中注入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()
###[ 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)
最佳答案
首先,让我们回答您的第一个问题(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/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我在使用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
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只
我实际上是在尝试使用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
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我正在玩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
我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r