Example #1
0
        public static void EnqueueSendMessage (IConnection connection, IEncryption encryptor, PeerMessage message, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor, AsyncIOCallback callback, object state)
        {
            int count = message.ByteLength;
            var buffer = ClientEngine.BufferManager.GetBuffer (count);
            message.Encode (buffer, 0);
            encryptor.Encrypt (buffer, 0, count);

            var data = sendCache.Dequeue ().Initialise (buffer, callback, state);
            NetworkIO.EnqueueSend (connection, buffer, 0, count, rateLimiter, peerMonitor, managerMonitor, EndSendCallback, data);
        }
Example #2
0
        public static void EnqueueReceiveMessage(IConnection connection, IEncryption decryptor, IRateLimiter rateLimiter,
			ConnectionMonitor monitor, TorrentManager manager, AsyncMessageReceivedCallback callback, object state)
        {
            // FIXME: Hardcoded number
            int count = 4;
            byte[] buffer = ClientEngine.BufferManager.GetBuffer(count);
            ReceiveMessageState data = receiveCache.Dequeue()
                .Initialise(connection, decryptor, rateLimiter, monitor, manager, buffer, callback, state);
            NetworkIO.EnqueueReceive(connection, buffer, 0, count, rateLimiter, monitor, data.ManagerMonitor,
                MessageLengthReceivedCallback, data);
        }
 public ReceiveMessageState Initialise (IConnection connection, IEncryption decryptor, IRateLimiter limiter, ConnectionMonitor peerMonitor, TorrentManager manager, byte[] buffer, AsyncMessageReceivedCallback callback, object state)
 {
     Connection = connection;
     Decryptor = decryptor;
     Manager = manager;
     Buffer = buffer;
     PeerMonitor = peerMonitor;
     RateLimiter = limiter;
     ManagerMonitor = manager == null ? null : manager.Monitor;
     Callback = callback;
     State = state;
     return this;
 }
 public AsyncIOState Initialise(IConnection connection, byte[] buffer, int offset, int count,
     AsyncIOCallback callback,
     object state, IRateLimiter limiter,
     ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor)
 {
     Connection = connection;
     Buffer = buffer;
     Count = count;
     Callback = callback;
     Offset = offset;
     ManagerMonitor = managerMonitor;
     PeerMonitor = peerMonitor;
     RateLimiter = limiter;
     Remaining = count;
     State = state;
     return this;
 }
Example #5
0
        internal PeerId(Peer peer, TorrentManager manager)
        {
            if (peer == null)
                throw new ArgumentNullException("peer");

            SuggestedPieces = new MonoTorrentCollection<int>();
            AmChoking = true;
            IsChoking = true;

            IsAllowedFastPieces = new MonoTorrentCollection<int>();
            AmAllowedFastPieces = new MonoTorrentCollection<int>();
            LastMessageReceived = DateTime.Now;
            LastMessageSent = DateTime.Now;
            Peer = peer;
            MaxPendingRequests = 2;
            MaxSupportedPendingRequests = 50;
            Monitor = new ConnectionMonitor();
            sendQueue = new MonoTorrentCollection<PeerMessage>(12);
            ExtensionSupports = new ExtensionSupports();
            TorrentManager = manager;
            InitializeTyrant();
        }
        internal async void ReceiveMessagesAsync(IPeerConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            await MainLoop.SwitchToThreadpool();

            SocketMemory currentBuffer = default;

            SocketMemory smallBuffer = default;

            ByteBufferPool.Releaser smallReleaser = default;

            SocketMemory largeBuffer = default;

            ByteBufferPool.Releaser largeReleaser = default;
            try {
                while (true)
                {
                    if (id.AmRequestingPiecesCount == 0)
                    {
                        if (!largeBuffer.IsEmpty)
                        {
                            largeReleaser.Dispose();
                            largeReleaser = default;
                            largeBuffer   = currentBuffer = default;
                        }
                        if (smallBuffer.IsEmpty)
                        {
                            smallReleaser = NetworkIO.BufferPool.Rent(ByteBufferPool.SmallMessageBufferSize, out smallBuffer);
                            currentBuffer = smallBuffer;
                        }
                    }
                    else
                    {
                        if (!smallBuffer.IsEmpty)
                        {
                            smallReleaser.Dispose();
                            smallReleaser = default;
                            smallBuffer   = currentBuffer = default;
                        }
                        if (largeBuffer.IsEmpty)
                        {
                            largeReleaser = NetworkIO.BufferPool.Rent(ByteBufferPool.LargeMessageBufferSize, out largeBuffer);
                            currentBuffer = largeBuffer;
                        }
                    }

                    (PeerMessage message, PeerMessage.Releaser releaser) = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, currentBuffer).ConfigureAwait(false);

                    HandleReceivedMessage(id, torrentManager, message, releaser);
                }
            } catch {
                await ClientEngine.MainLoop;
                CleanupSocket(torrentManager, id);
            } finally {
                smallReleaser.Dispose();
                largeReleaser.Dispose();
            }
        }
