示例#1
0
 protected ResponseMessage(NodeId id, BEncodedValue transactionId)
     : base(ResponseType)
 {
     Properties.Add(ReturnValuesKey, new BEncodedDictionary());
     Parameters.Add(IdKey, id.BencodedString());
     TransactionId = transactionId;
 }
示例#2
0
 protected Message(BEncodedValue messageType)
 {
     Properties.Add(TransactionIdKey, null);
     Properties.Add(MessageTypeKey, messageType);
     if (UseVersionKey)
         Properties.Add(VersionKey, DhtVersion);
 }
        public void Decode(BEncodedValue value)
        {
            BEncodedDictionary val = value as BEncodedDictionary;
            if (val != null)
            {
                //if do not find key do not throw exception just continue with default value ;)
                BEncodedValue result;
                //For number maybe best is to do ((int)((BEncodedNumber)result).Number) but keep using convert and ToString()

                if (val.TryGetValue(new BEncodedString("MaxDownloadSpeed"), out result))
                    MaxDownloadSpeed = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("MaxUploadSpeed"), out result))
                    MaxUploadSpeed = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("MaxConnections"), out result))
                    MaxConnections = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("UploadSlots"), out result))
                    UploadSlots = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("SavePath"), out result))
                    savePath = result.ToString();
            }
        }
        internal void LoadTorrents(List <string> torrentPaths, List <FH2File> obsoleteFiles)
        {
            StartDht(this.engine, Properties.Settings.Default.listenPort);
            this.engineState = EngineState.Downloading;
            this.managers.Clear();
            this.torrents.Clear();
            this.totalSize       = 0;
            this.downloadSize    = 0;
            this.initialProgress = -999999;
            this.lastProgress    = 0;
            this.lastTime        = -10000;
            this.activeWebSeeds  = 0;

            string             fastResumeFile = Path.Combine(this.parent.localAppDataFolder, "fastresume.data");
            BEncodedDictionary fastResume;

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

            foreach (string filePath in  torrentPaths)
            {
                Torrent torrent = null;
                try { torrent = Torrent.Load(filePath); }
                catch (Exception e) { Console.WriteLine(e); debug(e.ToString()); continue; }
                foreach (TorrentFile file in torrent.Files)
                {
                    //file.Priority = Priority.DoNotDownload;
                    //file.Priority = Priority.Normal;
                    this.totalSize += file.Length;
                    foreach (FH2File fh2File in obsoleteFiles)
                    {
                        if ((fh2File.fullPath == Path.Combine(torrent.Name, file.FullPath)) ||
                            (torrent.Name.ToLower().Contains("updater")) ||
                            ((fh2File.name.ToLower().Contains("ubuntu") && (fh2File.name.ToLower().Contains(".iso")))))
                        {
                            //file.Priority = Priority.Normal;
                            this.downloadSize += file.Length;
                            break;
                        }
                    }
                }
                this.torrents.Add(torrent);
                //TorrentSettings settings = new TorrentSettings(5, 50, 0, 0);
                TorrentSettings settings = new TorrentSettings(5, 50, 0, this.engine.Settings.GlobalMaxUploadSpeed);
                TorrentManager  manager  = new TorrentManager(torrent, engine.Settings.SavePath, settings);
                if (fastResume.ContainsKey(torrent.InfoHash.ToHex()))
                {
                    manager.LoadFastResume(new FastResume((BEncodedDictionary)fastResume[torrent.InfoHash.ToHex()]));
                }
                this.managers.Add(manager);
                manager.PeerConnected    += manager_PeerConnected;
                manager.PeerDisconnected += manager_PeerDisconnected;
                this.engine.Register(manager);
                manager.TorrentStateChanged += waitForFinish;
                manager.TrackerManager.Announce();
                // Disable rarest first and randomised picking - only allow priority based picking (i.e. selective downloading)
                //PiecePicker picker = new StandardPicker();
                //picker = new PriorityPicker(picker);
                //manager.ChangePicker(picker);
                try { manager.Start(); }
                catch (Exception e) {
                    MessageBox.Show("Could not start the torrent.\nError Message:\n" + e.Message);
                    Console.WriteLine(e); debug(e.ToString());
                }
            }
        }
