protected ResponseMessage(NodeId id, BEncodedValue transactionId) : base(ResponseType) { Properties.Add(ReturnValuesKey, new BEncodedDictionary()); Parameters.Add(IdKey, id.BencodedString()); TransactionId = transactionId; }
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()); } } }
public BEncodedDictionary ToDictionary() { return(BEncodedValue.Clone(Metadata)); }
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)); } }
public static Torrent Load(BEncodedDictionary torrentInformation) { return(LoadCore((BEncodedDictionary)BEncodedValue.Decode(torrentInformation.Encode()))); }
public void AddCustomSecure (BEncodedString key, BEncodedValue value) { Check.Key (key); Check.Value (value); info [key] = value; }
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()); }
public GetPeersResponse(NodeId id, BEncodedValue transactionId, BEncodedString token) : base(id, transactionId) { Parameters.Add(TokenKey, token); }
public void CorruptBenDataDecode() { string testString = "corruption!"; Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(testString))); }
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(); } }
public void DecodeString_TooShort() { string benString = "5:test"; Assert.Throws <BEncodingException> (() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(benString))); }
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); }
public void CorruptBenNumberDecode() { string testString = "i35212"; Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.UTF8.GetBytes(testString))); }
public void AddCustom (BEncodedString key, BEncodedValue value) { Check.Key (key); Check.Value (value); dict [key] = value; }
public PingResponse(NodeId id, BEncodedValue transactionId) : base(id, transactionId) { }
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(); } }
public void CorruptBenStringDecode2() { string s = "d8:completei2671e10:incompletei669e8:intervali1836e12min intervali918e5:peers0:e"; Assert.Throws <BEncodingException>(() => BEncodedValue.Decode(Encoding.ASCII.GetBytes(s))); }
internal BEncodedDictionary ToDictionary() { // Give the user a copy of the original dictionary. return(BEncodedValue.Clone(originalDictionary)); }
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); } } }
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}"); } }
internal static bool IsRegistered(BEncodedValue transactionId) { return(messages.ContainsKey(transactionId)); }
public GetPeersResponse(NodeId id, BEncodedValue transactionId, BEncodedString token) : base(id, transactionId) { ReturnValues.Add(_tokenKey, token); }
public override void Decode(byte[] buffer, int offset, int length) { Properties = BEncodedValue.Decode <BEncodedDictionary>(buffer, offset, length, false); }
public EditableTorrent(BEncodedDictionary metadata) { Check.Metadata(metadata); Initialise(BEncodedValue.Clone(metadata)); }
public void corruptBenStringDecode() { string testString = "50:i'm too short"; BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString)); }
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; }
public void corruptBenNumberDecode() { string testString = "i35212"; BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString)); }
internal static bool IsRegistered(BEncodedValue transactionId) { return messages.ContainsKey(transactionId); }
public void corruptBenListDecode() { string testString = "l3:3521:a3:ae"; BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString)); }
public void corruptBenDictionaryDecode() { string testString = "d3:3521:a3:aedddd"; BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString)); }
public void corruptBenDataDecode() { string testString = "corruption!"; BEncodedValue.Decode(System.Text.Encoding.UTF8.GetBytes(testString)); }
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); }
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(); } }