private void SendMessage(PeerId id, PeerMessage message, MessagingCallback callback)
        {
            try
            {
                id.MessageSentCallback     = callback;
                id.CurrentlySendingMessage = message;

                RateLimiterGroup limiter = id.TorrentManager.UploadLimiter;

                if (message is PieceMessage)
                {
                    PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, limiter, id.Monitor, id.TorrentManager.Monitor, endSendMessageCallback, id);
                    ClientEngine.BufferManager.FreeBuffer(ref ((PieceMessage)message).Data);
                    id.IsRequestingPiecesCount--;
                }
                else
                {
                    PeerIO.EnqueueSendMessage(id.Connection, id.Encryptor, message, null, id.Monitor, id.TorrentManager.Monitor, endSendMessageCallback, id);
                }
            }
            catch (Exception ex)
            {
                CleanupSocket(id, ex.Message);
            }
        }
示例#2
0
        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 ClientEngine (EngineSettings settings, Factories factories)
        {
            settings = settings ?? throw new ArgumentNullException (nameof (settings));
            Factories = factories ?? throw new ArgumentNullException (nameof (factories));

            // This is just a sanity check to make sure the ReusableTasks.dll assembly is
            // loadable.
            GC.KeepAlive (ReusableTasks.ReusableTask.CompletedTask);

            PeerId = GeneratePeerId ();
            Settings = settings ?? throw new ArgumentNullException (nameof (settings));
            CheckSettingsAreValid (Settings);

            allTorrents = new List<TorrentManager> ();
            dhtNodeLocker = new SemaphoreSlim (1, 1);
            publicTorrents = new List<TorrentManager> ();
            Torrents = new ReadOnlyCollection<TorrentManager> (publicTorrents);

            DiskManager = new DiskManager (Settings, Factories);

            ConnectionManager = new ConnectionManager (PeerId, Settings, Factories, DiskManager);
            listenManager = new ListenManager (this);
            PortForwarder = Factories.CreatePortForwarder ();

            MainLoop.QueueTimeout (TimeSpan.FromMilliseconds (TickLength), delegate {
                if (IsRunning && !Disposed)
                    LogicTick ();
                return !Disposed;
            });

            downloadLimiter = new RateLimiter ();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter = new RateLimiter ();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            PeerListener = (settings.ListenEndPoint == null ? null : Factories.CreatePeerConnectionListener (settings.ListenEndPoint)) ?? new NullPeerListener ();
            listenManager.SetListener (PeerListener);

            DhtListener = (settings.DhtEndPoint == null ? null : Factories.CreateDhtListener (settings.DhtEndPoint)) ?? new NullDhtListener ();
            DhtEngine = (settings.DhtEndPoint == null ? null : Factories.CreateDht ()) ?? new NullDhtEngine ();
            Dht = new DhtEngineWrapper (DhtEngine);
            DhtEngine.SetListenerAsync (DhtListener).GetAwaiter ().GetResult ();

            DhtEngine.StateChanged += DhtEngineStateChanged;
            DhtEngine.PeersFound += DhtEnginePeersFound;
            LocalPeerDiscovery = new NullLocalPeerDiscovery ();

            RegisterLocalPeerDiscovery (settings.AllowLocalPeerDiscovery ? Factories.CreateLocalPeerDiscovery () : null);
        }
示例#5
0
        public async Task ReceiveData_Unlimited()
        {
            var oneMegabyte = 1 * 1024 * 1024;
            var limiter     = new RateLimiterGroup();

            await Outgoing.SendAsync(new ByteBuffer (oneMegabyte), 0, oneMegabyte);

            await NetworkIO.ReceiveAsync(Incoming, new ByteBuffer (oneMegabyte), 0, oneMegabyte, limiter, null, null);

            Assert.AreEqual(1, Incoming.Receives.Count, "#1");
        }
