Beispiel #1
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));
            }
        }
Beispiel #2
0
        void CreateRateLimiters()
        {
            DownloadLimiter  = new RateLimiter();
            DownloadLimiters = new RateLimiterGroup {
                new PauseLimiter(this),
                DownloadLimiter
            };

            UploadLimiter  = new RateLimiter();
            UploadLimiters = new RateLimiterGroup {
                new PauseLimiter(this),
                UploadLimiter
            };
        }
Beispiel #3
0
        private short roundsChoked, roundsUnchoked;     // for stats measurement

        private void InitializeTyrant()
        {
            this.haveMessagesReceived = 0;
            this.startTime            = Stopwatch.GetTimestamp();

            this.rateLimiter              = new RateLimiter();
            this.uploadRateForRecip       = MARKET_RATE;
            this.lastRateReductionTime    = DateTime.Now;
            this.lastMeasuredDownloadRate = 0;

            this.maxObservedDownloadSpeed = 0;
            this.roundsChoked             = 0;
            this.roundsUnchoked           = 0;
        }
Beispiel #4
0
        private void InitializeTyrant()
        {
            HaveMessagesReceived = 0;
            TyrantStartTime.Restart();

            RateLimiter        = new RateLimiter();
            UploadRateForRecip = MARKET_RATE;
            LastRateReductionTime.Restart();
            lastMeasuredDownloadRate = 0;

            maxObservedDownloadSpeed = 0;
            RoundsChoked             = 0;
            RoundsUnchoked           = 0;
        }
        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);
        }
Beispiel #6
0
        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");
        }
Beispiel #7
0
        public ClientEngine(EngineSettings settings, IPieceWriter writer)
        {
            Check.Settings(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));

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

            DiskManager       = new DiskManager(Settings, writer);
            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);
        }
Beispiel #8
0
        internal DiskManager(EngineSettings settings, IPieceWriter writer = null)
        {
            ReadLimiter = new RateLimiter();
            ReadQueue   = new Queue <BufferedIO> ();

            WriteLimiter = new RateLimiter();
            WriteQueue   = new Queue <BufferedIO> ();

            UpdateTimer = ValueStopwatch.StartNew();

            Settings = settings ?? throw new ArgumentNullException(nameof(settings));

            writer ??= new DiskWriter(settings.MaximumOpenFiles);
            Cache = new MemoryCache(settings.DiskCacheBytes, writer);
        }
        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");
        }
Beispiel #10
0
        internal DiskManager(EngineSettings settings, IPieceWriter writer)
        {
            ReadLimiter = new RateLimiter();
            ReadMonitor = new SpeedMonitor();
            ReadQueue   = new Queue <BufferedIO> ();

            WriteLimiter = new RateLimiter();
            WriteMonitor = new SpeedMonitor();
            WriteQueue   = new Queue <BufferedIO> ();

            UpdateTimer = ValueStopwatch.StartNew();

            Settings = settings ?? throw new ArgumentNullException(nameof(settings));
            Writer   = writer ?? throw new ArgumentNullException(nameof(writer));
        }
Beispiel #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);
            });
        }
Beispiel #12
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);

            using var r1 = SocketMemoryPool.Default.Rent(oneMegabyte, out var sendBuffer);
            using var r2 = SocketMemoryPool.Default.Rent(oneMegabyte, out var 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");
        }
        internal DiskManager(EngineSettings settings, Factories factories, IPieceWriter?writer = null)
        {
            ReadLimiter = new RateLimiter();
            ReadQueue   = new Queue <BufferedIO> ();

            WriteLimiter = new RateLimiter();
            WriteQueue   = new Queue <BufferedIO> ();

            UpdateTimer = ValueStopwatch.StartNew();

            Factories = factories ?? throw new ArgumentNullException(nameof(factories));
            Settings  = settings ?? throw new ArgumentNullException(nameof(settings));

            writer ??= factories.CreatePieceWriter(settings.MaximumOpenFiles);
            Cache = factories.CreateBlockCache(writer, settings.DiskCacheBytes, BufferPool);
            Cache.ReadThroughCache    += (o, e) => WriterReadMonitor.AddDelta(e.RequestLength);
            Cache.WrittenThroughCache += (o, e) => WriterWriteMonitor.AddDelta(e.RequestLength);
            IncrementalHashCache       = new Cache <IncrementalHashData> (() => new IncrementalHashData());
        }