示例#5
0
 public BEncodedDictionary ToDictionary()
 {
     return(BEncodedValue.Clone(Metadata));
 }
示例#6
0
 public AnnouncePeerResponse(NodeId id, BEncodedValue transactionId)
     : base(id, transactionId)
 {
 }
        protected override void HandleLtMetadataMessage(PeerId id, LTMetadata message)
        {
            base.HandleLtMetadataMessage(id, message);

            switch (message.MetadataMessageType)
            {
            case LTMetadata.eMessageType.Data:
                if (stream == null)
                {
                    throw new Exception("Need extention handshake before ut_metadata message.");
                }

                stream.Seek(message.Piece * LTMetadata.BlockSize, SeekOrigin.Begin);
                stream.Write(message.MetadataPiece, 0, message.MetadataPiece.Length);
                bitField[message.Piece] = true;
                if (bitField.AllTrue)
                {
                    byte[] hash;
                    stream.Position = 0;
#if NETSTANDARD1_5
                    using (SHA1 hasher = SHA1.Create())
#else
                    using (SHA1 hasher = HashAlgoFactory.Create <SHA1>())
#endif
                        hash = hasher.ComputeHash(stream);

                    if (!Manager.InfoHash.Equals(hash))
                    {
                        bitField.SetAll(false);
                    }
                    else
                    {
                        System.Net.BitTorrent.Common.Torrent t;
                        stream.Position = 0;
                        BEncodedDictionary dict = new BEncodedDictionary();
                        dict.Add("info", BEncodedValue.Decode(stream));
                        // FIXME: Add the trackers too
                        if (System.Net.BitTorrent.Common.Torrent.TryLoad(dict.Encode(), out t))
                        {
                            try
                            {
                                if (Directory.Exists(savePath))
                                {
                                    savePath = Path.Combine(savePath, Manager.InfoHash.ToHex() + ".torrent");
                                }
                                File.WriteAllBytes(savePath, dict.Encode());
                            }
                            catch (Exception ex)
                            {
                                Logger.Log(null, "*METADATA EXCEPTION* - Can not write in {0} : {1}", savePath, ex);
                                Manager.Error = new Error(Reason.WriteFailure, ex);
                                Manager.Mode  = new ErrorMode(Manager);
                                return;
                            }
                            t.TorrentPath   = savePath;
                            Manager.Torrent = t;
                            SwitchToRegular();
                        }
                        else
                        {
                            bitField.SetAll(false);
                        }
                    }
                }
                //Double test because we can change the bitfield in the other block
                if (!bitField.AllTrue)
                {
                    RequestNextNeededPiece(id);
                }
                break;

            case LTMetadata.eMessageType.Reject:
                //TODO
                //Think to what we do in this situation
                //for moment nothing ;)
                //reject or flood?
                break;

            case LTMetadata.eMessageType.Request:    //ever done in base class but needed to avoid default
                break;

            default:
                throw new MessageException(string.Format("Invalid messagetype in LTMetadata: {0}", message.MetadataMessageType));
            }
        }
示例#8
0
 public static Torrent Load(BEncodedDictionary torrentInformation)
 {
     return(LoadCore((BEncodedDictionary)BEncodedValue.Decode(torrentInformation.Encode())));
 }
示例#9
0
 public void AddCustomSecure (BEncodedString key, BEncodedValue value)
 {
     Check.Key (key);
     Check.Value (value);
     info [key] = value;
 }
示例#10
0
        public void CorruptBenListDecode()
        {
            string testString = "l3:3521:a3:ae";

            Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(testString)));
        }
 public FindNodeResponse(NodeId id, BEncodedValue transactionId)
     : base(id, transactionId)
 {
     Parameters.Add(NodesKey, new BEncodedString());
 }
示例#12
0
 public GetPeersResponse(NodeId id, BEncodedValue transactionId, BEncodedString token)
     : base(id, transactionId)
 {
     Parameters.Add(TokenKey, token);
 }
