Exemple #1
0
        internal FastResume(BEncodedDictionary dict)
        {
            CheckVersion(dict);
            CheckContent(dict, InfoHashKey);
            CheckContent(dict, BitfieldKey);
            CheckContent(dict, BitfieldLengthKey);

            // BEP52: Support backwards/forwards compatibility
            var infoHash = InfoHash.FromMemory(((BEncodedString)dict[InfoHashKey]).AsMemory());

            if (infoHash.Span.Length == 20)
            {
                InfoHashes = InfoHashes.FromV1(infoHash);
            }
            else
            {
                InfoHashes = InfoHashes.FromV2(infoHash);
            }

            var data = ((BEncodedString)dict[BitfieldKey]).Span;

            Bitfield = new ReadOnlyBitField(data, (int)((BEncodedNumber)dict[BitfieldLengthKey]).Number);

            // If we're loading up an older version of the FastResume data then we
            if (dict.ContainsKey(UnhashedPiecesKey))
            {
                data           = ((BEncodedString)dict[UnhashedPiecesKey]).Span;
                UnhashedPieces = new ReadOnlyBitField(data, Bitfield.Length);
            }
            else
            {
                UnhashedPieces = new ReadOnlyBitField(Bitfield.Length);
            }
        }
        public void Add(InfoHashes skey)
        {
            var clone = new InfoHash[SKeys.Length + 1];

            Array.Copy(SKeys, clone, SKeys.Length);
            clone[clone.Length - 1] = skey.V1OrV2.Truncate();
            SKeys = clone;
        }
        public bool Contains (InfoHashes infoHashes)
        {
            CheckDisposed ();
            if (infoHashes == null)
                return false;

            return allTorrents.Exists (m => m.InfoHashes == infoHashes);
        }
        public void Remove(InfoHashes skey)
        {
            var clone = new InfoHash[SKeys.Length - 1];
            var index = Array.IndexOf(SKeys, skey.V1OrV2.Truncate());

            Array.Copy(SKeys, clone, index);
            Array.Copy(SKeys, index + 1, clone, index, clone.Length - index);
            SKeys = clone;
        }
Exemple #5
0
        public void DownloadMetadata_Cancelled()
        {
            var cts    = new CancellationTokenSource();
            var engine = new ClientEngine(EngineSettingsBuilder.CreateForTests());
            var task   = engine.DownloadMetadataAsync(new MagnetLink(InfoHashes.FromV1(new InfoHash(new byte[20]))), cts.Token);

            cts.Cancel();
            Assert.ThrowsAsync <OperationCanceledException> (() => task);
        }
        internal static List <int> Calculate(SHA1 hasher, byte[] addressBytes, InfoHashes infohashes, int count, uint numberOfPieces)
        {
            // BEP52: Support V2 torrents
            var infohash = infohashes.V1;

            if (infohash == null)
            {
                return(new List <int> ());
            }

            byte[] hashBuffer = new byte[24];           // The hash buffer to be used in hashing
            var    results    = new List <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
            uint 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
            infohash.Span.CopyTo(hashBuffer.AsSpan(4, 20));

            // 6) Keep hashing and cycling until we have AllowedFastPieceCount number of results
            // Then return that result
            while (true)
            {
                hashBuffer = hasher.ComputeHash(hashBuffer);

                for (int i = 0; i < 20; i += 4)
                {
                    uint result = (uint)IPAddress.HostToNetworkOrder(BitConverter.ToInt32(hashBuffer, i));

                    result %= numberOfPieces;
                    if (result > int.MaxValue)
                    {
                        return(results);
                    }

                    results.Add((int)result);

                    if (count == results.Count)
                    {
                        return(results);
                    }
                }
            }
        }
Exemple #7
0
        internal FastResume(InfoHashes infoHashes, ReadOnlyBitField bitfield, ReadOnlyBitField unhashedPieces)
        {
            InfoHashes     = infoHashes ?? throw new ArgumentNullException(nameof(infoHashes));
            Bitfield       = new ReadOnlyBitField(bitfield);
            UnhashedPieces = new ReadOnlyBitField(unhashedPieces);

            for (int i = 0; i < Bitfield.Length; i++)
            {
                if (bitfield[i] && unhashedPieces[i])
                {
                    throw new ArgumentException($"The bitfield is set to true at index {i} but that piece is marked as unhashed.");
                }
            }
        }
 internal static List <int> Calculate(SHA1 hasher, byte[] addressBytes, InfoHashes infohashes, uint numberOfPieces)
 {
     return(Calculate(hasher, addressBytes, infohashes, AllowedFastPieceCount, numberOfPieces));
 }
 internal async Task StreamAsync(InfoHashes infoHashes, CancellationToken token)
 => await StreamAsync(await Engine.AddStreamingAsync(new MagnetLink(infoHashes), DownloadDirectory), token);
 internal string GetMetadataPath(InfoHashes infoHashes)
 => Path.Combine(MetadataCacheDirectory, $"{infoHashes.V1OrV2.ToHex ()}.torrent");
 /// <summary>
 /// Returns the full path to the <see cref="FastResume"/> file for the specified torrent. This is
 /// where data will be written to, or loaded from, when <see cref="AutoSaveLoadFastResume"/> is enabled.
 /// </summary>
 /// <param name="infoHashes">The infohashes for the torrent</param>
 /// <returns></returns>
 public string GetFastResumePath(InfoHashes infoHashes)
 => Path.Combine(FastResumeCacheDirectory, $"{infoHashes.V1OrV2.ToHex ()}.fresume");
 async Task<bool> RemoveAsync (InfoHashes infoHashes, RemoveMode mode)
 {
     await MainLoop;
     var manager = allTorrents.FirstOrDefault (t => t.InfoHashes == infoHashes);
     return manager != null && await RemoveAsync (manager, mode);
 }