public GetPeersTask(DhtEngine engine, NodeId infohash)
 {
     _engine = engine;
     _infoHash = infohash;
     _closestNodes = new SortedList<NodeId, NodeId>(Bucket.MaxCapacity);
     ClosestActiveNodes = new SortedList<NodeId, Node>(Bucket.MaxCapacity*2);
 }
 private void Initialise(DhtEngine engine, IEnumerable<Node> nodes)
 {
     _engine = engine;
     _initialNodes = new List<Node>();
     if (nodes != null)
         _initialNodes.AddRange(nodes);
 }
        public override void Handle(DhtEngine engine, Node node)
        {
            base.Handle(engine, node);

            if (Parameters.ContainsKey(NodesKey))
                engine.Add(Node.FromCompactNode(Nodes.TextBytes));
        }
示例#4
0
 void Initialise(DhtEngine engine, IEnumerable<Node> nodes)
 {
     this.engine = engine;
     this.initialNodes = new List<Node>();
     if (nodes != null)
         initialNodes.AddRange(nodes);
 }
示例#5
0
		public override void Handle(DhtEngine engine, Node node)
		{
			base.Handle(engine, node);

			var m = new PingResponse(engine.RoutingTable.LocalNode.Id, TransactionId);
			engine.MessageLoop.EnqueueSend(m, node.EndPoint);
		}
示例#6
0
 public GetPeersTask(DhtEngine engine, NodeId infohash)
 {
     this.engine = engine;
     this.infoHash = infohash;
     this.closestNodes = new SortedList<NodeId, NodeId>(Bucket.MaxCapacity);
     this.queriedNodes = new SortedList<NodeId, Node>(Bucket.MaxCapacity * 2);
 }
示例#7
0
        public override void Handle(DhtEngine engine, Node node)
        {
            base.Handle(engine, node);

            var response = new FindNodeResponse(engine.RoutingTable.LocalNode.Id, TransactionId);

            var targetNode = engine.RoutingTable.FindNode(Target);
            response.Nodes = targetNode != null
                ? targetNode.CompactNode()
                : Node.CompactNode(engine.RoutingTable.GetClosest(Target));

            engine.MessageLoop.EnqueueSend(response, node.EndPoint);
        }
示例#8
0
        public SendQueryTask(DhtEngine engine, QueryMessage query, Node node, int retries)
        {
            if (engine == null)
                throw new ArgumentNullException("engine");
            if (query == null)
                throw new ArgumentNullException("message");
            if (node == null)
                throw new ArgumentNullException("message");

            this.engine = engine;
            this.query = query;
            this.node = node;
            this.retries = retries;
            this.origRetries = retries;
        }
        public SendQueryTask(DhtEngine engine, QueryMessage query, Node node, int retries)
        {
            if (engine == null)
                throw new ArgumentNullException(nameof(engine));
            if (query == null)
                throw new ArgumentNullException(nameof(query));
            if (node == null)
                throw new ArgumentNullException(nameof(node));

            this._engine = engine;
            this._query = query;
            Target = node;
            this._retries = retries;
            Retries = retries;
        }
示例#10
0
		public override void Handle(DhtEngine engine, Node node)
		{
			base.Handle(engine, node);

			if (!engine.Torrents.ContainsKey(InfoHash))
				engine.Torrents.Add(InfoHash, new List<Node>());

			Message response;
			if (engine.TokenManager.VerifyToken(node, Token))
			{
				engine.Torrents[InfoHash].Add(node);
				response = new AnnouncePeerResponse(engine.RoutingTable.LocalNode.Id, TransactionId);
			}
			else
				response = new ErrorMessage(ErrorCode.ProtocolError, "Invalid or expired token received");

			engine.MessageLoop.EnqueueSend(response, node.EndPoint);
		}
示例#11
0
		public override void Handle(DhtEngine engine, Node node)
		{
			base.Handle(engine, node);

			BEncodedString token = engine.TokenManager.GenerateToken(node);
			var response = new GetPeersResponse(engine.RoutingTable.LocalNode.Id, TransactionId, token);
			if (engine.Torrents.ContainsKey(InfoHash))
			{
				var list = new BEncodedList();
				foreach (Node n in engine.Torrents[InfoHash])
					list.Add(n.CompactPort());
				response.Values = list;
			}
			else
			{
				// Is this right?
				response.Nodes = Node.CompactNode(engine.RoutingTable.GetClosest(InfoHash));
			}

			engine.MessageLoop.EnqueueSend(response, node.EndPoint);
		}
示例#12
0
 public AnnounceTask(DhtEngine engine, InfoHash infoHash, int port)
     : this(engine, new NodeId(infoHash), port)
 {
 }
示例#13
0
        void SettingsManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
            case "IncomingPort":
                Client.Listener.ChangeEndpoint(new IPEndPoint(IPAddress.Any, SettingsManager.IncomingPort));
                if (SettingsManager.MapWithUPnP)
                {
                    MapPort();
                }
                break;

            case "MapWithUPnP":
                if (SettingsManager.MapWithUPnP)
                {
                    MapPort();
                }
                break;

            case "MaxUploadSpeed":
                Client.Settings.GlobalMaxUploadSpeed = SettingsManager.MaxUploadSpeed * 1024;
                break;

            case "MaxDownloadSpeed":
                Client.Settings.GlobalMaxDownloadSpeed = SettingsManager.MaxDownloadSpeed * 1024;
                break;

            case "MaxConnections":
                Client.Settings.GlobalMaxConnections = SettingsManager.MaxConnections;
                break;

            case "EnableDHT":
                if (SettingsManager.EnableDHT)
                {
                    var port = SettingsManager.IncomingPort;
                    if (SettingsManager.UseRandomPort)
                    {
                        port = new Random().Next(1, 65536);
                    }
                    var listener = new DhtListener(new IPEndPoint(IPAddress.Any, port));
                    var dht      = new DhtEngine(listener);
                    Client.RegisterDht(dht);
                    listener.Start();
                    if (File.Exists(SettingsManager.DhtCachePath))
                    {
                        dht.Start(File.ReadAllBytes(SettingsManager.DhtCachePath));
                    }
                    else
                    {
                        dht.Start();
                    }
                }
                else
                {
                    Client.DhtEngine.Stop();
                }
                break;

            case "EncryptionSettings":
                Client.Settings.AllowedEncryption = SettingsManager.EncryptionSettings;
                break;

            case "ProxyAddress":
            case "EnableProxyAuthentication":
            case "ProxyUsername":
            case "ProxyPassword":
                if (string.IsNullOrEmpty(SettingsManager.ProxyAddress))
                {
                    ConnectionFactory.RegisterTypeForProtocol("tcp", typeof(IPV4Connection));
                }
                else
                {
                    ConnectionFactory.RegisterTypeForProtocol("tcp", typeof(ProxiedConnection));
                    ushort port    = 1080;
                    string address = SettingsManager.ProxyAddress;
                    if (SettingsManager.ProxyAddress.Contains(':'))
                    {
                        var parts = SettingsManager.ProxyAddress.Split(':');
                        address = parts[0];
                        port    = ushort.Parse(parts[1]);
                    }
                    if (!SettingsManager.EnableProxyAuthentication)
                    {
                        ProxiedConnection.SetProxyDetails(address, port);
                    }
                    else
                    {
                        ProxiedConnection.SetProxyDetails(address, port, SettingsManager.ProxyUsername, SettingsManager.ProxyPassword);
                    }
                }
                break;
            }
        }
示例#14
0
        public AnnounceTask(DhtEngine engine, InfoHash infoHash, int port)
            : this(engine, new NodeId(infoHash), port)
        {

        }
示例#15
0
 public InitialiseTask(DhtEngine engine)
     : this(engine, Enumerable.Empty <Node> ())
 {
 }
 public InitialiseTask(DhtEngine engine, IEnumerable <Node> nodes)
 {
     Initialise(engine, nodes);
 }
 public InitialiseTask(DhtEngine engine, IEnumerable<Node> nodes)
 {
     Initialise(engine, nodes);
 }
        public override void Handle(DhtEngine engine, Node node)
        {
            base.Handle(engine, node);

            throw new MessageException(ErrorCode, Message);
        }
