public override void Send(Stream stream, TimeSpan timeout, Information options)
{
if (_disposed) throw new ObjectDisposedException(this.GetType().FullName);
if (stream == null) throw new ArgumentNullException(nameof(stream));
if (stream.Length == 0) throw new ArgumentOutOfRangeException(nameof(stream));
if (!_connect) throw new ConnectionException();
lock (_sendLock)
{
try
{
using (RangeStream targetStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true))
{
if (_version.HasFlag(SecureConnectionVersion.Version3))
{
using (BufferStream bufferStream = new BufferStream(_bufferManager))
{
bufferStream.SetLength(8);
bufferStream.Seek(8, SeekOrigin.Begin);
if (_informationVersion3.CryptoAlgorithm.HasFlag(SecureVersion3.CryptoAlgorithm.Aes256))
{
byte[] iv = new byte[16];
_random.GetBytes(iv);
bufferStream.Write(iv, 0, iv.Length);
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (CryptoStream cs = new CryptoStream(new WrapperStream(bufferStream, true), aes.CreateEncryptor(_informationVersion3.MyCryptoKey, iv), CryptoStreamMode.Write))
using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4))
{
int length;
while ((length = targetStream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0)
{
cs.Write(safeBuffer.Value, 0, length);
}
}
}
}
else
{
throw new ConnectionException();
}
_totalSendSize += (bufferStream.Length - 8);
bufferStream.Seek(0, SeekOrigin.Begin);
byte[] totalSendSizeBuff = NetworkConverter.GetBytes(_totalSendSize);
bufferStream.Write(totalSendSizeBuff, 0, totalSendSizeBuff.Length);
if (_informationVersion3.HashAlgorithm.HasFlag(SecureVersion3.HashAlgorithm.Sha256))
{
bufferStream.Seek(0, SeekOrigin.Begin);
byte[] hmacBuff = HmacSha256.ComputeHash(bufferStream, _informationVersion3.MyHmacKey);
bufferStream.Seek(0, SeekOrigin.End);
bufferStream.Write(hmacBuff, 0, hmacBuff.Length);
}
else
{
throw new ConnectionException();
}
bufferStream.Seek(0, SeekOrigin.Begin);
_connection.Send(bufferStream, timeout, options);
}
}
else
{
throw new ConnectionException();
}
}
}
catch (ConnectionException e)
{
throw e;
}
catch (Exception e)
{
throw new ConnectionException(e.Message, e);
}
}
}