public InfoHashTrackable(Torrent torrent) { Check.Torrent(torrent); name = torrent.Name; infoHash = torrent.InfoHash; }
public void MultipleAnnounce() { var announceCount = 0; var r = new Random(); var handle = new ManualResetEvent(false); for (var i = 0; i < 20; i++) { var infoHash = new InfoHash(new byte[20]); r.NextBytes(infoHash.Hash); var tier = new TrackerTier(new[] {uri.ToString()}); tier.Trackers[0].AnnounceComplete += delegate { if (++announceCount == 20) handle.Set(); }; var id = new TrackerConnectionID(tier.Trackers[0], false, TorrentEvent.Started, new ManualResetEvent(false)); MonoTorrent.Client.Tracker.AnnounceParameters parameters; parameters = new MonoTorrent.Client.Tracker.AnnounceParameters(0, 0, 0, TorrentEvent.Started, infoHash, false, new string('1', 20), "", 1411); tier.Trackers[0].Announce(parameters, id); } Assert.True(handle.WaitOne(5000, true), "Some of the responses weren't received"); }
public TorrentBDecoder(Stream stream, Encoding encoding) { _reader = new BinaryReader(stream); _streamEncoding = encoding; _infoHash = new InfoHash(); _indicator = 0; _inInfoMap = false; }
public PeerBEncryption(InfoHash[] possibleSkeYs, EncryptionTypes allowedEncryption) : base(allowedEncryption) { _possibleSkeYs = possibleSkeYs; _gotVerificationCallback = GotVerification; _gotPadCCallback = GotPadC; }
public PeerAEncryption(InfoHash InfoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { gotVerificationCallback = new AsyncCallback(gotVerification); gotPadDCallback = new AsyncCallback(gotPadD); SKEY = InfoHash; }
public PeerBEncryption(InfoHash[] possibleSKEYs, EncryptionTypes allowedEncryption) : base(allowedEncryption) { this.possibleSKEYs = possibleSKEYs; gotVerificationCallback = new AsyncCallback(gotVerification); gotPadCCallback = new AsyncCallback(gotPadC); }
public PeerAEncryption(InfoHash infoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { _gotVerificationCallback = GotVerification; _gotPadDCallback = GotPadD; Skey = infoHash; }
public CustomITrackable(Torrent t) { // Note: I'm just storing the files, infohash and name. A typical Torrent instance // is ~100kB in memory. A typical CustomITrackable will be ~100 bytes. files = t.Files; infoHash = t.InfoHash; name = t.Name; }
public PeerAEncryption(InfoHash InfoHash, EncryptionTypes allowedEncryption) : base(allowedEncryption) { gotVerificationCallback = gotVerification; gotPadDCallback = gotPadD; SKEY = InfoHash; }
internal static IAsyncResult BeginCheckEncryption(PeerId id, int bytesToReceive, AsyncCallback callback, object state, InfoHash[] sKeys) { var result = new EncryptorAsyncResult(id, callback, state) {SKeys = sKeys}; var c = id.Connection; ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(10), delegate { if (id.Encryptor == null || id.Decryptor == null) id.CloseConnection(); return false; }); try { // If the connection is incoming, receive the handshake before // trying to decide what encryption to use if (id.Connection.IsIncoming) { result.Buffer = new byte[bytesToReceive]; NetworkIO.EnqueueReceive(c, result.Buffer, 0, result.Buffer.Length, null, null, null, HandshakeReceivedCallback, result); } else { var usable = CheckRc4(id); var hasPlainText = Toolbox.HasEncryption(usable, EncryptionTypes.PlainText); var hasRc4 = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full) || Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header); if (id.Engine.Settings.PreferEncryption) { if (hasRc4) { result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable); result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result); } result.Complete(); } else { if (hasPlainText) { result.Complete(); } else { result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable); result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result); } } } } catch (Exception ex) { result.Complete(ex); } return result; }
public InfoHashTrackable(string name, InfoHash infoHash) { Check.InfoHash(infoHash); if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name cannot be null or empty", "name"); this.infoHash = infoHash; this.name = name; }
public FastResume(InfoHash infoHash, BitField bitfield) { if (infoHash == null) throw new ArgumentNullException(nameof(infoHash)); if (bitfield == null) throw new ArgumentNullException(nameof(bitfield)); Infohash = infoHash; Bitfield = bitfield; }
public FastResume(InfoHash infoHash, BitField bitfield) { if (infoHash == null) throw new ArgumentNullException("infoHash"); if (bitfield == null) throw new ArgumentNullException("bitfield"); this.infoHash = infoHash; this.bitfield = bitfield; }
public FastResume(InfoHash infoHash, BitField bitfield, IEnumerable<Priority> priorities) { if (infoHash==null) throw new ArgumentNullException("infoHash"); if(bitfield == null) throw new ArgumentNullException("bitfield"); this.infoHash = infoHash; this.bitfield = bitfield; this.priorities = priorities.ToArray(); }
public FastResume(BEncodedDictionary dict) { CheckContent(dict, VersionKey, 1); CheckContent(dict, InfoHashKey); CheckContent(dict, BitfieldKey); CheckContent(dict, BitfieldLengthKey); Infohash = new InfoHash(((BEncodedString) dict[InfoHashKey]).TextBytes); Bitfield = new BitField((int) ((BEncodedNumber) dict[BitfieldLengthKey]).Number); var data = ((BEncodedString) dict[BitfieldKey]).TextBytes; Bitfield.FromArray(data, 0, data.Length); }
public TorrentInfo(InfoHash hash, string name, int priority, ActiveStates activestate, DownloadStates downloadstate, IEnumerable<string> labels, ulong size, ulong remaining, ulong uploaded) { Hash = hash; Name = name; Priority = priority; ActiveState = activestate; DownloadState = downloadstate; Labels = new ReadOnlyCollection<string>(new List<string>(labels)); Size = size; Remaining = remaining; Uploaded = uploaded; }
public AnnounceParameters(long bytesDownloaded, long bytesUploaded, long bytesLeft, TorrentEvent clientEvent, InfoHash infohash, bool requireEncryption, string peerId, string ipaddress, int port) { BytesDownloaded = bytesDownloaded; BytesUploaded = bytesUploaded; BytesLeft = bytesLeft; ClientEvent = clientEvent; InfoHash = infohash; RequireEncryption = requireEncryption; PeerId = peerId; Ipaddress = ipaddress; Port = port; }
public AnnounceParameters(long bytesDownloaded, long bytesUploaded, long bytesLeft, TorrentEvent clientEvent, InfoHash infohash, bool requireEncryption, string peerId, string ipaddress, int port) { this.bytesDownloaded = bytesDownloaded; this.bytesUploaded = bytesUploaded; this.bytesLeft = bytesLeft; this.clientEvent = clientEvent; this.infohash = infohash; this.requireEncryption = requireEncryption; this.peerId = peerId; this.ipaddress = ipaddress; this.port = port; }
public void Setup() { pair = new ConnectionPair().WithTimeout(); InfoHash = new InfoHash(Enumerable.Repeat((byte)255, 20).ToArray()); SKeys = new[] { new InfoHash(Enumerable.Repeat((byte)254, 20).ToArray()), new InfoHash(Enumerable.Repeat((byte)253, 20).ToArray()), InfoHash, new InfoHash(Enumerable.Repeat((byte)252, 20).ToArray()) }; IncomingId = new BEncodedString(Enumerable.Repeat((byte)'0', 20).ToArray()); OutgoingId = new BEncodedString(Enumerable.Repeat((byte)'1', 20).ToArray()); }
public async Task MultipleAnnounce() { Random r = new Random(); for (int i = 0; i < 20; i++) { InfoHash infoHash = new InfoHash(new byte[20]); r.NextBytes(infoHash.Hash); TrackerTier tier = new TrackerTier(new[] { uri.ToString() }); var parameters = new AnnounceParameters(0, 0, 0, TorrentEvent.Started, infoHash, false, new string ('1', 20), "", 1411, false); Assert.IsTrue(tier.ActiveTracker.CanScrape); await tier.Trackers[0].AnnounceAsync(parameters, CancellationToken.None); } }
/// <summary> /// Initializes an instance of the Torrent.Client.TrackerRequest class with the specified parameters. /// </summary> /// <param name="infoHash">The SHA1 hash of the value of the info key from the torrent metadata.</param> /// <param name="peerId">The Peer ID, used to uniquely identify the peer. 20 bytes.</param> /// <param name="port">The port at which the client is listening on. Typically 6881-6889.</param> /// <param name="uploaded">The total count of uploaded bytes.</param> /// <param name="downloaded">The total count of downloaded bytes.</param> /// <param name="left">The count of bytes left to download for the download to be complete.</param> /// <param name="compact">Whether to request a compact response by the tracker. (binary peers representation)</param> /// <param name="omitPeerIds">Whether to request that the tracker should omit peer IDs in the peers dictionary.</param> /// <param name="event">Specifies the event that caused the request. None by default.</param> public TrackerRequest(InfoHash infoHash, string peerId, ushort port, long uploaded, long downloaded, long left, bool compact, bool omitPeerIds, EventType @event = EventType.None, int?numWant = null) { InfoHash = infoHash; PeerId = peerId; Port = port; Uploaded = uploaded; Downloaded = downloaded; Left = left; Compact = compact; OmitPeerIds = omitPeerIds; Event = @event; NumWant = numWant; }
public override void Decode(byte[] buffer, int offset, int length) { ProtocolStringLength = ReadByte(buffer, ref offset); // First byte is length // #warning Fix this hack - is there a better way of verifying the protocol string? Hack if (ProtocolStringLength != VersionInfo.ProtocolStringV100.Length) { ProtocolStringLength = VersionInfo.ProtocolStringV100.Length; } ProtocolString = ReadString(buffer, ref offset, ProtocolStringLength); CheckForSupports(buffer, ref offset); InfoHash = new InfoHash(ReadBytes(buffer, ref offset, 20)); PeerId = ReadBytes(buffer, ref offset, 20); }
internal AnnounceParameters(long bytesDownloaded, long bytesUploaded, long bytesLeft, TorrentEvent clientEvent, InfoHash infoHash, bool requireEncryption, BEncodedString peerId, string ipAddress, int port, bool supportsEncryption) { BytesDownloaded = bytesDownloaded; BytesUploaded = bytesUploaded; BytesLeft = bytesLeft; ClientEvent = clientEvent; InfoHash = infoHash; RequireEncryption = requireEncryption; PeerId = peerId; IPAddress = ipAddress; Port = port; SupportsEncryption = supportsEncryption; }
public InfoHashTrackable(string name, InfoHash infoHash) { if (infoHash == null) { throw new ArgumentNullException(nameof(infoHash)); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name), $"{nameof (name)} cannot be null or empty"); } InfoHash = infoHash; Name = name; }
public TorrentManager(InfoHash infoHash, StorageFolder savePath, TorrentSettings settings, StorageFolder torrentSaveFolder, IList <RawTrackerTier> announces) { Check.InfoHash(infoHash); Check.SaveFolder(savePath); Check.Settings(settings); Check.TorrentSave(torrentSaveFolder); Check.Announces(announces); InfoHash = infoHash; Settings = settings; _torrentSaveFolder = torrentSaveFolder; Initialise(savePath, "", announces); }
public async Task MultipleAnnounce() { Random r = new Random(); for (int i = 0; i < 20; i++) { var buffer = new byte[20]; r.NextBytes(buffer); var infoHash = new InfoHash(buffer); TrackerTier tier = new TrackerTier(Factories.Default, new[] { uri.ToString() }); var parameters = new MonoTorrent.Trackers.AnnounceRequest(0, 0, 0, TorrentEvent.Started, infoHash, false, new BEncodedString(new string ('1', 20)).Span.ToArray(), "", 1411, false); Assert.IsTrue(tier.ActiveTracker.CanScrape); await tier.Trackers[0].AnnounceAsync(parameters, CancellationToken.None); } }
public static void Main(string[] args) { Listener listener = new UdpListener(new IPEndPoint(IPAddress.Any, 15000)); listener.Start(); DhtEngine engine = new DhtEngine(listener); engine.PeersFound += EngineOnPeersFound; engine.Start(); Thread.Sleep(25000); engine.GetPeers(InfoHash.FromHex("b415c913643e5ff49fe37d304bbb5e6e11ad5101")); Console.ReadLine(); }
public HandshakeMessage(InfoHash infoHash, string peerId, string protocolString, bool enableFastPeer, bool enableExtended) { if (!ClientEngine.SupportsFastPeer && enableFastPeer) throw new ProtocolException("The engine does not support fast peer, but fast peer was requested"); if (!ClientEngine.SupportsExtended && enableExtended) throw new ProtocolException("The engine does not support extended, but extended was requested"); this.InfoHash = infoHash; PeerId = peerId; ProtocolString = protocolString; ProtocolStringLength = protocolString.Length; SupportsFastPeer = enableFastPeer; SupportsExtendedMessaging = enableExtended; }
public DhtBasedSwarm(InfoHash hash, int port, string nodeSavePath) : base(hash,port) { _nodeSavePath = nodeSavePath; _listener = new DhtListener(new IPEndPoint(IPAddress.Any, Port)); _engine = new DhtEngine(_listener); _engine.PeersFound += EnginePeersFound; _engine.StateChanged += EngineStateChanged; _listener.MessageReceived += ListenerMessageReceived; if (!String.IsNullOrWhiteSpace(_nodeSavePath) && File.Exists(_nodeSavePath)) { Log("Node File Found."); _nodes = File.ReadAllBytes(_nodeSavePath); } }
static IList <InfoHash> ParseHashes(string infoHash) { if (string.IsNullOrEmpty(infoHash)) { return(Array.Empty <InfoHash> ()); } var split = infoHash.Split(HashSeparators, StringSplitOptions.RemoveEmptyEntries); var result = new InfoHash[split.Length]; for (int i = 0; i < split.Length; i++) { result [i] = InfoHash.UrlDecode(split [i]); } return(result); }
public async void Announce(InfoHash infoHash, int port) { CheckDisposed(); if (infoHash is null) { throw new ArgumentNullException(nameof(infoHash)); } try { await MainLoop; var task = new AnnounceTask(this, infoHash, port); await task.ExecuteAsync(); } catch { // Ignore? } }
public AnnounceRequest(NameValueCollection collection, IPAddress address) : base(collection, address) { InfoHash = CheckMandatoryFields(); /* If the user has supplied an IP address, we use that instead of * the IP address we read from the announce request connection. */ if (IPAddress.TryParse(Parameters["ip"] ?? "", out IPAddress supplied) && !supplied.Equals(IPAddress.Any)) { ClientAddress = new IPEndPoint(supplied, Port); } else { ClientAddress = new IPEndPoint(address, Port); } }
public async void GetPeers(InfoHash infoHash) { CheckDisposed(); if (infoHash == null) { throw new ArgumentNullException(nameof(infoHash)); } try { await MainLoop; var task = new GetPeersTask(this, infoHash); await task.ExecuteAsync(); } catch { // Ignore? } }
public void InfoHashTest() { var link = new MagnetLink("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"); Assert.Equal(InfoHash.FromBase32("YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"), link.InfoHash); //base32 var initial = new InfoHash(Encoding.ASCII.GetBytes("foobafoobafoobafooba")); link = new MagnetLink("magnet:?xt=urn:sha1:MZXW6YTBMZXW6YTBMZXW6YTBMZXW6YTB"); Assert.Equal(initial, link.InfoHash); //base40 = hex var hash = Create(); var hex = hash.ToHex(); link = new MagnetLink("magnet:?xt=urn:btih:" + hex); Assert.Equal(hash, link.InfoHash); }
public void InfoHashTest() { MagnetLink link = new MagnetLink("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"); Assert.AreEqual(InfoHash.FromBase32 ("YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"), link.InfoHash , "#1"); //base32 InfoHash initial = new InfoHash (System.Text.Encoding.ASCII.GetBytes("foobafoobafoobafooba")); link = new MagnetLink("magnet:?xt=urn:sha1:MZXW6YTBMZXW6YTBMZXW6YTBMZXW6YTB"); Assert.AreEqual(initial, link.InfoHash , "#2"); //base40 = hex InfoHash hash = Create(); string hex = hash.ToHex(); link = new MagnetLink("magnet:?xt=urn:btih:" + hex); Assert.AreEqual(hash, link.InfoHash , "#3"); }
async ReusableTask <ScrapeResponse> ScrapeReceivedAsync(InfoHash infoHash, HttpResponseMessage response) { await new ThreadSwitcher(); int?complete = null, downloaded = null, incomplete = null; BEncodedDictionary dict = await DecodeResponseAsync(response).ConfigureAwait(false); // FIXME: Log the failure? if (!dict.ContainsKey("files")) { return(new ScrapeResponse(TrackerState.Ok, warningMessage: "Tracker did not have data for this torrent")); } var files = (BEncodedDictionary)dict["files"]; if (files.Count != 1) { throw new TrackerException("The scrape response contained unexpected data"); } var d = (BEncodedDictionary)files[new BEncodedString(infoHash.Span.ToArray())]; foreach (KeyValuePair <BEncodedString, BEncodedValue> kp in d) { switch (kp.Key.ToString()) { case "complete": complete = (int)((BEncodedNumber)kp.Value).Number; break; case "downloaded": downloaded = (int)((BEncodedNumber)kp.Value).Number; break; case "incomplete": incomplete = (int)((BEncodedNumber)kp.Value).Number; break; default: logger.InfoFormatted("Unknown scrape tag received: Key {0} Value {1}", kp.Key, kp.Value); break; } } return(new ScrapeResponse(TrackerState.Ok, complete: complete, incomplete: incomplete, downloaded: downloaded)); }
public TorrentHandler(InfoHash H, string DownloadDir = DOWNLOAD_DIR, bool ForceHash = false) { InitBase(DownloadDir); var CacheFile = Environment.ExpandEnvironmentVariables(TORRENT_DIR + $"\\{H.ToHex()}.torrent"); //Use cached torrent file if available if (!ForceHash && File.Exists(CacheFile)) { Torrent T = Torrent.Load(File.ReadAllBytes(CacheFile)); TM = new TorrentManager(T, Environment.ExpandEnvironmentVariables(DownloadDir), TS); } else { TM = new TorrentManager(H, Environment.ExpandEnvironmentVariables(DownloadDir), TS, Environment.ExpandEnvironmentVariables(TORRENT_DIR), InitTracker()); } Assign(); }
internal static MonoTorrentCollection <int> Calculate(byte[] addressBytes, InfoHash infohash, int count, UInt32 numberOfPieces) { byte[] hashBuffer = new byte[24]; // The hash buffer to be used in hashing MonoTorrentCollection <int> results = new MonoTorrentCollection <int>(count); // The results array which will be returned // 1) Convert the bytes into an int32 and make them Network order int ip = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(addressBytes, 0)); // 2) binary AND this value with 0xFFFFFF00 to select the three most sigificant bytes int ipMostSignificant = (int)(0xFFFFFF00 & ip); // 3) Make ipMostSignificant into NetworkOrder UInt32 ip2 = (UInt32)IPAddress.HostToNetworkOrder(ipMostSignificant); // 4) Copy ip2 into the hashBuffer Buffer.BlockCopy(BitConverter.GetBytes(ip2), 0, hashBuffer, 0, 4); // 5) Copy the infohash into the hashbuffer Buffer.BlockCopy(infohash.Hash, 0, hashBuffer, 4, 20); // 6) Keep hashing and cycling until we have AllowedFastPieceCount number of results // Then return that result while (true) { lock (hasher) hashBuffer = hasher.ComputeHash(hashBuffer); for (int i = 0; i < 20; i += 4) { UInt32 result = (UInt32)IPAddress.HostToNetworkOrder(BitConverter.ToInt32(hashBuffer, i)); result = result % numberOfPieces; if (result > int.MaxValue) { return(results); } results.Add((int)result); if (count == results.Count) { return(results); } } } }
public override void Decode(byte[] buffer, int offset, int length) { ConnectionId = ReadLong(buffer, ref offset); if (Action != ReadInt(buffer, ref offset)) ThrowInvalidActionException(); TransactionId = ReadInt(buffer, ref offset); Infohash = new InfoHash(ReadBytes(buffer, ref offset, 20)); PeerId = ReadString(buffer, ref offset, 20); Downloaded = ReadLong(buffer, ref offset); Left = ReadLong(buffer, ref offset); Uploaded = ReadLong(buffer, ref offset); TorrentEvent = (TorrentEvent) ReadInt(buffer, ref offset); Ip = (uint) ReadInt(buffer, ref offset); Key = (uint) ReadInt(buffer, ref offset); NumWanted = ReadInt(buffer, ref offset); Port = (ushort) ReadShort(buffer, ref offset); }
public FastResume(BEncodedDictionary dict) { CheckContent(dict, VersionKey, (BEncodedNumber)1); CheckContent(dict, InfoHashKey); CheckContent(dict, BitfieldKey); CheckContent(dict, BitfieldLengthKey); infoHash = new InfoHash(((BEncodedString)dict[InfoHashKey]).TextBytes); bitfield = new BitField((int)((BEncodedNumber)dict[BitfieldLengthKey]).Number); byte[] data = ((BEncodedString)dict[BitfieldKey]).TextBytes; bitfield.FromArray(data, 0, data.Length); if (dict.ContainsKey(PrioritiesKey)) { var list = (BEncodedList)dict[PrioritiesKey]; priorities = list.Select(v => (Priority)((BEncodedNumber)v).Number).ToArray(); } }
public FastResume(BEncodedDictionary dict) { CheckContent(dict, VersionKey, (BEncodedNumber)1); CheckContent(dict, InfoHashKey); CheckContent(dict, BitfieldKey); CheckContent(dict, BitfieldLengthKey); infoHash = new InfoHash(((BEncodedString)dict[InfoHashKey]).TextBytes); bitfield = new BitField((int)((BEncodedNumber)dict[BitfieldLengthKey]).Number); byte[] data = ((BEncodedString)dict[BitfieldKey]).TextBytes; bitfield.FromArray(data, 0, data.Length); if (dict.ContainsKey(PrioritiesKey)) { var list = (BEncodedList)dict[PrioritiesKey]; priorities = list.Select(v => (Priority)((BEncodedNumber)v).Number).ToArray(); } }
public void GetPeersQuery_Encoding() { TransactionID transactionId = new TransactionID(Encoding.UTF8.GetBytes("aa")); NodeID senderId = new NodeID(Encoding.UTF8.GetBytes("abcdefghij0123456789")); InfoHash infoHash = new InfoHash(Encoding.UTF8.GetBytes("mnopqrstuvwxyz123456")); GetPeersQuery testQuery = new GetPeersQuery(transactionId, senderId, infoHash); byte[] bencodedMessageBytes = testQuery.Construct().Encode(); Assert.Equal(MessageType.Query, KademliaRPC.TryParseMessage(bencodedMessageBytes, out BDictionary message)); Assert.Equal(QueryType.get_peers, KademliaRPC.TryGetQuery(message, out Query query)); Assert.True(query is GetPeersQuery); Assert.Equal(testQuery.TransactionID, query.TransactionID); Assert.Equal(testQuery.SenderNode, ((GetPeersQuery)query).SenderNode); Assert.Equal(testQuery.InfoHash, ((GetPeersQuery)query).InfoHash); Assert.Equal(TestBencodedMessage, Encoding.UTF8.GetString(bencodedMessageBytes)); }
public AnnounceMessage(int transactionId, long connectionId, AnnounceParameters parameters) : base(1, transactionId) { this.connectionId = connectionId; if (parameters == null) return; downloaded = parameters.BytesDownloaded; infoHash = parameters.InfoHash; ip = 0; key = (uint) DateTime.Now.GetHashCode(); // FIXME: Don't do this! It should be constant left = parameters.BytesLeft; numWanted = 50; peerId = parameters.PeerId; port = (ushort) parameters.Port; torrentEvent = parameters.ClientEvent; uploaded = parameters.BytesUploaded; }
private ScrapeResponse HandleScrapeResponse(BEncoding.Dictionary info) { BEncoding.Dictionary files; if (!info.TryGetDictionary("files", out files)) { return(null); } var torrentInfos = new List <ScrapeResponse.TorrentInfo>(files.Count); foreach (var torrentInfo in files) { var torrentInfoDict = (torrentInfo.Value as BEncoding.Dictionary); if (torrentInfoDict == null) { continue; } long completeCount, incompleteCount, downloadedCount; string torrentName; if (!torrentInfoDict.TryGetInteger("complete", out completeCount)) { completeCount = 0; } if (!torrentInfoDict.TryGetInteger("incomplete", out incompleteCount)) { incompleteCount = 0; } if (!torrentInfoDict.TryGetInteger("downloaded", out downloadedCount)) { downloadedCount = 0; } if (!torrentInfoDict.TryGetString("name", out torrentName)) { torrentName = null; } byte[] infoHashBytes = Encoding.UTF8.GetBytes(torrentInfo.Key); // TODO: Is this okay to do? var infoHash = new InfoHash(infoHashBytes); torrentInfos.Add(new ScrapeResponse.TorrentInfo(infoHash, (int)completeCount, (int)incompleteCount, (int)downloadedCount, torrentName)); } return(new ScrapeResponse(this, torrentInfos.ToArray())); }
internal static MonoTorrentCollection<int> Calculate(byte[] addressBytes, InfoHash infohash, int count, uint numberOfPieces) { var hashBuffer = new byte[24]; // The hash buffer to be used in hashing var results = new MonoTorrentCollection<int>(count); // The results array which will be returned // 1) Convert the bytes into an int32 and make them Network order var ip = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(addressBytes, 0)); // 2) binary AND this value with 0xFFFFFF00 to select the three most sigificant bytes var ipMostSignificant = (int) (0xFFFFFF00 & ip); // 3) Make ipMostSignificant into NetworkOrder var ip2 = (uint) IPAddress.HostToNetworkOrder(ipMostSignificant); // 4) Copy ip2 into the hashBuffer Buffer.BlockCopy(BitConverter.GetBytes(ip2), 0, hashBuffer, 0, 4); // 5) Copy the infohash into the hashbuffer Buffer.BlockCopy(infohash.Hash, 0, hashBuffer, 4, 20); // 6) Keep hashing and cycling until we have AllowedFastPieceCount number of results // Then return that result while (true) { lock (hasher) hashBuffer = hasher.ComputeHash(hashBuffer); for (var i = 0; i < 20; i += 4) { var result = (uint) IPAddress.HostToNetworkOrder(BitConverter.ToInt32(hashBuffer, i)); result = result%numberOfPieces; if (result > int.MaxValue) return results; results.Add((int) result); if (count == results.Count) return results; } } }
async void ReceiveAsync(UdpClient client, CancellationToken token) { while (!token.IsCancellationRequested) { try { UdpReceiveResult result = await client.ReceiveAsync().ConfigureAwait(false); string[] receiveString = Encoding.ASCII.GetString(result.Buffer) .Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); string portString = receiveString.FirstOrDefault(t => t.StartsWith("Port: ", StringComparison.Ordinal)); string hashString = receiveString.FirstOrDefault(t => t.StartsWith("Infohash: ", StringComparison.Ordinal)); string cookieString = receiveString.FirstOrDefault(t => t.StartsWith("cookie", StringComparison.Ordinal)); // An invalid response was received if these are missing. if (portString == null || hashString == null) { continue; } // If we received our own cookie we can ignore the message. if (cookieString != null && cookieString.Contains(Cookie)) { continue; } // If the port is invalid, ignore it! int portcheck = int.Parse(portString.Split(' ').Last()); if (portcheck <= 0 || portcheck > 65535) { continue; } var infoHash = InfoHash.FromHex(hashString.Split(' ').Last()); var uri = new Uri($"ipv4://{result.RemoteEndPoint.Address}{':'}{portcheck}"); PeerFound?.InvokeAsync(this, new LocalPeerFoundEventArgs(infoHash, uri)); } catch (FileNotFoundException) { throw; } catch { } } }
/// <summary> /// Creates a new tracker announce request. /// </summary> /// <param name="infoHash">The info hash.</param> /// <param name="peerID">The peer ID.</param> /// <param name="port">The port number used to listen for client connections on.</param> public AnnounceRequest(InfoHash infoHash, PeerID peerID, int port) { if (infoHash.Hash == null) { throw new ArgumentException("The info hash is invalid.", "infoHash"); } else if (peerID.ID == null) { throw new ArgumentException("The peer ID is invalid.", "infoHash"); } else if (port <= 0 || port > ushort.MaxValue) { throw new ArgumentOutOfRangeException("port"); } this.infoHash = infoHash; this.peerID = peerID; this.port = port; }
public override void Decode(ReadOnlySpan <byte> buffer) { ConnectionId = ReadLong(ref buffer); if (Action != ReadInt(ref buffer)) { ThrowInvalidActionException(); } TransactionId = ReadInt(ref buffer); InfoHash = InfoHash.FromMemory(ReadBytes(ref buffer, 20)); PeerId = ReadBytes(ref buffer, 20); Downloaded = ReadLong(ref buffer); Left = ReadLong(ref buffer); Uploaded = ReadLong(ref buffer); TorrentEvent = (TorrentEvent)ReadInt(ref buffer); IP = ReadUInt(ref buffer); Key = ReadUInt(ref buffer); NumWanted = ReadInt(ref buffer); Port = ReadUShort(ref buffer); }
public static void Main() { //https://wiki.theory.org/BitTorrentSpecification Listener listener = new UdpListener(new IPEndPoint(IPAddress.Any, 15000)); listener.Start(); DhtEngine engine = new DhtEngine(listener); engine.Start(); //Wait for the DHT to startup Task.Delay(30000).Wait(); engine.PeersFound += EngineOnPeersFound; engine.GetPeers(InfoHash.FromHex("0403FB4728BD788FBCB67E87D6FEB241EF38C75A")); Console.ReadLine(); }
/// <summary> /// Send an announce request for this InfoHash. /// </summary> /// <param name="infoHash"></param> /// <returns></returns> public async Task Announce(InfoHash infoHash) { var message = string.Format(BaseSearchString, Settings.ListenPort, infoHash.ToHex()); var data = Encoding.ASCII.GetBytes(message); // If there's another application on the system which joined the bittorrent LPD broadcast group, we'll be unable to // join it and will have a PortInUse error. However, we can still *send* broadcast messages using any UDP client. using (var sendingClient = new UdpClient()) foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) { try { //if (!nic.SupportsMulticast) continue; sendingClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(nic.GetIPProperties().GetIPv4Properties().Index)); await sendingClient.SendAsync(data, data.Length, BroadcastEndPoint); } catch { // If data can't be sent, just ignore the error } } }
public TorrentManager(MagnetLink magnetLink, string savePath, TorrentSettings settings, string torrentSave) { Check.MagnetLink(magnetLink); Check.InfoHash(magnetLink.InfoHash); Check.SavePath(savePath); Check.Settings(settings); Check.TorrentSave(torrentSave); this.infohash = magnetLink.InfoHash; this.settings = settings; this.torrentSave = torrentSave; IList <RawTrackerTier> announces = new RawTrackerTiers(); if (magnetLink.AnnounceUrls != null) { announces.Add(magnetLink.AnnounceUrls); } Initialise(savePath, "", announces); }
public HandshakeMessage(InfoHash infoHash, string peerId, string protocolString, bool enableFastPeer, bool enableExtended) { if (!ClientEngine.SupportsFastPeer && enableFastPeer) { throw new ProtocolException("The engine does not support fast peer, but fast peer was requested"); } if (!ClientEngine.SupportsExtended && enableExtended) { throw new ProtocolException("The engine does not support extended, but extended was requested"); } this.infoHash = infoHash; this.peerId = peerId; this.protocolString = protocolString; this.protocolStringLength = protocolString.Length; this.supportsFastPeer = enableFastPeer; this.extended = enableExtended; }
public static TorrentManager CreateManager(this InfoHash hash, StorageFolder saveFolder) { return(new TorrentManager(hash, saveFolder, new TorrentSettings(4, 150, 0, 0) { UseDht = true, EnablePeerExchange = true }, RawTrackerTier.CreateTiers(new[] { "udp://tracker.yify-torrents.com:80", "udp://tracker.yify-torrents.com:80", "udp://tracker.openbittorrent.com:80", "udp://tracker.publicbt.org:80", "udp://tracker.coppersurfer.tk:6969", "udp://tracker.leechers-paradise.org:6969", "udp://open.demonii.com:1337", "udp://p4p.arenabg.ch:1337", "udp://p4p.arenabg.com:1337" }))); }
public override void Decode(byte[] buffer, int offset, int length) { connectionId = ReadLong(buffer, ref offset); if (Action != ReadInt(buffer, ref offset)) { ThrowInvalidActionException(); } TransactionId = ReadInt(buffer, ref offset); infoHash = new InfoHash(ReadBytes(buffer, ref offset, 20)); peerId = ReadString(buffer, ref offset, 20); downloaded = ReadLong(buffer, ref offset); left = ReadLong(buffer, ref offset); uploaded = ReadLong(buffer, ref offset); torrentEvent = (TorrentEvent)ReadInt(buffer, ref offset); ip = (uint)ReadInt(buffer, ref offset); key = (uint)ReadInt(buffer, ref offset); numWanted = ReadInt(buffer, ref offset); port = (ushort)ReadShort(buffer, ref offset); }
public override void Decode(byte[] buffer, int offset, int length) { ConnectionId = ReadLong(buffer, ref offset); if (Action != ReadInt(buffer, ref offset)) { ThrowInvalidActionException(); } TransactionId = ReadInt(buffer, ref offset); Infohash = new InfoHash(ReadBytes(buffer, ref offset, 20)); PeerId = ReadString(buffer, ref offset, 20); Downloaded = ReadLong(buffer, ref offset); Left = ReadLong(buffer, ref offset); Uploaded = ReadLong(buffer, ref offset); TorrentEvent = (TorrentEvent)ReadInt(buffer, ref offset); Ip = (uint)ReadInt(buffer, ref offset); Key = (uint)ReadInt(buffer, ref offset); NumWanted = ReadInt(buffer, ref offset); Port = (ushort)ReadShort(buffer, ref offset); }
public void InfoHashTest() { MagnetLink link = new MagnetLink("magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"); Assert.Equal(InfoHash.FromBase32("YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"), link.InfoHash); //base32 InfoHash initial = new InfoHash(System.Text.Encoding.ASCII.GetBytes("foobafoobafoobafooba")); link = new MagnetLink("magnet:?xt=urn:sha1:MZXW6YTBMZXW6YTBMZXW6YTBMZXW6YTB"); Assert.Equal(initial, link.InfoHash); //base40 = hex InfoHash hash = Create(); string hex = hash.ToHex(); link = new MagnetLink("magnet:?xt=urn:btih:" + hex); Assert.Equal(hash, link.InfoHash); }
/// <summary> /// Initializes an instance of the Torrent.Client.TrackerRequest class with the specified parameters. /// </summary> /// <param name="infoHash">The SHA1 hash of the value of the info key from the torrent metadata.</param> /// <param name="peerId">The Peer ID, used to uniquely identify the peer. 20 bytes.</param> /// <param name="port">The port at which the client is listening on. Typically 6881-6889.</param> /// <param name="uploaded">The total count of uploaded bytes.</param> /// <param name="downloaded">The total count of downloaded bytes.</param> /// <param name="left">The count of bytes left to download for the download to be complete.</param> /// <param name="compact">Whether to request a compact response by the tracker. (binary peers representation)</param> /// <param name="omitPeerIds">Whether to request that the tracker should omit peer IDs in the peers dictionary.</param> /// <param name="event">Specifies the event that caused the request. None by default.</param> public TrackerRequest(InfoHash infoHash, string peerId, ushort port, long uploaded, long downloaded, long left, bool compact, bool omitPeerIds, EventType @event = EventType.None, int? numWant = null) { Contract.Requires(infoHash != null); Contract.Requires(peerId != null); Contract.Requires(port > 0); Contract.Requires(uploaded >= 0); Contract.Requires(downloaded >= 0); Contract.Requires(left >= 0); InfoHash = infoHash; PeerId = peerId; Port = port; Uploaded = uploaded; Downloaded = downloaded; Left = left; Compact = compact; OmitPeerIds = omitPeerIds; Event = @event; NumWant = numWant; }
public void GetPeers(InfoHash infohash) { }
/// <summary> /// Creates a new InfoHash object from an array of bytes. /// </summary> /// <param name="bytes">The array of bytes used to create this object from.</param> /// <returns>A new InfoHash object.</returns> public static InfoHash FromByteArray(byte[] bytes) { InfoHash infohash = new InfoHash(); infohash.Bytes = bytes; return infohash; }
public void Announce(InfoHash infohash, int port) { }