示例#13
0
        public void CorruptBenDataDecode()
        {
            string testString = "corruption!";

            Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(testString)));
        }
示例#14
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();
            }
        }
示例#15
0
        public void DecodeString_TooShort()
        {
            string benString = "5:test";

            Assert.Throws <BEncodingException> (() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(benString)));
        }
示例#16
0
        public void DecodeString_NoColon()
        {
            string benString = "12";

            Assert.Throws <BEncodingException> (() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(benString)));
        }
        public void SetCustom(BEncodedString key, BEncodedValue value)
        {
            Check.Key(key);
            Check.Value(value);

            if (InfoKey.Equals(key))
                CheckCanEditSecure();
            Metadata[key] = value;
        }
		/// <summary>
		/// Adds a custom value to the main bencoded dictionary
		/// </summary>        
		public void AddCustom(BEncodedString key, BEncodedValue value)
		{
			dict.Add(key, value);
		}
示例#19
0
        public void CorruptBenNumberDecode()
        {
            string testString = "i35212";

            Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(testString)));
        }
示例#20
0
 public void AddCustom (BEncodedString key, BEncodedValue value)
 {
     Check.Key (key);
     Check.Value (value);
     dict [key] = value;
 }
示例#21
0
 public PingResponse(NodeId id, BEncodedValue transactionId)
     : base(id, transactionId)
 {
 }
示例#22
0
        public void CorruptBenStringDecode()
        {
            string testString = "50:i'm too short";

            Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(testString)));
        }
        public void Decode(BEncodedValue value)
        {
            BEncodedDictionary val = value as BEncodedDictionary;
            if (val != null)
            {
                //if do not find key do not throw exception just continue with default value ;)
                BEncodedValue result;
                //For number maybe best is to do ((int)((BEncodedNumber)result).Number) but keep using convert and ToString()
                if (val.TryGetValue(new BEncodedString("SavePath"), out result))
                    SavePath = result.ToString();

                if (val.TryGetValue(new BEncodedString("GlobalMaxConnections"), out result))
                    GlobalMaxConnections = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("GlobalMaxHalfOpenConnections"), out result))
                    GlobalMaxHalfOpenConnections = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("GlobalMaxDownloadSpeed"), out result))
                    GlobalMaxDownloadSpeed = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("GlobalMaxUploadSpeed"), out result))
                    GlobalMaxUploadSpeed = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("ListenPort"), out result))
                    ListenPort = Convert.ToInt32(result.ToString());

                if (val.TryGetValue(new BEncodedString("UsePnP"), out result))
                    UsePnP = Convert.ToBoolean(result.ToString());

                if (val.TryGetValue(new BEncodedString("TorrentsPath"), out result))
                    TorrentsPath = result.ToString();
            }
        }
示例#24
0
        public void CorruptBenStringDecode2()
        {
            string s = "d8:completei2671e10:incompletei669e8:intervali1836e12min intervali918e5:peers0:e";

            Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.ASCII.GetBytes(s)));
        }
示例#25
0
 internal BEncodedDictionary ToDictionary()
 {
     // Give the user a copy of the original dictionary.
     return(BEncodedValue.Clone(originalDictionary));
 }
示例#26
0
 public FindNodeResponse(NodeId id, BEncodedValue transactionId)
     : base(id, transactionId)
 {
     Parameters.Add(NodesKey, new BEncodedString());
 }
