在每个套接字的基础上调整 MTU?
我想知道是否有任何方法可以调整(在 Linux 系统上)给定套接字的 MTU。 (使 IP 层分段成小于实际设备 MTU 的块)。
当我说对于给定的套接字时,我并不是指在拥有该套接字的应用程序代码中以编程方式,而是在外部,例如通过 sysfs 条目。
如果目前没有办法做到这一点,您是否有关于在 Linux 内核中的何处挂钩/修补以实现这种可能性的想法?
谢谢。
编辑:我到底为什么要这样做?
我正在做一些 Layer3-in-Layer4(例如:通过 TCP 隧道对 IP 及以上进行隧道传输)隧道。与类似 VPN 的解决方案不同,我没有使用虚拟接口来实现这一点。我正在使用 iptables 捕获数据包,以正常方式丢弃它们并将它们写入隧道套接字。
考虑一下大文件传输的情况,所有数据包都被填充到 MTU 大小。当我对它们进行隧道传输时,我增加了一些开销,导致每个原始数据包产生两个隧道数据包,这不是最佳的。
I was wondering if there is any way to tune (on a linux system), the MTU for a given socket. (To make IP layer fragmenting into chunks smaller that the actual device MTU).
When I say for a given socket, I don't mean programatically in the code of the application owning the socket but rather externally, for example via a sysfs entry.
If there is currently no way do that, do you have any ideas about where to hook/patch in linux kernel to implement such a possibility ?
Thanks.
EDIT: why the hell do I want to do that ?
I'm doing some Layer3-in-Layer4 (eg: tunneling IP and above through TCP tunnel) tunneling. Unlike VPN-like solutions, I'm not using a virtual interface to achieve that. I'm capturing packets using iptables, dropping them for their normal way and writing them to the tunnel socket.
Think about the case of a big file transfer, all packets are filled up to MTU size. When I tunnel them, I add some overhead, leading in every original packet to produce two tunneled packets, it's under-optimal.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果创建套接字时在传出数据包上设置 DF,那么您可能会幸运地欺骗(注入)一条需要 ICMP 分段的消息,直到您最终获得所需的 MTU。相当丑陋,但取决于你有多绝望,这可能是合适的。
例如,您可以使用 iptables 规则生成这些数据包,因此匹配和发送非常简单并且在您的应用程序外部。看起来 iptables 的 REJECT 目标没有需要碎片的拒绝,但添加一个可能不会太棘手。
另一种方法,如果您只关心 TCP 数据包,那么您可能会幸运地使用套接字选项 TCP_MAXSEG 或 TCPMSS 目标(如果这适合您的问题)。
对于 UDP 或 raw,您可以随意
send()
数据包,小到您想要的大小!更新:
基于“我为什么要这样做?”答案,如果未设置 DF,则似乎会对数据包进行分段,或者提高 ICMP“需要分段”,而丢弃实际上是正确的解决方案。
这是一个更“正常”的路由器会做的事情,只要防火墙不吃掉 ICMP 数据包,那么它在所有情况下都会表现得正常,而回顾性地改变事情会导致奇怪的行为。
iptables clamp mss 对于这个“VPN”上的 TCP 来说是一个很好的修复,尤其是当您似乎已经广泛使用 iptables 时。
If the socket is created such that DF set on outgoing packets you might have some luck in spoofing (injecting) an ICMP fragmentation needed message back at yourself until you end up with the desired MTU. Rather ugly, but depending on how desperate you are it might be appropriate.
You could for example generate these packets with iptables rules, so the matching and sending is simple and external to your application. It looks like the REJECT target for iptables doesn't have a reject-with of fragmentation needed though, it probably wouldn't be too tricky to add one.
The other approach, if it's only TCP packets you care about is you might have some luck with the socket option TCP_MAXSEG or the TCPMSS target if that's appropriate to your problem.
For UDP or raw you're free to
send()
packets as small as you fancy!Update:
Based on the "why would I want to do that?" answer, it seems like fragmenting packets if DF isn't set or raising ICMP "fragmentation needed" and dropping would actually be the correct solution.
It's what a more "normal" router would do and provided firewalls don't eat the ICMP packet then it will behave sanely in all scenarios, whereas retrospectively changing things is a recipe for odd behaviour.
The iptables clamp mss is quite a good fix for TCP over this "VPN" though, especially as you're already making extensive use of iptables it seems.
MTU 是链路的属性,而不是套接字的属性。它们属于堆栈的不同层。也就是说,TCP 在三向握手期间执行路径 MTU 发现,并尽力避免碎片。您将很难让 TCP 发送片段。对于 UDP,最简单的方法是使用
ifconfig(8)
然后发送大于该值的数据包。
MTU is a property of a link, not socket. They belong to different layers of the stack. That said TCP performs Path MTU discovery during the three-way handshake and tries very hard to avoid fragmentation. You'll have hard time making TCP send fragments. With UDP the easiest is to force some smallish MTU on an interface with
ifconfig(8)
and then send packets larger then that value.