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); RegisterDht(new NullDhtEngine()); 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 List <TorrentManager>(); this.torrentsReadonly = new ReadOnlyCollection <TorrentManager> (torrents); CreateRateLimiters(); this.peerId = GeneratePeerId(); localPeerListener = new LocalPeerListener(this); localPeerManager = new LocalPeerManager(); LocalPeerSearchEnabled = SupportsLocalPeerDiscovery; listenManager.Register(listener); // This means we created the listener in the constructor if (listener.Endpoint.Port == 0) { listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort)); } }
async Task ChangePieceWriterAsync (IPieceWriter writer) { writer = writer ?? throw new ArgumentNullException (nameof (writer)); await MainLoop; if (IsRunning) throw new InvalidOperationException ("You must stop all active downloads before changing the piece writer used to write data to disk."); await DiskManager.SetWriterAsync (writer); }
public void Setup() { rig = TestRig.CreateMultiFile(); diskManager = rig.Engine.DiskManager; writer = new ExceptionWriter(); diskManager.Writer = writer; handle = new ManualResetEvent(false); rig.Manager.Stop(); }
public void Setup() { writer = new PieceWriter(); for (int i = 0; i < fileData.Files.Count; i++) { writer.Data.Add(fileData.Files[i], fileData.Data[i]); } diskManager = new DiskManager(new EngineSettings(), writer); }
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); }
public void Setup() { writer = new PieceWriter(); for (int i = 0; i < fileData.Files.Count; i++) { writer.Data.Add(fileData.Files[i], fileData.Data[i]); } diskManager = new DiskManager(new EngineSettingsBuilder { DiskCacheBytes = 0 }.ToSettings(), Factories.Default, writer); }
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); }
public async Task MoveFile_SamePath() { using var tmp = TempDir.Create(); var file = TorrentFileInfo.Create(Constants.BlockSize, ("file.txt", 123456, Path.Combine(tmp.Path, "orig.txt"))).Single(); File.OpenWrite(file.FullPath).Close(); using var writer = new TestPieceWriter(); using var manager = new DiskManager(new EngineSettings(), Factories.Default, writer); await manager.MoveFileAsync(file, file.FullPath); Assert.IsTrue(File.Exists(file.FullPath)); }
public async Task MoveFile_ConvertsToFullPath() { using var writer = new TestPieceWriter(); using var manager = new DiskManager(new EngineSettings(), Factories.Default, writer); var file = TorrentFileInfo.Create(Constants.BlockSize, 123456).Single(); Assert.IsFalse(File.Exists(file.FullPath)); await manager.MoveFileAsync(file, "NewPath"); Assert.AreEqual(Path.GetFullPath("NewPath"), file.FullPath); Assert.IsFalse(File.Exists(file.FullPath)); }
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)); } }
public async Task MoveFile_TargetDirectoryDoesNotExist() { using var tmp = TempDir.Create(); var file = TorrentFileInfo.Create(Constants.BlockSize, ("file.txt", 123456, Path.Combine(tmp.Path, "orig.txt"))).Single(); File.OpenWrite(file.FullPath).Close(); using var writer = new TestPieceWriter(); using var manager = new DiskManager(new EngineSettings(), Factories.Default, writer); var fullPath = Path.Combine(tmp.Path, "New", "Path", "file.txt"); await manager.MoveFileAsync(file, fullPath); Assert.AreEqual(fullPath, file.FullPath); }
public void Dispose() { if (Disposed) { return; } Disposed = true; MainLoop.QueueWait(() => { DhtEngine.Dispose(); DiskManager.Dispose(); listenManager.Dispose(); LocalPeerDiscovery.Stop(); }); }
public async Task MoveFiles_Overwrite_SameDir() { using var tmp = TempDir.Create(); var file = TorrentFileInfo.Create(Constants.BlockSize, (Path.Combine("sub_dir", "orig.txt"), 123456, Path.Combine(tmp.Path, "sub_dir", "orig.txt"))).Single(); Directory.CreateDirectory(Path.GetDirectoryName(file.FullPath)); File.OpenWrite(file.FullPath).Close(); using var writer = new TestPieceWriter(); using var manager = new DiskManager(new EngineSettings(), Factories.Default, writer); await manager.MoveFilesAsync(new[] { file }, tmp.Path, true); Assert.AreEqual(Path.Combine(tmp.Path, file.Path), file.FullPath); Assert.IsTrue(File.Exists(file.FullPath)); }
public void Dispose () { if (Disposed) return; Disposed = true; MainLoop.QueueWait (() => { PeerListener.Stop (); listenManager.SetListener (new NullPeerListener ()); DhtListener.Stop (); DhtEngine.Dispose (); DiskManager.Dispose (); LocalPeerDiscovery.Stop (); }); }
public void Setup() { var files = new [] { new TorrentFileInfo(new TorrentFile("First", Piece.BlockSize / 2)), new TorrentFileInfo(new TorrentFile("Second", Piece.BlockSize)), new TorrentFileInfo(new TorrentFile("Third", Piece.BlockSize + Piece.BlockSize / 2)), new TorrentFileInfo(new TorrentFile("Fourth", Piece.BlockSize * 2 + Piece.BlockSize / 2)), }; buffer = new byte[Piece.BlockSize]; data = new TestTorrentData { Files = files, Size = files.Sum(f => f.Length), PieceLength = Piece.BlockSize * 2 }; writer = new ExceptionWriter(); diskManager = new DiskManager(new EngineSettings(), writer); }
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)); } }
public void Setup() { var pieceLength = Piece.BlockSize * 2; var files = TorrentFileInfo.Create(pieceLength, Piece.BlockSize / 2, Piece.BlockSize, Piece.BlockSize + Piece.BlockSize / 2, Piece.BlockSize * 2 + Piece.BlockSize / 2 ); buffer = new byte[Piece.BlockSize]; data = new TestTorrentData { Files = files, Size = files.Sum(f => f.Length), PieceLength = pieceLength }; writer = new ExceptionWriter(); diskManager = new DiskManager(new EngineSettings(), writer); }
public void Setup() { var pieceLength = Constants.BlockSize * 2; var files = TorrentFileInfo.Create(pieceLength, Constants.BlockSize / 2, Constants.BlockSize, Constants.BlockSize + Constants.BlockSize / 2, Constants.BlockSize * 2 + Constants.BlockSize / 2 ); buffer = new byte[Constants.BlockSize]; data = new TestTorrentData { Files = files, Size = files.Sum(f => f.Length), PieceLength = pieceLength }; writer = new ExceptionWriter(); diskManager = new DiskManager(new EngineSettings(), Factories.Default, writer); }
/// <summary> /// /// </summary> /// <param name="manager">The torrent which the peer is associated with.</param> /// <param name="id">The peer whose message queue you want to start processing</param> internal async void ProcessQueue(TorrentManager manager, PeerId id) { while (id.QueueLength > 0) { var msg = id.Dequeue(); var pm = msg as PieceMessage; try { if (pm != null) { pm.Data = ClientEngine.BufferManager.GetBuffer(pm.ByteLength); try { await DiskManager.ReadAsync(manager.Torrent, pm.StartOffset + ((long)pm.PieceIndex * manager.Torrent.PieceLength), pm.Data, pm.RequestLength); } catch (Exception ex) { manager.TrySetError(Reason.ReadFailure, ex); return; } id.PiecesSent++; } await PeerIO.SendMessageAsync(id.Connection, id.Encryptor, msg, manager.UploadLimiters, id.Monitor, manager.Monitor); if (msg is PieceMessage) { id.IsRequestingPiecesCount--; } id.LastMessageSent.Restart(); } catch { CleanupSocket(manager, id); break; } finally { if (pm?.Data != null) { ClientEngine.BufferManager.FreeBuffer(pm.Data); } } } id.ProcessingQueue = false; }
void LogicTick() { tickCount++; if (tickCount % 2 == 0) { downloadLimiter.UpdateChunks(Settings.MaximumDownloadSpeed, TotalDownloadSpeed); uploadLimiter.UpdateChunks(Settings.MaximumUploadSpeed, TotalUploadSpeed); } ConnectionManager.CancelPendingConnects(); ConnectionManager.TryConnect(); DiskManager.Tick(); for (int i = 0; i < allTorrents.Count; i++) { allTorrents[i].Mode.Tick(tickCount); } RaiseStatsUpdate(new StatsUpdateEventArgs()); }
public void Setup() { var random = new Random(); var files = new [] { new TorrentFile("First", Piece.BlockSize / 2), new TorrentFile("Second", Piece.BlockSize), new TorrentFile("Third", Piece.BlockSize + Piece.BlockSize / 2), new TorrentFile("Fourth", Piece.BlockSize * 6 + Piece.BlockSize / 2), }; var fileBytes = files .Select(f => { var b = new byte [f.Length]; random.NextBytes(b); return(b); }) .ToArray(); int pieceLength = Piece.BlockSize * 3; // Turn all the files into one byte array. Group the byte array into bittorrent pieces. Hash that piece. var hashes = fileBytes .SelectMany(t => t) .Partition(pieceLength) .Select(t => SHA1.Create().ComputeHash(t)) .ToArray(); fileData = new TestTorrentData { Data = fileBytes, Files = files, Hashes = hashes, Size = files.Sum(f => f.Length), PieceLength = pieceLength }; writer = new PieceWriter(); for (int i = 0; i < files.Length; i++) { writer.Data.Add(files[i], fileBytes[i]); } settings = new EngineSettings(); diskManager = new DiskManager(settings, writer); }
async Task UpdateSettingsAsync(EngineSettings oldSettings, EngineSettings newSettings) { await DiskManager.UpdateSettingsAsync(newSettings); if (newSettings.DiskCacheBytes != oldSettings.DiskCacheBytes) { await Task.WhenAll(Torrents.Select(t => DiskManager.FlushAsync(t))); } ConnectionManager.Settings = newSettings; if (oldSettings.AllowPortForwarding != newSettings.AllowPortForwarding) { if (newSettings.AllowPortForwarding) { await PortForwarder.StartAsync(CancellationToken.None); } else { await PortForwarder.StopAsync(removeExistingMappings : true, CancellationToken.None); } } if (oldSettings.DhtPort != newSettings.DhtPort) { if (DhtListener.EndPoint != null) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Udp, DhtListener.EndPoint.Port), CancellationToken.None); } else if (oldSettings.DhtPort > 0) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Udp, oldSettings.DhtPort), CancellationToken.None); } DhtListener = DhtListenerFactory.CreateUdp(newSettings.DhtPort); if (oldSettings.DhtPort == -1) { await RegisterDht(DhtEngineFactory.Create(DhtListener)); } else if (newSettings.DhtPort == -1) { await RegisterDht(new NullDhtEngine()); } DhtEngine.SetListener(DhtListener); if (IsRunning) { DhtListener.Start(); if (Listener is ISocketListener newDhtListener) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Udp, newDhtListener.EndPoint.Port)); } else { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Udp, newSettings.DhtPort)); } } } if (oldSettings.ListenPort != newSettings.ListenPort) { if (Listener is ISocketListener oldListener) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Tcp, oldListener.EndPoint.Port), CancellationToken.None); } else if (oldSettings.ListenPort > 0) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Tcp, oldSettings.ListenPort), CancellationToken.None); } Listener.Stop(); Listener = PeerListenerFactory.CreateTcp(newSettings.ListenPort); listenManager.SetListener(Listener); if (IsRunning) { Listener.Start(); // The settings could say to listen at port 0, which means 'choose one dynamically' if (Listener is ISocketListener peerListener) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Tcp, peerListener.EndPoint.Port)); } else { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Tcp, newSettings.ListenPort)); } } } // This depends on the Listener binding to it's local port. var localPort = newSettings.ListenPort; if (Listener is ISocketListener newListener) { localPort = newListener.EndPoint.Port; } if ((oldSettings.AllowLocalPeerDiscovery != newSettings.AllowLocalPeerDiscovery) || (oldSettings.ListenPort != newSettings.ListenPort)) { RegisterLocalPeerDiscovery(newSettings.AllowLocalPeerDiscovery && localPort > 0 ? new LocalPeerDiscovery(localPort) : null); } }
internal ConnectionManager(BEncodedString localPeerId, EngineSettings settings, DiskManager diskManager) { DiskManager = diskManager ?? throw new ArgumentNullException(nameof(diskManager)); LocalPeerId = localPeerId ?? throw new ArgumentNullException(nameof(localPeerId)); Settings = settings ?? throw new ArgumentNullException(nameof(settings)); PendingConnects = new List <AsyncConnectState>(); Torrents = new LinkedList <TorrentManager>(); }
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(); }
public DiskWriterLimiter(DiskManager manager) { this.manager = manager; }
public void FixtureSetup() { rig = TestRig.CreateMultiFile(); diskManager = rig.Engine.DiskManager; }
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); RegisterDht (new NullDhtEngine()); 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>(); CreateRateLimiters(); this.peerId = GeneratePeerId(); localPeerListener = new LocalPeerListener(this); localPeerManager = new LocalPeerManager(); LocalPeerSearchEnabled = SupportsLocalPeerDiscovery; listenManager.Register(listener); // This means we created the listener in the constructor if (listener.Endpoint.Port == 0) listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, settings.ListenPort)); }
/// <summary> /// /// </summary> /// <param name="manager">The torrent which the peer is associated with.</param> /// <param name="id">The peer whose message queue you want to start processing</param> internal async void TryProcessQueue(TorrentManager manager, PeerId id) { if (!id.MessageQueue.BeginProcessing()) { return; } await MainLoop.SwitchToThreadpool(); ByteBufferPool.Releaser messageBuffer = default; ByteBufferPool.Releaser pieceBuffer = default; PeerMessage msg; try { while ((msg = id.MessageQueue.TryDequeue()) != null) { var msgLength = msg.ByteLength; if (msg is PieceMessage pm) { if (pieceBuffer.Buffer == null) { pieceBuffer = DiskManager.BufferPool.Rent(msgLength, out ByteBuffer _); } pm.DataReleaser = pieceBuffer; try { await DiskManager.ReadAsync(manager, pm.StartOffset + ((long)pm.PieceIndex * manager.Torrent.PieceLength), pm.Data, pm.RequestLength).ConfigureAwait(false); } catch (Exception ex) { await ClientEngine.MainLoop; manager.TrySetError(Reason.ReadFailure, ex); return; } System.Threading.Interlocked.Increment(ref id.piecesSent); } else { pieceBuffer.Dispose(); } if (messageBuffer.Buffer == null || messageBuffer.Buffer.Data.Length < msg.ByteLength) { messageBuffer.Dispose(); messageBuffer = NetworkIO.BufferPool.Rent(msgLength, out ByteBuffer _); } await PeerIO.SendMessageAsync(id.Connection, id.Encryptor, msg, manager.UploadLimiters, id.Monitor, manager.Monitor, messageBuffer.Buffer).ConfigureAwait(false); if (msg is PieceMessage) { System.Threading.Interlocked.Decrement(ref id.isRequestingPiecesCount); } id.LastMessageSent.Restart(); } } catch { await ClientEngine.MainLoop; CleanupSocket(manager, id); } finally { messageBuffer.Dispose(); pieceBuffer.Dispose(); } }
public DistributedDiskManager(DiskManager diskManager, FileInfoTable<TorrentManager> tmTable) { _diskManager = diskManager; _torrentManagerTable = tmTable; }
async Task UpdateSettingsAsync(EngineSettings oldSettings, EngineSettings newSettings) { await DiskManager.UpdateSettingsAsync(newSettings); if (newSettings.DiskCacheBytes != oldSettings.DiskCacheBytes) { await Task.WhenAll(Torrents.Select(t => DiskManager.FlushAsync(t))); } ConnectionManager.Settings = newSettings; if (oldSettings.UsePartialFiles != newSettings.UsePartialFiles) { foreach (var manager in Torrents) { await manager.UpdateUsePartialFiles(newSettings.UsePartialFiles); } } if (oldSettings.AllowPortForwarding != newSettings.AllowPortForwarding) { if (newSettings.AllowPortForwarding) { await PortForwarder.StartAsync(CancellationToken.None); } else { await PortForwarder.StopAsync(removeExistingMappings : true, CancellationToken.None); } } if (oldSettings.DhtEndPoint != newSettings.DhtEndPoint) { if (DhtListener.LocalEndPoint != null) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Udp, DhtListener.LocalEndPoint.Port), CancellationToken.None); } DhtListener.Stop(); if (newSettings.DhtEndPoint == null) { DhtListener = new NullDhtListener(); await RegisterDht(new NullDhtEngine()); } else { DhtListener = Factories.CreateDhtListener(Settings.DhtEndPoint) ?? new NullDhtListener(); if (IsRunning) { DhtListener.Start(); } if (oldSettings.DhtEndPoint == null) { var dht = Factories.CreateDht(); await dht.SetListenerAsync(DhtListener); await RegisterDht(dht); } else { await DhtEngine.SetListenerAsync(DhtListener); } } if (DhtListener.LocalEndPoint != null) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Udp, DhtListener.LocalEndPoint.Port)); } } if (!Equals(oldSettings.ListenEndPoint, newSettings.ListenEndPoint)) { if (PeerListener.LocalEndPoint != null) { await PortForwarder.UnregisterMappingAsync(new Mapping (Protocol.Tcp, PeerListener.LocalEndPoint.Port), CancellationToken.None); } PeerListener.Stop(); PeerListener = (newSettings.ListenEndPoint == null ? null : Factories.CreatePeerConnectionListener(newSettings.ListenEndPoint)) ?? new NullPeerListener(); listenManager.SetListener(PeerListener); if (IsRunning) { PeerListener.Start(); // The settings could say to listen at port 0, which means 'choose one dynamically' if (PeerListener.LocalEndPoint != null) { await PortForwarder.RegisterMappingAsync(new Mapping (Protocol.Tcp, PeerListener.LocalEndPoint.Port)); } } } if (oldSettings.AllowLocalPeerDiscovery != newSettings.AllowLocalPeerDiscovery) { RegisterLocalPeerDiscovery(!newSettings.AllowLocalPeerDiscovery ? null : Factories.CreateLocalPeerDiscovery()); } }