private bool ProcessHandshakeC2(ReadOnlySequence <byte> buffer, ref int consumed)
        {
            if (buffer.Length - consumed < 1536)
            {
                return(false);
            }
            var arr = _arrayPool.Rent(1536);

            try
            {
                buffer.Slice(consumed, 1536).CopyTo(arr);
                consumed += 1536;
                var s1Timestamp = NetworkBitConverter.ToUInt32(arr.AsSpan(0, 4));
                if (s1Timestamp != _writerTimestampEpoch)
                {
                    throw new ProtocolViolationException();
                }
                if (!arr.AsSpan(8, 1528).SequenceEqual(_s1Data.AsSpan(0, 1528)))
                {
                    throw new ProtocolViolationException();
                }

                _ioPipeline.OnHandshakeSuccessful();
                return(true);
            }
            finally
            {
                _arrayPool.Return(_s1Data);
                _arrayPool.Return(arr);
                _s1Data = null;
                Dispose();
            }
        }
        private MessageData DeserializeMessage(Span <byte> buffer, out int consumed)
        {
            consumed = 0;
            var header = new MessageHeader();

            header.MessageType     = (MessageType)buffer[0];
            buffer                 = buffer.Slice(sizeof(byte));
            consumed              += sizeof(byte);
            header.MessageLength   = NetworkBitConverter.ToUInt24(buffer);
            buffer                 = buffer.Slice(3);
            consumed              += 3;
            header.Timestamp       = NetworkBitConverter.ToUInt32(buffer);
            buffer                 = buffer.Slice(sizeof(uint));
            consumed              += sizeof(uint);
            header.MessageStreamId = header.MessageStreamId;
            // Override message stream id
            buffer    = buffer.Slice(3);
            consumed += 3;
            var offset = consumed;

            consumed += (int)header.MessageLength;

            header.Timestamp += MessageHeader.Timestamp;

            return(new MessageData()
            {
                Header = header,
                DataOffset = offset,
                DataLength = header.MessageLength
            });
        }
Beispiel #3
0
        public override void Deserialize(SerializationContext context)
        {
            var span      = context.ReadBuffer.Span;
            var eventType = (UserControlEventType)NetworkBitConverter.ToUInt16(span);

            span = span.Slice(sizeof(ushort));
            Contract.Assert(eventType == UserControlEventType.StreamIsRecorded);
            StreamID = NetworkBitConverter.ToUInt32(span);
        }
 public bool ReadNet32(out uint x)
 {
     if (position + 4 > count)
     {
         x = 0;
         return(false);
     }
     x         = NetworkBitConverter.ToUInt32(data, position);
     position += 4;
     return(true);
 }
        private bool ProcessHandshakeC0C1(ReadOnlySequence <byte> buffer, ref int consumed)
        {
            if (buffer.Length - consumed < 1537)
            {
                return(false);
            }
            var arr = _arrayPool.Rent(1537);

            try
            {
                buffer.Slice(consumed, 9).CopyTo(arr);
                consumed += 9;
                var version = arr[0];
                //本文档中规范的版本号为 3。0、1、2 三个值是由早期其他产品使用的,是废弃值;4 - 31 被保留为 RTMP 协议的未来实现版本使用
                if (version < 3)
                {
                    throw new NotSupportedException();
                }
                if (version > 31)
                {
                    throw new ProtocolViolationException();
                }

                _readerTimestampEpoch = NetworkBitConverter.ToUInt32(arr.AsSpan(1, 4));
                _writerTimestampEpoch = 0;
                _s1Data = _arrayPool.Rent(1528);
                _random.NextBytes(_s1Data.AsSpan(0, 1528));

                // s0s1
                arr.AsSpan().Clear();
                arr[0] = 3;
                NetworkBitConverter.TryGetBytes(_writerTimestampEpoch, arr.AsSpan(1, 4));
                _s1Data.AsSpan(0, 1528).CopyTo(arr.AsSpan(9));
                _ = _ioPipeline.SendRawData(arr.AsMemory(0, 1537));

                // s2
                NetworkBitConverter.TryGetBytes(_readerTimestampEpoch, arr.AsSpan(0, 4));
                NetworkBitConverter.TryGetBytes((uint)0, arr.AsSpan(4, 4));

                _ = _ioPipeline.SendRawData(arr.AsMemory(0, 1536));

                buffer.Slice(consumed, 1528).CopyTo(arr.AsSpan(8));
                consumed += 1528;

                _ioPipeline.NextProcessState = ProcessState.HandshakeC2;
                return(true);
            }
            finally
            {
                _arrayPool.Return(arr);
            }
        }
