如何设置don't fragment (DF) flag 在socket上?
我们尝试设置 DF (don't fragment flag) 用于发送UCP 数据库包
我想尝试 使用setsockopt() 但是不能找到
你可以使用 setsockopt() call, 通过使用IP_DONTFRAG选项:
int val = 1;
setsockopt(sd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val));
int val = IP_PMTUDISC_DO;
setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
对于linux, 它似乎你必须使用之IP_MTU_DISCOVER 使用之IP_PMTUDISC_DO,
或者IP_PMTUDISC_DONT to turn it off
int val = IP_PMTUDISC_DO;
setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
我还没有测试过这个, 只是查看了头文件
至于是否有其他方法可以设置DF标志:
我在程序中找不到 设置 "force DF flag"的地方, 但tcpdump 建议它是,有没有其他方法可以设置?
IP_MTU_DISCOVER: 设置或者 接收 socket的 Path MTU Discovery 设置。
当启用时, Linux 执行 Path MTU Discovery 作为定义在RFC 1191 在这个socket.
这个数据包设置了不允许分片Don't fragment: Set
don't fragment flag is set 在所有的传达胡数据上 。
系统层面默认是通过ip_no_pmtu_disc sysctl 控制 用于SOCK_STREAM sockets
SOCK_STREAM是基于TCP的,数据传输比较有保障。SOCK_DGRAM是基于UDP的
对于非SOCK_STREAM sockets 它是用户的责任将数据打包在MTU大小下 。
在我看来,你可以设置 系统范围的 默认值
node2:/usr/local/python27/lib/python2.7#sysctl ip_no_pmtu_disc
error: "ip_no_pmtu_disc" is an unknown key
如果你是工作在 绕过内核网络堆栈,从而构建自己的包和头并将它们交给自定义内核模块,那么有一个比setsockopt()更好的选项。
你可以实际设置DF flag 像其他struct的字段一样定义 在inux/ip.h
3位 IP flags 是实际上frag_off的一部分
node2:/usr/local/python27/lib/python2.7#vi plat-linux2/IN.py
IP_MTU_DISCOVER = 10
IP_RECVERR = 11
IP_RECVTTL = 12
IP_RECVTOS = 13
IP_MULTICAST_IF = 32
IP_MULTICAST_TTL = 33
IP_MULTICAST_LOOP = 34
IP_ADD_MEMBERSHIP = 35
IP_DROP_MEMBERSHIP = 36
IP_RECVRETOPTS = IP_RETOPTS
IP_PMTUDISC_DONT = 0
默认0
IP_PMTUDISC_DONT = 0
IP_PMTUDISC_WANT = 1
IP_PMTUDISC_DO = 2
I agree with the paxdiablo's answer.
setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))
where val is one of:
#define IP_PMTUDISC_DONT 0 /* Never send DF frames. */
#define IP_PMTUDISC_WANT 1 /* Use per route hints. */
#define IP_PMTUDISC_DO 2 /* Always DF. */
#define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu. */
ip_no_pmtu_disc in kernel source:
if (ipv4_config.no_pmtu_disc)
inet->pmtudisc = IP_PMTUDISC_DONT;
else
inet->pmtudisc = IP_PMTUDISC_WANT;
hostName = #ip here
Port = 9999
s.connect((hostName, Port))
s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DO)
try:
s.send('#' * 1473)
except socket.error:
print 'The message did not make it'
option = getattr(IN, 'IP_MTU', 14)
print 'MTU:', s.getsockopt(socket.IPPROTO_IP, option)
else:
print 'The big message was sent! Your network supports really big packets!'
node2:/root/test#cat t17.py
import socket
# import IN
import struct
b=1
def getnum(x):
b='1'
for y in range(x):
#print y
b=b+'1'
if len(b) == x:
#print '-------------'
#print len(b)
return b
print getnum(1024)
c=getnum(10000)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
class IN:
IP_MTU = 14
IP_PMTUDISC_DONT = 0
IP_PMTUDISC_DO = 2
IP_MTU_DISCOVER=10
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER,IN.IP_PMTUDISC_DONT)
# print dir(s.setsockopt(socket.SOL_SOCKET))
s.connect(("192.168.137.2",8080))
# s.shutdown(2)
print len(c)
s.send(c)
option = getattr(IN, 'IP_MTU_DISCOVER', 10)
print 'MTU:', s.getsockopt(socket.IPPROTO_IP, option)
s.close()
node2:/root/test#python t17.py
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
10000
MTU: 0