zoukankan      html  css  js  c++  java
  • 如何设置don't fragment (DF) flag 在socket上? (实际模拟路径 MTU 发现)

    如何设置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
  • 相关阅读:
    SP笔记:交叉实现七行并成一行
    HTML tag 学习
    操作哈希表
    Efficient bipedal robots based on passivedynamic walkers
    Pushing People Around
    ZEROMOMENT PONTTHIRTY FIVE YEARS OF ITS LIFE

    Active Learning for RealTime Motion Controllers
    Accelerometerbased User Interfaces for the Control of a Physically Simulated Character
    Dynamic Response for Motion Capture Animation
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13348496.html
Copyright © 2011-2022 走看看