/// <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); }