Example #7
0
 internal static void EnqueueSend(IConnection connection, byte[] buffer, int offset, int count, AsyncTransfer callback, object state, RateLimiter limiter, ConnectionMonitor managerMonitor, ConnectionMonitor peerMonitor)
 {
     AsyncIO io = new AsyncIO(connection, buffer, offset, count, callback, state, limiter, managerMonitor, peerMonitor);
     EnqueueSend(io);
 }
Example #8
0
 public AsyncIO(IConnection connection, byte[] buffer, int offset, int total, AsyncTransfer callback, object state, RateLimiter limiter, ConnectionMonitor managerMonitor, ConnectionMonitor peerMonitor)
 {
     Connection = connection;
     Buffer = buffer;
     Offset = offset;
     Count = 0;
     Callback = callback;
     ManagerMonitor = managerMonitor;
     PeerMonitor = peerMonitor;
     RateLimiter = limiter;
     State = state;
     Total = total;
 }
Example #9
0
        internal PeerId(Peer peer, TorrentManager manager)
        {
            LastReviewUploadRate = 0;
            LastReviewDownloadRate = 0;
            BytesUploadedAtLastReview = 0;
            BytesDownloadedAtLastReview = 0;
            if (peer == null)
                throw new ArgumentNullException("peer");

            suggestedPieces = new MonoTorrentCollection<int>();
            amChoking = true;
            isChoking = true;

            IsAllowedFastPieces = new MonoTorrentCollection<int>();
            AmAllowedFastPieces = new MonoTorrentCollection<int>();
            lastMessageReceived = DateTime.Now;
            lastMessageSent = DateTime.Now;
            this.peer = peer;
            MaxPendingRequests = 2;
            MaxSupportedPendingRequests = 50;
            monitor = new ConnectionMonitor();
            sendQueue = new MonoTorrentCollection<PeerMessage>(12);
            ExtensionSupports = new ExtensionSupports();
            TorrentManager = manager;
            InitializeTyrant();
        }
Example #10
0
 internal static void EnqueueSend(IConnection connection, ArraySegment<byte> buffer, int offset, int count, AsyncTransfer callback, object state, RateLimiter limiter, ConnectionMonitor managerMonitor, ConnectionMonitor peerMonitor)
 {
     EnqueueSend(connection, buffer.Array, buffer.Offset + offset, count, callback, state, limiter, managerMonitor, peerMonitor);
 }
Example #11
0
        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);
            }
        }
Example #12
0
        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(buffer);
            }
        }
Example #13
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)
                {
                    connection.Dispose();
                    throw new ProtocolException($"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);
                // FIXME: manager should never be null, except some of the unit tests do that.
                var data = PeerMessage.DecodeMessage(messageBuffer, 0, messageLength + messageBody, manager?.Torrent);
                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);
            }
        }
Example #14
0
        public static void EnqueueReceiveMessage(IConnection connection, IEncryption decryptor, IRateLimiter rateLimiter, ConnectionMonitor monitor, TorrentManager manager, AsyncMessageReceivedCallback callback, object state)
        {
            // FIXME: Hardcoded number
            int count  = 4;
            var buffer = ClientEngine.BufferManager.GetBuffer(count);
            var data   = receiveCache.Dequeue().Initialise(connection, decryptor, rateLimiter, monitor, manager, buffer, callback, state);

            NetworkIO.EnqueueReceive(connection, buffer, 0, count, rateLimiter, monitor, data.ManagerMonitor, MessageLengthReceivedCallback, data);
        }
 public static void EnqueueReceive(IConnection connection, byte[] buffer, int offset, int count,
     IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor,
     AsyncIOCallback callback, object state)
 {
     var data = transferCache.Dequeue()
         .Initialise(connection, buffer, offset, count, callback, state, rateLimiter, peerMonitor, managerMonitor);
     lock (receiveQueue)
         ReceiveOrEnqueue(data);
 }
 public ReceiveMessageState Initialise(IConnection connection, IEncryption decryptor, IRateLimiter limiter, ConnectionMonitor peerMonitor, TorrentManager manager, byte[] buffer, AsyncMessageReceivedCallback callback, object state)
 {
     Connection     = connection;
     Decryptor      = decryptor;
     Manager        = manager;
     Buffer         = buffer;
     PeerMonitor    = peerMonitor;
     RateLimiter    = limiter;
     ManagerMonitor = manager == null ? null : manager.Monitor;
     Callback       = callback;
     State          = state;
     return(this);
 }