示例#27
0
        protected void LoadInternal(BEncodedDictionary torrentInformation)
        {
            Check.TorrentInformation(torrentInformation);
            originalDictionary = torrentInformation;
            torrentPath        = "";

            try
            {
                foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in torrentInformation)
                {
                    switch (keypair.Key.Text)
                    {
                    case ("announce"):
                        // Ignore this if we have an announce-list
                        if (torrentInformation.ContainsKey("announce-list"))
                        {
                            break;
                        }
                        announceUrls.Add(new RawTrackerTier());
                        announceUrls[0].Add(keypair.Value.ToString());
                        break;

                    case ("creation date"):
                        try
                        {
                            try
                            {
                                creationDate = creationDate.AddSeconds(long.Parse(keypair.Value.ToString()));
                            }
                            catch (Exception e)
                            {
                                if (e is ArgumentOutOfRangeException)
                                {
                                    creationDate = creationDate.AddMilliseconds(long.Parse(keypair.Value.ToString()));
                                }
                                else
                                {
                                    throw;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            if (e is ArgumentOutOfRangeException)
                            {
                                throw new BEncodingException("Argument out of range exception when adding seconds to creation date.", e);
                            }
                            else if (e is FormatException)
                            {
                                throw new BEncodingException(String.Format("Could not parse {0} into a number", keypair.Value), e);
                            }
                            else
                            {
                                throw;
                            }
                        }
                        break;

                    case ("nodes"):
                        nodes = (BEncodedList)keypair.Value;
                        break;

                    case ("comment.utf-8"):
                        if (keypair.Value.ToString().Length != 0)
                        {
                            comment = keypair.Value.ToString();           // Always take the UTF-8 version
                        }
                        break;                                            // even if there's an existing value

                    case ("comment"):
                        if (String.IsNullOrEmpty(comment))
                        {
                            comment = keypair.Value.ToString();
                        }
                        break;

                    case ("publisher-url.utf-8"):                         // Always take the UTF-8 version
                        publisherUrl = keypair.Value.ToString();          // even if there's an existing value
                        break;

                    case ("publisher-url"):
                        if (String.IsNullOrEmpty(publisherUrl))
                        {
                            publisherUrl = keypair.Value.ToString();
                        }
                        break;

                    case ("azureus_properties"):
                        azureusProperties = keypair.Value;
                        break;

                    case ("created by"):
                        createdBy = keypair.Value.ToString();
                        break;

                    case ("encoding"):
                        encoding = keypair.Value.ToString();
                        break;

                    case ("info"):
                        using (SHA1 s = HashAlgoFactory.Create <SHA1>())
                            infoHash = new InfoHash(s.ComputeHash(keypair.Value.Encode()));
                        ProcessInfo(((BEncodedDictionary)keypair.Value));
                        break;

                    case ("name"):                                                   // Handled elsewhere
                        break;

                    case ("announce-list"):
                        if (keypair.Value is BEncodedString)
                        {
                            break;
                        }
                        BEncodedList announces = (BEncodedList)keypair.Value;

                        for (int j = 0; j < announces.Count; j++)
                        {
                            if (announces[j] is BEncodedList)
                            {
                                BEncodedList  bencodedTier = (BEncodedList)announces[j];
                                List <string> tier         = new List <string>(bencodedTier.Count);

                                for (int k = 0; k < bencodedTier.Count; k++)
                                {
                                    tier.Add(bencodedTier[k].ToString());
                                }

                                Toolbox.Randomize <string>(tier);

                                RawTrackerTier collection = new RawTrackerTier();
                                for (int k = 0; k < tier.Count; k++)
                                {
                                    collection.Add(tier[k]);
                                }

                                if (collection.Count != 0)
                                {
                                    announceUrls.Add(collection);
                                }
                            }
                            else
                            {
                                throw new BEncodingException(String.Format("Non-BEncodedList found in announce-list (found {0})",
                                                                           announces[j].GetType()));
                            }
                        }
                        break;

                    case ("httpseeds"):
                        // This form of web-seeding is not supported.
                        break;

                    case ("url-list"):
                        if (keypair.Value is BEncodedString)
                        {
                            getRightHttpSeeds.Add(((BEncodedString)keypair.Value).Text);
                        }
                        else if (keypair.Value is BEncodedList)
                        {
                            foreach (BEncodedString str in (BEncodedList)keypair.Value)
                            {
                                GetRightHttpSeeds.Add(str.Text);
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                if (e is BEncodingException)
                {
                    throw;
                }
                else
                {
                    throw new BEncodingException("", e);
                }
            }
        }
示例#28
0
        protected override void HandleLtMetadataMessage(PeerId id, LTMetadata message)
        {
            base.HandleLtMetadataMessage(id, message);

            switch (message.MetadataMessageType)
            {
            case LTMetadata.eMessageType.Data:
                // If we've already received everything successfully, do nothing!
                if (bitField.AllTrue)
                {
                    return;
                }

                if (Stream == null)
                {
                    throw new Exception("Need extention handshake before ut_metadata message.");
                }

                Stream.Seek(message.Piece * LTMetadata.BlockSize, SeekOrigin.Begin);
                Stream.Write(message.MetadataPiece, 0, message.MetadataPiece.Length);
                bitField[message.Piece] = true;
                if (bitField.AllTrue)
                {
                    byte[] hash;
                    Stream.Position = 0;
                    using (SHA1 hasher = HashAlgoFactory.SHA1())
                        hash = hasher.ComputeHash(Stream);

                    if (!Manager.InfoHash.Equals(hash))
                    {
                        bitField.SetAll(false);
                    }
                    else
                    {
                        Stream.Position = 0;
                        BEncodedDictionary dict = new BEncodedDictionary();
                        dict.Add("info", BEncodedValue.Decode(Stream));

                        if (Manager.TrackerManager.Tiers != null && Manager.TrackerManager.Tiers.Count > 0)
                        {
                            BEncodedList announceTrackers = new BEncodedList();
                            foreach (var tier in Manager.TrackerManager.Tiers)
                            {
                                BEncodedList announceUrls = new BEncodedList();

                                foreach (var tracker in tier.Trackers)
                                {
                                    announceUrls.Add(new BEncodedString(tracker.Uri.OriginalString));
                                }

                                announceTrackers.Add(announceUrls);
                            }

                            dict.Add("announce-list", announceTrackers);
                        }
                        var rawData = dict.Encode();
                        if (Torrent.TryLoad(rawData, out Torrent t))
                        {
                            if (stopWhenDone)
                            {
                                Manager.RaiseMetadataReceived(rawData);
                                return;
                            }

                            try {
                                if (!Directory.Exists(Path.GetDirectoryName(savePath)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(savePath));
                                }
                                File.Delete(savePath);
                                File.WriteAllBytes(savePath, dict.Encode());
                            } catch (Exception ex) {
                                logger.ExceptionFormated(ex, "Cannot write metadata to path '{0}'", savePath);
                                Manager.TrySetError(Reason.WriteFailure, ex);
                                return;
                            }
                            Manager.SetMetadata(t);
                            _ = Manager.StartAsync();
                            Manager.RaiseMetadataReceived(rawData);
                        }
                        else
                        {
                            bitField.SetAll(false);
                        }
                    }
                }
                RequestNextNeededPiece(id);
                break;

            case LTMetadata.eMessageType.Reject:
                //TODO
                //Think to what we do in this situation
                //for moment nothing ;)
                //reject or flood?
                break;

            case LTMetadata.eMessageType.Request:    //ever done in base class but needed to avoid default
                break;

            default:
                throw new MessageException($"Invalid messagetype in LTMetadata: {message.MetadataMessageType}");
            }
        }
示例#29
0
 internal static bool IsRegistered(BEncodedValue transactionId)
 {
     return(messages.ContainsKey(transactionId));
 }
示例#30
0
 public GetPeersResponse(NodeId id, BEncodedValue transactionId, BEncodedString token)
     : base(id, transactionId)
 {
     ReturnValues.Add(_tokenKey, token);
 }
示例#31
0
 public PingResponse(NodeId id, BEncodedValue transactionId)
     : base(id, transactionId)
 {
 }
示例#32
0
 public override void Decode(byte[] buffer, int offset, int length)
 {
     Properties = BEncodedValue.Decode <BEncodedDictionary>(buffer, offset, length, false);
 }
示例#33
0
 public EditableTorrent(BEncodedDictionary metadata)
 {
     Check.Metadata(metadata);
     Initialise(BEncodedValue.Clone(metadata));
 }
示例#34
0
        public void corruptBenStringDecode()
        {
            string testString = "50:i'm too short";

            BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString));
        }
 public AnnouncePeerResponse(NodeId id, BEncodedValue transactionId)
     : base(id, transactionId)
 {
 }
示例#36
0
        public void corruptBenStringDecode2()
        {
            string s = "d8:completei2671e10:incompletei669e8:intervali1836e12min intervali918e5:peers0:e";

            BEncodedValue.Decode(Encoding.ASCII.GetBytes(s));
        }
        public void SetCustomSecure(BEncodedString key, BEncodedValue value)
        {
            CheckCanEditSecure();

            Check.Key(key);
            Check.Value(value);
            InfoDict[key] = value;
        }
示例#38
0
        public void corruptBenNumberDecode()
        {
            string testString = "i35212";

            BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString));
        }
示例#39
0
 internal static bool IsRegistered(BEncodedValue transactionId)
 {
     return messages.ContainsKey(transactionId);
 }
示例#40
0
        public void corruptBenListDecode()
        {
            string testString = "l3:3521:a3:ae";

            BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString));
        }