Beispiel #6
0
        public static ResourceRecord Parse(byte [] buffer, ref int offset)
        {
            string name;

            if ((buffer[offset] & 0xc0) == 0xc0)
            {
                // Detected compression.  Name is at offset in
                // lower 14 bits of next 2 bytes.
                int start = NetworkBitConverter.ToInt16(buffer, offset);
                if (LabelEncoding.GetString(buffer, start & 0x3fff,
                                            out name) == 0)
                {
                    throw new InvalidDnsFormatException("name");
                }
                offset += 2;
            }
            else
            {
                int used = LabelEncoding.GetString(buffer, offset, out name);
                if (used == 0)
                {
                    throw new InvalidDnsFormatException("name");
                }
                offset += used;
            }

            ushort rType = NetworkBitConverter.ToUInt16(buffer, offset);

            offset += 2;

            ushort rClass = NetworkBitConverter.ToUInt16(buffer, offset);

            offset += 2;

            uint ttlSeconds = NetworkBitConverter.ToUInt32(buffer, offset);

            offset += 4;

            ushort rdataLength = NetworkBitConverter.ToUInt16(buffer, offset);

            offset += 2;

            byte [] rdata = new byte[rdataLength];
            Array.Copy(buffer, offset, rdata, 0, rdataLength);
            offset += rdataLength;

            return(new ResourceRecord(name, (Type)rType, (Class)rClass,
                                      ttlSeconds, rdata));
        }
Beispiel #7
0
        public ArpHeader(Bytes packet, ushort index)
        {
            //since this is already known to be an arp request
            //we skip the sanity checks...

            VTable.Assert(packet.Length - index >= 96);

            // check hardware type == 0x0001 (Ethernet)
            htype = NetworkBitConverter.ToUInt16(packet, index);
            DebugStub.Assert(htype == 0x001);
            index += 2;

            // check protocol type == 0x0800 (IP)
            ptype = NetworkBitConverter.ToUInt16(packet, index);
            DebugStub.Assert(ptype == 0x0800);
            index += 2;

            // check hardware address len is 6 bytes
            hlen = packet[index++];
            DebugStub.Assert(hlen == 6);


            // check IP address len is 4 bytes
            plen = packet[index++];
            DebugStub.Assert(plen == 4);

            op     = NetworkBitConverter.ToUInt16(packet, index);
            index += 2;

            senderEthernetAddr = EthernetAddress.ParseBytes(packet.Array, packet.Start + index);
            index += EthernetAddress.Length;

            uint addr = NetworkBitConverter.ToUInt32(packet, index);

            index       += 4;
            senderIPAddr = new IPv4(addr);


            destEthernetAddr = EthernetAddress.ParseBytes(packet.Array, packet.Start + index);
            index           += EthernetAddress.Length;

            addr       = NetworkBitConverter.ToUInt32(packet, index);
            index     += 4;
            destIPAddr = new IPv4(addr);
            //sgc complains
            pad0 = 0;
            pad1 = 0;
        }
        public bool TryGetStrictArray(Span <byte> buffer, out List <object> array, out int consumedLength)
        {
            array          = default;
            consumedLength = default;

            if (!TryDescribeData(buffer, out var type, out _))
            {
                return(false);
            }

            if (type != Amf0Type.StrictArray)
            {
                return(false);
            }

            var obj = new List <object>();

            _referenceTable.Add(obj);

            var elementCount = NetworkBitConverter.ToUInt32(buffer.Slice(Amf0CommonValues.MARKER_LENGTH, sizeof(uint)));

            int consumed          = Amf0CommonValues.MARKER_LENGTH + sizeof(uint);
            var arrayBodyBuffer   = buffer.Slice(consumed);
            var elementBodyBuffer = arrayBodyBuffer;

            System.Diagnostics.Debug.WriteLine(elementCount);
            for (uint i = 0; i < elementCount; i++)
            {
                if (!TryGetValue(elementBodyBuffer, out _, out var element, out var bufferConsumed))
                {
                    return(false);
                }

                obj.Add(element);
                if (elementBodyBuffer.Length - bufferConsumed < 0)
                {
                    return(false);
                }
                elementBodyBuffer = elementBodyBuffer.Slice(bufferConsumed);
                consumed         += bufferConsumed;
            }
            array          = obj;
            consumedLength = consumed;

            return(true);
        }
        public bool TryGetMessage(Span <byte> buffer, out Message message, out int consumed)
        {
            message  = default;
            consumed = default;

            if (!TryGetStringImpl(buffer, Amf0CommonValues.STRING_HEADER_LENGTH, out var targetUri, out var targetUriConsumed))
            {
                return(false);
            }

            buffer = buffer.Slice(targetUriConsumed);
            if (!TryGetStringImpl(buffer, Amf0CommonValues.STRING_HEADER_LENGTH, out var responseUri, out var responseUriConsumed))
            {
                return(false);
            }

            buffer = buffer.Slice(responseUriConsumed);
            if (buffer.Length < sizeof(uint))
            {
                return(false);
            }
            var messageLength = NetworkBitConverter.ToUInt32(buffer);

            if (messageLength >= 0 && buffer.Length < messageLength)
            {
                return(false);
            }
            if (messageLength == 0 && StrictMode)
            {
                return(true);
            }
            buffer = buffer.Slice(sizeof(uint));
            if (!TryGetValue(buffer, out _, out var content, out var contentConsumed))
            {
                return(false);
            }
            consumed = targetUriConsumed + responseUriConsumed + sizeof(uint) + contentConsumed;
            message  = new Message()
            {
                TargetUri   = targetUri,
                ResponseUri = responseUri,
                Content     = content
            };
            return(true);
        }
