Ejemplo n.º 1
0
        public void TestDecode()
        {
            ShortHeaderPacket shp = new ShortHeaderPacket();

            shp.PacketNumber = 42;
            shp.DCID         = new byte[] { 0x00, 0x00, 0x00, 0x7b };
            shp.AddFrame(new DebugFrame {
                Message = "Message"
            });

            byte[] pack = shp.Encode();

            Packet p = Packet.Unpack(pack);

            Assert.AreEqual(p.GetType(), typeof(ShortHeaderPacket));
            ShortHeaderPacket sh = p as ShortHeaderPacket;

            CollectionAssert.AreEqual(sh.DCID, new byte[] { 0x00, 0x00, 0x00, 0x7b });
            Assert.AreEqual(sh.PacketNumber, (UInt64)42);
            Assert.AreEqual(sh.Spin, false);
            Assert.AreEqual(sh.KeyPhase, false);
            Assert.AreEqual(sh.PacketNumberLength, (UInt32)4);

            foreach (Frame f in p.Frames)
            {
                Assert.AreEqual(f.Type, 0x1e);
                DebugFrame fd = f as DebugFrame;
                Assert.AreEqual(fd.Message, "Message");
            }
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            byte[]          bytes    = new VariableInteger(12345);
            VariableInteger integer  = bytes;
            UInt64          uinteger = integer;
            int             size     = VariableInteger.Size(bytes[0]);

            InitialPacket packet = new InitialPacket()
            {
                Version                 = 16,
                SourceConnectionId      = 124,
                DestinationConnectionId = 0,
                PacketNumber            = 777521,
                TokenLength             = 0
            };

            packet = new PacketCreator().CreateInitialPacket(124, 0);

            ConnectionCloseFrame frame     = new ConnectionCloseFrame(ErrorCode.SERVER_BUSY, "The server is too busy to process your request.");
            MaxStreamIdFrame     msidframe = new MaxStreamIdFrame(144123, StreamType.ClientUnidirectional);

            //packet.AttachFrame(frame);
            packet.AttachFrame(msidframe);

            byte[] data = packet.Encode();
            string b64  = ToBase64(data);

            byte[] shpdata1 = new byte[] { 1, 1, 2, 3, 5, 8 };
            byte[] shpdata2 = new byte[] { 13, 21, 34, 55, 89, 144 };

            ShortHeaderPacket shp = new ShortHeaderPacket();

            shp.DestinationConnectionId = 124;
            shp.PacketNumber            = 2;

            shp.AttachFrame(new StreamFrame()
            {
                StreamId = 1, Length = new VariableInteger((UInt64)shpdata2.Length), StreamData = shpdata2, Offset = 6, EndOfStream = true
            });
            shp.AttachFrame(new StreamFrame()
            {
                StreamId = 1, Length = new VariableInteger((UInt64)shpdata1.Length), StreamData = shpdata1, Offset = 0
            });

            string shpb64 = ToBase64(shp.Encode());

            packet.Decode(data);

            byte[] ccfData = frame.Encode();
            frame.Decode(new ByteArray(ccfData));

            byte[]   streamIdData = new StreamId(123, StreamType.ClientUnidirectional);
            StreamId streamId     = streamIdData;

            QuicListener listener = new QuicListener(11000);

            listener.OnClientConnected += Listener_OnClientConnected;
            listener.Start();
        }
Ejemplo n.º 3
0
        public ShortHeaderPacket CreateDataPacket(UInt64 streamId, byte[] data)
        {
            ShortHeaderPacket packet = new ShortHeaderPacket();

            packet.PacketNumber            = _ns.Get();
            packet.DestinationConnectionId = (byte)_peerConnectionId;
            packet.AttachFrame(new StreamFrame(streamId, data, 0, true));

            return(packet);
        }
Ejemplo n.º 4
0
        public ShortHeaderPacket CreateConnectionClosePacket(ErrorCode code, string reason)
        {
            ShortHeaderPacket packet = new ShortHeaderPacket();

            packet.PacketNumber            = _ns.Get();
            packet.DestinationConnectionId = (byte)_peerConnectionId;
            packet.AttachFrame(new ConnectionCloseFrame(code, reason));

            return(packet);
        }