示例#19
0
 public ReplaceNodeTask(DhtEngine engine, Bucket bucket, Node newNode)
 {
     _engine  = engine;
     _bucket  = bucket;
     _newNode = newNode;
 }
示例#20
0
 public RefreshBucketTask(DhtEngine engine, Bucket bucket)
 {
     _engine = engine;
     _bucket = bucket;
 }
示例#21
0
 public RefreshBucketTask(DhtEngine engine, Bucket bucket)
 {
     _engine = engine;
     _bucket = bucket;
 }
示例#22
0
        private static async Task StartEngine()
        {
            int     port;
            Torrent torrent = null;

            // Ask the user what port they want to use for incoming connections
            // 询问用户要将使用哪个端口用于连接
            Console.Write($"{Environment.NewLine} 选择监听的端口: ");
            while (!Int32.TryParse(Console.ReadLine(), out port))
            {
            }

            // 创建一个引擎的默认配置
            // downloadsPath - 文件下载的目录
            // port - 引擎监听的端口
            EngineSettings engineSettings = new EngineSettings {
                SavePath   = downloadsPath,
                ListenPort = port
            };

            //engineSettings.GlobalMaxUploadSpeed = 30 * 1024;
            //engineSettings.GlobalMaxDownloadSpeed = 100 * 1024;
            //engineSettings.MaxReadRate = 1 * 1024 * 1024;

            // 创建一个 Torrent 默认的配置信息.
            TorrentSettings torrentDefaults = new TorrentSettings();

            // 创建一个客户端引擎.
            engine = new ClientEngine(engineSettings);

            byte[] nodes = Array.Empty <byte> ();
            try {
                if (File.Exists(dhtNodeFile))
                {
                    nodes = File.ReadAllBytes(dhtNodeFile);
                }
            } catch {
                Console.WriteLine("No existing dht nodes could be loaded");
            }

            DhtEngine dht = new DhtEngine(new IPEndPoint(IPAddress.Any, port));
            await engine.RegisterDhtAsync(dht);

            // 这将启动Dht引擎,但不会等待完全初始化完成.
            // 这是因为根据连接节点时超时的数量,启动最多需要2分钟.
            await engine.DhtEngine.StartAsync(nodes);

            // 如果下载路径不存在,则创建之.
            if (!Directory.Exists(engine.Settings.SavePath))
            {
                Directory.CreateDirectory(engine.Settings.SavePath);
            }

            // 如果Torrent存储目录不存在,则创建之.
            if (!Directory.Exists(torrentsPath))
            {
                Directory.CreateDirectory(torrentsPath);
            }

            BEncodedDictionary fastResume = new BEncodedDictionary();

            try {
                if (File.Exists(fastResumeFile))
                {
                    fastResume = BEncodedValue.Decode <BEncodedDictionary> (File.ReadAllBytes(fastResumeFile));
                }
            } catch {
            }

            // 将Torrents目录中的每个 torrent 文件将其加载到引擎中.
            foreach (string file in Directory.GetFiles(torrentsPath))
            {
                if (file.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase))
                {
                    try {
                        // 加载torrent文件到Torrent实例中,如果需要的话,可以使用它进行预处理
                        torrent = await Torrent.LoadAsync(file);

                        Console.WriteLine(torrent.InfoHash.ToString());
                    } catch (Exception e) {
                        Console.Write("Couldn't decode {0}: ", file);
                        Console.WriteLine(e.Message);
                        continue;
                    }
                    // 当任何预处理完成后,您将创建一个TorrentManager,然后在引擎上创建它.
                    TorrentManager manager = new TorrentManager(torrent, downloadsPath, torrentDefaults);
                    if (fastResume.ContainsKey(torrent.InfoHash.ToHex()))
                    {
                        manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.InfoHash.ToHex()]));
                    }
                    await engine.Register(manager);

                    // 将 TorrentManager 存储在列表中,方便以后访问它.
                    torrents.Add(manager);
                    manager.PeersFound += Manager_PeersFound;
                }
            }

            // If we loaded no torrents, just exist. The user can put files in the torrents directory and start the client again
            if (torrents.Count == 0)
            {
                Console.WriteLine("没有在目录中找到 torrent 文件");
                Console.WriteLine("退出...");
                engine.Dispose();
                return;
            }

            // 遍历存储在列表中的每个TorrentManager,在TorrentManager中连接到事件并启动引擎。
            foreach (TorrentManager manager in torrents)
            {
                manager.PeerConnected += (o, e) => {
                    lock (listener)
                        listener.WriteLine($"连接成功: {e.Peer.Uri}");
                };
                manager.ConnectionAttemptFailed += (o, e) => {
                    lock (listener)
                        listener.WriteLine(
                            $"连接失败: {e.Peer.ConnectionUri} - {e.Reason} - {e.Peer.AllowedEncryption}");
                };
                // 每次散列一个片段,就会触发这个.
                manager.PieceHashed += delegate(object o, PieceHashedEventArgs e) {
                    lock (listener)
                        listener.WriteLine($"散列的片段: {e.PieceIndex} - {(e.HashPassed ? "Pass" : "Fail")}");
                };

                // 每当状态改变时触发 (Stopped -> Seeding -> Downloading -> Hashing)
                manager.TorrentStateChanged += delegate(object o, TorrentStateChangedEventArgs e) {
                    lock (listener)
                        listener.WriteLine($"旧状态: {e.OldState} 新状态: {e.NewState}");
                };

                // 每当跟踪器的状态改变时,就会触发.
                manager.TrackerManager.AnnounceComplete += (sender, e) => {
                    listener.WriteLine($"{e.Successful}: {e.Tracker}");
                };

                // 开始运行TorrentManager.
                // 然后文件将散列(如果需要)并开始下载/发送.
                await manager.StartAsync();
            }

            // Enable automatic port forwarding. The engine will use Mono.Nat to search for
            // uPnP or NAT-PMP compatible devices and then issue port forwarding requests to it.
            await engine.EnablePortForwardingAsync(CancellationToken.None);

            // This is how to access the list of port mappings, and to see if they were
            // successful, pending or failed. If they failed it could be because the public port
            // is already in use by another computer on your network.
            foreach (var successfulMapping in engine.PortMappings.Created)
            {
            }
            foreach (var failedMapping in engine.PortMappings.Failed)
            {
            }
            foreach (var failedMapping in engine.PortMappings.Pending)
            {
            }

            // While the torrents are still running, print out some stats to the screen.
            // Details for all the loaded torrent managers are shown.
            int           i       = 0;
            bool          running = true;
            StringBuilder sb      = new StringBuilder(1024);

            while (running)
            {
                if ((i++) % 10 == 0)
                {
                    sb.Remove(0, sb.Length);
                    running = torrents.Exists(m => m.State != TorrentState.Stopped);

                    AppendFormat(sb, "总下载速度: {0:0.00}kB/sec", engine.TotalDownloadSpeed / 1024.0);
                    AppendFormat(sb, "总上传速度:   {0:0.00}kB/sec", engine.TotalUploadSpeed / 1024.0);
                    AppendFormat(sb, "磁盘读速度:      {0:0.00} kB/s", engine.DiskManager.ReadRate / 1024.0);
                    AppendFormat(sb, "磁盘写速度:     {0:0.00} kB/s", engine.DiskManager.WriteRate / 1024.0);
                    AppendFormat(sb, "Total Read:         {0:0.00} kB", engine.DiskManager.TotalRead / 1024.0);
                    AppendFormat(sb, "Total Written:      {0:0.00} kB", engine.DiskManager.TotalWritten / 1024.0);
                    AppendFormat(sb, "Open Connections:    {0}", engine.ConnectionManager.OpenConnections);

                    foreach (TorrentManager manager in torrents)
                    {
                        AppendSeparator(sb);
                        AppendFormat(sb, "状态:           {0}", manager.State);
                        AppendFormat(sb, "名称:            {0}", manager.Torrent == null ? "MetaDataMode" : manager.Torrent.Name);
                        AppendFormat(sb, "进度:           {0:0.00}", manager.Progress);
                        AppendFormat(sb, "下载速度:     {0:0.00} kB/s", manager.Monitor.DownloadSpeed / 1024.0);
                        AppendFormat(sb, "上传速度:       {0:0.00} kB/s", manager.Monitor.UploadSpeed / 1024.0);
                        AppendFormat(sb, "下载量:   {0:0.00} MB", manager.Monitor.DataBytesDownloaded / (1024.0 * 1024.0));
                        AppendFormat(sb, "上传量:     {0:0.00} MB", manager.Monitor.DataBytesUploaded / (1024.0 * 1024.0));
                        AppendFormat(sb, "Tracker Status");
                        foreach (var tier in manager.TrackerManager.Tiers)
                        {
                            AppendFormat(sb, $"\t{tier.ActiveTracker} : Announce Succeeded: {tier.LastAnnounceSucceeded}. Scrape Succeeded: {tier.LastScrapSucceeded}.");
                        }
                        if (manager.PieceManager != null)
                        {
                            AppendFormat(sb, "当前请求:   {0}", await manager.PieceManager.CurrentRequestCountAsync());
                        }

                        foreach (PeerId p in await manager.GetPeersAsync())
                        {
                            AppendFormat(sb, "\t{2} - {1:0.00}/{3:0.00}kB/sec - {0}", p.Uri,
                                         p.Monitor.DownloadSpeed / 1024.0,
                                         p.AmRequestingPiecesCount,
                                         p.Monitor.UploadSpeed / 1024.0);
                        }

                        AppendFormat(sb, "", null);
                        if (manager.Torrent != null)
                        {
                            foreach (TorrentFile file in manager.Torrent.Files)
                            {
                                AppendFormat(sb, "{1:0.00}% - {0}", file.Path, file.BitField.PercentComplete);
                            }
                        }
                    }
                    Console.Clear();
                    Console.WriteLine(sb.ToString());
                    listener.ExportTo(Console.Out);
                }

                Thread.Sleep(500);
            }

            // 停止搜索与uPnP或NAT-PMP兼容的设备,并删除所有已创建的映射.
            await engine.DisablePortForwardingAsync(CancellationToken.None);
        }