Example #17
0
        public static async Task SendAsync(IConnection connection, byte [] buffer, int offset, int count, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor)
        {
            await IOLoop;

            int remaining = count;

            while (remaining > 0)
            {
                int transferred;
                if (rateLimiter != null && !rateLimiter.Unlimited && !rateLimiter.TryProcess(Math.Min(ChunkLength, remaining)))
                {
                    var   tcs = new TaskCompletionSource <int> ();
                    await IOLoop;
                    sendQueue.Enqueue(new QueuedIO(connection, buffer, offset, Math.Min(ChunkLength, remaining), rateLimiter, tcs));
                    transferred = await tcs.Task.ConfigureAwait(false);
                }
                else
                {
                    transferred = await connection.SendAsync(buffer, offset, remaining).ConfigureAwait(false);
                }

                if (transferred == 0)
                {
                    throw new Exception("Socket is dead");
                }

                peerMonitor?.BytesSent(transferred, count > 8000 ? TransferType.Data : TransferType.Protocol);
                managerMonitor?.BytesSent(transferred, count > 8000 ? TransferType.Data : TransferType.Protocol);

                offset    += transferred;
                remaining -= transferred;
            }
        }
        internal async void ReceiveMessagesAsync(IConnection2 connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            try {
                while (true)
                {
                    Messages.PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager);

                    if (id.Disposed)
                    {
                        if (message is PieceMessage msg)
                        {
                            ClientEngine.BufferPool.Return(msg.Data);
                        }
                    }
                    else
                    {
                        id.LastMessageReceived.Restart();
                        message.Handle(torrentManager, id);
                    }
                }
            } catch {
                CleanupSocket(torrentManager, id);
            }
        }
        internal async void ReceiveMessagesAsync(IConnection2 connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            try {
                while (true)
                {
                    Messages.PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager.Torrent);

                    if (id.Disposed)
                    {
                        if (message is PieceMessage msg)
                        {
                            msg.DataReleaser.Dispose();
                        }
                        break;
                    }
                    else
                    {
                        id.LastMessageReceived.Restart();
                        torrentManager.Mode.HandleMessage(id, message);
                    }
                }
            } catch {
                CleanupSocket(torrentManager, id);
            }
        }
Example #20
0
        internal async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            await MainLoop.SwitchToThreadpool();

            ByteBufferPool.Releaser releaser = default;
            try {
                while (true)
                {
                    if (id.AmRequestingPiecesCount == 0 && releaser.Buffer != null)
                    {
                        releaser.Dispose();
                        releaser = NetworkIO.BufferPool.Rent(1, out ByteBuffer _);
                    }
                    else if (id.AmRequestingPiecesCount > 0 && releaser.Buffer == null)
                    {
                        releaser.Dispose();
                        releaser = NetworkIO.BufferPool.Rent(Piece.BlockSize, out ByteBuffer _);
                    }
                    PeerMessage message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager.Monitor, torrentManager, releaser.Buffer).ConfigureAwait(false);

                    HandleReceivedMessage(id, torrentManager, message);
                }
            } catch {
                releaser.Dispose();
                await ClientEngine.MainLoop;
                CleanupSocket(torrentManager, id);
            }
        }
Example #21
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);
            }
        }
Example #22
0
        internal PeerId(Peer peer, TorrentManager manager)
        {
            if (peer == null)
                throw new ArgumentNullException("peer");

            this.suggestedPieces = new MonoTorrentCollection<int>();
            this.amChoking = true;
            this.isChoking = true;

            this.isAllowedFastPieces = new MonoTorrentCollection<int>();
            this.amAllowedFastPieces = new MonoTorrentCollection<int>();
            this.lastMessageReceived = DateTime.Now;
            this.lastMessageSent = DateTime.Now;
            this.peer = peer;
            this.monitor = new ConnectionMonitor();
            this.sendQueue = new MonoTorrentCollection<PeerMessage>(12);
            TorrentManager = manager;
            InitializeTyrant();
        }
Example #23
0
        public static void EnqueueSendMessage(IConnection connection, IEncryption encryptor, PeerMessage message, IRateLimiter rateLimiter, ConnectionMonitor peerMonitor, ConnectionMonitor managerMonitor, AsyncIOCallback callback, object state)
        {
            int count  = message.ByteLength;
            var buffer = ClientEngine.BufferManager.GetBuffer(count);

            message.Encode(buffer, 0);
            encryptor.Encrypt(buffer, 0, count);

            var data = sendCache.Dequeue().Initialise(buffer, callback, state);

            NetworkIO.EnqueueSend(connection, buffer, 0, count, rateLimiter, peerMonitor, managerMonitor, EndSendCallback, data);
        }