Beispiel #1
0
        /// <summary>
        /// Expect a SYN and ACK Packet
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public RdpeudpPacket ExpectSynAndAckPacket(TimeSpan timeout)
        {
            if (Connected)
            {
                return(null);
            }

            DateTime endtime = DateTime.Now + timeout;

            while (DateTime.Now < endtime)
            {
                // Lock the ReceivePacket method if it is transferring to RDPEUDP2 to avoid processing RDPEUDP2 packets with the RDPEUDP logic.
                lock (receiveLock)
                {
                    for (int i = 0; i < unprocessedPacketBuffer.Count; i++)
                    {
                        RdpeudpPacket eudpPacket = unprocessedPacketBuffer[i];
                        if (eudpPacket.FecHeader.uFlags.HasFlag(RDPUDP_FLAG.RDPUDP_FLAG_SYN) &&
                            eudpPacket.FecHeader.uFlags.HasFlag(RDPUDP_FLAG.RDPUDP_FLAG_ACK))
                        {
                            unprocessedPacketBuffer.RemoveAt(i);

                            if (eudpPacket.SynDataEx.HasValue)
                            {
                                if (eudpPacket.SynDataEx.Value.uUdpVer == RDPUDP_PROTOCOL_VERSION.RDPUDP_PROTOCOL_VERSION_3)
                                {
                                    upgradedToRdpedup2 = true;
                                    DisposeTimers();
                                    rdpeudp2Handler = new Rdpeudp2ProtocolHandler(AutoHandle, SendBytesByUdp, Close, ReceiveDataOnHigherLayer);
                                    rdpeudp2Handler.SocketConfig.RetransmitDuration    = RTT * 2;
                                    rdpeudp2Handler.SocketConfig.DelayedAckTimeoutInMs = (int)(RTT.TotalMilliseconds / 2);
                                    return(eudpPacket);
                                }
                            }

                            // Analyse the SYN packet.
                            ProcessSynPacket(eudpPacket);

                            return(eudpPacket);
                        }
                    }
                }

                // If not receive a Packet, wait a while
                Thread.Sleep(RdpeudpSocketConfig.ReceivingInterval);
            }
            return(null);
        }
        /// <summary>
        /// Send a SYN and ACK diagram
        /// </summary>
        /// <param name="initSequenceNumber">Specify an initial sequence number</param>
        /// <returns></returns>
        public bool SendSynAndAckPacket(uint?initSequenceNumber = null, RDPUDP_PROTOCOL_VERSION?version = null)
        {
            if (Connected)
            {
                return(false);
            }

            // Lock the ReceivePacket method if it is transferring to RDPEUDP2 to avoid processing RDPEUDP2 packets with the RDPEUDP logic.
            lock (receiveLock)
            {
                RdpeudpPacket synAndAckPacket = new RdpeudpPacket();
                synAndAckPacket.FecHeader.snSourceAck        = SnSourceAck;
                synAndAckPacket.FecHeader.uReceiveWindowSize = UReceiveWindowSize;
                synAndAckPacket.FecHeader.uFlags             = RDPUDP_FLAG.RDPUDP_FLAG_SYN | RDPUDP_FLAG.RDPUDP_FLAG_ACK;
                if (version.HasValue)
                {
                    synAndAckPacket.FecHeader.uFlags |= RDPUDP_FLAG.RDPUDP_FLAG_SYNEX;
                    synAndAckPacket.SynDataEx         = CreateSynExData((RDPUDP_PROTOCOL_VERSION)version);
                }
                synAndAckPacket.SynData = CreateSynData(initSequenceNumber);
                SendPacket(synAndAckPacket);
                // Set the OutSnResetSeqNum value, number from which the receive thread decoding the state of the send packet.
                OutSnResetSeqNum = synAndAckPacket.SynData.Value.snInitialSequenceNumber + 1;

                if (version.HasValue && version.Value.HasFlag(RDPUDP_PROTOCOL_VERSION.RDPUDP_PROTOCOL_VERSION_3))
                {
                    upgradedToRdpedup2 = true;
                    DisposeTimers();
                    rdpeudp2Handler = new Rdpeudp2ProtocolHandler(AutoHandle, SendBytesByUdp, Close, ReceiveDataOnHigherLayer);
                    rdpeudp2Handler.SocketConfig.RetransmitDuration    = RTT * 2;
                    rdpeudp2Handler.SocketConfig.DelayedAckTimeoutInMs = (int)(RTT.TotalMilliseconds / 2);
                }
            }

            return(true);
        }