示例#23
0
 public AnnounceTask(DhtEngine engine, NodeId infoHash, int port)
 {
     _engine = engine;
     _infoHash = infoHash;
     _port = port;
 }
示例#24
0
 public ReplaceNodeTask(DhtEngine engine, Bucket bucket, Node newNode)
 {
     this.engine  = engine;
     this.bucket  = bucket;
     this.newNode = newNode;
 }
示例#25
0
 public InitialiseTask(DhtEngine engine, IEnumerable <Node> nodes)
 {
     this.engine            = engine;
     initialNodes           = new List <Node> (nodes);
     initializationComplete = new TaskCompletionSource <object> ();
 }
示例#26
0
        void Start()
        {
            //Start Torrent Engine
            torrents = new List <TorrentManager>();
            messages = new List <SimpleMessage>();

            //Torrents to remove
            seedingLimitTorrents = new List <Tuple <DateTime, TorrentManager> >();

            Console.WriteLine("simpletorrent: version {0}", VERSION);
            Console.WriteLine("simpletorrent: Reading configuration file (simple.cfg)...");

            config = new SimpleConfiguration("simple.cfg");
            string basePath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);

            Console.WriteLine("simpletorrent: ApplicationPath (derived) {0}", basePath);

            if (config.HasValue("Debug"))
            {
                debugWriter = new DebugWriter(true);
                Console.WriteLine("simpletorrent: Debugging Enabled!");
            }
            else
            {
                debugWriter = new DebugWriter(false);
            }

            PlatformID os = Environment.OSVersion.Platform;

            if (os == PlatformID.MacOSX)
            {
                Console.WriteLine("simpletorrent: We think we're on MacOSX");
                simpleOperatingSystem = SimpleTorrentOperatingMode.MacOSX;
            }
            else if (os == PlatformID.Unix)
            {
                Console.WriteLine("simpletorrent: We think we're on *nix");
                simpleOperatingSystem = SimpleTorrentOperatingMode.StarNix;
            }
            else
            {
                Console.WriteLine("simpletorrent: We think we're on Windows");
                simpleOperatingSystem = SimpleTorrentOperatingMode.Windows;
            }

            torrentsPath       = Path.GetFullPath(config.GetValue("TorrentPath", Path.Combine(basePath, "Torrents")));
            downloadsPath      = Path.GetFullPath(config.GetValue("DownloadPath", Path.Combine(basePath, "Downloads")));
            sslCertificatePath = Path.GetFullPath(config.GetValue("SslCertificatePath", Path.Combine(basePath, "simple.pfx")));
            useECDSA           = config.HasValue("SslCertificateECDSA");
            fastResumeFile     = Path.Combine(torrentsPath, "fastresume.data");
            dhtNodeFile        = Path.Combine(torrentsPath, "dht.data");

            requireProtocolEncryption = config.HasValue("RequireProtocolEncryption");

            sessionLimit = config.GetValueInt("SessionLimit", 20);
            seedingLimit = config.GetValueInt("SeedingLimit");

            // If the SavePath does not exist, we want to create it.
            if (!Directory.Exists(downloadsPath))
            {
                Directory.CreateDirectory(downloadsPath);
            }

            // If the torrentsPath does not exist, we want to create it
            if (!Directory.Exists(torrentsPath))
            {
                Directory.CreateDirectory(torrentsPath);
            }

            downloadsPathDrive = null;
            string myRootPath = Path.GetPathRoot(downloadsPath).ToLower();

            if (simpleOperatingSystem == SimpleTorrentOperatingMode.StarNix)
            {
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.EnableRaisingEvents              = false;
                proc.StartInfo.FileName               = "bash";
                proc.StartInfo.Arguments              = "-c \"df -h " + downloadsPath + " | awk '{print $6}' | tail -1\"";
                proc.StartInfo.UseShellExecute        = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.Start();
                string output = proc.StandardOutput.ReadToEnd().Trim().ToLower();
                proc.WaitForExit();

                if (proc.ExitCode == 0)
                {
                    myRootPath = output;
                    debugWriter.WriteLine("*nix override (bash -c 'df -h <path>') - \"" + output + "\"");
                }
            }
            else if (simpleOperatingSystem == SimpleTorrentOperatingMode.MacOSX)
            {
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.EnableRaisingEvents              = false;
                proc.StartInfo.FileName               = "bash";
                proc.StartInfo.Arguments              = "-c \"df -h " + downloadsPath + " | awk '{print $9}' | tail -1\"";
                proc.StartInfo.UseShellExecute        = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.Start();
                string output = proc.StandardOutput.ReadToEnd().Trim().ToLower();
                proc.WaitForExit();

                if (proc.ExitCode == 0)
                {
                    myRootPath = output;
                    debugWriter.WriteLine("*nix override (bash -c 'df -h <path>') - \"" + output + "\"");
                }
            }

            foreach (var drive in DriveInfo.GetDrives())
            {
                debugWriter.WriteLine("Enemerating Drives - " + drive.RootDirectory.FullName.ToString());

                if (drive.RootDirectory.FullName.ToLower()
                    == myRootPath)
                {
                    downloadsPathDrive = drive;
                    break;
                }
            }

            Console.WriteLine("simpletorrent: TorrentPath {0}", torrentsPath);
            Console.WriteLine("simpletorrent: DownloadPath {0}", downloadsPath);
            Console.WriteLine("simpletorrent: DownloadRootPath (derived) {0}", downloadsPathDrive);
            Console.WriteLine("simpletorrent: SslCertificatePath {0}", sslCertificatePath);
            Console.WriteLine("simpletorrent: SslCertificateECDSA {0}", useECDSA ? "Yes" : "No");
            Console.WriteLine("simpletorrent: RequireProtocolEncryption {0}", requireProtocolEncryption ? "Yes" : "No");
            Console.WriteLine("simpletorrent: SessionLimit {0}", sessionLimit);
            Console.WriteLine("simpletorrent: SeedingLimit {0}", seedingLimit.HasValue ? seedingLimit.Value.ToString() : "No");

            int?torrentListenPort = config.GetValueInt("TorrentListenPort");

            if (!torrentListenPort.HasValue)
            {
                throw new SimpleTorrentException("Configuration does not have a proper 'TorrentListenPort' value defined", null);
            }

            Console.WriteLine("simpletorrent: TorrentListenPort {0}", torrentListenPort);

            externalBanList  = new List <string>();
            externalBanLists = new Dictionary <string, BanList>();
            foreach (var i in config.GetValues("ExternalBanList"))
            {
                Console.WriteLine("simpletorrent: ExternalBanList {0}", i);
                externalBanList.Add(i);
            }

            externalBanListLimit = config.GetValueInt("ExternalBanListLimit");

            if (externalBanListLimit.HasValue)
            {
                Console.WriteLine("simpletorrent: ExternalBanListLimit {0}", externalBanListLimit.Value);
            }

            EngineSettings engineSettings = new EngineSettings(downloadsPath, torrentListenPort.Value);

            engineSettings.PreferEncryption     = true;
            engineSettings.AllowedEncryption    = requireProtocolEncryption ? EncryptionTypes.RC4Full : EncryptionTypes.All;
            engineSettings.GlobalMaxConnections = 500;

            torrentDefaults = new TorrentSettings(4, 500, 0, 0);
            engine          = new ClientEngine(engineSettings);
            engine.ChangeListenEndpoint(new IPEndPoint(IPAddress.Any, torrentListenPort.Value));

            byte[] nodes = null;
            try
            {
                nodes = File.ReadAllBytes(dhtNodeFile);
            }
            catch
            {
                Console.WriteLine("simpletorrent: No existing DHT nodes could be loaded");
            }

            dhtListner = new DhtListener(new IPEndPoint(IPAddress.Any, torrentListenPort.Value));
            DhtEngine dht = new DhtEngine(dhtListner);

            engine.RegisterDht(dht);
            dhtListner.Start();
            engine.DhtEngine.Start(nodes);

            foreach (var torrent in Directory.GetFiles(torrentsPath, "*.torrent"))
            {
                Torrent t = Torrent.Load(torrent);

                if (engine.Torrents.Where(i => i.InfoHash == t.InfoHash).Count() == 0)
                {
                    TorrentManager tm = new TorrentManager(t, downloadsPath, torrentDefaults);
                    engine.Register(tm);
                }
            }

            BEncodedDictionary fastResume;

            try
            {
                fastResume = BEncodedValue.Decode <BEncodedDictionary>(File.ReadAllBytes(fastResumeFile));
            }
            catch
            {
                fastResume = new BEncodedDictionary();
            }

            if (seedingLimit.HasValue)
            {
                Console.WriteLine("simpletorrent: Starting seeding limits watchdog timer...");
                seedingLimitTimer           = new System.Timers.Timer();
                seedingLimitTimer.AutoReset = true;
                seedingLimitTimer.Interval  = 60 * 1000;
                seedingLimitTimer.Elapsed  += (s, e) =>
                {
                    lock (seedingLimitTorrents)
                    {
                        var torrentsToRemove = seedingLimitTorrents.Where(a => (DateTime.Now - a.Item1).TotalSeconds >= seedingLimit).ToArray();
                        foreach (var i in torrentsToRemove)
                        {
                            try
                            {
                                seedingLimitTorrents.Remove(i);

                                if (i != null && i.Item2.State == TorrentState.Seeding)
                                {
                                    Console.WriteLine("simpletorrent: Automatically removing \"{0}\"...",
                                                      i.Item2.Torrent.Name);
                                    torrentInformation[i.Item2.InfoHash.ToHex()].ToRemove = "delete-torrent";
                                    i.Item2.Stop();
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                };
                seedingLimitTimer.Start();
            }

            //Ban List System
            UpdateBanLists();

            engine.ConnectionManager.BanPeer += (s, e) =>
            {
                bool ban = false;

                lock (externalBanLists)
                {
                    foreach (var i in externalBanLists)
                    {
                        ban |= i.Value.IsBanned(IPAddress.Parse(e.Peer.ConnectionUri.Host));
                    }
                }

                e.BanPeer = ban;

                if (e.BanPeer)
                {
                    debugWriter.WriteLine(string.Format("Connection from {0} denied.", e.Peer.ConnectionUri.Host));
                }
                else
                {
                    debugWriter.WriteLine(string.Format("Connection from {0} allowed.", e.Peer.ConnectionUri.Host));
                }
            };

            if (externalBanListLimit.HasValue)
            {
                Console.WriteLine("simpletorrent: Starting external ban list update timer...");
                externalBanListLimitTimer           = new System.Timers.Timer();
                externalBanListLimitTimer.AutoReset = true;
                externalBanListLimitTimer.Interval  = 1000 * externalBanListLimit.Value;
                externalBanListLimitTimer.Elapsed  += (s, e) =>
                {
                    UpdateBanLists();
                };

                externalBanListLimitTimer.Start();
            }

            using (var httpServer = new HttpServer(new HttpRequestProvider()))
            {
                Console.WriteLine("simpletorrent: Starting HTTP(S) server...");
                bool listeningOne = false;

                Console.WriteLine("simpletorrent: Creating session manager...");
                httpServer.Use(new SessionHandler <SimpleTorrentSession>(() =>
                                                                         new SimpleTorrentSession(), sessionLimit));

                foreach (var ip in config.GetValues("Listen"))
                {
                    try
                    {
                        TcpListener tl = getTcpListener(ip);
                        httpServer.Use(new TcpListenerAdapter(tl));
                        Console.WriteLine("simpletorrent: Listening for HTTP on {0}...", tl.LocalEndpoint);
                        listeningOne = true;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("simpletorrent: ({0}) " + ex.Message, ip);
                    }
                }


                System.Security.Cryptography.X509Certificates.X509Certificate2 cert = null;
                if (config.HasValue("ListenSsl"))
                {
                    cert = SSLSelfSigned.GetCertOrGenerate(sslCertificatePath, useECDSA);
                }

                foreach (var ip in config.GetValues("ListenSsl"))
                {
                    try
                    {
                        TcpListener tl = getTcpListener(ip);

                        //Mono does not support TLS 1.1 or 1.2 -->
#if MONO
                        httpServer.Use(new ListenerSslDecorator(new TcpListenerAdapter(tl), cert, System.Security.Authentication.SslProtocols.Ssl3 |
                                                                System.Security.Authentication.SslProtocols.Tls));
#else
                        //Force new systems to use TLS 1.1 or 1.2
                        httpServer.Use(new ListenerSslDecorator(new TcpListenerAdapter(tl), cert, System.Security.Authentication.SslProtocols.Tls11
                                                                | System.Security.Authentication.SslProtocols.Tls12));
#endif

                        Console.WriteLine("simpletorrent: Listening for HTTPS on {0}...", tl.LocalEndpoint);
                        listeningOne = true;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("simpletorrent: ({0}) " + ex.Message, ip);
                    }
                }

                if (!listeningOne)
                {
                    throw new SimpleTorrentException("simpletorrent was unable to bind to a single port.");
                }

                Console.WriteLine("simpletorrent: Running...");

                httpServer.Use((context, next) =>
                {
                    context.Response = ProcessRequest(context);

                    return(Task.Factory.GetCompleted());
                });

                foreach (var tm in engine.Torrents)
                {
                    SetupTorrent(tm);
                }

                httpServer.Start();

                Console.ReadLine();
            }
        }
示例#27
0
 public SendQueryTask(DhtEngine engine, QueryMessage query, Node node)
     : this(engine, query, node, 3)
 {
 }
 public InitialiseTask(DhtEngine engine)
 {
     Initialise(engine, null);
 }
示例#29
0
        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());
            }
        }
