public static async Task SendMessageAsync(IConnection connection, IEncryption encryptor, PeerMessage message, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor) { int count = message.ByteLength; var buffer = ClientEngine.BufferManager.GetBuffer(count); try { var pieceMessage = message as PieceMessage; message.Encode(buffer, 0); encryptor.Encrypt(buffer, 0, count); // Assume protocol first, then swap it to data once we successfully send the data bytes. await NetworkIO.SendAsync(connection, buffer, 0, count, pieceMessage == null?null : rateLimiter, peerMonitor?.DataUp, managerMonitor?.DataUp).ConfigureAwait(false); if (pieceMessage != null) { peerMonitor?.ProtocolUp.AddDelta(-pieceMessage.RequestLength); managerMonitor?.ProtocolUp.AddDelta(-pieceMessage.RequestLength); peerMonitor?.DataUp.AddDelta(pieceMessage.RequestLength); managerMonitor?.DataUp.AddDelta(pieceMessage.RequestLength); } } finally { ClientEngine.BufferManager.FreeBuffer(ref buffer); } }
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 async Task SendData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); await NetworkIO.SendAsync(Incoming, new byte[oneMegabyte], 0, oneMegabyte, limiter, null, null); Assert.AreEqual(1, Incoming.Sends.Count, "#1"); }
public async Task SendData_Unlimited() { var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiterGroup(); using var releaser = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> buffer); await NetworkIO.SendAsync(Incoming, buffer, limiter, null, null); Assert.AreEqual(1, Incoming.Sends.Count, "#1"); }
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 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 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 NegativeMessageBodyLength() { using var releaser = SocketMemoryPool.Default.Rent(20, out var buffer); Message.Write(buffer.Span, -6); await NetworkIO.SendAsync(pair.Outgoing, buffer); var receiveTask = PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance); Assert.ThrowsAsync <ProtocolException> (async() => await receiveTask, "#1"); Assert.ThrowsAsync <ConnectionClosedException> (async() => await PeerIO.ReceiveMessageAsync(pair.Outgoing, PlainTextEncryption.Instance), "#2"); }
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; }
public async Task NegativeMessageBodyLength() { var buffer = new byte[4]; Message.Write(buffer, 0, -6); await NetworkIO.SendAsync(pair.Outgoing, buffer, 0, buffer.Length); var receiveTask = PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance); Assert.ThrowsAsync <ProtocolException> (() => receiveTask, "#1"); Assert.ThrowsAsync <Exception> (() => PeerIO.ReceiveMessageAsync(pair.Outgoing, PlainTextEncryption.Instance), "#2"); }
public async Task LargeMessageBodyLength() { var buffer = new byte[4]; Message.Write(buffer, 0, int.MaxValue); await NetworkIO.SendAsync(pair.Outgoing, buffer, 0, buffer.Length); var receiveTask = PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance); Assert.ThrowsAsync <ProtocolException> (async() => await receiveTask, "#1"); Assert.ThrowsAsync <ConnectionClosedException> (async() => await PeerIO.ReceiveMessageAsync(pair.Outgoing, PlainTextEncryption.Instance), "#2"); }
public static async Task SendMessageAsync(IConnection connection, IEncryption encryptor, PeerMessage message, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor) { int count = message.ByteLength; var buffer = ClientEngine.BufferManager.GetBuffer(count); try { message.Encode(buffer, 0); encryptor.Encrypt(buffer, 0, count); await NetworkIO.SendAsync(connection, buffer, 0, count, rateLimiter, peerMonitor, managerMonitor).ConfigureAwait(false); } finally { ClientEngine.BufferManager.FreeBuffer(ref buffer); } }
public async Task SendData_RateLimited() { // Allow 1 megabyte worth of data var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiter(); limiter.UpdateChunks(oneMegabyte, oneMegabyte); await NetworkIO.SendAsync(Incoming, new byte[oneMegabyte], 0, oneMegabyte, limiter, null, null); var expectedChunks = (int)Math.Ceiling(oneMegabyte / (double)NetworkIO.ChunkLength); Assert.AreEqual(expectedChunks, Incoming.Sends.Count, "#1"); }
public async Task UnknownMessage() { using var releaser = SocketMemoryPool.Default.Rent(20, out var data); Message.Write(data.Span, 16); for (int i = 4; i < 16; i++) { data.Span [i] = byte.MaxValue; } var task = PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance); await NetworkIO.SendAsync(pair.Outgoing, data); Assert.ThrowsAsync <MessageException> (async() => await task, "#1"); }
public async Task ZeroMessageBodyIsKeepAlive() { using var releaser = SocketMemoryPool.Default.Rent(4, out var buffer); Message.Write(buffer.Span, 0); await NetworkIO.SendAsync(pair.Outgoing, buffer); Assert.IsInstanceOf <KeepAliveMessage> (await PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance)); new KeepAliveMessage().Encode(buffer.Span); await NetworkIO.SendAsync(pair.Outgoing, buffer); Assert.IsInstanceOf <KeepAliveMessage> (await PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance)); }
public async Task ZeroMessageBodyIsKeepAlive() { var buffer = new byte[4]; Message.Write(buffer, 0, 0); await NetworkIO.SendAsync(pair.Outgoing, buffer, 0, buffer.Length); Assert.IsInstanceOf <KeepAliveMessage> (await PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance)); buffer = new KeepAliveMessage().Encode(); await NetworkIO.SendAsync(pair.Outgoing, buffer, 0, buffer.Length); Assert.IsInstanceOf <KeepAliveMessage> (await PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance)); }
public async Task UnknownMessage() { var data = new byte[20]; Message.Write(data, 0, 16); for (int i = 4; i < 16; i++) { data [i] = byte.MaxValue; } var task = PeerIO.ReceiveMessageAsync(pair.Incoming, PlainTextEncryption.Instance, null, null, null); await NetworkIO.SendAsync(pair.Outgoing, data, 0, 20, null, null, null); Assert.ThrowsAsync <ProtocolException> (() => task, "#1"); }
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 SendData_RateLimited() { // Allow 1 megabyte worth of data var oneMegabyte = 1 * 1024 * 1024; var limiter = new RateLimiter(); limiter.UpdateChunks(oneMegabyte, oneMegabyte, NetworkIO.ChunkLength); using var releaser = MemoryPool.Default.Rent(oneMegabyte, out Memory <byte> buffer); await NetworkIO.SendAsync(Incoming, buffer, limiter, null, null); var expectedChunks = (int)Math.Ceiling(oneMegabyte / (double)NetworkIO.ChunkLength); Assert.AreEqual(expectedChunks, Incoming.Sends.Count, "#1"); }
async Task Send(byte[] buffer, int offset, int count, int maxBytesPerChunk = -1) { if (maxBytesPerChunk == -1) { await NetworkIO.SendAsync(connection, buffer, offset, count, null, null, null); } else { while (count > 0) { var toSend = Math.Min(maxBytesPerChunk, count); await NetworkIO.SendAsync(connection, buffer, offset, toSend, null, null, null); count -= toSend; } } }
async Task Send(SocketMemory buffer, int maxBytesPerChunk = -1) { if (maxBytesPerChunk == -1) { await NetworkIO.SendAsync(connection, buffer, null, null, null); } else { while (buffer.Length > 0) { var toSend = Math.Min(maxBytesPerChunk, buffer.Length); await NetworkIO.SendAsync(connection, buffer.Slice(0, toSend), null, null, null); buffer = buffer.Slice(toSend); } } }
public async Task ReceiveTwoKeepAlives() { var message = new KeepAliveMessage(); var buffer = message.Encode(); var handle = new AutoResetEvent(false); await NetworkIO.SendAsync(Outgoing, buffer, 0, buffer.Length, null, null, null); var sendTask = NetworkIO.SendAsync(Outgoing, buffer, 0, buffer.Length, null, null, null); var task = PeerIO.ReceiveMessageAsync(Incoming, PlainTextEncryption.Instance, null, null, null); Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(2)), "#Should receive first message"); task = PeerIO.ReceiveMessageAsync(Incoming, PlainTextEncryption.Instance, null, null, null); Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(2)), "#Should receive second message"); await sendTask; }
public void DoSend(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; var task = NetworkIO.SendAsync(Outgoing, data, 0, data.Length, null, null, null); int received = 0; byte[] buffer = new byte[data.Length]; while (received != buffer.Length) { int r = Incoming.Receive(buffer, received, buffer.Length - received); Assert.AreNotEqual(0, r, "#Received data"); received += r; } Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(1)), "Data should be all sent"); Assert.IsTrue(Toolbox.ByteMatch(buffer, data), "Data matches"); }
public async Task InvalidMessage() { Buffer.BlockCopy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(16)), 0, data, 0, 4); for (int i = 4; i < 16; i++) { data[i] = byte.MaxValue; } var task = PeerIO.ReceiveMessageAsync(Incoming, PlainTextEncryption.Instance, null, null, null); await NetworkIO.SendAsync(Outgoing, data, 0, 20, null, null, null); try { await task; Assert.Fail("An exception should've been thrown"); } catch { } }
async Task DoSend(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; var data = new byte[16384]; new Random().NextBytes(data); var task = NetworkIO.SendAsync(Outgoing, data, 0, data.Length, null, null, null); int received = 0; byte[] buffer = new byte[data.Length]; while (received != buffer.Length) { int r = await Incoming.ReceiveAsync(buffer, received, buffer.Length - received); Assert.AreNotEqual(0, r, "#Received data"); received += r; } Assert.DoesNotThrowAsync(() => task.WithTimeout(TimeSpan.FromSeconds(1)), "Data should be all sent"); Assert.IsTrue(Toolbox.ByteMatch(buffer, data), "Data matches"); }
async Task DoSend(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; using var r1 = MemoryPool.Default.Rent(16384, out Memory <byte> sendBuffer); using var r2 = MemoryPool.Default.Rent(16384, out Memory <byte> receiveBuffer); new Random().NextBytes(sendBuffer.Span); var task = NetworkIO.SendAsync(Outgoing, sendBuffer, null, null, null); int received = 0; while (received != receiveBuffer.Length) { int r = await Incoming.ReceiveAsync(receiveBuffer.Slice(received)); Assert.AreNotEqual(0, r, "#Received data"); received += r; } await task.WithTimeout(TimeSpan.FromSeconds(10)); Assert.IsTrue(receiveBuffer.Span.SequenceEqual(sendBuffer.Span), "Data matches"); }
async Task DoSend(bool slowOutgoing, bool slowIncoming) { Incoming.SlowConnection = slowIncoming; Outgoing.SlowConnection = slowOutgoing; var data = new ByteBuffer(16384); new Random().NextBytes(data.Data); var task = NetworkIO.SendAsync(Outgoing, data, 0, data.Data.Length, null, null, null); int received = 0; var buffer = new ByteBuffer(data.Data.Length); while (received != buffer.Data.Length) { int r = await Incoming.ReceiveAsync(buffer, received, buffer.Data.Length - received); Assert.AreNotEqual(0, r, "#Received data"); received += r; } await task.WithTimeout(TimeSpan.FromSeconds(10)); Assert.IsTrue(Toolbox.ByteMatch(buffer.Data, data.Data), "Data matches"); }
public static async ReusableTask SendMessageAsync(IConnection connection, IEncryption encryptor, PeerMessage message, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor, ByteBuffer buffer = null) { await MainLoop.SwitchToThreadpool(); int count = message.ByteLength; using (buffer == null ? NetworkIO.BufferPool.Rent(count, out buffer) : default) { var pieceMessage = message as PieceMessage; message.Encode(buffer.Data, 0); encryptor.Encrypt(buffer.Data, 0, count); // Assume protocol first, then swap it to data once we successfully send the data bytes. await NetworkIO.SendAsync(connection, buffer, 0, count, pieceMessage == null?null : rateLimiter, peerMonitor?.ProtocolUp, managerMonitor?.ProtocolUp).ConfigureAwait(false); if (pieceMessage != null) { peerMonitor?.ProtocolUp.AddDelta(-pieceMessage.RequestLength); managerMonitor?.ProtocolUp.AddDelta(-pieceMessage.RequestLength); peerMonitor?.DataUp.AddDelta(pieceMessage.RequestLength); managerMonitor?.DataUp.AddDelta(pieceMessage.RequestLength); } } }