Beispiel #10
0
        //create a byte aligned ipheader
        //index marks the starting location of the ip header within the buffer
        public IpHeader(Bytes packet, int index)
        {
            //assert that the packet is large enough for a ipheader
            VTable.Assert(packet.Length - index > 20);

            verLen      = packet[index++];
            tos         = packet[index++];
            totalLength = NetworkBitConverter.ToUInt16(packet, index);
            index      += 2;
            id          = NetworkBitConverter.ToUInt16(packet, index);
            index      += 2;
            offset      = NetworkBitConverter.ToUInt16(packet, index);
            index      += 2;
            ttl         = packet[index++];
            protocol    = packet[index++];
            checksum    = NetworkBitConverter.ToUInt16(packet, index);
            index      += 2;
            uint addr;

            addr        = NetworkBitConverter.ToUInt32(packet, index);
            srcAddress  = new IPv4(addr);
            index      += 4;
            addr        = NetworkBitConverter.ToUInt32(packet, index);
            destAddress = new IPv4(addr);
#if false
            DebugStub.Print("IpHeader verlen 0x{0,8:x}\n tos {1}\n" +
                            " totalLength {2}\n ttl {3}\n protocol 0x{4,4:x}\n" +
                            " checksum 0x{5,4:x}\n src {6}\n, dest {7}\n",
                            DebugStub.ArgList(verLen, tos, totalLength, ttl, protocol, checksum, srcAddress,
                                              destAddress));
#endif
            //sgc complains...
            pad0 = 0;
            pad1 = 0;
            pad2 = 0;
            pad3 = 0;
        }
Beispiel #11
0
        internal bool TryGetStringImpl(Span <byte> buffer, int lengthOfLengthField, out string value, out int consumedLength)
        {
            value          = default;
            consumedLength = default;
            var stringLength = 0;

            if (lengthOfLengthField == Amf0CommonValues.STRING_HEADER_LENGTH)
            {
                stringLength = (int)NetworkBitConverter.ToUInt16(buffer);
            }
            else
            {
                stringLength = (int)NetworkBitConverter.ToUInt32(buffer);
            }

            if (buffer.Length - lengthOfLengthField < stringLength)
            {
                return(false);
            }

            value          = Encoding.UTF8.GetString(buffer.Slice(lengthOfLengthField, stringLength));
            consumedLength = lengthOfLengthField + stringLength;
            return(true);
        }
Beispiel #12
0
 public override void Deserialize(SerializationContext context)
 {
     BytesReceived = NetworkBitConverter.ToUInt32(context.ReadBuffer.Span);
 }
Beispiel #13
0
 public override void Deserialize(SerializationContext context)
 {
     WindowSize = NetworkBitConverter.ToUInt32(context.ReadBuffer.Span);
 }
Beispiel #14
0
 public override void Deserialize(SerializationContext context)
 {
     AbortedChunkStreamId = NetworkBitConverter.ToUInt32(context.ReadBuffer.Span);
 }
