public void Test_BufferStream() { //for (int i = 0; i < 10; i++) Parallel.For(0, 32, new ParallelOptions() { MaxDegreeOfParallelism = 64 }, i => { //using (MemoryStream stream = new MemoryStream()) using (BufferStream stream = new BufferStream(_bufferManager)) { byte[] buffer = _bufferManager.TakeBuffer(1024 * 1024); //new byte[_random.Next(128, 1024 * 1024 * 10)]; long seek = _random.Next(64, buffer.Length); //long seek = 0; _random.NextBytes(buffer); stream.Write(buffer, 0, buffer.Length); stream.Position = seek; byte[] buff2 = _bufferManager.TakeBuffer(buffer.Length); //new byte[buffer.Length]; stream.Read(buff2, (int)seek, buff2.Length - (int)seek); if (!CollectionUtilities.Equals(buffer, (int)seek, buff2, (int)seek, buffer.Length - (int)seek)) { Assert.IsTrue(CollectionUtilities.Equals(buffer, (int)seek, buff2, (int)seek, buffer.Length - (int)seek)); } _bufferManager.ReturnBuffer(buffer); _bufferManager.ReturnBuffer(buff2); } }); using (MemoryStream mstream = new MemoryStream()) using (BufferStream stream = new BufferStream(_bufferManager)) { for (int i = 0; i < 1024 * 1024; i++) { var v = (byte)_random.Next(0, 255); mstream.WriteByte(v); stream.WriteByte(v); } mstream.Seek(0, SeekOrigin.Begin); stream.Seek(0, SeekOrigin.Begin); Assert.IsTrue(mstream.Length == stream.Length); for (int i = 0; i < 1024 * 1024; i++) { Assert.IsTrue(mstream.ReadByte() == stream.ReadByte()); } } }
public override System.IO.Stream Receive(TimeSpan timeout, Information options) { if (_disposed) throw new ObjectDisposedException(this.GetType().FullName); if (!_connect) throw new ConnectionException(); lock (_receiveLock) { Stream stream = null; try { stream = _connection.Receive(timeout, options); var version = (byte)stream.ReadByte(); Stream dataStream = null; try { dataStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position); if (version == (byte)0) { return dataStream; } else if (version == (byte)1) { BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(dataStream, CompressionMode.Decompress, true)) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 4)) { int length; while ((length = deflateStream.Read(safeBuffer.Value, 0, safeBuffer.Value.Length)) > 0) { deflateBufferStream.Write(safeBuffer.Value, 0, length); if (deflateBufferStream.Length > _maxReceiveCount) throw new ConnectionException(); } } } catch (Exception e) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } throw e; } #if DEBUG Debug.WriteLine("Receive : {0}→{1} {2}", NetworkConverter.ToSizeString(stream.Length), NetworkConverter.ToSizeString(deflateBufferStream.Length), NetworkConverter.ToSizeString(stream.Length - deflateBufferStream.Length)); #endif deflateBufferStream.Seek(0, SeekOrigin.Begin); dataStream.Dispose(); return deflateBufferStream; } else { throw new ArgumentException("ArgumentException"); } } catch (ConnectionException e) { if (dataStream != null) dataStream.Dispose(); throw e; } catch (Exception e) { if (dataStream != null) dataStream.Dispose(); throw new ConnectionException(e.Message, e); } } catch (ConnectionException e) { if (stream != null) stream.Dispose(); throw e; } catch (Exception e) { if (stream != null) stream.Dispose(); throw new ConnectionException(e.Message, e); } } }
public override void Connect(TimeSpan timeout, Information options) { if (_disposed) throw new ObjectDisposedException(this.GetType().FullName); lock (this.ThisLock) { try { var stopwatch = new Stopwatch(); stopwatch.Start(); using (BufferStream stream = new BufferStream(_bufferManager)) { byte[] buffer = NetworkConverter.GetBytes((uint)_myCompressAlgorithm); stream.Write(buffer, 0, buffer.Length); stream.Flush(); stream.Seek(0, SeekOrigin.Begin); _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout)); } using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout))) { byte[] buffer = new byte[4]; stream.Read(buffer, 0, buffer.Length); _otherCompressAlgorithm = (CompressAlgorithm)NetworkConverter.ToUInt32(buffer); } } catch (ConnectionException ex) { throw ex; } catch (Exception ex) { throw new ConnectionException(ex.Message, ex); } _connect = true; } }
public override void Send(Stream stream, TimeSpan timeout, Information options) { if (_disposed) throw new ObjectDisposedException(this.GetType().FullName); if (!_connect) throw new ConnectionException(); if (stream == null) throw new ArgumentNullException(nameof(stream)); if (stream.Length == 0) throw new ArgumentOutOfRangeException(nameof(stream)); lock (_sendLock) { using (RangeStream targetStream = new RangeStream(stream, stream.Position, stream.Length - stream.Position, true)) { try { _sendStopwatch.Restart(); Stream headerStream = new BufferStream(_bufferManager); headerStream.Write(NetworkConverter.GetBytes((int)targetStream.Length), 0, 4); using (Stream dataStream = new UniteStream(headerStream, new WrapperStream(targetStream, true))) using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 32)) { for (;;) { var sendLength = (int)Math.Min(dataStream.Length - dataStream.Position, safeBuffer.Value.Length); if (sendLength == 0) break; if (_bandwidthLimit != null && _bandwidthLimit.Out != 0) { sendLength = _bandwidthLimit.GetOutBandwidth(this, sendLength); if (sendLength < 0) throw new ConnectionException(); } dataStream.Read(safeBuffer.Value, 0, sendLength); var time = Connection.CheckTimeout(_sendStopwatch.Elapsed, timeout); time = (time < _sendTimeSpan) ? time : _sendTimeSpan; _cap.Send(safeBuffer.Value, 0, sendLength, time); _aliveStopwatch.Restart(); _sentByteCount.Add(sendLength); } } _aliveTimer.Change(1000 * 30); } catch (ConnectionException e) { throw e; } catch (Exception e) { throw new ConnectionException(e.Message, e); } } } }
public static string GetSignature(Certificate certificate) { if (certificate == null || certificate.Nickname == null || certificate.PublicKey == null) return null; try { if (certificate.DigitalSignatureAlgorithm == DigitalSignatureAlgorithm.EcDsaP521_Sha256 || certificate.DigitalSignatureAlgorithm == DigitalSignatureAlgorithm.Rsa2048_Sha256) { using (BufferStream bufferStream = new BufferStream(_bufferManager)) { Signature.WriteString(bufferStream, certificate.Nickname); bufferStream.Write(certificate.PublicKey, 0, certificate.PublicKey.Length); bufferStream.Seek(0, SeekOrigin.Begin); var signature = certificate.Nickname + "@" + NetworkConverter.ToBase64UrlString(Sha256.ComputeHash(bufferStream)); return _signatureCache.GetValue(signature, certificate); } } return null; } catch (Exception) { return null; } }
public override void Send(Stream stream, TimeSpan timeout, Information options) { if (_disposed) throw new ObjectDisposedException(this.GetType().FullName); if (stream == null) throw new ArgumentNullException("stream"); if (stream.Length == 0) throw new ArgumentOutOfRangeException("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)) { byte[] sendBuffer = null; try { sendBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = targetStream.Read(sendBuffer, 0, sendBuffer.Length)) > 0) { cs.Write(sendBuffer, 0, i); } } finally { if (sendBuffer != null) { _bufferManager.ReturnBuffer(sendBuffer); } } } } } 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); } } }
public override Stream Receive(TimeSpan timeout, Information options) { if (_disposed) throw new ObjectDisposedException(this.GetType().FullName); if (!_connect) throw new ConnectionException(); lock (_receiveLock) { try { _receiveStopwatch.Restart(); Restart:; int length = 0; { byte[] lengthBuffer = new byte[4]; var time = Connection.CheckTimeout(_receiveStopwatch.Elapsed, timeout); time = (time < _receiveTimeSpan) ? time : _receiveTimeSpan; _cap.Receive(lengthBuffer, time); _receivedByteCount.Add(4); length = NetworkConverter.ToInt32(lengthBuffer); } if (length == 0) { Thread.Sleep(300); goto Restart; } else if (length > _maxReceiveCount) { throw new ConnectionException(); } BufferStream bufferStream = null; try { bufferStream = new BufferStream(_bufferManager); using (var safeBuffer = _bufferManager.CreateSafeBuffer(1024 * 32)) { do { int receiveLength = Math.Min(safeBuffer.Value.Length, length); var time = Connection.CheckTimeout(_receiveStopwatch.Elapsed, timeout); time = (time < _receiveTimeSpan) ? time : _receiveTimeSpan; if (_bandwidthLimit != null && _bandwidthLimit.In != 0) { if (_cap.Available == 0) { Thread.Sleep(300); continue; } receiveLength = _bandwidthLimit.GetInBandwidth(this, Math.Min(_cap.Available, receiveLength)); if (receiveLength < 0) throw new ConnectionException(); } _cap.Receive(safeBuffer.Value, 0, receiveLength, time); _receivedByteCount.Add(receiveLength); bufferStream.Write(safeBuffer.Value, 0, receiveLength); length -= receiveLength; } while (length > 0); } } catch (Exception e) { if (bufferStream != null) { bufferStream.Dispose(); } throw e; } bufferStream.Seek(0, SeekOrigin.Begin); return bufferStream; } catch (ConnectionException e) { throw e; } catch (Exception e) { throw new ConnectionException(e.Message, e); } } }
private static Stream Encrypt(Stream stream, IExchangeEncrypt publicKey) { if (stream == null) throw new ArgumentNullException("stream"); if (publicKey == null) throw new ArgumentNullException("publicKey"); try { BufferStream outStream = null; try { outStream = new BufferStream(_bufferManager); outStream.WriteByte((byte)ConvertCryptoAlgorithm.Aes256); byte[] cryptoKey = new byte[32]; _random.GetBytes(cryptoKey); { var encryptedBuffer = Exchange.Encrypt(publicKey, cryptoKey); outStream.Write(NetworkConverter.GetBytes((int)encryptedBuffer.Length), 0, 4); outStream.Write(encryptedBuffer, 0, encryptedBuffer.Length); } byte[] iv = new byte[32]; _random.GetBytes(iv); outStream.Write(iv, 0, iv.Length); using (Stream inStream = new WrapperStream(stream, true)) { using (var rijndael = new RijndaelManaged() { KeySize = 256, BlockSize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) using (CryptoStream cs = new CryptoStream(inStream, rijndael.CreateEncryptor(cryptoKey, iv), CryptoStreamMode.Read)) { byte[] buffer = null; try { buffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = cs.Read(buffer, 0, buffer.Length)) > 0) { outStream.Write(buffer, 0, i); } } finally { if (buffer != null) { _bufferManager.ReturnBuffer(buffer); } } } } outStream.Seek(0, SeekOrigin.Begin); } catch (Exception) { if (outStream != null) { outStream.Dispose(); } throw; } return outStream; } catch (Exception e) { throw new ArgumentException(e.Message, e); } }
public static string GetSignature(DigitalSignature digitalSignature) { if (digitalSignature == null || digitalSignature.Nickname == null || digitalSignature.PublicKey == null) return null; try { if (digitalSignature.DigitalSignatureAlgorithm == DigitalSignatureAlgorithm.EcDsaP521_Sha256 || digitalSignature.DigitalSignatureAlgorithm == DigitalSignatureAlgorithm.Rsa2048_Sha256) { using (BufferStream bufferStream = new BufferStream(_bufferManager)) { Signature.WriteString(bufferStream, digitalSignature.Nickname); bufferStream.Write(digitalSignature.PublicKey, 0, digitalSignature.PublicKey.Length); bufferStream.Seek(0, SeekOrigin.Begin); return string.Concat(digitalSignature.Nickname, "@", NetworkConverter.ToBase64UrlString(Sha256.ComputeHash(bufferStream))); } } return null; } catch (Exception) { return null; } }
private static Stream Decrypt(Stream stream, IExchangeDecrypt privateKey) { if (stream == null) throw new ArgumentNullException("stream"); if (privateKey == null) throw new ArgumentNullException("privateKey"); try { byte type = (byte)stream.ReadByte(); if (type == (byte)ConvertCryptoAlgorithm.Aes256) { byte[] cryptoKey; { byte[] lengthBuffer = new byte[4]; if (stream.Read(lengthBuffer, 0, lengthBuffer.Length) != lengthBuffer.Length) throw new ArgumentException(); int length = NetworkConverter.ToInt32(lengthBuffer); byte[] encryptedBuffer = new byte[length]; if (stream.Read(encryptedBuffer, 0, encryptedBuffer.Length) != encryptedBuffer.Length) throw new ArgumentException(); cryptoKey = Exchange.Decrypt(privateKey, encryptedBuffer); } BufferStream outStream = null; try { outStream = new BufferStream(_bufferManager); using (Stream dataStream = new WrapperStream(stream, true)) { var iv = new byte[32]; dataStream.Read(iv, 0, iv.Length); using (var rijndael = new RijndaelManaged() { KeySize = 256, BlockSize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }) using (var inStream = new RangeStream(dataStream, dataStream.Position, dataStream.Length - dataStream.Position)) using (CryptoStream cs = new CryptoStream(inStream, rijndael.CreateDecryptor(cryptoKey, iv), CryptoStreamMode.Read)) { byte[] buffer = null; try { buffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = cs.Read(buffer, 0, buffer.Length)) > 0) { outStream.Write(buffer, 0, i); } } finally { _bufferManager.ReturnBuffer(buffer); } } } outStream.Seek(0, SeekOrigin.Begin); } catch (Exception) { if (outStream != null) { outStream.Dispose(); } throw; } return outStream; } throw new NotSupportedException(); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }
private static Stream Decompress(Stream stream) { if (stream == null) throw new ArgumentNullException("stream"); try { var targetStream = new RangeStream(stream, true); byte type = (byte)targetStream.ReadByte(); if (type == (byte)ConvertCompressionAlgorithm.None) { return new RangeStream(targetStream); } else if (type == (byte)ConvertCompressionAlgorithm.Deflate) { using (Stream dataStream = new WrapperStream(targetStream, true)) { BufferStream deflateBufferStream = null; try { deflateBufferStream = new BufferStream(_bufferManager); using (DeflateStream deflateStream = new DeflateStream(dataStream, CompressionMode.Decompress, true)) { byte[] decompressBuffer = null; try { decompressBuffer = _bufferManager.TakeBuffer(1024 * 4); int i = -1; while ((i = deflateStream.Read(decompressBuffer, 0, decompressBuffer.Length)) > 0) { deflateBufferStream.Write(decompressBuffer, 0, i); } } finally { if (decompressBuffer != null) { _bufferManager.ReturnBuffer(decompressBuffer); } } } deflateBufferStream.Seek(0, SeekOrigin.Begin); #if DEBUG Debug.WriteLine("ContentConverter Decompress {3} : {0}→{1} {2}", NetworkConverter.ToSizeString(dataStream.Length), NetworkConverter.ToSizeString(deflateBufferStream.Length), NetworkConverter.ToSizeString(dataStream.Length - deflateBufferStream.Length), ConvertCompressionAlgorithm.Deflate); #endif return deflateBufferStream; } catch (Exception) { if (deflateBufferStream != null) { deflateBufferStream.Dispose(); } } } } throw new ArgumentException("ArgumentException"); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }
private static Stream AddType(Stream stream, string type) { if (stream == null) throw new ArgumentNullException("stream"); List<Stream> streams = new List<Stream>(); Encoding encoding = new UTF8Encoding(false); // Type if (type != null) { BufferStream bufferStream = new BufferStream(_bufferManager); bufferStream.SetLength(4); bufferStream.Seek(4, SeekOrigin.Begin); using (WrapperStream wrapperStream = new WrapperStream(bufferStream, true)) using (StreamWriter writer = new StreamWriter(wrapperStream, encoding)) { writer.Write(type); } bufferStream.Seek(0, SeekOrigin.Begin); bufferStream.Write(NetworkConverter.GetBytes((int)bufferStream.Length - 4), 0, 4); streams.Add(bufferStream); } streams.Add(new WrapperStream(stream, true)); return new UniteStream(streams); }
private static Stream AddPadding(Stream stream, int size) { if (stream == null) throw new ArgumentNullException("stream"); try { byte[] seedBuffer = new byte[4]; _random.GetBytes(seedBuffer); Random random = new Random(NetworkConverter.ToInt32(seedBuffer)); BufferStream metadataStream = new BufferStream(_bufferManager); byte[] lengthBuffer = NetworkConverter.GetBytes((int)stream.Length); metadataStream.Write(lengthBuffer, 0, lengthBuffer.Length); int paddingLength = size - ((int)stream.Length + 4); BufferStream paddingStream = new BufferStream(_bufferManager); { byte[] buffer = null; try { buffer = _bufferManager.TakeBuffer(1024); while (paddingLength > 0) { int writeSize = Math.Min(paddingLength, buffer.Length); random.NextBytes(buffer); paddingStream.Write(buffer, 0, writeSize); paddingLength -= writeSize; } } finally { _bufferManager.ReturnBuffer(buffer); } } return new UniteStream(metadataStream, new WrapperStream(stream, true), paddingStream); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }
private static Stream AddHash(Stream stream) { if (stream == null) throw new ArgumentNullException("stream"); try { var targetStream = new RangeStream(stream, true); BufferStream metadataStream = new BufferStream(_bufferManager); metadataStream.WriteByte((byte)ConvertHashAlgorithm.Sha256); targetStream.Seek(0, SeekOrigin.Begin); var hash = Sha256.ComputeHash(targetStream); BufferStream hashStream = new BufferStream(_bufferManager); hashStream.Write(hash, 0, hash.Length); return new UniteStream(metadataStream, targetStream, hashStream); } catch (Exception e) { throw new ArgumentException(e.Message, e); } }