示例#6
0
        public ClientEngine(EngineSettings settings)
        {
            settings = settings ?? throw new ArgumentNullException(nameof(settings));

            // This is just a sanity check to make sure the ReusableTasks.dll assembly is
            // loadable.
            GC.KeepAlive(ReusableTasks.ReusableTask.CompletedTask);

            PeerId   = GeneratePeerId();
            Settings = settings ?? throw new ArgumentNullException(nameof(settings));
            CheckSettingsAreValid(Settings);

            allTorrents    = new List <TorrentManager> ();
            publicTorrents = new List <TorrentManager> ();
            Torrents       = new ReadOnlyCollection <TorrentManager> (publicTorrents);

            DiskManager = new DiskManager(Settings);
            DiskManager.ChangePieceWriter(new DiskWriter(Settings.MaximumOpenFiles));

            ConnectionManager = new ConnectionManager(PeerId, Settings, DiskManager);
            listenManager     = new ListenManager(this);
            PortForwarder     = new MonoNatPortForwarder();

            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });

            downloadLimiter  = new RateLimiter();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter  = new RateLimiter();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            Listener = PeerListenerFactory.CreateTcp(settings.ListenPort);
            listenManager.SetListener(Listener);

            DhtListener             = DhtListenerFactory.CreateUdp(settings.DhtPort);
            DhtEngine               = settings.DhtPort == -1 ? new NullDhtEngine() : DhtEngineFactory.Create(DhtListener);
            DhtEngine.StateChanged += DhtEngineStateChanged;
            DhtEngine.PeersFound   += DhtEnginePeersFound;

            RegisterLocalPeerDiscovery(settings.AllowLocalPeerDiscovery && settings.ListenPort > 0 ? LocalPeerDiscoveryFactory.Create(settings.ListenPort) : null);
        }
        void CreateRateLimiters()
        {
            RateLimiter downloader = new RateLimiter();

            downloadLimiter = new RateLimiterGroup();
            downloadLimiter.Add(new PauseLimiter(this));
            downloadLimiter.Add(downloader);

            RateLimiter uploader = new RateLimiter();

            uploadLimiter = new RateLimiterGroup();
            uploadLimiter.Add(new PauseLimiter(this));
            uploadLimiter.Add(uploader);
        }
示例#8
0
        void CreateRateLimiters()
        {
            DownloadLimiter  = new RateLimiter();
            DownloadLimiters = new RateLimiterGroup {
                new PauseLimiter(this),
                DownloadLimiter
            };

            UploadLimiter  = new RateLimiter();
            UploadLimiters = new RateLimiterGroup {
                new PauseLimiter(this),
                UploadLimiter
            };
        }
        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");
        }
示例#10
0
        public ClientEngine(EngineSettings settings, IPeerListener listener, IPieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            // This is just a sanity check to make sure the ReusableTasks.dll assembly is
            // loadable.
            GC.KeepAlive(ReusableTasks.ReusableTask.CompletedTask);

            PeerId   = GeneratePeerId();
            Listener = listener ?? throw new ArgumentNullException(nameof(listener));
            Settings = settings ?? throw new ArgumentNullException(nameof(settings));

            allTorrents    = new List <TorrentManager> ();
            publicTorrents = new List <TorrentManager> ();
            Torrents       = new ReadOnlyCollection <TorrentManager> (publicTorrents);

            DiskManager       = new DiskManager(Settings, writer);
            ConnectionManager = new ConnectionManager(PeerId, Settings, DiskManager);
            DhtEngine         = new NullDhtEngine();
            listenManager     = new ListenManager(this);
            PortForwarder     = new MonoNatPortForwarder();

            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });

            downloadLimiter  = new RateLimiter();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter  = new RateLimiter();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            listenManager.Register(listener);

            if (SupportsLocalPeerDiscovery)
            {
                RegisterLocalPeerDiscovery(new LocalPeerDiscovery(Settings));
            }
        }
示例#11
0
        void CreateRateLimiters()
        {
            RateLimiter downloader = new RateLimiter();

            downloadLimiter = new RateLimiterGroup();
            downloadLimiter.Add(new DiskWriterLimiter(DiskManager));
            downloadLimiter.Add(downloader);

            RateLimiter uploader = new RateLimiter();

            uploadLimiter = new RateLimiterGroup();
            uploadLimiter.Add(uploader);

            MainLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate {
                downloader.UpdateChunks(Settings.GlobalMaxDownloadSpeed, TotalDownloadSpeed);
                uploader.UpdateChunks(Settings.GlobalMaxUploadSpeed, TotalUploadSpeed);
                return(!Disposed);
            });
        }