Beispiel #14
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));
            }
        }
Beispiel #15
0
        internal DiskManager(ClientEngine engine, PieceWriter writer)
        {
            this.bufferedReads  = new Queue <BufferedIO>();
            this.bufferedWrites = new Queue <BufferedIO>();
            this.engine         = engine;
            this.ReadLimiter    = new RateLimiter();
            this.readMonitor    = new SpeedMonitor();
            this.writeMonitor   = new SpeedMonitor();
            this.WriteLimiter   = new RateLimiter();
            this.Writer         = writer;

            IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), () => {
                readMonitor.Tick();
                writeMonitor.Tick();

                WriteLimiter.UpdateChunks(engine.Settings.MaxWriteRate, WriteRate);
                ReadLimiter.UpdateChunks(engine.Settings.MaxReadRate, ReadRate);

                ProcessBufferedIO();

                return(!Disposed);
            });
        }
Beispiel #16
0
        public ClientEngine(EngineSettings settings, PeerListener listener, PieceWriter writer)
        {
            Check.Settings(settings);
            Check.Listener(listener);
            Check.Writer(writer);

            this.listener = listener;
            this.settings = settings;

            this.connectionManager = new ConnectionManager(this);
            this.dhtListener = new UdpListener(new IPEndPoint(IPAddress.Any, settings.ListenPort));
            this.dhtEngine = new DhtEngine(dhtListener);
            this.diskManager = new DiskManager(this, writer);
            this.listenManager = new ListenManager(this);
            MainLoop.QueueTimeout(TimeSpan.FromMilliseconds(TickLength), delegate {
                if (IsRunning && !disposed)
                    LogicTick();
                return !disposed;
            });
            this.torrents = new MonoTorrentCollection<TorrentManager>();
            this.downloadLimiter = new RateLimiter();
            this.uploadLimiter = new RateLimiter();
            this.peerId = GeneratePeerId();

            listenManager.Register(listener);

            dhtEngine.StateChanged += delegate {
                if (dhtEngine.State != State.Ready)
                    return;
                MainLoop.Queue(delegate {
                    foreach (TorrentManager manager in torrents)
                    {
                        if (!manager.CanUseDht)
                            continue;

                        dhtEngine.Announce(manager.Torrent.infoHash, Listener.Endpoint.Port);
                        dhtEngine.GetPeers(manager.Torrent.infoHash);
                    }
                });
            };
            // This means we created the listener in the constructor
            if (listener.Endpoint.Port == 0)
                listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort));

            listener.Start();
        }
Beispiel #17
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);
 }
Beispiel #18
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;
            });
        }
