Esempio n. 1
0
        /// <summary>
        /// Creates a serialized request packet (DtmPacket)
        /// </summary>
        private MemoryStream CreateRequest(DtmPacketFlags Message, short State)
        {
            MemoryStream ret = new DtmPacketStruct(Message, 0, 0, State).ToStream();

            ret.Seek(0, SeekOrigin.Begin);
            return(ret);
        }
Esempio n. 2
0
 private void Resend(DtmPacketStruct PacketHeader)
 {
     if (_sndBuffer.Exists(PacketHeader.Sequence))
     {
         MemoryStream pktStm = _sndBuffer.Peek(PacketHeader.Sequence);
         if (pktStm != null)
         {
             if (pktStm.Length > 0)
             {
                 pktStm.WriteTo(_clientSocket.TcpStream);
             }
         }
     }
 }
Esempio n. 3
0
        private void Transmit(DtmPacketFlags PacketType, short PacketFlag, long OptionFlag = 0, MemoryStream Payload = null)
        {
            lock (_sndLock)
            {
                long pldLen = Payload == null ? 0 : Payload.Length;
                // create a new packet: packet flag, payload size, sequence, and state flag
                MemoryStream pktStm = new DtmPacketStruct(PacketType, pldLen, _sndSequence, PacketFlag, OptionFlag).ToStream();

                // add payload
                if (Payload != null)
                {
                    // copy to output
                    pktStm.Seek(0, SeekOrigin.End);
                    Payload.WriteTo(pktStm);
                    pktStm.Seek(0, SeekOrigin.Begin);
                }

                // store in the file packet buffer
                _sndBuffer.Push(_sndSequence, pktStm);
                // increment file send counter
                _sndSequence++;

                // transmit to remote client
                if (_clientSocket.IsConnected)
                {
                    try
                    {
                        _clientSocket.SendAsync(pktStm);
                    }
                    catch (CryptoSocketException ce)
                    {
                        SocketException se = ce.InnerException as SocketException;

                        if (se.SocketErrorCode == SocketError.WouldBlock ||
                            se.SocketErrorCode == SocketError.IOPending ||
                            se.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                        {
                            // buffer is full, throttle down
                            Throttle(pktStm);
                        }
                        else
                        {
                            // possible connection dropped, alert app
                            if (SessionError != null)
                            {
                                DtmErrorArgs args = new DtmErrorArgs(ce, DtmErrorSeverityFlags.Connection);
                                SessionError(this, args);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        // possible connection dropped, alert app
                        if (SessionError != null)
                        {
                            DtmErrorArgs args = new DtmErrorArgs(ex, DtmErrorSeverityFlags.Connection);
                            SessionError(this, args);
                        }
                    }

                    // notify app
                    if (PacketSent != null)
                    {
                        PacketSent(this, new DtmPacketArgs((short)DtmTransferFlags.DataChunk, pldLen));
                    }
                }
            }
        }
Esempio n. 4
0
        private void ProcessAndPush(PacketBuffer Buffer, MemoryStream PacketStream)
        {
            int hdrLen = DtmPacketStruct.GetHeaderSize();
            int pktLen = 0;
            // get the header
            DtmPacketStruct pktHdr = new DtmPacketStruct(PacketStream);

            PacketStream.Seek(0, SeekOrigin.Begin);

            // track high sequence number
            if (pktHdr.Sequence > _seqCounter)
            {
                _seqCounter = pktHdr.Sequence;
            }

            // out of sync, possible packet loss
            if (_seqCounter - _rcvSequence > _bufferCount / 4)
            {
                // request a retransmission
                Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, _rcvSequence + 1);
            }

            // packet aligned
            if (pktHdr.PayloadLength + hdrLen == PacketStream.Length)
            {
                // resend was already processed
                if (pktHdr.Sequence < _rcvSequence)
                {
                    return;
                }

                // push onto buffer
                Buffer.Push(pktHdr.Sequence, PacketStream);
            }
            // more than one packet
            else if (pktHdr.PayloadLength + hdrLen < PacketStream.Length)
            {
                byte[] buffer;
                long   pos = 0;

                do
                {
                    // get packet position and size
                    pos = PacketStream.Position;

                    if (PacketStream.Length - pos < DtmPacketStruct.GetHeaderSize())
                    {
                        // next packet corrupted, request a retransmission and exit
                        Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1);
                        return;
                    }

                    pktHdr = new DtmPacketStruct(PacketStream);
                    pktLen = (int)(hdrLen + pktHdr.PayloadLength);

                    if (pktLen > MAXRCVBUFFER || pktLen < 0 || PacketStream.Length - pos < pktLen)
                    {
                        // packet corrupted, request a retransmission and exit
                        Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1);
                        return;
                    }
                    else
                    {
                        // create the buffer
                        buffer = new byte[pktLen];
                        PacketStream.Seek(pos, SeekOrigin.Begin);
                        PacketStream.Read(buffer, 0, (int)pktLen);
                        // push onto buffer
                        Buffer.Push(pktHdr.Sequence, new MemoryStream(buffer));
                    }
                } while (PacketStream.Position < PacketStream.Length);
            }
            // malformed packet, send retransmit request
            else if (pktHdr.PayloadLength > MAXRCVBUFFER || pktHdr.PayloadLength < 0 || pktHdr.PayloadLength + hdrLen > PacketStream.Length)
            {
                // packet corrupted, request a retransmission of last in queue + 1
                Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1);
            }
        }