Ejemplo n.º 5
0
        public ShortHeaderPacket CreateDataPacket(UInt64 streamId, byte[] data, UInt64 offset, bool eos)
        {
            ShortHeaderPacket packet = new ShortHeaderPacket(_peerConnectionId.Size);

            packet.PacketNumber            = _ns.Get();
            packet.DestinationConnectionId = (byte)_peerConnectionId;
            packet.AttachFrame(new StreamFrame(streamId, data, offset, eos));

            return(packet);
        }
Ejemplo n.º 6
0
        public ShortHeaderPacket CreateDataPacket(ulong streamId, byte[] data)
        {
            var packet = new ShortHeaderPacket
            {
                PacketNumber = _ns.Get(), DestinationConnectionId = (byte)_peerConnectionId
            };

            packet.AttachFrame(new StreamFrame(streamId, data, 0, true));
            return(packet);
        }
Ejemplo n.º 7
0
        private void ProcessShortHeaderPacket(Packet packet)
        {
            ShortHeaderPacket shp = (ShortHeaderPacket)packet;

            QuicConnection connection = ConnectionPool.Find(shp.DestinationConnectionId);

            if (connection == null)
            {
                return; // TODO: Figure out if the packet should be discarded in that case?
            }
            connection.ProcessFrames(shp.GetFrames());
        }
