private string _tempPath = ""; // temp file path #endregion Fields #region Constructors public DtmFileTransfer(ICipherMode Cipher, long FileId = 0, int BufferCount = 1024, int BufferSize = 262144) { _fileSymProcessor = Cipher; _fileId = FileId; _rcvBuffer = new PacketBuffer(BufferCount); _sndBuffer = new PacketBuffer(BufferCount); _bufferSize = BufferSize; _bufferCount = BufferCount; }
/// <summary> /// Disconnect from the remote host and teardown the connection /// </summary> public void Disconnect() { _isEstablished = false; _isDisconnecting = true; // stop sending keepalives StopPulse(); try { if (_clientSocket.IsConnected) { Transmit(DtmPacketTypes.Service, (short)DtmServiceFlags.Terminate, 0, null, true); _clientSocket.TcpStream.Flush(); _clientSocket.Close(); } } catch { } try { if (_clientSocket != null) { _clientSocket.Dispose(); _clientSocket = null; } if (_evtSendWait != null) { _evtSendWait.Dispose(); _evtSendWait = null; } if (_rcvBuffer != null) { _rcvBuffer.Dispose(); _rcvBuffer = null; } if (_sndBuffer != null) { _sndBuffer.Dispose(); _sndBuffer = null; } } catch { } try { TearDown(); } catch (Exception ex) { if (SessionError != null) SessionError(this, new DtmErrorEventArgs(new CryptoProcessingException("DtmKex:Disconnect", "The tear down operation experienced an error!", ex), DtmErrorSeverity.Warning)); } finally { if (Disconnected != null) Disconnected(this); } }
/// <summary> /// Initialize this class with a random generator /// </summary> /// /// <param name="Parameters">A populated <see cref="DtmParameters"/> class containing the session parameters</param> /// <param name="Host">A populated <see cref="DtmClient"/> class containing the servers identity data</param> /// <param name="Generator">The initialized <see cref="IRandom"/> Prng instance</param> /// <param name="BufferCount">The number of send/receive buffers, default is 1024</param> /// <param name="DisposeEngines">if set to true (default), the primary symmetric ciphers are disposed when this class is disposed</param> public DtmKex(DtmParameters Parameters, DtmClient Host, IRandom Generator, int BufferCount = 1024, bool DisposeEngines = true) { _disposeEngines = DisposeEngines; _dtmParameters = Parameters; _dtmHost = Host; _srvIdentity = new DtmIdentity(Host.PublicId, Parameters.AuthPkeId, Parameters.AuthSession, 0); _exchangeState = DtmExchangeFlags.Connect; _rcvBuffer = new PacketBuffer(BufferCount); _sndBuffer = new PacketBuffer(BufferCount); _rndGenerator = Generator; _bufferCount = BufferCount; }
/// <summary> /// Processes and queues incoming packets /// </summary> private void ProcessAndPush(PacketBuffer Buffer, MemoryStream PacketStream) { int hdrLen = DtmPacket.GetHeaderSize(); int pktLen = 0; // process the whole packet PacketStream.Seek(0, SeekOrigin.Begin); // get the header DtmPacket dtmPkt = new DtmPacket(PacketStream); PacketStream.Seek(0, SeekOrigin.Begin); // track high sequence number, filters corrupt packets if (dtmPkt.Sequence > _seqCounter && dtmPkt.PayloadLength < MAXRCVBUFFER && dtmPkt.OptionFlag < 1000) _seqCounter = dtmPkt.Sequence; // out of sync, possible packet loss if (_seqCounter - _rcvSequence > ResendThreshold) { // request a retransmission Transmit(DtmPacketTypes.Service, (short)DtmServiceFlags.Resend, _rcvSequence + 1); } if (dtmPkt.PayloadLength + hdrLen == PacketStream.Length) { // resend was already processed if (dtmPkt.Sequence < _rcvSequence) return; // push onto buffer Buffer.Push(dtmPkt.Sequence, PacketStream); } // more than one packet else if (dtmPkt.PayloadLength + hdrLen < PacketStream.Length) { byte[] buffer; long pos = 0; do { // get packet position and size pos = PacketStream.Position; if (PacketStream.Length - pos < DtmPacket.GetHeaderSize()) { // next packet corrupted, request a retransmission and exit Transmit(DtmPacketTypes.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1); return; } dtmPkt = new DtmPacket(PacketStream); pktLen = (int)(hdrLen + dtmPkt.PayloadLength); if (pktLen > MAXRCVBUFFER || pktLen < 0 || PacketStream.Length - pos < pktLen) { // packet corrupted, request a retransmission and exit Transmit(DtmPacketTypes.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(dtmPkt.Sequence, new MemoryStream(buffer)); } } while (PacketStream.Position < PacketStream.Length); } // malformed packet, send retransmit request else if (dtmPkt.PayloadLength > MAXRCVBUFFER || dtmPkt.PayloadLength < 0 || dtmPkt.PayloadLength + hdrLen > PacketStream.Length) { // packet corrupted, request a retransmission of last in queue + 1 Transmit(DtmPacketTypes.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1); } }