示例#30
0
 public virtual void Handle(DhtEngine engine, Node node)
 {
     node.Seen();
 }
示例#31
0
        public override async Task HandleAsync(DhtEngine engine, Node node)
        {
            await base.HandleAsync(engine, node);

            await engine.AddAsync(Node.FromCompactNode(Nodes.TextBytes));
        }
示例#32
0
 public GetPeersTask(DhtEngine engine, InfoHash infohash)
     : this(engine, new NodeId(infohash))
 {
     iInfoHash = infohash;
 }
示例#33
0
        private static void StartEngine()
        {
            int     port;
            Torrent torrent = null;

            // Ask the user what port they want to use for incoming connections
            Console.Write(Environment.NewLine + "Choose a listen port: ");
            while (!Int32.TryParse(Console.ReadLine(), out port))
            {
            }



            // Create the settings which the engine will use
            // downloadsPath - this is the path where we will save all the files to
            // port - this is the port we listen for connections on
            EngineSettings engineSettings = new EngineSettings(downloadsPath, port);

            engineSettings.PreferEncryption  = false;
            engineSettings.AllowedEncryption = EncryptionTypes.All;

            //engineSettings.GlobalMaxUploadSpeed = 30 * 1024;
            //engineSettings.GlobalMaxDownloadSpeed = 100 * 1024;
            //engineSettings.MaxReadRate = 1 * 1024 * 1024;


            // Create the default settings which a torrent will have.
            // 4 Upload slots - a good ratio is one slot per 5kB of upload speed
            // 50 open connections - should never really need to be changed
            // Unlimited download speed - valid range from 0 -> int.Max
            // Unlimited upload speed - valid range from 0 -> int.Max
            TorrentSettings torrentDefaults = new TorrentSettings(4, 150, 0, 0);

            // Create an instance of the engine.
            engine = new ClientEngine(engineSettings);
            engine.ChangeListenEndpoint(new IPEndPoint(IPAddress.Any, port));
            byte[] nodes = null;
            try
            {
                nodes = File.ReadAllBytes(dhtNodeFile);
            }
            catch
            {
                Console.WriteLine("No existing dht nodes could be loaded");
            }

            DhtListener dhtListner = new DhtListener(new IPEndPoint(IPAddress.Any, port));
            DhtEngine   dht        = new DhtEngine(dhtListner);

            engine.RegisterDht(dht);
            dhtListner.Start();
            engine.DhtEngine.Start(nodes);

            // If the SavePath does not exist, we want to create it.
            if (!Directory.Exists(engine.Settings.SavePath))
            {
                Directory.CreateDirectory(engine.Settings.SavePath);
            }

            // If the torrentsPath does not exist, we want to create it
            if (!Directory.Exists(torrentsPath))
            {
                Directory.CreateDirectory(torrentsPath);
            }

            BEncodedDictionary fastResume;

            try
            {
                fastResume = BEncodedValue.Decode <BEncodedDictionary>(File.ReadAllBytes(fastResumeFile));
            }
            catch
            {
                fastResume = new BEncodedDictionary();
            }

            // For each file in the torrents path that is a .torrent file, load it into the engine.
            foreach (string file in Directory.GetFiles(torrentsPath))
            {
                if (file.EndsWith(".torrent"))
                {
                    try
                    {
                        // Load the .torrent from the file into a Torrent instance
                        // You can use this to do preprocessing should you need to
                        torrent = Torrent.Load(file);
                        Console.WriteLine(torrent.InfoHash.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.Write("Couldn't decode {0}: ", file);
                        Console.WriteLine(e.Message);
                        continue;
                    }
                    // When any preprocessing has been completed, you create a TorrentManager
                    // which you then register with the engine.
                    TorrentManager manager = new TorrentManager(torrent, downloadsPath, torrentDefaults);
                    if (fastResume.ContainsKey(torrent.InfoHash.ToHex()))
                    {
                        manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.infoHash.ToHex()]));
                    }
                    engine.Register(manager);

                    // Store the torrent manager in our list so we can access it later
                    torrents.Add(manager);
                    manager.PeersFound += new EventHandler <PeersAddedEventArgs>(manager_PeersFound);
                }
            }

            // If we loaded no torrents, just exist. The user can put files in the torrents directory and start
            // the client again
            if (torrents.Count == 0)
            {
                Console.WriteLine("No torrents found in the Torrents directory");
                Console.WriteLine("Exiting...");
                engine.Dispose();
                return;
            }

            // For each torrent manager we loaded and stored in our list, hook into the events
            // in the torrent manager and start the engine.
            foreach (TorrentManager manager in torrents)
            {
                // Every time a piece is hashed, this is fired.
                manager.PieceHashed += delegate(object o, PieceHashedEventArgs e) {
                    lock (listener)
                        listener.WriteLine(string.Format("Piece Hashed: {0} - {1}", e.PieceIndex, e.HashPassed ? "Pass" : "Fail"));
                };

                // Every time the state changes (Stopped -> Seeding -> Downloading -> Hashing) this is fired
                manager.TorrentStateChanged += delegate(object o, TorrentStateChangedEventArgs e) {
                    lock (listener)
                        listener.WriteLine("OldState: " + e.OldState.ToString() + " NewState: " + e.NewState.ToString());
                };

                // Every time the tracker's state changes, this is fired
                foreach (TrackerTier tier in manager.TrackerManager)
                {
                    foreach (System.Net.BitTorrent.Client.Tracker.Tracker t in tier.Trackers)
                    {
                        t.AnnounceComplete += delegate(object sender, AnnounceResponseEventArgs e) {
                            listener.WriteLine(string.Format("{0}: {1}", e.Successful, e.Tracker.ToString()));
                        };
                    }
                }
                // Start the torrentmanager. The file will then hash (if required) and begin downloading/seeding
                manager.Start();
            }

            // While the torrents are still running, print out some stats to the screen.
            // Details for all the loaded torrent managers are shown.
            int           i       = 0;
            bool          running = true;
            StringBuilder sb      = new StringBuilder(1024);

            while (running)
            {
                if ((i++) % 10 == 0)
                {
                    sb.Remove(0, sb.Length);
                    running = torrents.Exists(delegate(TorrentManager m) { return(m.State != TorrentState.Stopped); });

                    AppendFormat(sb, "Total Download Rate: {0:0.00}kB/sec", engine.TotalDownloadSpeed / 1024.0);
                    AppendFormat(sb, "Total Upload Rate:   {0:0.00}kB/sec", engine.TotalUploadSpeed / 1024.0);
                    AppendFormat(sb, "Disk Read Rate:      {0:0.00} kB/s", engine.DiskManager.ReadRate / 1024.0);
                    AppendFormat(sb, "Disk Write Rate:     {0:0.00} kB/s", engine.DiskManager.WriteRate / 1024.0);
                    AppendFormat(sb, "Total Read:         {0:0.00} kB", engine.DiskManager.TotalRead / 1024.0);
                    AppendFormat(sb, "Total Written:      {0:0.00} kB", engine.DiskManager.TotalWritten / 1024.0);
                    AppendFormat(sb, "Open Connections:    {0}", engine.ConnectionManager.OpenConnections);

                    foreach (TorrentManager manager in torrents)
                    {
                        AppendSeperator(sb);
                        AppendFormat(sb, "State:           {0}", manager.State);
                        AppendFormat(sb, "Name:            {0}", manager.Torrent == null ? "MetaDataMode" : manager.Torrent.Name);
                        AppendFormat(sb, "Progress:           {0:0.00}", manager.Progress);
                        AppendFormat(sb, "Download Speed:     {0:0.00} kB/s", manager.Monitor.DownloadSpeed / 1024.0);
                        AppendFormat(sb, "Upload Speed:       {0:0.00} kB/s", manager.Monitor.UploadSpeed / 1024.0);
                        AppendFormat(sb, "Total Downloaded:   {0:0.00} MB", manager.Monitor.DataBytesDownloaded / (1024.0 * 1024.0));
                        AppendFormat(sb, "Total Uploaded:     {0:0.00} MB", manager.Monitor.DataBytesUploaded / (1024.0 * 1024.0));
                        System.Net.BitTorrent.Client.Tracker.Tracker tracker = manager.TrackerManager.CurrentTracker;
                        //AppendFormat(sb, "Tracker Status:     {0}", tracker == null ? "<no tracker>" : tracker.State.ToString());
                        AppendFormat(sb, "Warning Message:    {0}", tracker == null ? "<no tracker>" : tracker.WarningMessage);
                        AppendFormat(sb, "Failure Message:    {0}", tracker == null ? "<no tracker>" : tracker.FailureMessage);
                        if (manager.PieceManager != null)
                        {
                            AppendFormat(sb, "Current Requests:   {0}", manager.PieceManager.CurrentRequestCount());
                        }

                        foreach (PeerId p in manager.GetPeers())
                        {
                            AppendFormat(sb, "\t{2} - {1:0.00}/{3:0.00}kB/sec - {0}", p.Peer.ConnectionUri,
                                         p.Monitor.DownloadSpeed / 1024.0,
                                         p.AmRequestingPiecesCount,
                                         p.Monitor.UploadSpeed / 1024.0);
                        }

                        AppendFormat(sb, "", null);
                        if (manager.Torrent != null)
                        {
                            foreach (TorrentFile file in manager.Torrent.Files)
                            {
                                AppendFormat(sb, "{1:0.00}% - {0}", file.Path, file.BitField.PercentComplete);
                            }
                        }
                    }
                    Console.Clear();
                    Console.WriteLine(sb.ToString());
                    listener.ExportTo(Console.Out);
                }

                System.Threading.Thread.Sleep(500);
            }
        }
 public InitialiseTask(DhtEngine engine, byte[] initialNodes)
 {
     Initialise(engine, initialNodes == null ? null :  Node.FromCompactNode(initialNodes));
 }