Beispiel #15
0
        public bool TryGetEcmaArray(Span <byte> buffer, out Dictionary <string, object> value, out int consumedLength)
        {
            value          = default;
            consumedLength = default;
            int consumed = 0;

            if (!TryDescribeData(buffer, out var type, out _))
            {
                return(false);
            }

            if (type != Amf0Type.EcmaArray)
            {
                return(false);
            }

            var obj = new Dictionary <string, object>();

            _referenceTable.Add(obj);

            var elementCount = NetworkBitConverter.ToUInt32(buffer.Slice(Amf0CommonValues.MARKER_LENGTH, sizeof(uint)));

            var arrayBodyBuffer = buffer.Slice(Amf0CommonValues.MARKER_LENGTH + sizeof(uint));

            consumed = Amf0CommonValues.MARKER_LENGTH + sizeof(uint);
            if (StrictMode)
            {
                for (int i = 0; i < elementCount; i++)
                {
                    if (!TryGetKeyValuePair(arrayBodyBuffer, out var kv, out _, out var kvConsumed))
                    {
                        return(false);
                    }
                    arrayBodyBuffer = arrayBodyBuffer.Slice(kvConsumed);
                    consumed       += kvConsumed;
                    obj.Add(kv.Key, kv.Value);
                }
                if (!TryGetStringImpl(arrayBodyBuffer, Amf0CommonValues.STRING_HEADER_LENGTH, out var emptyStr, out var emptyStrConsumed))
                {
                    return(false);
                }
                if (emptyStr.Any())
                {
                    return(false);
                }
                consumed       += emptyStrConsumed;
                arrayBodyBuffer = arrayBodyBuffer.Slice(emptyStrConsumed);
                if (!TryDescribeData(arrayBodyBuffer, out var objEndType, out var objEndConsumed))
                {
                    return(false);
                }
                if (objEndType != Amf0Type.ObjectEnd)
                {
                    return(false);
                }
                consumed += objEndConsumed;
            }
            else
            {
                while (true)
                {
                    if (!TryGetKeyValuePair(arrayBodyBuffer, out var kv, out var isEnd, out var kvConsumed))
                    {
                        return(false);
                    }
                    arrayBodyBuffer = arrayBodyBuffer.Slice(kvConsumed);
                    consumed       += kvConsumed;
                    if (isEnd)
                    {
                        break;
                    }
                    obj.Add(kv.Key, kv.Value);
                }
            }


            value          = obj;
            consumedLength = consumed;
            return(true);
        }
 public override void Deserialize(SerializationContext context)
 {
     WindowSize = NetworkBitConverter.ToUInt32(context.ReadBuffer.Span);
     LimitType  = (LimitType)context.ReadBuffer.Span.Slice(sizeof(uint))[0];
 }
Beispiel #17
0
        public static DhcpFormat Parse(Bytes buffer)
        {
            DhcpFormat p = new DhcpFormat(BootType.NotSpecified);

            p.optionsUsedLength = 0;

            if (buffer.Length < DhcpFormat.MinLength)
            {
                throw new InvalidDhcpFormatException("Format less than minimum size");
            }
            int offset = 0;

            p.op = buffer[offset++];
            if (p.op != (byte)BootType.Request &&
                p.op != (byte)BootType.Reply)
            {
                throw new InvalidDhcpFormatException("Bad Type (op = {0})", p.op);
            }
            p.htype = buffer[offset++];
            // No check

            p.hlen = buffer[offset++];
            if (p.hlen > HardwareAddressLength)
            {
                throw new InvalidDhcpFormatException("Bad address length (hlen {0})",
                                                     p.hlen);
            }
            p.hops = buffer[offset++];
            // No check

            p.xid   = NetworkBitConverter.ToUInt32(buffer, offset);
            offset += 4;

            p.secs  = NetworkBitConverter.ToUInt16(buffer, offset);
            offset += 2;

            p.flags = NetworkBitConverter.ToUInt16(buffer, offset);
            offset += 2;

            p.ciaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            p.yiaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            p.siaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            p.giaddr = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;

            Bitter.ToByteArray(buffer, offset, HardwareAddressLength, p.chaddr, 0);
            offset += HardwareAddressLength;
            Bitter.ToByteArray(buffer, offset, ServerNameLength, p.sname, 0);
            offset += ServerNameLength;
            Bitter.ToByteArray(buffer, offset, BootFileLength, p.file, 0);
            offset += BootFileLength;

            p.cookie = NetworkBitConverter.ToUInt32(buffer, offset);
            offset  += 4;
            if (p.cookie != DhcpCookie)
            {
                throw new InvalidDhcpFormatException("Bad cookie (0x{0x:x8})",
                                                     p.cookie);
            }
            int available = buffer.Length - offset;

            if (available > p.options.Length)
            {
                p.options = new byte [available];
            }
            p.optionsUsedLength = available;
            Bitter.ToByteArray(buffer, offset, available, p.options, 0);

            return(p);
        }