Esempio n. 5
0
        private void Process(MemoryStream PacketStream)
        {
            // increment rcv sequence
            _rcvSequence++;
            // get the header
            DtmPacketStruct pktHdr = new DtmPacketStruct(PacketStream);

            PacketStream.Seek(0, SeekOrigin.Begin);

            switch (pktHdr.PacketType)
            {
            // file transfer
            case DtmPacketFlags.Transfer:
            {
                switch ((DtmTransferFlags)pktHdr.PacketFlag)
                {
                case DtmTransferFlags.DataChunk:
                {
                    try
                    {
                        lock (_rcvLock)
                        {
                            // received file data
                            Receive(PacketStream);
                        }
                    }
                    catch (Exception)
                    {
                        // packet corrupted, request a retransmission and exit
                        Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, pktHdr.Sequence);
                        return;
                    }

                    // echo the packet to remove it from remote buffer
                    Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Echo, pktHdr.Sequence);
                    break;
                }
                }
                break;
            }

            // service messages
            case DtmPacketFlags.Service:
            {
                switch ((DtmServiceFlags)pktHdr.PacketFlag)
                {
                case DtmServiceFlags.Resend:
                {
                    // resend the packet
                    Resend(pktHdr);
                    break;
                }

                case DtmServiceFlags.Echo:
                {
                    // remove from local buffer
                    if (_sndBuffer.Exists(pktHdr.OptionFlag))
                    {
                        _sndBuffer.Destroy(pktHdr.OptionFlag);
                    }

                    break;
                }
                }
                break;
            }

            default:
            {
                throw new CryptoKeyExchangeException("DtmFileTransfer:Process", "The packet type is unknown!", new InvalidDataException());
            }
            }

            // notify parent
            if (PacketReceived != null)
            {
                PacketReceived(this, new DtmPacketArgs(pktHdr.PacketFlag, pktHdr.PayloadLength));
            }
        }
