問題描述
我正在嘗試設置 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 theip_no_pmtu_disc
sysctl
forSOCK_STREAM
sockets, and disabled on all others. For nonSOCK_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 (withEMSGSIZE
).
在我看來,您可以使用 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) 標志?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!