Ejemplo n.º 8
0
        public void TestEncode()
        {
            ShortHeaderPacket shp = new ShortHeaderPacket();

            shp.PacketNumber = 42;
            shp.DCID         = new byte[] { 0x00, 0x00, 0x00, 0x7b };
            shp.AddFrame(new DebugFrame {
                Message = "Message"
            });

            byte[] pack = shp.Encode();

            /*
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | 0 | 1 | S | R | R | K | P P |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | Destination Connection ID(0..160)           ...
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | Packet Number(8 / 16 / 24 / 32)...
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | Protected Payload(*)...
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             */
            Assert.AreEqual(pack.Length, 17);

            Assert.AreEqual(pack[0] & 0x80, 0);    // First bit
            Assert.AreEqual(pack[0] & 0x40, 0x40); // Second bit
            Assert.AreEqual(pack[0] & 0x20, 0);
            Assert.AreEqual(pack[0] & 0x04, 0);
            Assert.AreEqual(pack[0] & 0x02, 0x02);
            Assert.AreEqual(pack[0] & 0x01, 0x01);

            Assert.AreEqual(pack[1], 0);
            Assert.AreEqual(pack[2], 0);
            Assert.AreEqual(pack[3], 0);
            Assert.AreEqual(pack[4], 0x7b);

            Assert.AreEqual(pack[5], 0);
            Assert.AreEqual(pack[6], 0);
            Assert.AreEqual(pack[7], 0);
            Assert.AreEqual(pack[8], 42);

            // Payload
            Assert.AreEqual(pack[9], 0x1e); // Type Debug
            Assert.AreEqual(pack[10], Convert.ToByte('M'));
            Assert.AreEqual(pack[11], Convert.ToByte('e'));
            Assert.AreEqual(pack[12], Convert.ToByte('s'));
            Assert.AreEqual(pack[13], Convert.ToByte('s'));
            Assert.AreEqual(pack[14], Convert.ToByte('a'));
            Assert.AreEqual(pack[15], Convert.ToByte('g'));
            Assert.AreEqual(pack[16], Convert.ToByte('e'));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Processes short header packet, by distributing the frames towards connections.
        /// </summary>
        /// <param name="packet"></param>
        private void ProcessShortHeaderPacket(Packet packet)
        {
            ShortHeaderPacket shp = (ShortHeaderPacket)packet;

            QuicConnection connection = ConnectionPool.Find(shp.DestinationConnectionId);

            // No suitable connection found. Discard the packet.
            if (connection == null)
            {
                return;
            }

            connection.ProcessFrames(shp.GetFrames());
        }
Ejemplo n.º 10
0
        public void ProcessData(StreamFrame frame)
        {
            // Do not accept data if the stream is reset.
            if (State == StreamState.ResetRecvd)
            {
                return;
            }

            byte[] data = frame.StreamData;
            if (frame.Offset != null)
            {
                _data.Add(frame.Offset.Value, frame.StreamData);
            }
            else
            {
                // TODO: Careful with duplicate 0 offset packets on the same stream. Probably PROTOCOL_VIOLATION?
                _data.Add(0, frame.StreamData);
            }

            // Either this frame marks the end of the stream,
            // or fin frame came before the data frames
            if (frame.EndOfStream)
            {
                State = StreamState.SizeKnown;
            }

            _currentTransferRate += (UInt64)data.Length;

            // Terminate connection if maximum stream data is reached
            if (_currentTransferRate >= _maximumStreamData)
            {
                ShortHeaderPacket errorPacket = _connection.PacketCreator.CreateConnectionClosePacket(Infrastructure.ErrorCode.FLOW_CONTROL_ERROR, frame.ActualType, ErrorConstants.MaxDataTransfer);
                _connection.SendData(errorPacket);
                _connection.TerminateConnection();

                return;
            }

            if (State == StreamState.SizeKnown && IsStreamFull())
            {
                State = StreamState.DataRecvd;

                OnStreamDataReceived?.Invoke(this, Data);
            }
        }
Ejemplo n.º 11
0
        public bool Send(byte[] data)
        {
            if (Type == StreamType.ServerUnidirectional)
            {
                throw new StreamException("Cannot send data on unidirectional stream.");
            }

            _connection.IncrementRate(data.Length);

            ShortHeaderPacket packet = _connection.PacketCreator.CreateDataPacket(this.StreamId.IntegerValue, data);

            if (_connection.MaximumReached())
            {
                packet.AttachFrame(new StreamDataBlockedFrame(StreamId.IntegerValue, (UInt64)data.Length));
            }

            return(_connection.SendData(packet));
        }
Ejemplo n.º 12
0
        public bool Send(byte[] data)
        {
            if (Type == StreamType.ServerUnidirectional)
            {
                throw new StreamException("Cannot send data on unidirectional stream.");
            }

            _connection.IncrementRate(data.Length);

            int numberOfPackets = (data.Length / QuicSettings.PMTU) + 1;
            int leftoverCarry   = data.Length % QuicSettings.PMTU;

            for (int i = 0; i < numberOfPackets; i++)
            {
                bool eos      = false;
                int  dataSize = QuicSettings.PMTU;
                if (i == numberOfPackets - 1)
                {
                    eos      = true;
                    dataSize = leftoverCarry;
                }

                byte[] buffer = new byte[dataSize];
                Buffer.BlockCopy(data, (Int32)_sendOffset, buffer, 0, dataSize);

                ShortHeaderPacket packet = _connection.PacketCreator.CreateDataPacket(this.StreamId.IntegerValue, buffer, _sendOffset, eos);
                if (i == 0 && data.Length >= QuicSettings.MaxStreamData)
                {
                    packet.AttachFrame(new MaxStreamDataFrame(this.StreamId.IntegerValue, (UInt64)(data.Length + 1)));
                }

                if (_connection.MaximumReached())
                {
                    packet.AttachFrame(new StreamDataBlockedFrame(StreamId.IntegerValue, (UInt64)data.Length));
                }

                _sendOffset += (UInt64)buffer.Length;

                _connection.SendData(packet);
            }

            return(true);
        }
Ejemplo n.º 13
0
        public Packet Unpack(byte[] data)
        {
            Packet result = null;

            var type = GetPacketType(data);

            switch (type)
            {
            case QuicPacketType.Initial: result = new InitialPacket(); break;

            case QuicPacketType.ShortHeader: result = new ShortHeaderPacket(); break;
            }

            if (result == null)
            {
                return(null);
            }

            result.Decode(data);

            return(result);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Client only!
        /// </summary>
        /// <returns></returns>
        internal void ReceivePacket()
        {
            Packet packet = _pwt.ReadPacket();

            if (packet is ShortHeaderPacket)
            {
                ShortHeaderPacket shp = (ShortHeaderPacket)packet;
                ProcessFrames(shp.GetFrames());
            }

            // If the connection has been closed
            if (_state == ConnectionState.Draining)
            {
                if (string.IsNullOrWhiteSpace(_lastError))
                {
                    _lastError = "Protocol error";
                }

                TerminateConnection();

                throw new QuicConnectivityException(_lastError);
            }
        }
Ejemplo n.º 15
0
        internal void SendMaximumStreamReachedError()
        {
            ShortHeaderPacket packet = PacketCreator.CreateConnectionClosePacket(Infrastructure.ErrorCode.STREAM_LIMIT_ERROR, 0x00, ErrorConstants.MaxNumberOfStreams);

            Send(packet);
        }
Ejemplo n.º 16
0
        internal void SendMaximumStreamReachedError()
        {
            ShortHeaderPacket packet = PacketCreator.CreateConnectionClosePacket(Infrastructure.ErrorCode.STREAM_LIMIT_ERROR, "Maximum number of streams reached.");

            Context.Send(packet);
        }