/// <summary>Reads a new <see cref="WaveFormatChunk"/> from the specified stream.</summary> /// <param name="preRead">Pre-parsed <see cref="RiffChunk"/> header.</param> /// <param name="source">Source stream to read data from.</param> /// <exception cref="InvalidOperationException">WAVE format or extra parameters section too small, wave file corrupted.</exception> /// <exception cref="InvalidDataException">Invalid bit rate encountered - wave file bit rates must be a multiple of 8.</exception> public WaveFormatChunk(RiffChunk preRead, Stream source) : base(preRead, RiffTypeID) { int length = ChunkSize; byte[] buffer = BufferPool.TakeBuffer(length); try { int bytesRead = source.Read(buffer, 0, length); // Initialize class from buffer ParseBinaryImage(buffer, 0, bytesRead); // Read extra parameters, if any if (m_extraParametersSize > 0) { m_extraParameters = new byte[m_extraParametersSize]; bytesRead = source.Read(m_extraParameters, 0, m_extraParametersSize); if (bytesRead < m_extraParametersSize) { throw new InvalidOperationException("WAVE extra parameters section too small, wave file corrupted"); } } } finally { if (buffer != null) { BufferPool.ReturnBuffer(buffer); } } }
private static void SpinCrcComputations(BlockingCollection <CrcComputationWork> crcComputationWork) { // These computation actors will perform the actual CRC computation, we can // probably optimize the CRC routine, but it is cheaper to just run it on multiple threads instead // of going to near assembly in managed code. // Our costs are going to be in the I/O mostly, anyway. for (int i = 0; i < Math.Max(4, Environment.ProcessorCount); i++) { Task.Factory.StartNew(() => { while (true) { var work = crcComputationWork.Take(); try { var crc = work.Crc(); Console.WriteLine("{0} = {1:x}", work.FileName, crc); } finally { // Now it goes back to the pool, and can be used again foreach (var buffer in work.Buffers) { BufferPool.ReturnBuffer(buffer); } } } }); } }
protected static void UpdateRecordMacLength(IMac mac, int len) { byte[] longLen = BufferPool.GetBuffer(8); Pack.UInt64_To_LE((ulong)len, longLen); mac.BlockUpdate(longLen, 0, longLen.Length); BufferPool.ReturnBuffer(longLen); }
// Static Methods /// <summary> /// Attempts to read the next RIFF chunk from the <paramref name="source"/> stream. /// </summary> /// <param name="source">Source stream for next RIFF chunk.</param> /// <returns>Next RIFF chunk read from the <paramref name="source"/> stream.</returns> /// <exception cref="InvalidOperationException">RIFF chunk too small, media file corrupted.</exception> public static RiffChunk ReadNext(Stream source) { RiffChunk riffChunk = new RiffChunk(); int length = riffChunk.BinaryLength; byte[] buffer = BufferPool.TakeBuffer(length); try { int bytesRead = source.Read(buffer, 0, length); if (bytesRead < length) { throw new InvalidOperationException("RIFF chunk too small, media file corrupted"); } riffChunk.TypeID = Encoding.ASCII.GetString(buffer, 0, 4); riffChunk.ChunkSize = EndianOrder.LittleEndian.ToInt32(buffer, 4); return(riffChunk); } finally { if (buffer != null) { BufferPool.ReturnBuffer(buffer); } } }
// Encrypt a private connect token public static int EncryptPrivateConnectToken(byte[] privateConnectToken, ulong protocolID, ulong expireTimestamp, ulong sequence, byte[] key, byte[] outBuffer) { int len = privateConnectToken.Length; byte[] additionalData = BufferPool.GetBuffer(Defines.NETCODE_VERSION_INFO_BYTES + 8 + 8); using (var writer = ByteArrayReaderWriter.Get(additionalData)) { writer.WriteASCII(Defines.NETCODE_VERSION_INFO_STR); writer.Write(protocolID); writer.Write(expireTimestamp); } byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(sequence); } var ret = CryptoUtils.Encrypt(privateConnectToken, 0, len - Defines.MAC_SIZE, additionalData, nonce, key, outBuffer); BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
public bool Read(ByteArrayReaderWriter stream, int length, byte[] key, ulong protocolID) { if (length != 8 + Defines.MAC_SIZE) { return(false); } byte[] tempBuffer = BufferPool.GetBuffer(length); try { PacketIO.ReadPacketData(Header, stream, length, protocolID, key, tempBuffer); } catch { BufferPool.ReturnBuffer(tempBuffer); return(false); } using (var dataReader = ByteArrayReaderWriter.Get(tempBuffer)) { ClientIndex = dataReader.ReadUInt32(); MaxSlots = dataReader.ReadUInt32(); } return(true); }
public bool Read(ByteArrayReaderWriter stream, int length, byte[] key, ulong protocolID) { byte[] packetBuffer = BufferPool.GetBuffer(8 + 300 + Defines.MAC_SIZE); int packetLen = 0; try { packetLen = PacketIO.ReadPacketData(Header, stream, length, protocolID, key, packetBuffer); } catch (System.Exception e) { BufferPool.ReturnBuffer(packetBuffer); return(false); } if (packetLen != 308) { BufferPool.ReturnBuffer(packetBuffer); return(false); } ChallengeTokenBytes = BufferPool.GetBuffer(300); using (var reader = ByteArrayReaderWriter.Get(packetBuffer)) { ChallengeTokenSequence = reader.ReadUInt64(); reader.ReadBytesIntoBuffer(ChallengeTokenBytes, 300); } BufferPool.ReturnBuffer(packetBuffer); return(true); }
public async Task <byte[]> Decompress(byte[] compressedArray, int bufferSize) { using (var stream = new MemoryStream(compressedArray)) using (var decompressor = new DeflateStream(stream, CompressionMode.Decompress)) { var buffer = BufferPool.GetBuffer(bufferSize); try { using (var output = new MemoryStream()) { int read; while ((read = await decompressor.ReadAsync(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, read); } return(output.ToArray()); } } finally { BufferPool.ReturnBuffer(buffer); } } }
/// <summary> /// Decrypt a challenge token /// </summary> public static int DecryptChallengeToken(ulong sequenceNum, byte[] packetData, byte[] key, byte[] outBuffer) { byte[] additionalData = BufferPool.GetBuffer(0); byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(sequenceNum); } int ret; try { ret = CryptoUtils.Decrypt(packetData, 0, 300, additionalData, nonce, key, outBuffer); } catch (Exception e) { BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); throw e; } BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
// encrypts a packet and sends it to the endpoint private void sendPacketToClient(NetcodePacketHeader packetHeader, byte[] packetData, int packetDataLen, EndPoint endpoint, byte[] key) { // assign a sequence number to this packet packetHeader.SequenceNumber = this.nextSequenceNumber++; // encrypt packet data byte[] encryptedPacketBuffer = BufferPool.GetBuffer(2048); int encryptedBytes = PacketIO.EncryptPacketData(packetHeader, protocolID, packetData, packetDataLen, key, encryptedPacketBuffer); int packetLen = 0; // write packet to byte array var packetBuffer = BufferPool.GetBuffer(2048); using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer)) { packetHeader.Write(packetWriter); packetWriter.WriteBuffer(encryptedPacketBuffer, encryptedBytes); packetLen = (int)packetWriter.WritePosition; } // send packet listenSocket.SendTo(packetBuffer, packetLen, endpoint); BufferPool.ReturnBuffer(packetBuffer); BufferPool.ReturnBuffer(encryptedPacketBuffer); }
/// <summary> /// Copy streams asynchronously /// </summary> /// <param name="input"></param> /// <param name="output"></param> /// <param name="onCopy"></param> /// <param name="bufferSize"></param> /// <param name="cancellationToken"></param> internal static async Task CopyToAsync(this Stream input, Stream output, Action <byte[], int, int> onCopy, int bufferSize, CancellationToken cancellationToken) { byte[] buffer = BufferPool.GetBuffer(bufferSize); try { while (!cancellationToken.IsCancellationRequested) { // cancellation is not working on Socket ReadAsync // https://github.com/dotnet/corefx/issues/15033 int num = await input.ReadAsync(buffer, 0, buffer.Length, CancellationToken.None).WithCancellation(cancellationToken); int bytesRead; if ((bytesRead = num) != 0 && !cancellationToken.IsCancellationRequested) { await output.WriteAsync(buffer, 0, bytesRead, CancellationToken.None); onCopy?.Invoke(buffer, 0, bytesRead); } else { break; } } } finally { BufferPool.ReturnBuffer(buffer); } }
/// <summary> /// Decrypt a packet's data /// </summary> public static int DecryptPacketData(NetcodePacketHeader header, ulong protocolID, byte[] packetData, int packetDataLen, byte[] key, byte[] outBuffer) { byte[] additionalData = BufferPool.GetBuffer(Defines.NETCODE_VERSION_INFO_BYTES + 8 + 1); using (var writer = ByteArrayReaderWriter.Get(additionalData)) { writer.WriteASCII(Defines.NETCODE_VERSION_INFO_STR); writer.Write(protocolID); writer.Write(header.ReadSequenceByte); } byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(header.SequenceNumber); } int ret; try { ret = AEAD_Chacha20_Poly1305.Decrypt(packetData, 0, packetDataLen, additionalData, nonce, key, outBuffer); } catch (Exception e) { BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); throw e; } BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
/// <summary> /// Resets <see cref="TransportProvider{T}"/>. /// </summary> public void Reset() { if (m_receiveBuffer != null) { BufferPool.ReturnBuffer(m_receiveBuffer); } m_receiveBuffer = null; m_receiveBufferSize = 0; m_sendBuffer = null; BytesReceived = -1; // Reset the statistics. Statistics.Reset(); // Cleanup the provider. try { if ((object)Provider != null) { ((IDisposable)Provider).Dispose(); } } catch { // Ignore encountered exception during dispose. } finally { Provider = default(T); } }
public void Dispose() { if (!disposed) { disposed = true; BufferPool.ReturnBuffer(Buffer); } }
public void Return() { if (_pool != null) { _pool.ReturnBuffer(ref _buffer); _count = 0; } }
private static void SpinFileReaders(BlockingCollection <ReadFileWork> readFileWork, BlockingCollection <CrcComputationWork> crcComputationWork) { // These I/O Actors allows us to parallelize all the I/O work. On slow / cloud machines, that allows the I/O subsystem to get // bulk read speed from the underlying systems. for (int i = 0; i < Environment.ProcessorCount; i++) { Task.Factory.StartNew(() => { while (true) { var work = readFileWork.Take(); var fileInfo = new FileInfo(work.FileName); // some buffers can be very large, we will use consistent 16KB buffers // and if the file is too large, we will use multiple 16KB buffers. // For a file that is 260 KB (jQuery 1.8.3 is 261.46 KB) in size, that means we will use 272 KB only, // versus the 512KB we would use if we used a power of two approach. // So we'll waste only 12KB instead of 252KB var buffers = new List <byte[]>(); try { const int bufferSize = 16 * 1024; using (var fs = fileInfo.OpenRead()) { for (int j = 0; j < fileInfo.Length; j += bufferSize) { var buffer = BufferPool.GetBuffer(bufferSize); buffers.Add(buffer); // we can't call fs.Read here, it will allocate a 4KB buffer that will then be discarded. // so we use the native ReadFile method and read directly to our pooled buffer int read; if (ReadFile(fs.SafeFileHandle, buffer, buffer.Length, out read, IntPtr.Zero) == false) { throw new Win32Exception(); } } } } catch (Exception) { // If there has ben any error in reading from the file or opening it, we've have // to make sure that we won't forget about this buffer. Even with the error that just // happened, we can still make use of it. foreach (var buffer in buffers) { BufferPool.ReturnBuffer(buffer); } throw; } crcComputationWork.Add(new CrcComputationWork { Length = (int)fileInfo.Length, Buffers = buffers, // the SpinCrcComputations will be returning the bufer to the ppol FileName = work.FileName }); } }); } }
public void Dispose() { if (!disposed) { disposed = true; var buf = buffer; buffer = null; BufferPool.ReturnBuffer(buf); } }
public void BufferPool() { BufferPool bp = new BufferPool(10000); int ct = 1000; for (int i = 0; i < ct; i++) { byte[] b = bp.GetBuffer(); Assert.AreEqual(10000, b.Length); bp.ReturnBuffer(b); } Console.WriteLine("{0} allocations for {1} uses of buffer pool.", bp.NumAllocations, ct); }
// sends a connection challenge packet to the endpoint private void sendConnectionChallenge(NetcodePrivateConnectToken connectToken, EndPoint endpoint) { log("Sending connection challenge", NetcodeLogLevel.Debug); var challengeToken = new NetcodeChallengeToken(); challengeToken.ClientID = connectToken.ClientID; challengeToken.UserData = connectToken.UserData; ulong challengeSequence = nextChallengeSequenceNumber++; byte[] tokenBytes = BufferPool.GetBuffer(300); using (var tokenWriter = ByteArrayReaderWriter.Get(tokenBytes)) challengeToken.Write(tokenWriter); byte[] encryptedToken = BufferPool.GetBuffer(300); int encryptedTokenBytes; try { encryptedTokenBytes = PacketIO.EncryptChallengeToken(challengeSequence, tokenBytes, challengeKey, encryptedToken); } catch { BufferPool.ReturnBuffer(tokenBytes); BufferPool.ReturnBuffer(encryptedToken); return; } var challengePacket = new NetcodeConnectionChallengeResponsePacket(); challengePacket.ChallengeTokenSequence = challengeSequence; challengePacket.ChallengeTokenBytes = encryptedToken; var cryptIdx = encryptionManager.FindEncryptionMapping(endpoint, time); if (cryptIdx == -1) { return; } var cryptKey = encryptionManager.GetSendKey(cryptIdx); serializePacket(new NetcodePacketHeader() { PacketType = NetcodePacketType.ConnectionChallenge }, (writer) => { challengePacket.Write(writer); }, endpoint, cryptKey); BufferPool.ReturnBuffer(tokenBytes); BufferPool.ReturnBuffer(encryptedToken); }
public bool Read(byte[] token, byte[] key, ulong protocolID, ulong expiration, ulong sequence) { byte[] tokenBuffer = BufferPool.GetBuffer(Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES); int tokenLen = 0; try { tokenLen = PacketIO.DecryptPrivateConnectToken(token, protocolID, expiration, sequence, key, tokenBuffer); } catch { BufferPool.ReturnBuffer(tokenBuffer); return(false); } try { using (var reader = ByteArrayReaderWriter.Get(tokenBuffer)) { this.ClientID = reader.ReadUInt64(); this.TimeoutSeconds = (int)reader.ReadUInt32(); uint numServerAddresses = reader.ReadUInt32(); if (numServerAddresses == 0 || numServerAddresses > Defines.MAX_SERVER_ADDRESSES) { BufferPool.ReturnBuffer(tokenBuffer); return(false); } this.ConnectServers = new ConnectTokenServerEntry[numServerAddresses]; for (int i = 0; i < numServerAddresses; i++) { this.ConnectServers[i] = new ConnectTokenServerEntry(); this.ConnectServers[i].ReadData(reader); } ClientToServerKey = new byte[32]; ServerToClientKey = new byte[32]; UserData = new byte[256]; reader.ReadBytesIntoBuffer(ClientToServerKey, 32); reader.ReadBytesIntoBuffer(ServerToClientKey, 32); reader.ReadBytesIntoBuffer(UserData, 256); } } catch { BufferPool.ReturnBuffer(tokenBuffer); return(false); } return(true); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream" /> and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!disposed) { disposed = true; baseStream.Dispose(); BufferPool.ReturnBuffer(streamBuffer); streamBuffer = null; #if NET45 readCallback = null; #endif } }
private void serializePacket(NetcodePacketHeader packetHeader, Action <ByteArrayReaderWriter> write, byte[] key) { byte[] tempPacket = BufferPool.GetBuffer(2048); int writeLen = 0; using (var writer = ByteArrayReaderWriter.Get(tempPacket)) { write(writer); writeLen = (int)writer.WritePosition; } sendPacket(packetHeader, tempPacket, writeLen, key); BufferPool.ReturnBuffer(tempPacket); }
public void SendAck(byte channelID) { ushort ack; uint ackBits; receivedPackets.GenerateAckBits(out ack, out ackBits); byte[] transmitData = BufferPool.GetBuffer(16); int headerBytes = PacketIO.WriteAckPacket(transmitData, channelID, ack, ackBits); config.TransmitPacketCallback(transmitData, headerBytes); BufferPool.ReturnBuffer(transmitData); }
public static int Encrypt(byte[] plaintext, int offset, int len, byte[] additionalData, byte[] nonce, byte[] key, byte[] outBuffer) { lock (mutex) { if (cipher == null) { cipher = new ChaCha7539Engine(); } else { cipher.Reset(); } if (_encryptKey == null) { _encryptKey = new KeyParameter(key); } else { _encryptKey.Reset(); _encryptKey.SetKey(key); } if (_temp_Params == null) { _temp_Params = new ParametersWithIV(_encryptKey, nonce); } else { _temp_Params.Reset(); _temp_Params.Set(_encryptKey, nonce); } cipher.Init(true, _temp_Params); byte[] firstBlock = BufferPool.GetBuffer(64); KeyParameter macKey = GenerateRecordMacKey(cipher, firstBlock); cipher.ProcessBytes(plaintext, offset, len, outBuffer, 0); byte[] mac = BufferPool.GetBuffer(16); int macsize = CalculateRecordMac(macKey, additionalData, outBuffer, 0, len, mac); Array.Copy(mac, 0, outBuffer, len, macsize); BufferPool.ReturnBuffer(mac); BufferPool.ReturnBuffer(firstBlock); return(len + 16); } }
/// <summary> /// Writes a byte to the current position in the stream and advances the position within the stream by one byte. /// </summary> /// <param name="value">The byte to write to the stream.</param> public override void WriteByte(byte value) { var buffer = BufferPool.GetBuffer(BufferSize); try { buffer[0] = value; OnDataWrite(buffer, 0, 1); baseStream.Write(buffer, 0, 1); } finally { BufferPool.ReturnBuffer(buffer); } }
public void SendAck(byte channelID) { ushort ack; uint ackBits; lock (receivedPackets) { receivedPackets.GenerateAckBits(out ack, out ackBits); } byte[] buffer = BufferPool.GetBuffer(16); int arg = PacketIO.WriteAckPacket(buffer, channelID, ack, ackBits); config.TransmitPacketCallback(buffer, arg); BufferPool.ReturnBuffer(buffer); }
private void sendConnectionRequest(EndPoint server) { byte[] packetBuffer = BufferPool.GetBuffer(1 + 13 + 8 + 8 + 8 + Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES); using (var stream = ByteArrayReaderWriter.Get(packetBuffer)) { stream.Write((byte)0); stream.WriteASCII(Defines.NETCODE_VERSION_INFO_STR); stream.Write(connectToken.ProtocolID); stream.Write(connectToken.ExpireTimestamp); stream.Write(connectToken.ConnectTokenSequence); stream.Write(connectToken.PrivateConnectTokenBytes); } socket.SendTo(packetBuffer, server); BufferPool.ReturnBuffer(packetBuffer); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream" /> and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!disposed) { disposed = true; closed = true; if (!leaveOpen) { baseStream.Dispose(); } var buffer = streamBuffer; streamBuffer = null; BufferPool.ReturnBuffer(buffer); } }
/// <summary> /// Establishes (or reestablishes) a receive buffer of a given size. /// </summary> /// <param name="size">Desired minimum size of receive buffer.</param> /// <returns>New receive buffer.</returns> public byte[] SetReceiveBuffer(int size) { if (size != m_receiveBufferSize) { if (m_receiveBuffer != null) { BufferPool.ReturnBuffer(m_receiveBuffer); } // Take a buffer from the pool of the desired size m_receiveBuffer = BufferPool.TakeBuffer(size); // The buffer returned may be bigger than the requested size, but only the specified size will be usable m_receiveBufferSize = size; } return(m_receiveBuffer); }
public override void EnsureSize(int size) { if (this.Size < size) { if (this.autoGrow) { byte[] newBuffer = BufferPool.TakeBuffer(this.capacity * 2); System.Buffer.BlockCopy(this.buffer, this.start, newBuffer, 0, this.Length); BufferPool.ReturnBuffer(this.buffer); this.buffer = newBuffer; this.capacity = newBuffer.Length; } else { throw new InvalidOperationException("EnsureSize"); } } }
/// <summary> /// Read and decrypt packet data into an output buffer /// </summary> public static int ReadPacketData(NetcodePacketHeader header, ByteArrayReaderWriter stream, int length, ulong protocolID, byte[] key, byte[] outputBuffer) { byte[] encryptedBuffer = BufferPool.GetBuffer(2048); stream.ReadBytesIntoBuffer(encryptedBuffer, length); int decryptedBytes; try { decryptedBytes = DecryptPacketData(header, protocolID, encryptedBuffer, length, key, outputBuffer); } catch (Exception e) { BufferPool.ReturnBuffer(encryptedBuffer); throw e; } return(decryptedBytes); }