Beispiel #1
0
        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);
                }
            }
        }
Beispiel #2
0
        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}");
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #9
0
        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;
        }
Beispiel #10
0
        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;
        }
Beispiel #12
0
        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");
        }
Beispiel #13
0
        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;
        }
Beispiel #14
0
        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]);
            }
        }
Beispiel #15
0
        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));
            }
        }
Beispiel #16
0
        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);
            }
        }
Beispiel #17
0
        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");
        }
Beispiel #19
0
        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);
            }
        }
Beispiel #20
0
        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;
        }
Beispiel #21
0
        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;
        }
Beispiel #23
0
        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);
            }
        }
Beispiel #24
0
        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");
        }
Beispiel #25
0
        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;
        }
Beispiel #26
0
        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);
            }
        }
Beispiel #27
0
        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");
        }
Beispiel #29
0
        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);
            }
        }