示例#41
0
        public void corruptBenDictionaryDecode()
        {
            string testString = "d3:3521:a3:aedddd";

            BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString));
        }
示例#42
0
        public void corruptBenDataDecode()
        {
            string testString = "corruption!";

            BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString));
        }
 public GetPeersResponse(NodeId id, BEncodedValue transactionId, BEncodedString token)
     : base(id, transactionId)
 {
     Parameters.Add(TokenKey, token);
 }
示例#44
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 {
                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;

            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", 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;

                    var streamProvider = new StreamProvider(manager);
                    var stream         = await streamProvider.CreateStreamAsync(manager.Torrent.Files.First());

                    Core.Initialize();

                    libvlc      = new LibVLC();
                    mediaPlayer = new MediaPlayer(libvlc)
                    {
                        Media = new Media(libvlc, stream)
                    };
                }
            }

            // 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();
            }

            mediaPlayer.Play();

            // 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);
            }
        }
		static void Set(BEncodedDictionary dictionary, BEncodedString key, BEncodedValue value)
		{
			if (dictionary.ContainsKey(key)) dictionary[key] = value;
			else dictionary.Add(key, value);
		}
示例#46
0
        public void Decode(BEncodedValue value)
        {
            BEncodedDictionary val = value as BEncodedDictionary;
            if (val != null)
            {
                //if do not find key do not throw exception just continue with default value ;)
                BEncodedValue result;

                //For number maybe best is to do ((int)((BEncodedNumber)result).Number) but keep using convert and ToString()

                if (val.TryGetValue("Width", out result))
                    width = Convert.ToInt32(result.ToString());

                if (val.TryGetValue("height", out result))
                    height = Convert.ToInt32(result.ToString());

                if (val.TryGetValue("splitterDistance", out result))
                    splitterDistance = Convert.ToInt32(result.ToString());

                if (val.TryGetValue("VScrollValue", out result))
                    VScrollValue = Convert.ToInt32(result.ToString());

                if (val.TryGetValue("HScrollValue", out result))
                    HScrollValue = Convert.ToInt32(result.ToString());

                if (val.TryGetValue("ShowToolbar", out result))
                    ShowToolbar = Convert.ToBoolean(result.ToString());

                if (val.TryGetValue("ShowDetail", out result))
                    ShowDetail = Convert.ToBoolean(result.ToString());

                if (val.TryGetValue("ShowStatusbar", out result))
                    ShowStatusbar = Convert.ToBoolean(result.ToString());
                
                int i =0;
                while (val.TryGetValue("TorrentViewColumnWidth" + i.ToString(), out result))
                {
                    torrentViewColumnWidth.Add(Convert.ToInt32(result.ToString()));
                    i++;
                }

                i = 0;
                while (val.TryGetValue("PeerViewColumnWidth" + i.ToString(), out result))
                {
                    peerViewColumnWidth.Add(Convert.ToInt32(result.ToString()));
                    i++;
                }

                i = 0;
                while (val.TryGetValue("PieceViewColumnWidth" + i.ToString(), out result))
                {
                    pieceViewColumnWidth.Add(Convert.ToInt32(result.ToString()));
                    i++;
                }

                if (val.TryGetValue("CustomButtonPath", out result))
                    CustomButtonPath = result.ToString();
            }
        }