async Task DoReceive(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; var data = new byte [16384]; new Random().NextBytes(data); int sent = 0; var buffer = new byte [data.Length]; var task = NetworkIO.ReceiveAsync(Outgoing, buffer, 0, buffer.Length, null, null, null); while (sent != buffer.Length) { int r = await Incoming.SendAsync(data, sent, data.Length - sent); Assert.AreNotEqual(0, r, "#Received data"); sent += r; } Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(10)), "Data should be all received"); for (int i = 0; i < buffer.Length; i++) { if (data[i] != buffer[i]) { Assert.Fail("Buffers differ at position " + i); } } }
async Task DoReceive(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; var data = new ByteBuffer(16384); new Random().NextBytes(data.Data); int sent = 0; var buffer = new ByteBuffer(data.Data.Length); var task = NetworkIO.ReceiveAsync(Outgoing, buffer, 0, buffer.Data.Length, null, null, null); while (sent != buffer.Data.Length) { int r = await Incoming.SendAsync(data, sent, data.Data.Length - sent); Assert.AreNotEqual(0, r, "#Received data"); sent += r; } await task.WithTimeout(TimeSpan.FromSeconds(10)); for (int i = 0; i < buffer.Data.Length; i++) { if (data.Data[i] != buffer.Data[i]) { Assert.Fail($"Buffers differ at position {i}"); } } }
public static async ReusableTask <(PeerMessage message, PeerMessage.Releaser releaser)> ReceiveMessageAsync(IPeerConnection connection, IEncryption decryptor, IRateLimiter?rateLimiter, ConnectionMonitor?peerMonitor, ConnectionMonitor?managerMonitor, ITorrentManagerInfo?torrentData, Memory <byte> buffer) { await MainLoop.SwitchToThreadpool(); int messageHeaderLength = 4; int messageBodyLength; Memory <byte> messageHeaderBuffer = buffer; Memory <byte> messageBuffer = buffer; ByteBufferPool.Releaser messageHeaderReleaser = default; ByteBufferPool.Releaser messageBufferReleaser = default; if (messageHeaderBuffer.IsEmpty) { messageHeaderReleaser = NetworkIO.BufferPool.Rent(messageHeaderLength, out messageHeaderBuffer); } using (messageHeaderReleaser) { await NetworkIO.ReceiveAsync(connection, messageHeaderBuffer.Slice(0, messageHeaderLength), rateLimiter, peerMonitor?.ProtocolDown, managerMonitor?.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageHeaderBuffer.Span.Slice(0, messageHeaderLength)); messageBodyLength = Message.ReadInt(messageHeaderBuffer.Span); if (messageBodyLength < 0 || messageBodyLength > MaxMessageLength) { connection.Dispose(); throw new ProtocolException($"Invalid message length received. Value was '{messageBodyLength}'"); } if (messageBodyLength == 0) { return(KeepAliveMessage.Instance, default);
async Task DoReceive(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; using var r1 = MemoryPool.Default.Rent(16384, out Memory <byte> data); using var r2 = MemoryPool.Default.Rent(16384, out Memory <byte> buffer); new Random().NextBytes(data.Span); int sent = 0; var task = NetworkIO.ReceiveAsync(Outgoing, buffer, null, null, null); while (sent != buffer.Length) { int r = await Incoming.SendAsync(data.Slice(sent)); Assert.AreNotEqual(0, r, "#Received data"); sent += r; } await task.WithTimeout(TimeSpan.FromSeconds(10)); for (int i = 0; i < buffer.Length; i++) { if (!data.Span.SequenceEqual(buffer.Span)) { Assert.Fail($"Buffers differ at position {i}"); } } }
public void ZeroSentClosesConnection() { using var releaser = MemoryPool.Default.Rent(100, out Memory <byte> buffer); Incoming.ManualBytesSent = 0; var task = NetworkIO.SendAsync(Incoming, buffer, null, null, null); _ = NetworkIO.ReceiveAsync(Outgoing, buffer, null, null, null); Assert.ThrowsAsync <ConnectionClosedException> (async() => await task); }
public void ZeroSentClosesConnection() { var data = new ByteBuffer(100); Incoming.ManualBytesSent = 0; var task = NetworkIO.SendAsync(Incoming, data, 0, data.Data.Length, null, null, null); _ = NetworkIO.ReceiveAsync(Outgoing, data, 0, data.Data.Length, null, null, null); Assert.ThrowsAsync <ConnectionClosedException> (async() => await task); }
public void ZeroSentClosesConnection() { var data = new byte[100]; Incoming.ManualBytesSent = 0; var task = NetworkIO.SendAsync(Incoming, data, 0, data.Length, null, null, null); _ = NetworkIO.ReceiveAsync(Outgoing, data, 0, data.Length, null, null, null); Assert.ThrowsAsync <Exception> (() => task); }
public async Task ZeroSentClosesConnection() { Incoming.ManualBytesSent = 0; var task = NetworkIO.SendAsync(Incoming, data, 0, 100, null, null, null); _ = NetworkIO.ReceiveAsync(Outgoing, data, 0, 100, null, null, null); try { await task; } catch { } Assert.IsTrue(task.IsFaulted); }
public async Task RecieveFirst() { byte[] buffer = new byte[1024 * 1024 * 3]; var receiveTask = NetworkIO.ReceiveAsync(connection, buffer, 0, 4, null, null, null); var task = Send(requests.Encode(), 0, requests.ByteLength); await CompleteSendOrReceiveFirst(buffer, receiveTask.ContinueWith(t => 4)); await task; }
public static async ReusableTask <PeerMessage> ReceiveMessageAsync(IConnection connection, IEncryption decryptor, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor, ITorrentData torrentData, ByteBuffer buffer) { await MainLoop.SwitchToThreadpool(); int messageHeaderLength = 4; int messageBodyLength; ByteBuffer messageHeaderBuffer = buffer; ByteBuffer messageBuffer = buffer; ByteBufferPool.Releaser messageBufferReleaser = default; using (var headerReleaser = buffer == null ? NetworkIO.BufferPool.Rent(messageHeaderLength, out messageHeaderBuffer) : default) { await NetworkIO.ReceiveAsync(connection, messageHeaderBuffer, 0, messageHeaderLength, rateLimiter, peerMonitor?.ProtocolDown, managerMonitor?.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageHeaderBuffer.Data, 0, messageHeaderLength); messageBodyLength = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(messageHeaderBuffer.Data, 0)); if (messageBodyLength < 0 || messageBodyLength > MaxMessageLength) { connection.Dispose(); throw new ProtocolException($"Invalid message length received. Value was '{messageBodyLength}'"); } if (messageBodyLength == 0) { return(new KeepAliveMessage()); } if (buffer == null || buffer.Data.Length < messageBodyLength + messageHeaderLength) { messageBufferReleaser = NetworkIO.BufferPool.Rent(messageBodyLength + messageHeaderLength, out messageBuffer); Buffer.BlockCopy(messageHeaderBuffer.Data, 0, messageBuffer.Data, 0, messageHeaderLength); } } using (messageBufferReleaser) { // Always assume protocol first, then convert to data when we what message it is! await NetworkIO.ReceiveAsync(connection, messageBuffer, messageHeaderLength, messageBodyLength, rateLimiter, peerMonitor?.ProtocolDown, managerMonitor?.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageBuffer.Data, messageHeaderLength, messageBodyLength); // FIXME: manager should never be null, except some of the unit tests do that. var data = PeerMessage.DecodeMessage(messageBuffer.Data, 0, messageHeaderLength + messageBodyLength, torrentData); if (data is PieceMessage msg) { peerMonitor?.ProtocolDown.AddDelta(-msg.RequestLength); managerMonitor?.ProtocolDown.AddDelta(-msg.RequestLength); peerMonitor?.DataDown.AddDelta(msg.RequestLength); managerMonitor?.DataDown.AddDelta(msg.RequestLength); } return(data); } }
public async Task ZeroReceivedClosesConnection() { using var releaser = MemoryPool.Default.Rent(100, out Memory <byte> buffer); Incoming.ManualBytesReceived = 0; var receiveTask = NetworkIO.ReceiveAsync(Incoming, buffer, null, null, null); var sendTask = NetworkIO.SendAsync(Outgoing, buffer, null, null, null); Assert.ThrowsAsync <ConnectionClosedException> (async() => await receiveTask); await sendTask; }
public async Task ReceiveData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); await Outgoing.SendAsync(new byte[oneMegabyte], 0, oneMegabyte); await NetworkIO.ReceiveAsync(Incoming, new byte[oneMegabyte], 0, oneMegabyte, limiter, null, null); Assert.AreEqual(1, Incoming.Receives.Count, "#1"); }
public async Task ZeroReceivedClosesConnection() { var data = new byte[100]; Incoming.ManualBytesReceived = 0; var receiveTask = NetworkIO.ReceiveAsync(Incoming, data, 0, data.Length, null, null, null); var sendTask = NetworkIO.SendAsync(Outgoing, data, 0, data.Length, null, null, null); Assert.ThrowsAsync <Exception> (() => receiveTask); await sendTask; }
private async Task CompleteSendOrReceiveFirst(SocketMemory buffer) { var allRequests = new List <RequestMessage> (); var requestsBuffer = requests.Encode().AsMemory(); while (requestsBuffer.Length > 0) { var message = (RequestMessage)PeerMessage.DecodeMessage(requestsBuffer.Span, null).message; allRequests.Add(message); requestsBuffer = requestsBuffer.Slice(message.ByteLength); } while (allRequests.Count > 0) { int size = Message.ReadInt(buffer.Span); await NetworkIO.ReceiveAsync(connection, buffer.Slice(4, size), null, null, null); PieceMessage m = (PieceMessage)PeerMessage.DecodeMessage(buffer.AsSpan(0, size + 4), rig.Manager).message; var request = allRequests[0]; Assert.AreEqual(request.PieceIndex, m.PieceIndex, "#1"); Assert.AreEqual(request.RequestLength, m.RequestLength, "#1"); Assert.AreEqual(request.StartOffset, m.StartOffset, "#1"); for (int i = 0; i < request.RequestLength; i++) { if (buffer.Span[i + 13] != (byte)(m.PieceIndex * rig.Torrent.PieceLength + m.StartOffset + i)) { throw new Exception("Corrupted data received"); } } allRequests.RemoveAt(0); if (allRequests.Count == 0) { break; } else { await NetworkIO.ReceiveAsync(connection, buffer.Slice(0, 4), null, null, null);; } } Uri baseUri = new Uri(ListenerURL); baseUri = new Uri(baseUri, $"{rig.Manager.Torrent.Name}/"); if (rig.Manager.Torrent.Files.Count > 1) { Assert.AreEqual(new Uri(baseUri, rig.Manager.Torrent.Files[0].Path), requestedUrl[0]); Assert.AreEqual(new Uri(baseUri, rig.Manager.Torrent.Files[1].Path), requestedUrl[1]); } }
public static async ReusableTask <HandshakeMessage> ReceiveHandshakeAsync(IPeerConnection connection, IEncryption decryptor) { await MainLoop.SwitchToThreadpool(); using (NetworkIO.BufferPool.Rent(HandshakeMessage.HandshakeLength, out Memory <byte> buffer)) { await NetworkIO.ReceiveAsync(connection, buffer, null, null, null).ConfigureAwait(false); decryptor.Decrypt(buffer.Span); return(new HandshakeMessage(buffer.Span)); } }
public static async ReusableTask <PeerMessage> ReceiveMessageAsync(IConnection2 connection, IEncryption decryptor, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor, ITorrentData torrentData) { byte[] messageLengthBuffer = null; byte[] messageBuffer = null; int messageLength = 4; int messageBody; try { messageLengthBuffer = ClientEngine.BufferPool.Rent(messageLength); await NetworkIO.ReceiveAsync(connection, messageLengthBuffer, 0, messageLength, rateLimiter, peerMonitor?.ProtocolDown, managerMonitor?.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageLengthBuffer, 0, messageLength); messageBody = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(messageLengthBuffer, 0)); if (messageBody < 0 || messageBody > MaxMessageLength) { connection.Dispose(); throw new ProtocolException($"Invalid message length received. Value was '{messageBody}'"); } if (messageBody == 0) { return(new KeepAliveMessage()); } messageBuffer = ClientEngine.BufferPool.Rent(messageBody + messageLength); Buffer.BlockCopy(messageLengthBuffer, 0, messageBuffer, 0, messageLength); } finally { ClientEngine.BufferPool.Return(messageLengthBuffer); } try { // Always assume protocol first, then convert to data when we what message it is! await NetworkIO.ReceiveAsync(connection, messageBuffer, messageLength, messageBody, rateLimiter, peerMonitor?.ProtocolDown, managerMonitor?.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageBuffer, messageLength, messageBody); // FIXME: manager should never be null, except some of the unit tests do that. var data = PeerMessage.DecodeMessage(messageBuffer, 0, messageLength + messageBody, torrentData); if (data is PieceMessage msg) { peerMonitor?.ProtocolDown.AddDelta(-msg.RequestLength); managerMonitor?.ProtocolDown.AddDelta(-msg.RequestLength); peerMonitor?.DataDown.AddDelta(msg.RequestLength); managerMonitor?.DataDown.AddDelta(msg.RequestLength); } return(data); } finally { ClientEngine.BufferPool.Return(messageBuffer); } }
public static async Task <PeerMessage> ReceiveMessageAsync(IConnection connection, IEncryption decryptor, IRateLimiter rateLimiter, ConnectionMonitor monitor, TorrentManager manager) { byte[] messageLengthBuffer = null; byte[] messageBuffer = null; int messageLength = 4; int messageBody; try { messageLengthBuffer = ClientEngine.BufferManager.GetBuffer(messageLength); await NetworkIO.ReceiveAsync(connection, messageLengthBuffer, 0, messageLength, rateLimiter, monitor?.ProtocolDown, manager?.Monitor.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageLengthBuffer, 0, messageLength); messageBody = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(messageLengthBuffer, 0));; if (messageBody < 0 || messageBody > MaxMessageLength) { throw new Exception($"Invalid message length received. Value was '{messageBody}'"); } if (messageBody == 0) { return(new KeepAliveMessage()); } messageBuffer = ClientEngine.BufferManager.GetBuffer(messageBody + messageLength); Buffer.BlockCopy(messageLengthBuffer, 0, messageBuffer, 0, messageLength); } finally { ClientEngine.BufferManager.FreeBuffer(messageLengthBuffer); } try { // Always assume protocol first, then convert to data when we what message it is! await NetworkIO.ReceiveAsync(connection, messageBuffer, messageLength, messageBody, rateLimiter, monitor?.ProtocolDown, manager?.Monitor.ProtocolDown).ConfigureAwait(false); decryptor.Decrypt(messageBuffer, messageLength, messageBody); var data = PeerMessage.DecodeMessage(messageBuffer, 0, messageLength + messageBody, manager); if (data is PieceMessage msg) { monitor?.ProtocolDown.AddDelta(-msg.RequestLength); manager?.Monitor.ProtocolDown.AddDelta(-msg.RequestLength); monitor?.DataDown.AddDelta(msg.RequestLength); manager?.Monitor.DataDown.AddDelta(msg.RequestLength); } return(data); } finally { ClientEngine.BufferManager.FreeBuffer(messageBuffer); } }
public async Task ReceiveData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); using var r1 = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> sendBuffer); using var r2 = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> receiveBuffer); await Outgoing.SendAsync(sendBuffer); await NetworkIO.ReceiveAsync(Incoming, receiveBuffer, limiter, null, null); Assert.AreEqual(1, Incoming.Receives.Count, "#1"); }
public static async ReusableTask <HandshakeMessage> ReceiveHandshakeAsync(IConnection connection, IEncryption decryptor) { await MainLoop.SwitchToThreadpool(); using (NetworkIO.BufferPool.Rent(HandshakeMessage.HandshakeLength, out ByteBuffer buffer)) { await NetworkIO.ReceiveAsync(connection, buffer, 0, HandshakeMessage.HandshakeLength, null, null, null).ConfigureAwait(false); decryptor.Decrypt(buffer.Data, 0, HandshakeMessage.HandshakeLength); var message = new HandshakeMessage(); message.Decode(buffer.Data, 0, HandshakeMessage.HandshakeLength); return(message); } }
public async Task ReceiveFirst() { (_, var buffer) = new SocketMemoryPool().Rent(1024 * 1024 * 3); (_, var sendBuffer) = new SocketMemoryPool().Rent(requests.ByteLength); requests.Encode(sendBuffer.Span); var receiveTask = NetworkIO.ReceiveAsync(connection, buffer.Slice(0, 4), null, null, null); var task = Send(sendBuffer); await receiveTask; await CompleteSendOrReceiveFirst(buffer); await task; }
public async Task ZeroReceivedClosesConnection() { Incoming.ManualBytesReceived = 0; var receiveTask = NetworkIO.ReceiveAsync(Incoming, data, 0, 100, null, null, null); var sendTask = NetworkIO.SendAsync(Outgoing, data, 0, 100, null, null, null); try { await receiveTask; } catch { } Assert.IsTrue(receiveTask.IsFaulted); await sendTask; }
public async Task ReceiveFirst() { using var releaser = new MemoryPool().Rent(1024 * 1024 * 3, out Memory <byte> buffer); using var sendReleaser = new MemoryPool().Rent(requests.ByteLength, out Memory <byte> sendBuffer); requests.Encode(sendBuffer.Span); var receiveTask = NetworkIO.ReceiveAsync(connection, buffer.Slice(0, 4), null, null, null); var task = Send(sendBuffer); await receiveTask; await CompleteSendOrReceiveFirst(buffer); await task; }
public static async ReusableTask <HandshakeMessage> ReceiveHandshakeAsync(IConnection2 connection, IEncryption decryptor) { byte[] buffer = ClientEngine.BufferPool.Rent(HandshakeMessage.HandshakeLength); try { await NetworkIO.ReceiveAsync(connection, buffer, 0, HandshakeMessage.HandshakeLength, null, null, null).ConfigureAwait(false); decryptor.Decrypt(buffer, 0, HandshakeMessage.HandshakeLength); var message = new HandshakeMessage(); message.Decode(buffer, 0, HandshakeMessage.HandshakeLength); return(message); } finally { ClientEngine.BufferPool.Return(buffer); } }
public async Task ReceiveData_RateLimited() { // Allow 1 megabyte worth of data var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiter(); limiter.UpdateChunks(oneMegabyte, oneMegabyte); await Outgoing.SendAsync(new byte[oneMegabyte], 0, oneMegabyte); await NetworkIO.ReceiveAsync(Incoming, new byte[oneMegabyte], 0, oneMegabyte, limiter, null, null); var expectedChunks = (int)Math.Ceiling(oneMegabyte / (double)NetworkIO.ChunkLength); Assert.AreEqual(expectedChunks, Incoming.Receives.Count, "#1"); }
public async Task ReceiveFirst() { var buffer = new ByteBuffer(1024 * 1024 * 3); var sendBuffer = new ByteBuffer(requests.ByteLength); requests.Encode(sendBuffer.Data, 0); var receiveTask = NetworkIO.ReceiveAsync(connection, buffer, 0, 4, null, null, null); var task = Send(sendBuffer, 0, requests.ByteLength); await receiveTask; await CompleteSendOrReceiveFirst(buffer); await task; }
public static async Task <HandshakeMessage> ReceiveHandshakeAsync(IConnection connection, IEncryption decryptor) { var buffer = ClientEngine.BufferManager.GetBuffer(HandshakeMessage.HandshakeLength); try { await NetworkIO.ReceiveAsync(connection, buffer, 0, HandshakeMessage.HandshakeLength, null, null, null).ConfigureAwait(false); decryptor.Decrypt(buffer, 0, HandshakeMessage.HandshakeLength); var message = new HandshakeMessage(); message.Decode(buffer, 0, HandshakeMessage.HandshakeLength); return(message); } finally { ClientEngine.BufferManager.FreeBuffer(ref buffer); } }
private async Task CompleteSendOrReceiveFirst(byte[] buffer) { var allRequests = requests.ToRequestMessages().ToList(); while (allRequests.Count > 0) { int size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0)); await NetworkIO.ReceiveAsync(connection, buffer, 4, size, null, null, null); PieceMessage m = (PieceMessage)PeerMessage.DecodeMessage(buffer, 0, size + 4, rig.Manager.Torrent); var request = allRequests[0]; Assert.AreEqual(request.PieceIndex, m.PieceIndex, "#1"); Assert.AreEqual(request.RequestLength, m.RequestLength, "#1"); Assert.AreEqual(request.StartOffset, m.StartOffset, "#1"); for (int i = 0; i < request.RequestLength; i++) { if (buffer[i + 13] != (byte)(m.PieceIndex * rig.Torrent.PieceLength + m.StartOffset + i)) { throw new Exception("Corrupted data received"); } } allRequests.RemoveAt(0); if (allRequests.Count == 0) { break; } else { await NetworkIO.ReceiveAsync(connection, buffer, 0, 4, null, null, null); } } Uri baseUri = new Uri(ListenerURL); baseUri = new Uri(baseUri, $"{rig.Manager.Torrent.Name}/"); if (rig.Manager.Torrent.Files.Length > 1) { Assert.AreEqual(new Uri(baseUri, rig.Manager.Torrent.Files[0].Path), requestedUrl[0]); Assert.AreEqual(new Uri(baseUri, rig.Manager.Torrent.Files[1].Path), requestedUrl[1]); } }
public async Task ReceiveData_RateLimited() { // Allow 1 megabyte worth of data var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiter(); limiter.UpdateChunks(oneMegabyte, oneMegabyte, NetworkIO.ChunkLength); using var r1 = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> sendBuffer); using var r2 = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> receiveBuffer); await Outgoing.SendAsync(sendBuffer); await NetworkIO.ReceiveAsync(Incoming, receiveBuffer, limiter, null, null); var expectedChunks = (int)Math.Ceiling(oneMegabyte / (double)NetworkIO.ChunkLength); Assert.AreEqual(expectedChunks, Incoming.Receives.Count, "#1"); }
public static async Task <PeerMessage> ReceiveMessageAsync(IConnection connection, IEncryption decryptor, IRateLimiter rateLimiter, ConnectionMonitor monitor, TorrentManager manager) { var messageLengthBuffer = BufferManager.EmptyBuffer; var messageBuffer = BufferManager.EmptyBuffer; try { int messageLength = 4; ClientEngine.BufferManager.GetBuffer(ref messageLengthBuffer, messageLength); await NetworkIO.ReceiveAsync(connection, messageLengthBuffer, 0, messageLength, rateLimiter, monitor, manager?.Monitor).ConfigureAwait(false); decryptor.Decrypt(messageLengthBuffer, 0, messageLength); int messageBody = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(messageLengthBuffer, 0));; if (messageBody < 0 || messageBody > MaxMessageLength) { throw new Exception($"Invalid message length received. Value was '{messageBody}'"); } if (messageBody == 0) { return(new KeepAliveMessage()); } ClientEngine.BufferManager.GetBuffer(ref messageBuffer, messageBody + messageLength); Buffer.BlockCopy(messageLengthBuffer, 0, messageBuffer, 0, messageLength); ClientEngine.BufferManager.FreeBuffer(ref messageLengthBuffer); await NetworkIO.ReceiveAsync(connection, messageBuffer, messageLength, messageBody, rateLimiter, monitor, manager?.Monitor).ConfigureAwait(false); decryptor.Decrypt(messageBuffer, messageLength, messageBody); return(PeerMessage.DecodeMessage(messageBuffer, 0, messageLength + messageBody, manager)); } finally { ClientEngine.BufferManager.FreeBuffer(ref messageLengthBuffer); ClientEngine.BufferManager.FreeBuffer(ref messageBuffer); } }