如何在套接字上设置不分段 (DF) 标志? [英] How to set the don't fragment (DF) flag on a socket?

查看:60
本文介绍了如何在套接字上设置不分段 (DF) 标志?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置 DF(不分段标志)以使用 UDP 发送数据包.

I am trying to set the DF (don't fragment flag) for sending packets using UDP.

看Richard Steven 的书Volume 1 Unix Network Programming;Sockets Networking API,我找不到如何设置它.

Looking at the Richard Steven's book Volume 1 Unix Network Programming; The Sockets Networking API, I am unable to find how to set this.

我怀疑我会用 setsockopt() 来做,但在第 193 页的表格中找不到它.

I suspect that I would do it with setsockopt() but can't find it in the table on page 193.

请建议如何做到这一点.

Please suggest how this is done.

推荐答案

您可以使用 setsockopt() 调用来实现,使用 IP_DONTFRAG 选项:

You do it with the setsockopt() call, by using the IP_DONTFRAG option:

int val = 1;
setsockopt(sd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val));

这是一个解释这个的页面更详细.

Here's a page explaining this in further detail.

对于 Linux,您似乎必须使用值为 IP_PMTUDISC_DO(或 IP_PMTUDISC_DONT 以将其关闭)的 IP_MTU_DISCOVER 选项:

For Linux, it appears you have to use the IP_MTU_DISCOVER option with the value IP_PMTUDISC_DO (or IP_PMTUDISC_DONT to turn it off):

int val = IP_PMTUDISC_DO;
setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));

我没有测试过这个,只是查看了头文件和一些网络搜索,所以你需要测试它.

I haven't tested this, just looked in the header files and a bit of a web search so you'll need to test it.

至于是否有另一种方式可以设置 DF 标志:

As to whether there's another way the DF flag could be set:

我在我的程序中找不到强制 DF 标志"的任何地方已设置,但 tcpdump 表明已设置.还有其他方法可以设置吗?

I find nowhere in my program where the "force DF flag" is set, yet tcpdump suggests it is. Is there any other way this could get set?

从这个优秀的页面这里:

IP_MTU_DISCOVER: 设置或接收套接字的路径 MTU 发现设置.启用后,Linux 将在此套接字上执行 RFC 1191 中定义的路径 MTU 发现.在所有传出数据报上都设置了不分段标志.系统范围的默认值由 ip_no_pmtu_disc sysctl 控制,用于 SOCK_STREAM 套接字,并在所有其他套接字上禁用.对于非 SOCK_STREAM 套接字,用户有责任将数据打包成 MTU 大小的块,并在必要时进行重新传输.如果设置了此标志(使用 EMSGSIZE),内核将拒绝大于已知路径 MTU 的数据包.

IP_MTU_DISCOVER: Sets or receives the Path MTU Discovery setting for a socket. When enabled, Linux will perform Path MTU Discovery as defined in RFC 1191 on this socket. The don't fragment flag is set on all outgoing datagrams. The system-wide default is controlled by the ip_no_pmtu_disc sysctl for SOCK_STREAM sockets, and disabled on all others. For non SOCK_STREAM sockets it is the user's responsibility to packetize the data in MTU sized chunks and to do the retransmits if necessary. The kernel will reject packets that are bigger than the known path MTU if this flag is set (with EMSGSIZE).

在我看来,您可以使用 sysctl 设置系统范围的默认值:

This looks to me like you can set the system-wide default using sysctl:

    sysctl ip_no_pmtu_disc

返回<代码>错误:ip_no_pmtu_disc";在我的系统上是一个未知的密钥,但它可能被设置在你的系统上.除此之外,我不知道还有什么会影响设置(除了前面提到的 setsockopt()).

returns "error: "ip_no_pmtu_disc" is an unknown key" on my system but it may be set on yours. Other than that, I'm not aware of anything else (other than setsockopt() as previously mentioned) that can affect the setting.

这篇关于如何在套接字上设置不分段 (DF) 标志?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