• 如何设置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
  • 相关阅读:
    ios开发中的基本设计模式
    Swift进阶
    转帖:深入理解JavaScript系列
    触摸事件、手势识别、摇晃事件、耳机线控
    打造自己的“美图秀秀”
    地图与定位
    python 深拷贝,浅拷贝
    Django 路由(SimpleRouter, DefaultRouter,ExtendedDefaultRouter)
    Django 国际化(翻译)
    wkhtmltopdf 转换后 表格不显示 python解决方案
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13348496.html
Copyright © 2020-2023  润新知