C/C++ 设置Socket的IP_TOS选项

发布于:2024-03-28 ⋅ 阅读:(22) ⋅ 点赞:(0)

IP TOS选项是指示IP报文转发的优先级,QOS控制的一种,常规的IP协议TOS都为0,就是普通报文。

设置:

IPV4/TOS设置(Socket),IPTOS_LOWDELAY 表示FLASH优先级(一般用在游戏,即时通信这块,因为需要包转发要足够快)

        bool Socket::SetTypeOfService(int fd, int tos) noexcept {
            if (fd == -1) {
                return false;
            }

            if (tos < 0) {
                tos = IPTOS_LOWDELAY; 
            }

            Byte b = tos; /* IPTOS_LOWDELAY */
#if defined(_MACOS)
            return ::setsockopt(fd, IPPROTO_IP, IP_TOS, (char*)&b, sizeof(b)) == 0;
#else
            return ::setsockopt(fd, SOL_IP, IP_TOS, (char*)&b, sizeof(b)) == 0;
#endif
        }

设置

IPV4/IPV6 TOS设置(Socket)

        void Socket::AdjustDefaultSocketOptional(int sockfd, bool in4) noexcept {
            if (sockfd != -1) {
                uint8_t tos = IPTOS_LOWDELAY;
                if (in4) {
                    if (SOCKET_RESTRICTIONS_.IP_TOS_ON) {
#if defined(_MACOS)
                        ::setsockopt(sockfd, IPPROTO_IP, IP_TOS, (char*)&tos, sizeof(tos));
#else
                        ::setsockopt(sockfd, SOL_IP, IP_TOS, (char*)&tos, sizeof(tos));
#endif
                    }

#if IP_DONTFRAGMENT
                    int dont_frag = IP_PMTUDISC_DO;
                    ::setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAGMENT, (char*)&dont_frag, sizeof(dont_frag));
#elif IP_PMTUDISC_WANT
                    int dont_frag = IP_PMTUDISC_WANT;
                    ::setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &dont_frag, sizeof(dont_frag));
#endif
                }
                else {
                    // linux-user: Add missing IP_TOS, IPV6_TCLASS and IPV6_RECVTCLASS sockopts
                    // QEMU:
                    // https://patchwork.kernel.org/project/qemu-devel/patch/20170311195906.GA13187@ls3530.fritz.box/
#if IPV6_TCLASS
                    if (SOCKET_RESTRICTIONS_.IPV6_TCLASS_ON) {
                        ::setsockopt(sockfd, IPPROTO_IPV6, IPV6_TCLASS, (char*)&tos, sizeof(tos)); /* SOL_IPV6 */
                    }
#endif

#if IPV6_MTU_DISCOVER && IPV6_PMTUDISC_WANT
                    int dont_frag = IPV6_PMTUDISC_WANT;
                    ::setsockopt(sockfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &dont_frag, sizeof(dont_frag));
#endif
                }

#if defined(SO_NOSIGPIPE)
                int no_sigpipe = 1;
                ::setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
#endif
            }
        }

本文含有隐藏内容,请 开通VIP 后查看