示例#35
0
 public GetPeersTask(DhtEngine engine, NodeId infohash)
 {
     Engine     = engine;
     InfoHash   = infohash;
     FoundPeers = new HashSet <PeerInfo> ();
 }
示例#36
0
 public AnnounceTask(DhtEngine engine, NodeId infoHash, int port)
 {
     this.engine   = engine;
     this.infoHash = infoHash;
     this.port     = port;
 }
示例#37
0
        private void DownloaderWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (e.Argument == null)
                {
                    return;
                }

                basePath       = Environment.CurrentDirectory;
                dhtNodeFile    = System.IO.Path.Combine(basePath, "DhtNodes");
                downloadsPath  = System.IO.Path.Combine(basePath, "Downloads");
                torrentsPath   = System.IO.Path.Combine(basePath, "Torrents");
                fastResumeFile = System.IO.Path.Combine(torrentsPath, "fastresume.data");
                torrents       = new List <TorrentManager>(); // The list where all the torrentManagers will be stored that the engine gives us
                listener       = new Top10Listener(10);

                string torrentpath = e.Argument.ToString();

                int     port    = 6969;
                Torrent torrent = null;

                // Create the settings which the engine will use
                // downloadsPath - this is the path where we will save all the files to
                // port - this is the port we listen for connections on
                EngineSettings engineSettings = new EngineSettings(downloadsPath, port);
                engineSettings.PreferEncryption  = false;
                engineSettings.AllowedEncryption = EncryptionTypes.All;

                //engineSettings.GlobalMaxUploadSpeed = 30 * 1024;
                //engineSettings.GlobalMaxDownloadSpeed = 100 * 1024;
                //engineSettings.MaxReadRate = 1 * 1024 * 1024;


                // Create the default settings which a torrent will have.
                // 4 Upload slots - a good ratio is one slot per 5kB of upload speed
                // 50 open connections - should never really need to be changed
                // Unlimited download speed - valid range from 0 -> int.Max
                // Unlimited upload speed - valid range from 0 -> int.Max
                TorrentSettings torrentDefaults = new TorrentSettings(4, 150, 0, 0);

                // Create an instance of the engine.
                engine = new ClientEngine(engineSettings);
                engine.ChangeListenEndpoint(new IPEndPoint(IPAddress.Any, port));
                byte[] nodes = null;
                try
                {
                    nodes = File.ReadAllBytes(dhtNodeFile);
                }
                catch
                {
                    Console.WriteLine("No existing dht nodes could be loaded");
                }

                DhtListener dhtListner = new DhtListener(new IPEndPoint(IPAddress.Any, port));
                DhtEngine   dht        = new DhtEngine(dhtListner);
                engine.RegisterDht(dht);
                dhtListner.Start();
                engine.DhtEngine.Start(nodes);

                // If the SavePath does not exist, we want to create it.
                if (!Directory.Exists(engine.Settings.SavePath))
                {
                    Directory.CreateDirectory(engine.Settings.SavePath);
                }

                // If the torrentsPath does not exist, we want to create it
                if (!Directory.Exists(torrentsPath))
                {
                    Directory.CreateDirectory(torrentsPath);
                }

                BEncodedDictionary fastResume;
                try
                {
                    fastResume = BEncodedValue.Decode <BEncodedDictionary>(File.ReadAllBytes(fastResumeFile));
                }
                catch
                {
                    fastResume = new BEncodedDictionary();
                }


                // Load the .torrent from the file into a Torrent instance
                // You can use this to do preprocessing should you need to
                torrent = Torrent.Load(torrentpath);

                // When any preprocessing has been completed, you create a TorrentManager
                // which you then register with the engine.
                TorrentManager manager = new TorrentManager(torrent, downloadsPath, torrentDefaults);
                //if (fastResume.ContainsKey(torrent.InfoHash.ToHex()))
                //    manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.infoHash.ToHex()]));
                engine.Register(manager);

                // Store the torrent manager in our list so we can access it later
                torrents.Add(manager);
                manager.PeersFound += new EventHandler <PeersAddedEventArgs>(manager_PeersFound);


                // Every time a piece is hashed, this is fired.
                manager.PieceHashed += delegate(object o, PieceHashedEventArgs ec)
                {
                    lock (listener)
                        listener.WriteLine(string.Format("Piece Hashed: {0} - {1}", ec.PieceIndex, ec.HashPassed ? "Pass" : "Fail"));
                };

                // Every time the state changes (Stopped -> Seeding -> Downloading -> Hashing) this is fired
                manager.TorrentStateChanged += delegate(object o, TorrentStateChangedEventArgs ev)
                {
                    lock (listener)
                        listener.WriteLine("OldState: " + ev.OldState.ToString() + " NewState: " + ev.NewState.ToString());
                };

                // Every time the tracker's state changes, this is fired
                //foreach (TrackerTier tier in manager.TrackerManager)
                //{
                //    //foreach (MonoTorrent.Client.Tracker.Tracker t in tier.Trackers)
                //    //{
                //    //    t.AnnounceComplete += delegate (object sender, AnnounceResponseEventArgs e)
                //    //    {
                //    //        listener.WriteLine(string.Format("{0}: {1}", e.Successful, e.Tracker.ToString()));
                //    //    };
                //    //}
                //}
                // Start the torrentmanager. The file will then hash (if required) and begin downloading/seeding
                manager.Start();


                // While the torrents are still running, print out some stats to the screen.
                // Details for all the loaded torrent managers are shown.
                bool          running = true;
                StringBuilder sb      = new StringBuilder(1024);
                while (running)
                {
                    //if ((i++) % 10 == 0)
                    //{
                    sb.Remove(0, sb.Length);
                    running = torrents.Exists(delegate(TorrentManager m) { return(m.State != TorrentState.Stopped); });

                    //AppendFormat(sb, "Total Download Rate: {0:0.00}kB/sec", engine.TotalDownloadSpeed / 1024.0);
                    downloadspeed = (engine.TotalDownloadSpeed / 1024.0).ToString();
                    //AppendFormat(sb, "Total Upload Rate:   {0:0.00}kB/sec", engine.TotalUploadSpeed / 1024.0);
                    //AppendFormat(sb, "Disk Read Rate:      {0:0.00} kB/s", engine.DiskManager.ReadRate / 1024.0);
                    //AppendFormat(sb, "Disk Write Rate:     {0:0.00} kB/s", engine.DiskManager.WriteRate / 1024.0);
                    //AppendFormat(sb, "Total Read:         {0:0.00} kB", engine.DiskManager.TotalRead / 1024.0);
                    //AppendFormat(sb, "Total Written:      {0:0.00} kB", engine.DiskManager.TotalWritten / 1024.0);
                    //AppendFormat(sb, "Open Connections:    {0}", engine.ConnectionManager.OpenConnections);


                    //AppendSeperator(sb);
                    //AppendFormat(sb, "State:           {0}", manager.State);
                    //AppendFormat(sb, "Name:            {0}", manager.Torrent == null ? "MetaDataMode" : manager.Torrent.Name);
                    //AppendFormat(sb, "Progress:           {0:0.00}", manager.Progress);
                    //progress = manager.Progress.ToString();
                    //AppendFormat(sb, "Download Speed:     {0:0.00} kB/s", manager.Monitor.DownloadSpeed / 1024.0);
                    //AppendFormat(sb, "Upload Speed:       {0:0.00} kB/s", manager.Monitor.UploadSpeed / 1024.0);
                    //AppendFormat(sb, "Total Downloaded:   {0:0.00} MB", manager.Monitor.DataBytesDownloaded / (1024.0 * 1024.0));
                    //AppendFormat(sb, "Total Uploaded:     {0:0.00} MB", manager.Monitor.DataBytesUploaded / (1024.0 * 1024.0));
                    MonoTorrent.Client.Tracker.Tracker tracker = manager.TrackerManager.CurrentTracker;
                    //AppendFormat(sb, "Tracker Status:     {0}", tracker == null ? "<no tracker>" : tracker.State.ToString());
                    //AppendFormat(sb, "Warning Message:    {0}", tracker == null ? "<no tracker>" : tracker.WarningMessage);
                    //AppendFormat(sb, "Failure Message:    {0}", tracker == null ? "<no tracker>" : tracker.FailureMessage);
                    //if (manager.PieceManager != null)
                    //    AppendFormat(sb, "Current Requests:   {0}", manager.PieceManager.CurrentRequestCount());

                    //foreach (PeerId p in manager.GetPeers())
                    //    AppendFormat(sb, "\t{2} - {1:0.00}/{3:0.00}kB/sec - {0}", p.Peer.ConnectionUri,
                    //                                                              p.Monitor.DownloadSpeed / 1024.0,
                    //                                                              p.AmRequestingPiecesCount,
                    //                                                              p.Monitor.UploadSpeed / 1024.0);

                    //AppendFormat(sb, "", null);
                    //if (manager.Torrent != null)
                    //    foreach (TorrentFile file in manager.Torrent.Files)
                    //        AppendFormat(sb, "{1:0.00}% - {0}", file.Path, file.BitField.PercentComplete);

                    //Console.Clear();
                    //Console.WriteLine(sb.ToString());
                    //listener.ExportTo(Console.Out);
                    //}
                    DownloaderWorker.ReportProgress(Convert.ToInt32(manager.Progress), manager.State.ToString());
                    System.Threading.Thread.Sleep(500);
                }
            }
            catch (Exception ex)
            {
            }
        }
