遥感流通的是 QUIC 协议报文

95 篇文章 2 订阅

仅感知 Initial、Handshake QUIC部分协议,通常感知两者就知道是否在通过 QUIC协议载荷流量,然后该阻断的阻断,该警告的警告。

C++

        inline Byte GetBitValueAt(Byte b, Byte offset, Byte length) {
            return (Byte)((b >> offset) & ~(0xff << length));
        }

        inline Byte GetBitValueAt(Byte b, Byte offset) { 
            return GetBitValueAt(b, offset, 1);
        }

        inline Byte SetBitValueAt(Byte b, Byte offset, Byte length, Byte value) { 
            int mask = ~(0xff << length);
            value = (Byte)(value & mask);
            
            return (Byte)((value << offset) | (b & ~(mask << offset)));
        }

        inline Byte SetBitValueAt(Byte b, Byte offset, Byte value) { 
            return SetBitValueAt(b, offset, 1, value);
        }

        inline bool PacketIsQUIC(const IPEndPoint& destinationEP, Byte* p, int length) {
            if (NULL == p || length < 1) {
                return false;
            }
            if (destinationEP.Port != 443 && destinationEP.Port != 80) {
                return false;
            }
            Byte* l = p + length; // QUIC IETF
            Byte kf = *p++;
            int F_Header_Form = GetBitValueAt(kf, 7);
            int F_Fixed_Bit = GetBitValueAt(kf, 6);
            int F_Packet_Type_Bit = GetBitValueAt(kf, 5) << 1 | GetBitValueAt(kf, 4);
            if (F_Header_Form != 0x01 || F_Fixed_Bit != 0x01) {
                return false;
            }
            if (F_Packet_Type_Bit == 0x00) { // Initial(0)
                int F_Reserved_Bit = GetBitValueAt(kf, 3) << 1 | GetBitValueAt(kf, 3);
                int F_Packet_Number_Length_Bit = GetBitValueAt(kf, 1) << 1 | GetBitValueAt(kf, 0);
                if (F_Packet_Number_Length_Bit == 0x00 && F_Reserved_Bit == 0x00) {
                    return false;
                }
            }
            else if (F_Packet_Type_Bit != 0x02) { // Handshake(2)
                return false;
            }
            p += 0x04;
            if (p > l) {
                return false;
            }
            UInt32 Version = ntohl(((UInt32*)p)[-1]);
            if (Version != 0x01) { // Version
                return false;
            }
            int Destination_Connection_ID_Length = *p++;
            p += Destination_Connection_ID_Length;
            if (p > l || Destination_Connection_ID_Length < 0x01) {
                return false;
            }
            int Source_Connection_ID_Length = *p++;
            p += Source_Connection_ID_Length;
            if (p > l) {
                return false;
            }
            if (F_Packet_Type_Bit == 0x00) { // Initial(0)
                int Token_Length = *p++;
                p += Token_Length;
                if (p > l || Token_Length < 0x01)
                {
                    return false;
                }
            }
            int Packet_Length = ntohs(*(UInt16*)p) & 0x3FFF;
            p += 0x02;
            if (p > l || Packet_Length < 0x01) {
                return false;
            }
            p += Packet_Length;
            return p == l;
        }

C#

 

        [SecurityCritical]
        [SecuritySafeCritical]
        public unsafe static bool PacketIsQUIC(IPEndPoint destinationEP, BufferSegment messages)
        {
            if (destinationEP == null || messages == null || messages.Length < 1)
            {
                return false;
            }
            if (destinationEP.Port != 443 && destinationEP.Port != 80)
            {
                return false;
            }
            try
            {
                fixed (byte* pinned = messages.Buffer)  // QUIC IETF
                {
                    byte* p = pinned + messages.Offset;
                    byte* l = p + messages.Length;
                    byte kf = *p++;
                    int F_Header_Form = Extension.GetBitValueAt(kf, 7);
                    int F_Fixed_Bit = Extension.GetBitValueAt(kf, 6);
                    int F_Packet_Type_Bit = Extension.GetBitValueAt(kf, 5) << 1 | Extension.GetBitValueAt(kf, 4);
                    if (F_Header_Form != 0x01 || F_Fixed_Bit != 0x01)
                    {
                        return false;
                    }
                    if (F_Packet_Type_Bit == 0x00) // Initial(0)
                    {
                        int F_Reserved_Bit = Extension.GetBitValueAt(kf, 3) << 1 | Extension.GetBitValueAt(kf, 3);
                        int F_Packet_Number_Length_Bit = Extension.GetBitValueAt(kf, 1) << 1 | Extension.GetBitValueAt(kf, 0);
                        if (F_Packet_Number_Length_Bit == 0x00 && F_Reserved_Bit == 0x00)
                        {
                            return false;
                        }
                    }
                    else if (F_Packet_Type_Bit != 0x02) // Handshake(2)
                    {
                        return false;
                    }
                    p += 0x04;
                    if (p > l)
                    {
                        return false;
                    }
                    uint Version = CheckSum.ntohl(((uint*)p)[-1]);
                    if (Version != 0x01) // Version
                    {
                        return false;
                    }
                    int Destination_Connection_ID_Length = *p++;
                    p += Destination_Connection_ID_Length;
                    if (p > l || Destination_Connection_ID_Length < 0x01)
                    {
                        return false;
                    }
                    int Source_Connection_ID_Length = *p++;
                    p += Source_Connection_ID_Length;
                    if (p > l)
                    {
                        return false;
                    }
                    if (F_Packet_Type_Bit == 0x00) // Initial(0)
                    {
                        int Token_Length = *p++;
                        p += Token_Length;
                        if (p > l || Token_Length < 0x01)
                        {
                            return false;
                        }
                    }
                    int Packet_Length = CheckSum.ntohs(*(ushort*)p) & 0x3FFF;
                    p += 0x02;
                    if (p > l || Packet_Length < 0x01)
                    {
                        return false;
                    }
                    p += Packet_Length;
                    return p == l;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值