示例#12
0
        public ClientEngine(EngineSettings settings, IPeerListener listener, IPieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            PeerId   = GeneratePeerId();
            Listener = listener ?? throw new ArgumentNullException(nameof(listener));
            Settings = settings ?? throw new ArgumentNullException(nameof(settings));

            torrents = new List <TorrentManager>();
            Torrents = new ReadOnlyCollection <TorrentManager> (torrents);

            DiskManager       = new DiskManager(Settings, writer);
            ConnectionManager = new ConnectionManager(PeerId, Settings, DiskManager);
            DhtEngine         = new NullDhtEngine();
            listenManager     = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !Disposed)
                {
                    LogicTick();
                }
                return(!Disposed);
            });

            downloadLimiter  = new RateLimiter();
            downloadLimiters = new RateLimiterGroup {
                new DiskWriterLimiter(DiskManager),
                downloadLimiter,
            };

            uploadLimiter  = new RateLimiter();
            uploadLimiters = new RateLimiterGroup {
                uploadLimiter
            };

            listenManager.Register(listener);

            if (SupportsLocalPeerDiscovery)
            {
                RegisterLocalPeerDiscovery(new LocalPeerDiscovery(Settings));
            }
        }
示例#13
0
        void CreateRateLimiters()
        {
            RateLimiter downloader = new RateLimiter();
            downloadLimiter = new RateLimiterGroup();
            downloadLimiter.Add(new DiskWriterLimiter(DiskManager));
            downloadLimiter.Add(downloader);

            RateLimiter uploader = new RateLimiter();
            uploadLimiter = new RateLimiterGroup();
            downloadLimiter.Add(new DiskWriterLimiter(DiskManager));
            uploadLimiter.Add(uploader);

            ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate {
                downloader.UpdateChunks(Settings.GlobalMaxDownloadSpeed, TotalDownloadSpeed);
                uploader.UpdateChunks(Settings.GlobalMaxUploadSpeed, TotalUploadSpeed);
                return !disposed;
            });
        }
示例#14
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);
            }
        }
示例#15
0
        async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            try {
                while (true)
                {
                    var message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager);

                    if (id.Disposed)
                    {
                        if (message is PieceMessage msg)
                        {
                            ClientEngine.BufferManager.FreeBuffer(msg.Data);
                        }
                    }
                    else
                    {
                        id.LastMessageReceived.Restart();

                        if (PeerMessageTransferred != null)
                        {
                            RaisePeerMessageTransferred(new PeerMessageEventArgs(id.TorrentManager, message, Direction.Incoming, id));
                        }

                        message.Handle(id);
                    }
                }
            } catch {
                CleanupSocket(id, "Could not receive a message");
            }
        }
示例#16
0
        internal async void ReceiveMessagesAsync(IPeerConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            await MainLoop.SwitchToThreadpool();

            Memory <byte> currentBuffer = default;

            Memory <byte> smallBuffer = default;

            ByteBufferPool.Releaser smallReleaser = default;

            Memory <byte> 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();
            }
        }
示例#17
0
        async void ReceiveMessagesAsync(IConnection connection, IEncryption decryptor, RateLimiterGroup downloadLimiter, ConnectionMonitor monitor, TorrentManager torrentManager, PeerId id)
        {
            try {
                while (true)
                {
                    var message = await PeerIO.ReceiveMessageAsync(connection, decryptor, downloadLimiter, monitor, torrentManager);

                    if (id.Disposed)
                    {
                        if (message is PieceMessage msg)
                        {
                            ClientEngine.BufferManager.FreeBuffer(msg.Data);
                        }
                    }
                    else
                    {
                        id.LastMessageReceived.Restart();
                        message.Handle(torrentManager, id);
                    }
                }
            } catch {
                CleanupSocket(torrentManager, id);
            }
        }
示例#18
0
        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);
            }
        }