示例#38
0
        public override void Handle(DhtEngine engine, Node node)
        {
            base.Handle(engine, node);

            throw new MessageException(ErrorCode, Message);
        }
示例#39
0
 public virtual void Handle(DhtEngine engine, Node node)
 {
     node.Seen();
 }
示例#40
0
 public AnnounceTask(DhtEngine engine, NodeId infoHash, int port)
 {
     this.engine = engine;
     this.infoHash = infoHash;
     this.port = port;
 }
 public RefreshBucketTask(DhtEngine engine, Bucket bucket)
 {
     this.engine = engine;
     this.bucket = bucket;
 }
示例#42
0
 public override async Task HandleAsync(DhtEngine engine, Node node)
 {
     await base.HandleAsync(engine, node);
 }
示例#43
0
 public InitialiseTask(DhtEngine engine, IEnumerable <Node> nodes)
 {
     this.engine  = engine;
     initialNodes = new List <Node> (nodes);
 }
 public override void Handle(DhtEngine engine, Node node)
 {
     base.Handle(engine, node);
     engine.Add(Node.FromCompactNode(Nodes.TextBytes));
 }
示例#45
0
        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);
            }
        }
 public InitialiseTask(DhtEngine engine, byte[] initialNodes)
 {
     Initialise(engine, initialNodes == null ? null : Node.FromCompactNode(initialNodes));
 }
