Exemplo n.º 1
0
        /// <summary>
        /// Processes incomming initial packet and creates or halts a connection.
        /// </summary>
        /// <param name="packet">Initial Packet</param>
        /// <param name="endPoint">Peer's endpoint</param>
        /// <returns></returns>
        private QuicConnection ProcessInitialPacket(Packet packet, IPEndPoint endPoint)
        {
            QuicConnection result = null;
            UInt32         availableConnectionId;

            byte[] data;
            // Unsupported version. Version negotiation packet is sent only on initial connection. All other packets are dropped. (5.2.2 / 16th draft)
            if (packet.Version != QuicVersion.CurrentVersion || !QuicVersion.SupportedVersions.Contains(packet.Version))
            {
                VersionNegotiationPacket vnp = _packetCreator.CreateVersionNegotiationPacket();
                data = vnp.Encode();

                _client.Send(data, data.Length, endPoint);
                return(null);
            }

            InitialPacket cast = packet as InitialPacket;
            InitialPacket ip   = _packetCreator.CreateInitialPacket(0, cast.SourceConnectionId);

            // Protocol violation if the initial packet is smaller than the PMTU. (pt. 14 / 16th draft)
            if (cast.Encode().Length < QuicSettings.PMTU)
            {
                ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.PROTOCOL_VIOLATION, "PMTU have not been reached."));
            }
            else if (ConnectionPool.AddConnection(new ConnectionData(_pwt, cast.SourceConnectionId, 0), out availableConnectionId) == true)
            {
                // Tell the peer the available connection id
                ip.SourceConnectionId = (byte)availableConnectionId;

                // We're including the maximum possible stream id during the connection handshake. (4.5 / 16th draft)
                ip.AttachFrame(new MaxStreamsFrame(QuicSettings.MaximumStreamId, StreamType.ServerBidirectional));

                // Set the return result
                result = ConnectionPool.Find(availableConnectionId);
            }
            else
            {
                // Not accepting connections. Send initial packet with CONNECTION_CLOSE frame.
                // TODO: Buffering. The server might buffer incomming 0-RTT packets in anticipation of late delivery InitialPacket.
                // Maximum buffer size should be set in QuicSettings.
                ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.SERVER_BUSY, "The server is too busy to process your request."));
            }

            data = ip.Encode();
            int dataSent = _client.Send(data, data.Length, endPoint);

            if (dataSent > 0)
            {
                return(result);
            }

            return(null);
        }
Exemplo n.º 2
0
        public InitialPacket CreateInitialPacket(GranularInteger sourceConnectionId, GranularInteger destinationConnectionId)
        {
            InitialPacket packet = new InitialPacket(destinationConnectionId, sourceConnectionId);

            packet.PacketNumber            = 0;
            packet.SourceConnectionId      = sourceConnectionId;
            packet.DestinationConnectionId = destinationConnectionId;
            packet.Version = QuicVersion.CurrentVersion;

            int length  = packet.Encode().Length;
            int padding = QuicSettings.PMTU - length;

            for (int i = 0; i < padding; i++)
            {
                packet.AttachFrame(new PaddingFrame());
            }

            return(packet);
        }
Exemplo n.º 3
0
        public InitialPacket CreateInitialPacket(byte sourceConnectionId, byte destinationConnectionId)
        {
            var packet = new InitialPacket
            {
                PacketNumber            = 0,
                SourceConnectionId      = sourceConnectionId,
                DestinationConnectionId = destinationConnectionId,
                Version = QuicVersion.CurrentVersion
            };

            var length  = packet.Encode().Length;
            var padding = QuicSettings.PMTU - length;

            for (var i = 0; i < padding; i++)
            {
                packet.AttachFrame(new PaddingFrame());
            }

            return(packet);
        }