Example #1
0
        /// <summary>
        /// Frame and Transmit the packet to the remote client
        /// </summary>
        /// 
        /// <param name="PacketType">The packet class</param>
        /// <param name="PacketFlag">The packet message type flag</param>
        /// <param name="OptionFlag">The option flag</param>
        /// <param name="Payload">The packet payload flag</param>
        /// <param name="Blocking">Blocking or Async transmit</param>
        private void Transmit(DtmPacketTypes PacketType, short PacketFlag, long OptionFlag = 0, MemoryStream Payload = null, bool Blocking = false)
        {
            lock (_sendLock)
            {
                long pldLen = Payload == null ? 0 : Payload.Length;
                // create a new packet: packet flag, payload size, sequence, and state flag
                MemoryStream pktStm = new DtmPacket(PacketType, pldLen, _sndSequence, PacketFlag, OptionFlag).ToStream();

                // add payload
                if (Payload != null)
                {
                    // store total encrypted bytes sent
                    if (_isEstablished)
                        _bytesSent += Payload.Length;

                    // copy to output
                    pktStm.Seek(0, SeekOrigin.End);
                    Payload.WriteTo(pktStm);
                    pktStm.Seek(0, SeekOrigin.Begin);
                }

                // service requests are not buffered
                if (PacketType != DtmPacketTypes.Service)
                {
                    // store in the packet buffer
                    _sndBuffer.Push(_sndSequence, pktStm);
                }

                // increment send counter
                _sndSequence++;

                // transmit to remote client
                if (_clientSocket.IsConnected)
                {
                    if (Blocking)
                    {
                        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, slow down
                                Throttle(pktStm);
                            }
                            else if (se.SocketErrorCode != SocketError.Success)
                            {
                                // possible connection dropped, alert app
                                if (SessionError != null)
                                {
                                    DtmErrorEventArgs args = new DtmErrorEventArgs(ce, DtmErrorSeverity.Connection);
                                    SessionError(this, args);

                                    if (args.Cancel == true)
                                        Disconnect();
                                }
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            pktStm.WriteTo(_clientSocket.TcpStream);
                        }
                        catch (Exception ex)
                        {
                            // internal error, alert app
                            if (SessionError != null)
                            {
                                DtmErrorEventArgs args = new DtmErrorEventArgs(ex, DtmErrorSeverity.Critical);
                                SessionError(this, args);

                                if (args.Cancel == true)
                                    Disconnect();
                            }
                        }
                    }

                    // notify app
                    if (PacketSent != null)
                        PacketSent(this, new DtmPacketEventArgs((short)_exchangeState, pldLen));
                }
                else
                {
                    // possible connection dropped, alert app
                    if (SessionError != null)
                    {
                        DtmErrorEventArgs args = new DtmErrorEventArgs(new SocketException((int)SocketError.ConnectionReset), DtmErrorSeverity.Connection);
                        SessionError(this, args);

                        if (args.Cancel == true)
                            Disconnect();
                    }
                }
            }
        }
Example #2
0
        private void Transmit(DtmPacketTypes 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 DtmPacket(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)
                            {
                                DtmErrorEventArgs args = new DtmErrorEventArgs(ce, DtmErrorSeverity.Connection);
                                SessionError(this, args);
                            }
                        }
                    }
                    catch (Exception)
                    {

                    }

                    // notify app
                    if (PacketSent != null)
                        PacketSent(this, new DtmPacketEventArgs((short)DtmTransferFlags.DataChunk, pldLen));
                }
            }
        }
Example #3
0
        /// <summary>
        /// Blocking transceiver; sends a packet and waits for a response.
        /// <para>For use with time sensitive data, that requires fast synchronous processing.
        /// Sent and received packets are not queued or buffered.</para>
        /// </summary>
        /// 
        /// <param name="DataStream">The payload data to send to the remote host</param>
        /// <param name="TimeOut">The number of milliseconds to wait before timing out (default is infinite)</param>
        /// 
        /// <returns>The return streams decrypted payload data, or an empty stream on failure</returns>
        public MemoryStream SendReceive(MemoryStream DataStream, int TimeOut = Timeout.Infinite)
        {
            if (!_isEstablished)
                throw new CryptoProcessingException("DtmKex:SendReceive", "The VPN is not established!", new InvalidOperationException());

            byte[] data = DataStream.ToArray();
            // append/prepend random
            data = WrapMessage(data, _dtmParameters.MaxMessageAppend, _dtmParameters.MaxMessagePrePend);
            // encrypt the data with the clients symmetric processor
            byte[] enc = SymmetricTransform(_srvSymProcessor, data);
            // store total bytes sent
            _bytesSent += enc.Length;

            // optional delay before transmission
            if (_dtmParameters.MaxMessageDelayMS > 0)
                SendWait(_dtmParameters.MaxMessageDelayMS);

            // create the packet
            MemoryStream pktStm = new DtmPacket(DtmPacketTypes.Message, enc.Length, _sndSequence, (short)DtmMessageFlags.Transmission).ToStream();
            pktStm.Seek(0, SeekOrigin.End);
            pktStm.Write(enc, 0, enc.Length);
            pktStm.Seek(0, SeekOrigin.Begin);
            // transmit data
            _clientSocket.Send(pktStm);
            _sndSequence++;

            // wait for response
            pktStm = BlockingReceive();
            // get the header
            DtmPacket dtmHdr = new DtmPacket(pktStm);
            // payload buffer
            data = new byte[dtmHdr.PayloadLength];
            // copy data to buffer
            pktStm.Write(data, 0, data.Length);
            // decrypt response
            data = SymmetricTransform(_cltSymProcessor, data);
            // remove padding
            data = UnwrapMessage(data);
            // increment rcv counter
            _rcvSequence++;
            // record encrypted byte count for resync
            _bytesReceived += dtmHdr.PayloadLength;

            return new MemoryStream(data);
        }
Example #4
0
 /// <summary>
 /// Creates a serialized request packet (DtmPacket)
 /// </summary>
 private MemoryStream CreateRequest(DtmPacketTypes Message, short State)
 {
     MemoryStream ret = new DtmPacket(Message, 0, 0, State).ToStream();
     ret.Seek(0, SeekOrigin.Begin);
     return ret;
 }