Esempio n. 6
0
        public void SendFile()
        {
            int              bytesRead = 0;
            long             len       = new FileInfo(_filePath).Length;
            DtmFileInfoSruct flHdr     = new DtmFileInfoSruct(_filePath, len, 0);
            int              ckSize    = _clientSocket.SendBufferSize - (flHdr.GetHeaderSize() + DtmPacketStruct.GetHeaderSize());

            byte[] inputBuffer = new byte[ckSize];

            try
            {
                using (FileStream inStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    // loop through file
                    while ((bytesRead = inStream.Read(inputBuffer, 0, ckSize)) > 0)
                    {
                        // wrap in a file info; option flag is used for payload length
                        flHdr.OptionsFlag = bytesRead;
                        byte[] hdrArr = flHdr.ToBytes();

                        // add data
                        if (bytesRead == ckSize)
                        {
                            hdrArr = ArrayUtils.Concat(hdrArr, inputBuffer);
                        }
                        else
                        {
                            hdrArr = ArrayUtils.Concat(hdrArr, ArrayUtils.GetRange(inputBuffer, 0, bytesRead));
                        }

                        // encrypt the header and data
                        byte[] enc = SymmetricTransform(_fileSymProcessor, hdrArr);
                        // send to the remote host
                        Transmit(DtmPacketFlags.Transfer, (short)DtmTransferFlags.DataChunk, _fileId, new MemoryStream(enc));
                        // increment counter
                        _bytesSent += bytesRead;

                        // progress
                        if (ProgressPercent != null)
                        {
                            double progress = 100.0 * (double)_bytesSent / inStream.Length;
                            ProgressPercent(this, new System.ComponentModel.ProgressChangedEventArgs((int)progress, (object)inStream.Length));
                        }
                    }
                }
                // notify app
                if (FileTransferred != null)
                {
                    FileTransferred(this, new DtmPacketArgs((short)DtmTransferFlags.Sent, _fileId));
                }
            }
            catch (Exception ex)
            {
                throw new CryptoFileTransferException("DtmFileTransfer:SendFile", "The file transfer did not complete!", ex);
            }
            finally
            {
                // flush
                SendFlush();
            }
        }
Esempio n. 7
0
        private void Receive(Stream PacketStream)
        {
            // get the packet header
            DtmPacketStruct prcPacket = new DtmPacketStruct(PacketStream);

            // read the packet
            byte[] enc = new byte[prcPacket.PayloadLength];
            // get the encrypted data
            PacketStream.Read(enc, 0, enc.Length);
            // decrypt it using file crypto processor
            byte[] dec = SymmetricTransform(_fileSymProcessor, enc);
            // get file info header
            DtmFileInfoSruct pktFi = new DtmFileInfoSruct(dec);
            // store file name and size
            string fileName  = pktFi.FileName;
            long   fileSize  = pktFi.FileSize;
            long   streamLen = 0;

            try
            {
                using (FileStream outStream = new FileStream(_tempPath, FileMode.Append, FileAccess.Write, FileShare.Read))
                {
                    // calculate offsets
                    int hdrSize = pktFi.GetHeaderSize();
                    int len     = dec.Length - hdrSize;
                    // write to file
                    outStream.Write(ArrayUtils.GetRange(dec, hdrSize, len), 0, len);
                    // store length
                    streamLen = outStream.Length;

                    // progress
                    if (ProgressPercent != null)
                    {
                        double progress = 100.0 * (double)pktFi.OptionsFlag / fileSize;
                        ProgressPercent(this, new System.ComponentModel.ProgressChangedEventArgs((int)progress, (object)fileSize));
                    }
                }

                // transfer completed
                if (streamLen == fileSize)
                {
                    // reset attributes
                    File.SetAttributes(_tempPath, File.GetAttributes(_tempPath) & ~FileAttributes.Hidden);
                    // rename the file
                    File.Move(_tempPath, VTDev.Libraries.CEXEngine.Tools.FileTools.GetUniqueName(_filePath));

                    // notify app
                    if (FileTransferred != null)
                    {
                        FileTransferred(this, new DtmPacketArgs((short)DtmTransferFlags.Received, prcPacket.OptionFlag));
                    }

                    // flush and close
                    ReceiveClose();
                }
            }
            catch (Exception ex)
            {
                throw new CryptoFileTransferException("DtmFileTransfer:Receive", "The file transfer did not complete!", ex);
            }
        }