Esempio n. 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);
            }
        }
Esempio n. 2
0
 public override void Decode(ReadOnlySpan <byte> buffer)
 {
     ConnectionId = ReadLong(ref buffer);
     if (Action != ReadInt(ref buffer))
     {
         throw new MessageException("Udp message decoded incorrectly");
     }
     TransactionId = ReadInt(ref buffer);
     while (buffer.Length >= 20)
     {
         InfoHashes.Add(InfoHash.FromMemory(ReadBytes(ref buffer, 20)));
     }
 }
        public void ScrapeMessageTest()
        {
            List <InfoHash> hashes = new List <InfoHash> ();
            Random          r      = new Random();

            byte[] hash1 = new byte[20];
            byte[] hash2 = new byte[20];
            byte[] hash3 = new byte[20];
            r.NextBytes(hash1);
            r.NextBytes(hash2);
            r.NextBytes(hash3);
            hashes.Add(InfoHash.FromMemory(hash1));
            hashes.Add(InfoHash.FromMemory(hash2));
            hashes.Add(InfoHash.FromMemory(hash3));

            ScrapeMessage m = new ScrapeMessage(12345, 123, hashes);
            ScrapeMessage d = (ScrapeMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), MessageType.Request);

            Check(m, MessageType.Request);

            Assert.AreEqual(2, m.Action);
            Assert.AreEqual(m.Action, d.Action);
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()));
        }
Esempio n. 4
0
        public override void Decode(ReadOnlySpan <byte> buffer)
        {
            ProtocolStringLength = ReadByte(ref buffer);                   // First byte is length

            // #warning Fix this hack - is there a better way of verifying the protocol string? Hack
            if (ProtocolStringLength != Constants.ProtocolStringV100.Length)
            {
                ProtocolStringLength = Constants.ProtocolStringV100.Length;
            }

            ProtocolString = ReadString(ref buffer, ProtocolStringLength);
            CheckForSupports(ref buffer);
            InfoHash = InfoHash.FromMemory(ReadBytes(ref buffer, 20));
            PeerId   = BEncodedString.FromMemory(ReadBytes(ref buffer, 20));
        }
Esempio n. 5
0
 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);
 }
Esempio n. 6
0
        internal FastResume(BEncodedDictionary dict)
        {
            CheckVersion(dict);
            CheckContent(dict, InfoHashKey);
            CheckContent(dict, BitfieldKey);
            CheckContent(dict, BitfieldLengthKey);

            Infohash = InfoHash.FromMemory(((BEncodedString)dict[InfoHashKey]).AsMemory());

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

            Bitfield = new BitField(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 BitField(data, Bitfield.Length);
            }
            else
            {
                UnhashedPieces = new BitField(Bitfield.Length);
            }
        }
Esempio n. 7
0
        protected override void HandleLtMetadataMessage(PeerId id, LTMetadata message)
        {
            base.HandleLtMetadataMessage(id, message);

            switch (message.MetadataMessageType)
            {
            case LTMetadata.MessageType.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)
                {
                    InfoHash hash;
                    Stream.Position = 0;
                    using (SHA1 hasher = Manager.Engine.Factories.CreateSHA1())
                        hash = InfoHash.FromMemory(hasher.ComputeHash(Stream));

                    if (Manager.InfoHash != 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 (this.Settings.AutoSaveLoadMagnetLinkMetadata)
                                {
                                    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.MessageType.Reject:
                //TODO
                //Think to what we do in this situation
                //for moment nothing ;)
                //reject or flood?
                break;

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

            default:
                throw new MessageException($"Invalid messagetype in LTMetadata: {message.MetadataMessageType}");
            }
        }
Esempio n. 8
0
 internal void RaisePeersFound(NodeId infoHash, IList <PeerInfo> peers)
 {
     PeersFound?.Invoke(this, new PeersFoundEventArgs(InfoHash.FromMemory(infoHash.AsMemory()), peers));
 }