示例#47
0
 public GetPeersTask(DhtEngine engine, NodeId infohash)
 {
     Engine   = engine;
     InfoHash = infohash;
 }
 public ReplaceNodeTask(DhtEngine engine, Bucket bucket, Node newNode)
 {
     _engine = engine;
     _bucket = bucket;
     _newNode = newNode;
 }
示例#49
0
 public override void Handle(DhtEngine engine, Node node)
 {
     base.Handle(engine, node);
     engine.Add(Node.FromCompactNode(Nodes.TextBytes));
 }
 public override void Handle(DhtEngine engine, Node node)
 {
     base.Handle(engine, node);
     node.Token = Token;
     if (Nodes != null)
         engine.Add(Node.FromCompactNode(Nodes));
 }
示例#51
0
 public GetPeersTask(DhtEngine engine, InfoHash infohash)
     : this(engine, new NodeId(infohash))
 {
 }
示例#52
0
 public ReplaceNodeTask(DhtEngine engine, Bucket bucket, Node newNode)
 {
     this.engine = engine;
     this.bucket = bucket;
     this.newNode = newNode;
 }
 public InitialiseTask(DhtEngine engine)
 {
     Initialise(engine, null);
 }
示例#54
0
        private static async Task StartEngine()
        {
            int     port;
            Torrent torrent = null;

            // Ask the user what port they want to use for incoming connections
            Console.Write($"{Environment.NewLine}Choose a listen port: ");
            while (!Int32.TryParse(Console.ReadLine(), out port))
            {
            }

            // Create the settings which the engine will use
            // downloadsPath - this is the path where we will save all the files to
            // port - this is the port we listen for connections on
            EngineSettings engineSettings = new EngineSettings {
                SavePath   = downloadsPath,
                ListenPort = port
            };

            //engineSettings.GlobalMaxUploadSpeed = 30 * 1024;
            //engineSettings.GlobalMaxDownloadSpeed = 100 * 1024;
            //engineSettings.MaxReadRate = 1 * 1024 * 1024;

            // Create the default settings which a torrent will have.
            TorrentSettings torrentDefaults = new TorrentSettings();

            // Create an instance of the engine.
            engine = new ClientEngine(engineSettings);

            byte[] nodes = Array.Empty <byte> ();
            try {
                if (File.Exists(dhtNodeFile))
                {
                    nodes = File.ReadAllBytes(dhtNodeFile);
                }
            } catch {
                Console.WriteLine("No existing dht nodes could be loaded");
            }

            DhtEngine dht = new DhtEngine(new IPEndPoint(IPAddress.Any, port));
            await engine.RegisterDhtAsync(dht);

            // This starts the Dht engine but does not wait for the full initialization to
            // complete. This is because it can take up to 2 minutes to bootstrap, depending
            // on how many nodes time out when they are contacted.
            await engine.DhtEngine.StartAsync(nodes);

            // If the SavePath does not exist, we want to create it.
            if (!Directory.Exists(engine.Settings.SavePath))
            {
                Directory.CreateDirectory(engine.Settings.SavePath);
            }

            // If the torrentsPath does not exist, we want to create it
            if (!Directory.Exists(torrentsPath))
            {
                Directory.CreateDirectory(torrentsPath);
            }

            BEncodedDictionary fastResume = new BEncodedDictionary();

            try {
                if (File.Exists(fastResumeFile))
                {
                    fastResume = BEncodedValue.Decode <BEncodedDictionary> (File.ReadAllBytes(fastResumeFile));
                }
            } catch {
            }

            // For each file in the torrents path that is a .torrent file, load it into the engine.
            foreach (string file in Directory.GetFiles(torrentsPath))
            {
                if (file.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase))
                {
                    try {
                        // Load the .torrent from the file into a Torrent instance
                        // You can use this to do preprocessing should you need to
                        torrent = await Torrent.LoadAsync(file);

                        Console.WriteLine(torrent.InfoHash.ToString());
                    } catch (Exception e) {
                        Console.Write("Couldn't decode {0}: ", file);
                        Console.WriteLine(e.Message);
                        continue;
                    }
                    // When any preprocessing has been completed, you create a TorrentManager
                    // which you then register with the engine.
                    TorrentManager manager = new TorrentManager(torrent, downloadsPath, torrentDefaults);
                    if (fastResume.ContainsKey(torrent.InfoHash.ToHex()))
                    {
                        manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.InfoHash.ToHex()]));
                    }
                    await engine.Register(manager);

                    // Store the torrent manager in our list so we can access it later
                    torrents.Add(manager);
                    manager.PeersFound += manager_PeersFound;
                }
            }

            // If we loaded no torrents, just exist. The user can put files in the torrents directory and start
            // the client again
            if (torrents.Count == 0)
            {
                Console.WriteLine("No torrents found in the Torrents directory");
                Console.WriteLine("Exiting...");
                engine.Dispose();
                return;
            }

            // For each torrent manager we loaded and stored in our list, hook into the events
            // in the torrent manager and start the engine.
            foreach (TorrentManager manager in torrents)
            {
                manager.PeerConnected += (o, e) => {
                    lock (listener)
                        listener.WriteLine($"Connection succeeded: {e.Peer.Uri}");
                };
                manager.ConnectionAttemptFailed += (o, e) => {
                    lock (listener)
                        listener.WriteLine(
                            $"Connection failed: {e.Peer.ConnectionUri} - {e.Reason} - {e.Peer.AllowedEncryption}");
                };
                // Every time a piece is hashed, this is fired.
                manager.PieceHashed += delegate(object o, PieceHashedEventArgs e) {
                    lock (listener)
                        listener.WriteLine($"Piece Hashed: {e.PieceIndex} - {(e.HashPassed ? "Pass" : "Fail")}");
                };

                // Every time the state changes (Stopped -> Seeding -> Downloading -> Hashing) this is fired
                manager.TorrentStateChanged += delegate(object o, TorrentStateChangedEventArgs e) {
                    lock (listener)
                        listener.WriteLine($"OldState: {e.OldState} NewState: {e.NewState}");
                };

                // Every time the tracker's state changes, this is fired
                manager.TrackerManager.AnnounceComplete += (sender, e) => {
                    listener.WriteLine($"{e.Successful}: {e.Tracker}");
                };

                // Start the torrentmanager. The file will then hash (if required) and begin downloading/seeding
                await manager.StartAsync();
            }

            // While the torrents are still running, print out some stats to the screen.
            // Details for all the loaded torrent managers are shown.
            int           i       = 0;
            bool          running = true;
            StringBuilder sb      = new StringBuilder(1024);

            while (running)
            {
                if ((i++) % 10 == 0)
                {
                    sb.Remove(0, sb.Length);
                    running = torrents.Exists(m => m.State != TorrentState.Stopped);

                    AppendFormat(sb, "Total Download Rate: {0:0.00}kB/sec", engine.TotalDownloadSpeed / 1024.0);
                    AppendFormat(sb, "Total Upload Rate:   {0:0.00}kB/sec", engine.TotalUploadSpeed / 1024.0);
                    AppendFormat(sb, "Disk Read Rate:      {0:0.00} kB/s", engine.DiskManager.ReadRate / 1024.0);
                    AppendFormat(sb, "Disk Write Rate:     {0:0.00} kB/s", engine.DiskManager.WriteRate / 1024.0);
                    AppendFormat(sb, "Total Read:         {0:0.00} kB", engine.DiskManager.TotalRead / 1024.0);
                    AppendFormat(sb, "Total Written:      {0:0.00} kB", engine.DiskManager.TotalWritten / 1024.0);
                    AppendFormat(sb, "Open Connections:    {0}", engine.ConnectionManager.OpenConnections);

                    foreach (TorrentManager manager in torrents)
                    {
                        AppendSeparator(sb);
                        AppendFormat(sb, "State:           {0}", manager.State);
                        AppendFormat(sb, "Name:            {0}", manager.Torrent == null ? "MetaDataMode" : manager.Torrent.Name);
                        AppendFormat(sb, "Progress:           {0:0.00}", manager.Progress);
                        AppendFormat(sb, "Download Speed:     {0:0.00} kB/s", manager.Monitor.DownloadSpeed / 1024.0);
                        AppendFormat(sb, "Upload Speed:       {0:0.00} kB/s", manager.Monitor.UploadSpeed / 1024.0);
                        AppendFormat(sb, "Total Downloaded:   {0:0.00} MB", manager.Monitor.DataBytesDownloaded / (1024.0 * 1024.0));
                        AppendFormat(sb, "Total Uploaded:     {0:0.00} MB", manager.Monitor.DataBytesUploaded / (1024.0 * 1024.0));
                        AppendFormat(sb, "Tracker Status");
                        foreach (var tier in manager.TrackerManager.Tiers)
                        {
                            AppendFormat(sb, $"\t{tier.ActiveTracker} : Announce Succeeded: {tier.LastAnnounceSucceeded}. Scrape Succeeded: {tier.LastScrapSucceeded}.");
                        }
                        if (manager.PieceManager != null)
                        {
                            AppendFormat(sb, "Current Requests:   {0}", await manager.PieceManager.CurrentRequestCountAsync());
                        }

                        foreach (PeerId p in await manager.GetPeersAsync())
                        {
                            AppendFormat(sb, "\t{2} - {1:0.00}/{3:0.00}kB/sec - {0}", p.Uri,
                                         p.Monitor.DownloadSpeed / 1024.0,
                                         p.AmRequestingPiecesCount,
                                         p.Monitor.UploadSpeed / 1024.0);
                        }

                        AppendFormat(sb, "", null);
                        if (manager.Torrent != null)
                        {
                            foreach (TorrentFile file in manager.Torrent.Files)
                            {
                                AppendFormat(sb, "{1:0.00}% - {0}", file.Path, file.BitField.PercentComplete);
                            }
                        }
                    }
                    Console.Clear();
                    Console.WriteLine(sb.ToString());
                    listener.ExportTo(Console.Out);
                }

                Thread.Sleep(500);
            }
        }
示例#55
0
 public AnnounceTask(DhtEngine engine, NodeId infoHash, int port)
 {
     _engine   = engine;
     _infoHash = infoHash;
     _port     = port;
 }
示例#56
0
 public SendQueryTask(DhtEngine engine, QueryMessage query, Node node)
     : this(engine, query, node, 3)
 {
 }
示例#57
0
 public GetPeersTask(DhtEngine engine, byte[] infohash)
     : this(engine, new NodeId(infohash))
 {
 }