Beispiel #1
0
        public static async ReusableTask <(PeerMessage message, PeerMessage.Releaser releaser)> ReceiveMessageAsync(IPeerConnection connection, IEncryption decryptor, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor, ITorrentData torrentData, SocketMemory buffer)
        {
            await MainLoop.SwitchToThreadpool();

            int messageHeaderLength = 4;
            int messageBodyLength;

            SocketMemory messageHeaderBuffer = buffer;
            SocketMemory 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.AsSpan(0, messageHeaderLength));

                messageBodyLength = Message.ReadInt(messageHeaderBuffer.AsSpan());
                if (messageBodyLength < 0 || messageBodyLength > MaxMessageLength)
                {
                    connection.Dispose();
                    throw new ProtocolException($"Invalid message length received. Value was '{messageBodyLength}'");
                }

                if (messageBodyLength == 0)
                {
                    return(KeepAliveMessage.Instance, default);
        protected async ReusableTask ReceiveMessageAsync(SocketMemory buffer)
        {
            if (buffer.Length == 0)
            {
                return;
            }
            if (!initialBuffer.IsEmpty)
            {
                int toCopy = Math.Min(initialBuffer.Length, buffer.Length);
                initialBuffer.Span.Slice(0, toCopy).CopyTo(buffer.AsSpan());
                initialBuffer = initialBuffer.Slice(toCopy);

                if (toCopy != buffer.Length)
                {
                    await NetworkIO.ReceiveAsync(socket, buffer.Slice(toCopy, buffer.Length - toCopy), null, null, null).ConfigureAwait(false);

                    bytesReceived += buffer.Length - toCopy;
                }
            }
            else
            {
                await NetworkIO.ReceiveAsync(socket, buffer, null, null, null).ConfigureAwait(false);

                bytesReceived += buffer.Length;
            }
        }
Beispiel #3
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]);
            }
        }