Beispiel #19
0
        internal DiskManager(ClientEngine engine, PieceWriter writer)
        {
            this.bufferedReads  = new Queue <BufferedIO>();
            this.bufferedWrites = new Queue <BufferedIO>();
            this.cache          = new Cache <BufferedIO>(true).Synchronize();
            this.engine         = engine;
            this.readLimiter    = new RateLimiter();
            this.readMonitor    = new SpeedMonitor();
            this.writeMonitor   = new SpeedMonitor();
            this.writeLimiter   = new RateLimiter();
            this.writer         = writer;

            LoopTask = delegate {
                if (disposed)
                {
                    return;
                }

                while (this.bufferedWrites.Count > 0 && writeLimiter.TryProcess(bufferedWrites.Peek().buffer.Length / 2048))
                {
                    BufferedIO write;
                    lock (bufferLock)
                        write = this.bufferedWrites.Dequeue();
                    try
                    {
                        PerformWrite(write);
                        cache.Enqueue(write);
                    }
                    catch (Exception ex)
                    {
                        //if (write.Manager != null)
                        //    SetError(write.Manager, Reason.WriteFailure, ex);
                    }
                }

                while (this.bufferedReads.Count > 0 && readLimiter.TryProcess(bufferedReads.Peek().Count / 2048))
                {
                    BufferedIO read;
                    lock (bufferLock)
                        read = this.bufferedReads.Dequeue();

                    try
                    {
                        PerformRead(read);
                        cache.Enqueue(read);
                    }
                    catch (Exception ex)
                    {
                        if (read.Manager != null)
                        {
                            SetError(read.Manager, Reason.ReadFailure, ex);
                        }
                    }
                }
            };

            IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate {
                if (disposed)
                {
                    return(false);
                }

                readMonitor.Tick();
                writeMonitor.Tick();
                LoopTask();
                return(true);
            });
        }
Beispiel #20
0
        private void InitializeTyrant()
        {
            this.haveMessagesReceived = 0;
            this.startTime = Stopwatch.GetTimestamp();

            this.rateLimiter = new RateLimiter();
            this.uploadRateForRecip = MARKET_RATE;
            this.lastMeasuredDownloadRate = 0;

            this.maxObservedDownloadSpeed = 0;
            this.roundsChoked = 0;
            this.roundsUnchoked = 0;
        }
        internal DiskManager(ClientEngine engine, PieceWriter writer)
        {
            this.bufferedReads = new Queue<BufferedIO>();
            this.bufferedWrites = new Queue<BufferedIO>();
            this.cache = new Cache<BufferedIO>(true).Synchronize ();
            this.engine = engine;
            this.readLimiter = new RateLimiter();
            this.readMonitor = new SpeedMonitor();
            this.writeMonitor = new SpeedMonitor();
            this.writeLimiter = new RateLimiter();
            this.writer = writer;

            LoopTask = delegate {
                if (disposed)
                    return;

                while (this.bufferedWrites.Count > 0 && writeLimiter.TryProcess(bufferedWrites.Peek ().buffer.Length / 2048))
                {
                    BufferedIO write;
                    lock (bufferLock)
                        write = this.bufferedWrites.Dequeue();
                    try
                    {
                        PerformWrite(write);
                        cache.Enqueue (write);
                    }
                    catch (Exception ex)
                    {
                        if (write.Manager != null)
                            SetError(write.Manager, Reason.WriteFailure, ex);
                    }
                }

                while (this.bufferedReads.Count > 0 && readLimiter.TryProcess(bufferedReads.Peek().Count / 2048))
                {
                    BufferedIO read;
                    lock(bufferLock)
                        read = this.bufferedReads.Dequeue();

                    try
                    {
                        PerformRead(read);
                        cache.Enqueue (read);
                    }
                    catch (Exception ex)
                    {
                        if(read.Manager != null)
                            SetError(read.Manager, Reason.ReadFailure, ex);
                    }
                }
            };

            IOLoop.QueueTimeout(TimeSpan.FromSeconds(1), delegate {
                if (disposed)
                    return false;

                readMonitor.Tick();
                writeMonitor.Tick();
                LoopTask();
                return true;
            });
        }
Beispiel #22
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);
 }
Beispiel #23
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;
 }
Beispiel #24
0
        private void InitializeTyrant()
        {
            haveMessagesReceived = 0;
            startTime = Stopwatch.GetTimestamp();

            RateLimiter = new RateLimiter();
            uploadRateForRecip = MARKET_RATE;
            lastRateReductionTime = DateTime.Now;
            lastMeasuredDownloadRate = 0;

            maxObservedDownloadSpeed = 0;
            RoundsChoked = 0;
            RoundsUnchoked = 0;
        }