예제 #1
0
파일: Utils.cs 프로젝트: chitza/uDir
        /// <summary>
        /// Reads the file list from a .torrent file.
        /// </summary>
        /// <param name="downloadPath"></param>
        /// <returns></returns>
        public static List<SimpleFileInfo> ReadTorrentFileList(string torrentFile)
        {
            if (!File.Exists(torrentFile))
                throw new FileNotFoundException("Can't find file " + torrentFile);

            var ret = new List<SimpleFileInfo>();

            //read and decode the .torrent file
            byte[] torrentBytes = File.ReadAllBytes(torrentFile);
            var torrentData = BEncodedValue.Decode<BEncodedDictionary>(torrentBytes);

            BEncodedList fileList = new BEncodedList();

            try
            {
                fileList = torrentData.Item<BEncodedDictionary>("info").Item<BEncodedList>("files");
            }
            catch { };

            foreach (var fileItem in fileList)
            {
                var fileData = fileItem as BEncodedDictionary;

                string filePath = BuildPathFromDirectoryList(fileData.Item<BEncodedList>("path"));
                long length = fileData.Item<BEncodedNumber>("length").Number;

                ret.Add(new SimpleFileInfo(filePath, length));
            }
            ret.Sort( new Comparison<SimpleFileInfo>( FileNameComparison));

            return ret;
        }
예제 #2
0
 public void CorruptDictionary()
 {
     var l = new BEncodedList();
     var d = new BEncodedDictionary();
     l.Add(d);
     IList<Peer> decoded = Peer.Decode(l);
     Assert.Equal(0, decoded.Count);
 }
예제 #3
0
 public void CorruptDictionary()
 {
     BEncodedList l = new BEncodedList();
     BEncodedDictionary d = new BEncodedDictionary();
     l.Add(d);
     IList<Peer> decoded = Peer.Decode(l);
     Assert.AreEqual(0, decoded.Count, "#1");
 }
예제 #4
0
 public ErrorMessage(ErrorCode error, string message)
     : base(ErrorType)
 {
     var l = new BEncodedList();
     l.Add(new BEncodedNumber((int) error));
     l.Add(new BEncodedString(message));
     properties.Add(ErrorListKey, l);
 }
예제 #5
0
        public void CorruptDictionary()
        {
            var list = new BEncodedList();
            var dictionary = new BEncodedDictionary();

            list.Add(dictionary);
            IList<Peer> decoded = Peer.Decode(list);
            Assert.AreEqual(0, decoded.Count, "#1");
        }
예제 #6
0
 public void benDictionaryEncodingBuffered()
 {
     var data = Encoding.UTF8.GetBytes("d4:spaml1:a1:bee");
     var dict = new BEncodedDictionary();
     var list = new BEncodedList();
     list.Add(new BEncodedString("a"));
     list.Add(new BEncodedString("b"));
     dict.Add("spam", list);
     var result = new byte[dict.LengthInBytes()];
     dict.Encode(result, 0);
     Assert.True(Toolbox.ByteMatch(data, result));
 }
예제 #7
0
        public void benDictionaryEncoding()
        {
            var data = Encoding.UTF8.GetBytes("d4:spaml1:a1:bee");

            var dict = new BEncodedDictionary();
            var list = new BEncodedList();
            list.Add(new BEncodedString("a"));
            list.Add(new BEncodedString("b"));
            dict.Add("spam", list);
            Assert.Equal(Encoding.UTF8.GetString(data), Encoding.UTF8.GetString(dict.Encode()));
            Assert.True(Toolbox.ByteMatch(data, dict.Encode()));
        }
예제 #8
0
        public void benDictionaryEncoding()
        {
            byte[] data = System.Text.Encoding.UTF8.GetBytes("d4:spaml1:a1:bee");

            BEncodedDictionary dict = new BEncodedDictionary();
            BEncodedList list = new BEncodedList();
            list.Add(new BEncodedString("a"));
            list.Add(new BEncodedString("b"));
            dict.Add("spam", list);
            Assert.AreEqual(System.Text.Encoding.UTF8.GetString(data), System.Text.Encoding.UTF8.GetString(dict.Encode()));
            Assert.IsTrue(Toolbox.ByteMatch(data, dict.Encode()));
        }
예제 #9
0
        public void CorruptList()
        {
            var list = new BEncodedList();
            for (var i = 0; i < peers.Count; i++)
                list.Add((BEncodedString) peers[i].CompactPeer());

            list.Insert(2, new BEncodedNumber(5));
            VerifyDecodedPeers(Peer.Decode(list));

            list.Clear();
            list.Add(new BEncodedString(new byte[3]));
            IList<Peer> decoded = Peer.Decode(list);
            Assert.Equal(0, decoded.Count);
        }
        private void AddCommonStuff(BEncodedDictionary torrent)
        {
            if (Announces.Count > 0 && Announces[0].Count > 0)
                Announce = Announces[0][0];

            if (GetrightHttpSeeds.Count > 0)
            {
                var seedlist = new BEncodedList();
                seedlist.AddRange(
                    GetrightHttpSeeds.ConvertAll<BEncodedValue>(delegate(string s) { return (BEncodedString) s; }));
                torrent["url-list"] = seedlist;
            }

            var span = DateTime.Now - new DateTime(1970, 1, 1);
            torrent["creation date"] = new BEncodedNumber((long) span.TotalSeconds);
        }
예제 #11
0
        private static BEncodedDictionary CreateTorrent(int pieceLength)
        {
            var infoDict = new BEncodedDictionary();
            infoDict[new BEncodedString("piece length")] = new BEncodedNumber(pieceLength);
            infoDict[new BEncodedString("pieces")] = new BEncodedString(new byte[20*15]);
            infoDict[new BEncodedString("length")] = new BEncodedNumber(15*256*1024 - 1);
            infoDict[new BEncodedString("name")] = new BEncodedString("test.files");

            var dict = new BEncodedDictionary();
            dict[new BEncodedString("info")] = infoDict;

            var announceTier = new BEncodedList();
            announceTier.Add(new BEncodedString("custom://transfers1/announce"));
            announceTier.Add(new BEncodedString("custom://transfers2/announce"));
            announceTier.Add(new BEncodedString("http://transfers3/announce"));
            var announceList = new BEncodedList();
            announceList.Add(announceTier);
            dict[new BEncodedString("announce-list")] = announceList;
            return dict;
        }
예제 #12
0
		public override void Handle(DhtEngine engine, Node node)
		{
			base.Handle(engine, node);

			BEncodedString token = engine.TokenManager.GenerateToken(node);
			var response = new GetPeersResponse(engine.RoutingTable.LocalNode.Id, TransactionId, token);
			if (engine.Torrents.ContainsKey(InfoHash))
			{
				var list = new BEncodedList();
				foreach (Node n in engine.Torrents[InfoHash])
					list.Add(n.CompactPort());
				response.Values = list;
			}
			else
			{
				// Is this right?
				response.Nodes = Node.CompactNode(engine.RoutingTable.GetClosest(InfoHash));
			}

			engine.MessageLoop.EnqueueSend(response, node.EndPoint);
		}
예제 #13
0
 public static MonoTorrentCollection<Peer> Decode(BEncodedList peers)
 {
     var list = new MonoTorrentCollection<Peer>(peers.Count);
     foreach (var value in peers)
     {
         try
         {
             if (value is BEncodedDictionary)
                 list.Add(DecodeFromDict((BEncodedDictionary) value));
             else if (value is BEncodedString)
                 foreach (var p in Decode((BEncodedString) value))
                     list.Add(p);
         }
         catch
         {
             // If something is invalid and throws an exception, ignore it
             // and continue decoding the rest of the peers
         }
     }
     return list;
 }
예제 #14
0
        void AddCommonStuff(BEncodedDictionary torrent)
        {
            if (Announces.Count == 0 || (Announces.Count == 1 && Announces[0].Count <= 1))
            {
                RemoveCustom("announce-list");
            }

            if (Announces.Count > 0 && Announces[0].Count > 0)
            {
                Announce = Announces[0][0];
            }

            if (GetrightHttpSeeds.Count > 0)
            {
                var seedlist = new BEncodedList();
                seedlist.AddRange(GetrightHttpSeeds.Select(s => (BEncodedString)s));
                torrent["url-list"] = seedlist;
            }

            TimeSpan span = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            torrent["creation date"] = new BEncodedNumber((long)span.TotalSeconds);
        }
예제 #15
0
        void Initialise(BEncodedDictionary metadata)
        {
            Metadata = metadata;

            BEncodedValue value;

            if (!Metadata.TryGetValue(AnnounceListKey, out value))
            {
                value = new BEncodedList();
                Metadata.Add(AnnounceListKey, value);
            }
            Announces = new RawTrackerTiers((BEncodedList)value);

            if (string.IsNullOrEmpty(Encoding))
            {
                Encoding = "UTF-8";
            }

            if (InfoDict == null)
            {
                InfoDict = new BEncodedDictionary();
            }
        }
예제 #16
0
        public override void Handle(DhtEngine engine, Node node)
        {
            base.Handle(engine, node);

            BEncodedString token    = engine.TokenManager.GenerateToken(node);
            var            response = new GetPeersResponse(engine.RoutingTable.LocalNode.Id, TransactionId, token);

            if (engine.Torrents.ContainsKey(InfoHash))
            {
                var list = new BEncodedList();
                foreach (Node n in engine.Torrents[InfoHash])
                {
                    list.Add(n.CompactPort());
                }
                response.Values = list;
            }
            else
            {
                response.Nodes = Node.CompactNode(engine.RoutingTable.GetClosest(InfoHash));
            }

            engine.MessageLoop.EnqueueSend(response, node, node.EndPoint);
        }
예제 #17
0
        private static BEncodedDictionary CreateTorrent(int pieceLength)
        {
            BEncodedDictionary infoDict = new BEncodedDictionary();

            infoDict[new BEncodedString("piece length")] = new BEncodedNumber(pieceLength);
            infoDict[new BEncodedString("pieces")]       = new BEncodedString(new byte[20 * 15]);
            infoDict[new BEncodedString("length")]       = new BEncodedNumber(15 * 256 * 1024 - 1);
            infoDict[new BEncodedString("name")]         = new BEncodedString("test.files");

            BEncodedDictionary dict = new BEncodedDictionary();

            dict[new BEncodedString("info")] = infoDict;

            BEncodedList announceTier = new BEncodedList();

            announceTier.Add(new BEncodedString("custom://transfers1/announce"));
            announceTier.Add(new BEncodedString("custom://transfers2/announce"));
            announceTier.Add(new BEncodedString("http://transfers3/announce"));
            BEncodedList announceList = new BEncodedList();

            announceList.Add(announceTier);
            dict[new BEncodedString("announce-list")] = announceList;
            return(dict);
        }
예제 #18
0
        void AddFiles(BEncodedDictionary dict, TorrentFile[] files)
        {
            long         totalSize = piecelength - 1;
            BEncodedList bFiles    = new BEncodedList();

            for (int i = 0; i < files.Length; i++)
            {
                BEncodedList path = new BEncodedList();
                foreach (string s in files[i].Path.Split('/'))
                {
                    path.Add((BEncodedString)s);
                }
                BEncodedDictionary d = new BEncodedDictionary();
                d["path"]   = path;
                d["length"] = (BEncodedNumber)files[i].Length;
                bFiles.Add(d);
                totalSize += files[i].Length;
            }

            dict[new BEncodedString("files")]        = bFiles;
            dict[new BEncodedString("name")]         = new BEncodedString("test.files");
            dict[new BEncodedString("piece length")] = new BEncodedNumber(piecelength);
            dict[new BEncodedString("pieces")]       = new BEncodedString(new byte[20 * (totalSize / piecelength)]);
        }
		///<summary>
		///this method is used for multi file mode torrents to return a dictionary with
		///file relevant informations. 
		///<param name="file">the file to report the informations for</param>
		///<param name="basePath">used to subtract the absolut path information</param>
		///</summary>
		BEncodedDictionary GetFileInfoDict(TorrentFile file)
		{
			var fileDict = new BEncodedDictionary();

			fileDict.Add("length", new BEncodedNumber(file.Length));

			var filePath = new BEncodedList();
			var splittetPath = file.Path.Split(System.IO.Path.DirectorySeparatorChar);

			foreach (var s in splittetPath)
			{
				if (s.Length > 0) //exclude empties
					filePath.Add(new BEncodedString(s));
			}

			fileDict.Add("path", filePath);

			return fileDict;
		}
예제 #20
0
        /// <summary>
        /// Retrieves a semi-random list of peers which can be used to fulfill an Announce request
        /// </summary>
        /// <param name="response">The bencoded dictionary to add the peers to</param>
        /// <param name="count">The number of peers to add</param>
        /// <param name="compact">True if the peers should be in compact form</param>
        /// <param name="exlude">The peer to exclude from the list</param>
        internal void GetPeers(BEncodedDictionary response, int count, bool compact)
        {
            byte[] compactResponse = null;
            BEncodedList nonCompactResponse = null;

            int total = Math.Min(peers.Count, count);
            // If we have a compact response, we need to create a single BencodedString
            // Otherwise we need to create a bencoded list of dictionaries
            if (compact)
                compactResponse = new byte[total * 6];
            else
                nonCompactResponse = new BEncodedList(total);

            int start = random.Next(0, peers.Count);

            lock (buffer)
            {
                if (buffer.Count != peers.Values.Count)
                    buffer = new List<Peer>(peers.Values);
            }
            List<Peer> p = buffer;

            while (total > 0)
            {
                Peer current = p[(start++) % p.Count];
                if (compact)
                {
                    Buffer.BlockCopy(current.CompactEntry, 0, compactResponse, (total - 1) * 6, 6);
                }
                else
                {
                    nonCompactResponse.Add(current.NonCompactEntry);
                }
                total--;
            }

            if (compact)
                response.Add(Tracker.PeersKey, (BEncodedString)compactResponse);
            else
                response.Add(Tracker.PeersKey, nonCompactResponse);
        }
예제 #21
0
        public byte[] SaveNodes()
        {
            BEncodedList details = new BEncodedList();

            MainLoop.QueueWait((MainLoopTask)delegate {
                foreach (Bucket b in RoutingTable.Buckets)
                {
                    foreach (Node n in b.Nodes)
                        if (n.State != NodeState.Bad)
                            details.Add(n.CompactNode());

                    if (b.Replacement != null)
                        if (b.Replacement.State != NodeState.Bad)
                            details.Add(b.Replacement.CompactNode());
                }
            });

            return details.Encode();
        }
예제 #22
0
 public RawTrackerTier(BEncodedList tier)
 {
     Tier = tier;
 }
예제 #23
0
 public void Add(BEncodedList nodes)
 {
 }
예제 #24
0
        /// <summary>
        /// 将作为接入点被连接时候需要返回给对方的信息编码以供发送。
        /// </summary>
        /// <returns>一个 B-编码形式的字节数组,包含了所需的信息。</returns>
        private byte[] EncodeTargetInformation(IPEndPoint targetEndPoint)
        {
            // 返回当前所有的连接信息
            // 结构:
            // d
            // {
            //     "connections" : l
            //         {
            //             d
            //                 {
            //                     "ip" : ip(4)
            //                     "port" : port(2)
            //                 }
            //         }
            //     "peers" : d
            //         {
            //             infohash_1 : l
            //                 {
            //                     d
            //                         {
            //                             "ip" : ip(4)
            //                             "port" : port(2)
            //                         }
            //                 }
            //             ... infohash_n
            //         }
            //     "your endpoint" : d
            //     {
            //         "ip" : ip(4)
            //         "port" : port(2)
            //     }
            // }
            BEncodedDictionary dictionary = new BEncodedDictionary();
            BEncodedList       connList   = new BEncodedList(ConnectionList.Count);

            lock (ConnectionList)
            {
                foreach (var item in ConnectionList)
                {
                    var d = new BEncodedDictionary();
                    d.Add("ip", item.ClientLocation.GetAddressBytes());
                    d.Add("port", item.ClientLocation.GetPortBytes());
                    connList.Add(d);
                }
            }
            dictionary.Add("connections", connList);
            BEncodedDictionary peersList = new BEncodedDictionary();

            lock (TrackerServer.Seeds)
            {
                foreach (var item in TrackerServer.Seeds)
                {
                    var list = new BEncodedList(item.Value.Count);
                    foreach (var t in item.Value)
                    {
                        var d = new BEncodedDictionary();
                        d.Add("ip", t.EndPoint.GetAddressBytes());
                        d.Add("port", t.EndPoint.GetPortBytes());
                        list.Add(d);
                    }
                    peersList.Add(item.Key.ToByteArray(), list);
                }
            }
            dictionary.Add("peers", peersList);
            BEncodedDictionary yourEndPoint = new BEncodedDictionary();

            yourEndPoint.Add("ip", targetEndPoint.Address.GetAddressBytes());
            yourEndPoint.Add("port", BitConverter.GetBytes((ushort)(targetEndPoint.Port & 0xffff)));
            dictionary.Add("your endpoint", yourEndPoint);
            byte[] data = dictionary.Encode();
            return(data);
        }
예제 #25
0
 public void benListEncodingBuffered()
 {
     byte[] data = System.Text.Encoding.UTF8.GetBytes("l4:test5:tests6:testede");
     BEncodedList list = new BEncodedList();
     list.Add(new BEncodedString("test"));
     list.Add(new BEncodedString("tests"));
     list.Add(new BEncodedString("tested"));
     byte[] result = new byte[list.LengthInBytes()];
     list.Encode(result, 0);
     Assert.IsTrue(Toolbox.ByteMatch(data, result));
 }
예제 #26
0
        /// <summary>
        /// 解码连接到接入点时收到的字节数组,并应用这些信息。
        /// </summary>
        /// <param name="data">收到的数据。</param>
        ///// <param name="sendPeerEnter">解码过程中是否应该广播 PeerEnterNetwork 消息。</param>
        /// <exception cref="System.FormatException">解码失败时发生。</exception>
        /// <remarks>
        /// 需要发送 PeerEnterNetwork 消息的情况会发生于:A开启客户端和μT,B开启客户端和μT,A(用户列表非空)再尝试连接B,此时如果B并没有保存全网的用户列表,那么A就要广播 PeerEnterNetwork。
        /// </remarks>
        private void DecodeTargetInformation(byte[] data)
        {
            // 如果对方发过来的是空,那么就肯定不会有数据啦
            if (data.Length > 0)
            {
                BEncodedDictionary dictionary = BEncodedDictionary.Decode(data) as BEncodedDictionary;
                if (dictionary == null)
                {
                    throw new FormatException("无法解码。");
                }
                BEncodedList       connList  = dictionary["connections"] as BEncodedList;
                BEncodedDictionary peersDict = dictionary["peers"] as BEncodedDictionary;

                // 规范 v1.2
                // 先确认自己,同时 if ... 是兼容老版的通信
                if (dictionary.ContainsKey("your endpoint"))
                {
                    BEncodedDictionary yourEndPoint = dictionary["your endpoint"] as BEncodedDictionary;
                    var ip   = new IPAddress((yourEndPoint["ip"] as BEncodedString).TextBytes);
                    var port = BitConverter.ToUInt16((yourEndPoint["port"] as BEncodedString).TextBytes, 0);
                    // 分别设置 KClient、TrackerServer 和 BT 客户端的自己
                    SetLocalEndPoint(new IPEndPoint(ip, port));
                    TrackerServer.SetLocalEndPoint(new IPEndPoint(ip, TrackerServer.LocalEndPoint.Port));
                    TrackerServer.SetMyself(new IPEndPoint(ip, TrackerServer.Myself.EndPoint.GetPortNumber()));

                    this.FreeToGo          = true;
                    TrackerServer.FreeToGo = true;
                }

                // ...
                lock (ConnectionList)
                {
                    foreach (var item in connList)
                    {
                        var       d   = item as BEncodedDictionary;
                        KEndPoint kep = KEndPoint.Empty;
                        kep.SetAddress((d["ip"] as BEncodedString).TextBytes);
                        kep.SetPort((int)BitConverter.ToUInt16((d["port"] as BEncodedString).TextBytes, 0));
                        try
                        {
                            AddToConnectionList(kep);
                        }
                        catch (Exception)
                        {
                        }
                    }
                }

                // 如果已经有用户登记了,那么应该广播
                if (TrackerServer.Seeds.Count > 0)
                {
                    lock (TrackerServer.Seeds)
                    {
                        foreach (var kv in TrackerServer.Seeds)
                        {
                            // 广播消息
                            BroadcastMyselfAddAsPeer(kv.Key);
                        }
                    }
                }
                lock (TrackerServer.Seeds)
                {
                    foreach (var kv in peersDict)
                    {
                        InfoHash    infoHash = InfoHash.FromByteArray(kv.Key.TextBytes);
                        List <Peer> peers    = new List <Peer>((kv.Value as BEncodedList).Count);
                        foreach (var item in (kv.Value as BEncodedList))
                        {
                            var       d   = item as BEncodedDictionary;
                            KEndPoint kep = KEndPoint.Empty;
                            kep.SetAddress((d["ip"] as BEncodedString).TextBytes);
                            kep.SetPort((int)BitConverter.ToUInt16((d["port"] as BEncodedString).TextBytes, 0));
                            Peer peer = Peer.Create(kep);
                            peers.Add(peer);
                        }
                        try
                        {
                            TrackerServer.Seeds.Add(infoHash, peers);
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
            }
            else
            {
                Logger.Log("待解码的数据为空,这意味着对方客户端目前持有的连接列表和用户列表为空。");
            }
        }
예제 #27
0
        private void AddFiles(BEncodedDictionary dict, TorrentFile[] files)
        {
            long totalSize = piecelength - 1;
            var bFiles = new BEncodedList();
            for (var i = 0; i < files.Length; i++)
            {
                var path = new BEncodedList();
                foreach (var s in files[i].Path.Split('/'))
                    path.Add((BEncodedString) s);
                var d = new BEncodedDictionary();
                d["path"] = path;
                d["length"] = (BEncodedNumber) files[i].Length;
                bFiles.Add(d);
                totalSize += files[i].Length;
            }

            dict[new BEncodedString("files")] = bFiles;
            dict[new BEncodedString("name")] = new BEncodedString("test.files");
            dict[new BEncodedString("piece length")] = new BEncodedNumber(piecelength);
            dict[new BEncodedString("pieces")] = new BEncodedString(new byte[20*(totalSize/piecelength)]);
        }
예제 #28
0
        public void benListEncoding()
        {
            byte[] data = System.Text.Encoding.UTF8.GetBytes("l4:test5:tests6:testede");
            BEncodedList list = new BEncodedList();
            list.Add(new BEncodedString("test"));
            list.Add(new BEncodedString("tests"));
            list.Add(new BEncodedString("tested"));

            Assert.IsTrue(Toolbox.ByteMatch(data, list.Encode()));
        }
예제 #29
0
 private static void AddAnnounces(BEncodedDictionary dict, string[][] tiers)
 {
     var announces = new BEncodedList();
     foreach (var tier in tiers)
     {
         var bTier = new BEncodedList();
         announces.Add(bTier);
         foreach (var s in tier)
             bTier.Add((BEncodedString) s);
     }
     dict["announce"] = (BEncodedString) tiers[0][0];
     dict["announce-list"] = announces;
 }
예제 #30
0
        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;
                    using (SHA1 hasher = HashAlgoFactory.Create <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);
                        }
                        if (Torrent.TryLoad(dict.Encode(), out Torrent t))
                        {
                            Manager.RaiseMetadataReceived(t, dict);
                            if (stopWhenDone)
                            {
                                return;
                            }

                            try {
                                if (Directory.Exists(savePath))
                                {
                                    savePath = Path.Combine(savePath, $"{Manager.InfoHash.ToHex ()}.torrent");
                                }
                                File.Delete(savePath);
                                File.WriteAllBytes(savePath, dict.Encode());
                            } catch (Exception ex) {
                                Logger.Log(null, "*METADATA EXCEPTION* - Can not write in {0} : {1}", savePath, ex);
                                Manager.TrySetError(Reason.WriteFailure, ex);
                                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($"Invalid messagetype in LTMetadata: {message.MetadataMessageType}");
            }
        }
예제 #31
0
        /// <summary>
        /// 处理 Tracker 请求的方法。
        /// </summary>
        /// <param name="processor">为此请求生成的 <see cref="Kei.KTracker.HttpProcessor"/> 对象。</param>
        /// <param name="ioStream"><see cref="Kei.KTracker.HttpProcessor"/> 为此请求开启的 <see cref="System.IO.Stream"/>。</param>
        /// <param name="parameters">URL 请求参数。</param>
        private void HandleTrackerRequest(HttpProcessor processor, Stream ioStream, string parameters)
        {
            // parameters 传入类似 info_hash=XXXX&port=XXXX&ipv6=XXXX 的形式
            var args = Utilities.DecomposeParameterString(parameters);

            Logger.Log("[Tracker]请求: " + processor.RequestUrl);

            try
            {
                Logger.Log("[Tracker]解码收到的参数。");
                // 先解码处理各种参数(注意可能会引发异常)
                string     infoHashString = Utilities.UnescapePartialUriEncodedString(args["info_hash"]);
                InfoHash   infoHash       = InfoHash.FromHexString(infoHashString);
                int        portNo         = Convert.ToInt32(args["port"]);
                TaskStatus taskStatus;
                if (args.ContainsKey("event"))
                {
                    switch (args["event"])
                    {
                    case "started":
                        taskStatus = TaskStatus.Started;
                        break;

                    case "stopped":
                        taskStatus = TaskStatus.Stopped;
                        break;

                    case "paused":
                        taskStatus = TaskStatus.Paused;
                        break;

                    default:
                        taskStatus = TaskStatus.None;
                        break;
                    }
                }
                else
                {
                    taskStatus = TaskStatus.None;
                }
                bool compact;
                if (args.ContainsKey("compact"))
                {
                    var n = Convert.ToInt32(args["compact"]);
                    compact = n != 0;
                }
                else
                {
                    compact = false;
                }
                bool noPeerID;
                if (args.ContainsKey("no_peer_id"))
                {
                    var n = Convert.ToInt32(args["no_peer_id"]);
                    noPeerID = n != 0;
                }
                else
                {
                    noPeerID = false;
                }
                var peerIDString = Utilities.UnescapePartialUriEncodedString(args["peer_id"]);

                // 别忘了重新确认自己
                IPEndPoint newMyself = new IPEndPoint(LocalEndPoint.Address, portNo);
                Logger.Log("[Tracker]新的自己(BitTorrent 客户端): " + newMyself.ToString());
                SetMyself(newMyself, peerIDString);

                List <Peer>          peers = null;
                TrackerCommEventArgs eventArgs;

                // 如果接入分布网络完成
                if (FreeToGo)
                {
                    // 触发事件,得到新的可用用户列表
                    if (Seeds.TryGetValue(infoHash, out peers))
                    {
                        peers = Seeds[infoHash];
                        if (peers.IndexOf(_myself) < 0)
                        {
                            // 如果之前我不在种子列表中
                            // TODO: 添加 myself
                            peers.Add(_myself);
                            // 而且此时确认为自己加入网络,强制设定 event=started
                            taskStatus = TaskStatus.Started;
                        }
                    }
                    else
                    {
                        // 如果之前没有相关种子
                        peers = new List <Peer>();
                        // TODO: 添加 myself
                        peers.Add(_myself);
                        Seeds.Add(infoHash, peers);
                        // 而且此时确认为自己加入网络,强制设定 event=started
                        taskStatus = TaskStatus.Started;
                    }
                }
                eventArgs = new TrackerCommEventArgs(infoHash, peers, portNo, peerIDString, compact, noPeerID, taskStatus);
                EventHelper.RaiseEventAsync(TrackerComm, this, eventArgs);
                //if (eventArgs.Peers == null)
                //{
                //    throw new NullReferenceException("Peers list is null");
                //}
                if (eventArgs.Peers != null)
                {
                    peers = eventArgs.Peers;
                }

                // 生成返回给 μTorrent 的信息
                Logger.Log("[Tracker]反馈给 BitTorrent 客户端。");
                if (peers != null)
                {
                    string peersListString = "[Tracker]种子 " + infoHash.ToString() + " 的用户列表如下:";
                    foreach (var p in peers)
                    {
                        peersListString += Environment.NewLine + p.EndPoint.ToString();
                    }
                    Logger.Log(peersListString);
                }
                else
                {
                    Logger.Log("[Tracker]种子 " + infoHash.ToString() + " 的用户列表为空。");
                }
                BEncodedDictionary data = new BEncodedDictionary();
                data.Add("interval", 60);
                if (peers != null)
                {
                    // 如果种子列表里有种子
                    // 为了防止其他线程修改这个 list 导致迭代器失效,先锁定这个对象
                    lock (peers)
                    {
                        if (compact)
                        {
                            // 生成字节数组
                            byte[] peersArray = new byte[peers.Count * 6];
                            byte[] tmp;
                            int    i = 0;
                            foreach (var peer in peers)
                            {
                                tmp = peer.ToByteArray();
                                Array.Copy(tmp, 0, peersArray, i * 6, 6);
                                i++;
                            }
                            data.Add("peers", peersArray);
                        }
                        else
                        {
                            // 生成列表
                            BEncodedList peersList = new BEncodedList(peers.Count);
                            foreach (var peer in peers)
                            {
                                BEncodedDictionary peerDict = new BEncodedDictionary();
                                peerDict.Add("id", peer.ID);
                                peerDict.Add("ip", peer.EndPoint.GetAddressString());
                                peerDict.Add("port", peer.EndPoint.GetPortNumber());
                                peersList.Add(peerDict);
                            }
                            data.Add("peers", peersList);
                        }
                    }
                    data.Add("complete", peers.Count);
                }
                else
                {
                    // 如果没有种子,就返回空列表
                    data.Add("peers", string.Empty);
                }

                // 输出
                Logger.Log("[Tracker]写入“成功”头。");
                processor.WriteSuccess(null, "text/plain");
                Logger.Log("[Tracker]编码返回数据。");
                var dataBytes = data.Encode();
                Logger.Log("[Tracker]写入返回数据。");
                ioStream.Write(dataBytes, 0, dataBytes.Length);
                Logger.Log("[Tracker]向 BitTorrent 客户端返回了: " + Encoding.ASCII.GetString(dataBytes));
                ioStream.Flush();
            }
            catch (Exception ex)
            {
                Logger.Log(ex.Message + Environment.NewLine + ex.StackTrace);
                processor.WriteFailure();
                ioStream.WriteLine(ex.Message);
                ioStream.WriteLine(ex.StackTrace);
            }
        }
예제 #32
0
        /// <summary>
        /// This method is called internally to load in all the files found within the "Files" section
        /// of the .torrents infohash
        /// </summary>
        /// <param name="list">The list containing the files available to download</param>
        private void LoadTorrentFiles(BEncodedList list)
        {
            List <TorrentFile> files = new List <TorrentFile>();
            int    endIndex;
            long   length;
            string path;

            byte[]        md5sum;
            byte[]        ed2k;
            byte[]        sha1;
            int           startIndex;
            StringBuilder sb = new StringBuilder(32);

            foreach (BEncodedDictionary dict in list)
            {
                length = 0;
                path   = null;
                md5sum = null;
                ed2k   = null;
                sha1   = null;

                foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in dict)
                {
                    switch (keypair.Key.Text)
                    {
                    case ("sha1"):
                        sha1 = ((BEncodedString)keypair.Value).TextBytes;
                        break;

                    case ("ed2k"):
                        ed2k = ((BEncodedString)keypair.Value).TextBytes;
                        break;

                    case ("length"):
                        length = long.Parse(keypair.Value.ToString());
                        break;

                    case ("path.utf-8"):
                        foreach (BEncodedString str in ((BEncodedList)keypair.Value))
                        {
                            sb.Append(str.Text);
                            sb.Append(Path.DirectorySeparatorChar);
                        }
                        path = sb.ToString(0, sb.Length - 1);
                        sb.Remove(0, sb.Length);
                        break;

                    case ("path"):
                        if (string.IsNullOrEmpty(path))
                        {
                            foreach (BEncodedString str in ((BEncodedList)keypair.Value))
                            {
                                sb.Append(str.Text);
                                sb.Append(Path.DirectorySeparatorChar);
                            }
                            path = sb.ToString(0, sb.Length - 1);
                            sb.Remove(0, sb.Length);
                        }
                        break;

                    case ("md5sum"):
                        md5sum = ((BEncodedString)keypair.Value).TextBytes;
                        break;

                    default:
                        break;     //FIXME: Log unknown values
                    }
                }

                // A zero length file always belongs to the same piece as the previous file
                if (length == 0)
                {
                    if (files.Count > 0)
                    {
                        startIndex = files[files.Count - 1].EndPieceIndex;
                        endIndex   = files[files.Count - 1].EndPieceIndex;
                    }
                    else
                    {
                        startIndex = 0;
                        endIndex   = 0;
                    }
                }
                else
                {
                    startIndex = (int)(size / pieceLength);
                    endIndex   = (int)((size + length) / pieceLength);
                    if ((size + length) % pieceLength == 0)
                    {
                        endIndex--;
                    }
                }

                files.Add(new TorrentFile(path, length, path, startIndex, endIndex, (int)(size % pieceLength), md5sum, ed2k, sha1));
                size += length;
            }

            this.torrentFiles = files.ToArray();
        }
예제 #33
0
        /// <summary>
        /// Construis l'instance
        /// </summary>
        private void LoadTorrent()
        {
            if (_data == null)
            {
                throw new ArgumentNullException("_data", "_data cannot be null.");
            }

            //on récupère chacune des données si présentes
            if (_data.ContainsKey("creation date"))
            {
                CreationDate = _data["creation date"];
            }

            if (_data.ContainsKey("created by"))
            {
                CreatedBy = _data["created by"];
            }

            if (_data.ContainsKey("comment"))
            {
                Comment = _data["comment"];
            }

            if (_data.ContainsKey("announce"))
            {
                Tracker tracker = new Tracker(_data["announce"]);
                Trackers.Add(new TorrentTracker(this, tracker));
            }

            if (_data.ContainsKey("info"))
            {
                BEncodedDictionary info = (BEncodedDictionary)_data["info"];

                if (info.ContainsKey("piece length"))
                {
                    PieceLength = info["piece length"];
                }

                if (info.ContainsKey("pieces"))
                {
                    Pieces = info["pieces"];
                }

                if (info.ContainsKey("name"))
                {
                    Name = info["name"];
                }

                //on véfifie la présence des fichiers
                if (info.ContainsKey("files"))
                {
                    BEncodedList files = (BEncodedList)info["files"];

                    foreach (var item in files)
                    {
                        BEncodedDictionary fileEncoded = (BEncodedDictionary)item;

                        File file = new File(fileEncoded["path"], fileEncoded["length"]);
                        Files.Add(file);
                    }
                }
            }
        }
예제 #34
0
        IList <TorrentFile> LoadTorrentFiles(BEncodedList list)
        {
            var sb = new StringBuilder(32);

            var files = new List <(string path, long length, byte[] md5sum, byte[]  ed2k, byte[] sha1)> ();

            foreach (BEncodedDictionary dict in list)
            {
                long   length = 0;
                string path   = null;
                byte[] md5sum = null;
                byte[] ed2k   = null;
                byte[] sha1   = null;

                foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in dict)
                {
                    switch (keypair.Key.Text)
                    {
                    case ("sha1"):
                        sha1 = ((BEncodedString)keypair.Value).TextBytes;
                        break;

                    case ("ed2k"):
                        ed2k = ((BEncodedString)keypair.Value).TextBytes;
                        break;

                    case ("length"):
                        length = long.Parse(keypair.Value.ToString());
                        break;

                    case ("path.utf-8"):
                        foreach (BEncodedString str in ((BEncodedList)keypair.Value))
                        {
                            sb.Append(str.Text);
                            sb.Append(Path.DirectorySeparatorChar);
                        }
                        path = sb.ToString(0, sb.Length - 1);
                        sb.Remove(0, sb.Length);
                        break;

                    case ("path"):
                        if (string.IsNullOrEmpty(path))
                        {
                            foreach (BEncodedString str in ((BEncodedList)keypair.Value))
                            {
                                sb.Append(str.Text);
                                sb.Append(Path.DirectorySeparatorChar);
                            }
                            path = sb.ToString(0, sb.Length - 1);
                            sb.Remove(0, sb.Length);
                        }
                        break;

                    case ("md5sum"):
                        md5sum = ((BEncodedString)keypair.Value).TextBytes;
                        break;

                    default:
                        break;     //FIXME: Log unknown values
                    }
                }

                PathValidator.Validate(path);
                files.Add((path, length, md5sum, ed2k, sha1));
                Size += length;
            }

            return(Array.AsReadOnly(TorrentFile.Create(PieceLength, files.ToArray())));
        }
예제 #35
0
        public void SaveFastResume()
        {
            if (string.IsNullOrWhiteSpace(settings.FastResumePath))
                return;

            var encodedList = new BEncodedList();
            var fastResumeData = torrentsReadonly
                .Where(x => x.HashChecked)
                .Select(tm => tm.SaveFastResume().Encode());
            foreach (var data in fastResumeData)
                encodedList.Add(data);

            File.WriteAllBytes(settings.FastResumePath, encodedList.Encode());
        }
예제 #36
0
        public void GetPeersResponseDecode()
        {
            GetPeersEncode();
            MessageFactory.RegisterSend(message);

            string text = "d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re";
            GetPeersResponse m = (GetPeersResponse)Decode(text);

            Assert.AreEqual(token, m.Token, "#1");
            Assert.AreEqual(id, m.Id, "#2");

            BEncodedList l = new BEncodedList();
            l.Add((BEncodedString)"axje.u");
            l.Add((BEncodedString)"idhtnm");
            Assert.AreEqual(l, m.Values, "#3");

            Compare(m, text);
        }
예제 #37
0
파일: Utils.cs 프로젝트: chitza/uDir
        /// <summary>
        /// Builds an complete path from a list of directories.
        /// </summary>
        /// <param name="pathParts"></param>
        /// <returns></returns>
        private static string BuildPathFromDirectoryList(BEncodedList pathParts)
        {
            string ret = string.Empty;

            foreach (var p in pathParts)
                ret = Path.Combine(ret, (p as BEncodedString).Text);

            return ret;
        }
        private BEncodedValue ToFileInfoDict(TorrentFile file)
        {
            var fileDict = new BEncodedDictionary();

            var filePath = new BEncodedList();
            var splittetPath = file.Path.Split(new[] {Path.DirectorySeparatorChar},
                StringSplitOptions.RemoveEmptyEntries);
            foreach (var s in splittetPath)
                filePath.Add(new BEncodedString(s));

            fileDict["length"] = new BEncodedNumber(file.Length);
            fileDict["path"] = filePath;
            if (file.MD5 != null)
                fileDict["md5sum"] = (BEncodedString) file.MD5;

            return fileDict;
        }
 public RawTrackerTiers(BEncodedList tiers)
 {
     Tiers = tiers;
 }
예제 #40
0
 public void Add(BEncodedList nodes)
 {
     // Maybe we should pipeline all our tasks to ensure we don't flood the DHT engine.
     // I don't think it's *bad* that we can run several initialise tasks simultaenously
     // but it might be better to run them sequentially instead. We should also
     // run GetPeers and Announce tasks sequentially.
     InitialiseTask task = new InitialiseTask(this, Node.FromCompactNode (nodes));
     task.Execute();
 }
		///<summary>
		///this adds stuff common to single and multi file torrents
		///</summary>
		void AddCommonStuff(BEncodedDictionary torrent)
		{
			if (announces.Count > 0 && announces[0].Count > 0) torrent.Add("announce", new BEncodedString(announces[0][0]));

			// If there is more than one tier or the first tier has more than 1 tracker
			if (announces.Count > 1 || (announces.Count > 0 && announces[0].Count > 1))
			{
				var announceList = new BEncodedList();
				for (var i = 0; i < announces.Count; i++)
				{
					var tier = new BEncodedList();
					for (var j = 0; j < announces[i].Count; j++) tier.Add(new BEncodedString(announces[i][j]));

					announceList.Add(tier);
				}

				torrent.Add("announce-list", announceList);
			}

			var epocheStart = new DateTime(1970, 1, 1);
			var span = DateTime.Now - epocheStart;
			Logger.Log(null, "creation date: {0} - {1} = {2}:{3}", DateTime.Now, epocheStart, span, span.TotalSeconds);
			torrent.Add("creation date", new BEncodedNumber((long)span.TotalSeconds));
		}
예제 #42
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 (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.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}");
            }
        }
예제 #43
0
        private void ProcessTorrentGen(string sContentUniqueId, ContentGenRecipes oRecipes, EventHandler <TorrentCreatorEventArgs> callbackHashed, out string sContentHashCode)
        {
            long   lPieceLengthKB              = AppConfig.ContentGenJob.PieceLengthKB;
            string sCreatedBy                  = AppConfig.ContentGenJob.CreatedBy;
            string sTrackerAnnounceUrl         = AppConfig.ContentGenJob.TrackerAnnounceUrl;
            string sInternalTrackerAnnounceUrl = AppConfig.ContentGenJob.InternalTrackerAnnounceUrl;

            // Initialization
            _InterruptFlag   = false;
            sContentHashCode = "";

            // Initialize the torrent creation task
            MetafileGenTask oMG = new MetafileGenTask();

            oMG.Hashed += callbackHashed;

            // Set the torrent info
            oMG.PieceLength = lPieceLengthKB * 1024; // Torrent info: PieceLength
            oMG.StoreMD5    = false;                 // Don't store MD5SUM in the torrent file
            oMG.Private     = true;                  // Always be private torrent
            oMG.CreatedBy   = sCreatedBy;            // Torrent info: CreatedBy
            if (oRecipes.HttpSeedsUrl != null && oRecipes.HttpSeedsUrl.Length > 0)
            {
                List <string> listUrls = oRecipes.HttpSeedsUrlList;
                listUrls.ForEach(sUrl => { oMG.GetrightHttpSeeds.Add(sUrl); }); // URL seed
            }
            List <string> oAnn = new List <string>();

            oAnn.Add(sTrackerAnnounceUrl);
            oMG.Announces.Add(oAnn); // Torrent Info: Tracker Server
            // Assign the custom fields to the "info" section of the torrent
            oMG.AddCustomSecure("ga account name", new BEncodedString(oRecipes.GAProfileId));
            oMG.AddCustomSecure("ga host name", new BEncodedString("http://www.gamania.com"));
            oMG.AddCustomSecure("custom display name", new BEncodedString(oRecipes.DownloaderDisplayName));

            // Begin the async torrent creation process
            IAsyncResult asyncResult = oMG.BeginCreate(
                oRecipes.ContentSourceUrl, // Content Source URL
                null,                      // No callback needed
                oRecipes.ContentSourceUrl  // Async state
                );

            // Wait for the completion or the aborting
            if (!asyncResult.IsCompleted)
            {
                while (!asyncResult.AsyncWaitHandle.WaitOne(1000))
                {
                    if (_InterruptFlag)
                    {
                        oMG.AbortCreation();                 // Try to abort the task
                    }
                }
            }
            // End of the async torre creation
            BEncodedDictionary oTorrentBenDict = oMG.EndCreate(asyncResult);

            // Get the content hash code from the torrent file
            sContentHashCode = Torrent.Load(oTorrentBenDict).InfoHash.ToHex();
            lock (sigLock)
            {
                // ========= Save 3 types of torrent files for 3 different usages ==============
                // 1. Save the torrent file which contains the public tracker announce URL
                File.WriteAllBytes(
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + TorrentExtension,
                    oTorrentBenDict.Encode());

                // 2. Save the VIP torrent file contains the public tracker announce URL
                if (oRecipes.VipHttpSeedsUrl != null && oRecipes.VipHttpSeedsUrl.Length > 0)
                {
                    // Add more Url Seed Urls
                    List <string> listUrls = oRecipes.VipHttpSeedsUrlList;
                    listUrls.ForEach(sUrl => { oMG.GetrightHttpSeeds.Add(sUrl); }); // Add more URL seed
                    // Convert to Ben-Encoded List
                    BEncodedList listUrlSeeds = new BEncodedList();
                    listUrlSeeds.AddRange(oMG.GetrightHttpSeeds.ConvertAll <BEncodedValue>(s => { return((BEncodedString)s); }));
                    oTorrentBenDict[TorrentInfoUrlListKey] = listUrlSeeds;
                }
                // Save the VIP Torrent file
                File.WriteAllBytes(
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + TorrentVipExtension,
                    oTorrentBenDict.Encode());
                // 3. Save the FQDN torrent file which contains the internal tracker announce URL
                // First, add the content source URL to the torrent to accelerate the download speed
                if (-1 == oRecipes.HttpSeedsUrlList.FindIndex(x => { return(x.Equals(oRecipes.ContentSourceUrl)); }) &&
                    -1 == oRecipes.VipHttpSeedsUrlList.FindIndex(x => { return(x.Equals(oRecipes.ContentSourceUrl)); }))
                {
                    // Add the content source URL to the TorrentInfoUrlListKey
                    // together with the VIP URL seeds just added previously
                    oMG.GetrightHttpSeeds.Add(oRecipes.ContentSourceUrl);
                    // Convert to Ben-Encoded List
                    BEncodedList listUrlSeeds = new BEncodedList();
                    listUrlSeeds.AddRange(oMG.GetrightHttpSeeds.ConvertAll <BEncodedValue>(s => { return((BEncodedString)s); }));
                    oTorrentBenDict[TorrentInfoUrlListKey] = listUrlSeeds;
                }
                // Second, replace the tracker announce URL with the internal tracker announce URL
                oTorrentBenDict[TorrentInfoAnnounceKey] = new BEncodedString(sInternalTrackerAnnounceUrl);
                // Save the FQDN Torrent file
                File.WriteAllBytes(
                    ContentWorkingPath + "\\" +
                    sContentUniqueId + "\\" +
                    sContentHashCode + TorrentFqdnExtension,
                    oTorrentBenDict.Encode());
            }
        }
예제 #44
0
 internal static IList <Peer> Decode(BEncodedList l)
 => PeerDecoder.Decode(l).Select(t => new Peer(BEncodedString.FromMemory(t.PeerId), t.Uri)).ToArray();
예제 #45
0
        private BEncodedList CreateFiles()
        {
            var files = new BEncodedList();
            var path  = new BEncodedList {
                new BEncodedString("file1.txt")
            };

            var file = new BEncodedDictionary
            {
                {
                    "sha1",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1")))
                },
                {
                    "ed2k",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2")))
                },
                { "length", new BEncodedNumber(50000) },
                {
                    "md5sum",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3")))
                },
                { "path.utf-8", path },
                { "path", path }
            };

            files.Add(file);

            path = new BEncodedList
            {
                new BEncodedString("subfolder1"),
                new BEncodedString("file2.txt")
            };

            file = new BEncodedDictionary
            {
                {
                    "sha1",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1")))
                },
                {
                    "ed2k",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2")))
                },
                { "length", new BEncodedNumber(60000) },
                {
                    "md5sum",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3")))
                },
                { "path.utf-8", path },
                { "path", path }
            };

            files.Add(file);

            path = new BEncodedList
            {
                new BEncodedString("subfolder1"),
                new BEncodedString("subfolder2"),
                new BEncodedString("file3.txt")
            };

            file = new BEncodedDictionary
            {
                {
                    "sha1",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1")))
                },
                {
                    "ed2k",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2")))
                },
                { "length", new BEncodedNumber(70000) },
                {
                    "md5sum",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3")))
                },
                { "path.utf-8", path },
                { "path", path }
            };

            files.Add(file);

            path = new BEncodedList
            {
                new BEncodedString("subfolder1"),
                new BEncodedString("subfolder2"),
                new BEncodedString("file4.txt")
            };

            file = new BEncodedDictionary
            {
                {
                    "sha1",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1")))
                },
                {
                    "ed2k",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2")))
                },
                { "length", new BEncodedNumber(80000) },
                {
                    "md5sum",
                    new BEncodedString(_sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3")))
                },
                { "path.utf-8", path },
                { "path", path }
            };

            files.Add(file);

            return(files);
        }
		///<summary>
		///used for creating multi file mode torrents.
		///</summary>
		///<returns>the dictionary representing which is stored in the torrent file</returns>
		protected void CreateMultiFileTorrent(BEncodedDictionary dictionary, TorrentFile[] files, PieceWriter writer, string name)
		{
			AddCommonStuff(dictionary);
			var info = (BEncodedDictionary)dictionary["info"];

			var torrentFiles = new BEncodedList(); //the dict which hold the file infos

			for (var i = 0; i < files.Length; i++) torrentFiles.Add(GetFileInfoDict(files[i]));

			info.Add("files", torrentFiles);

			Logger.Log(null, "Topmost directory: {0}", name);
			info.Add("name", new BEncodedString(name));

			info.Add("pieces", new BEncodedString(CalcPiecesHash(Path, files, writer)));
		}
예제 #47
0
        public void DecodeDictionary()
        {
            var list = new BEncodedList();
            foreach (var p in peers)
            {
                var dict = new BEncodedDictionary();
                dict.Add("ip", (BEncodedString) p.ConnectionUri.Host);
                dict.Add("port", (BEncodedNumber) p.ConnectionUri.Port);
                dict.Add("peer id", (BEncodedString) p.PeerId);
                list.Add(dict);
            }

            VerifyDecodedPeers(Peer.Decode(list));
        }
예제 #48
0
        private BEncodedList CreateFiles()
        {
            BEncodedList       files = new BEncodedList();
            BEncodedDictionary file;
            BEncodedList       path;

            path = new BEncodedList();
            path.Add(new BEncodedString("file1.txt"));

            file = new BEncodedDictionary();
            file.Add("sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))));
            file.Add("ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))));
            file.Add("length", new BEncodedNumber(50000));
            file.Add("md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))));
            file.Add("path.utf-8", path);
            file.Add("path", path);

            files.Add(file);


            path = new BEncodedList();
            path.Add(new BEncodedString("subfolder1"));
            path.Add(new BEncodedString("file2.txt"));

            file = new BEncodedDictionary();
            file.Add("sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))));
            file.Add("ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))));
            file.Add("length", new BEncodedNumber(60000));
            file.Add("md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))));
            file.Add("path.utf-8", path);
            file.Add("path", path);

            files.Add(file);


            path = new BEncodedList();
            path.Add(new BEncodedString("subfolder1"));
            path.Add(new BEncodedString("subfolder2"));
            path.Add(new BEncodedString("file3.txt"));

            file = new BEncodedDictionary();
            file.Add("sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))));
            file.Add("ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))));
            file.Add("length", new BEncodedNumber(70000));
            file.Add("md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))));
            file.Add("path.utf-8", path);
            file.Add("path", path);

            files.Add(file);


            path = new BEncodedList();
            path.Add(new BEncodedString("subfolder1"));
            path.Add(new BEncodedString("subfolder2"));
            path.Add(new BEncodedString("file4.txt"));

            file = new BEncodedDictionary();
            file.Add("sha1", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash1"))));
            file.Add("ed2k", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash2"))));
            file.Add("length", new BEncodedNumber(80000));
            file.Add("md5sum", new BEncodedString(sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes("file1 hash3"))));
            file.Add("path.utf-8", path);
            file.Add("path", path);

            files.Add(file);

            return(files);
        }
예제 #49
0
        public void DecodeList()
        {
            // List of String
            var list = new BEncodedList();
            foreach (var p in peers)
                list.Add((BEncodedString) p.CompactPeer());

            VerifyDecodedPeers(Peer.Decode(list));
        }
예제 #50
0
 public void Add(BEncodedList nodes)
 {
 }
예제 #51
0
        /// <summary>
        ///
        /// </summary>
        public void Request()
        {
            string encoded_hash = Torrent.GetEncodedInfoHash();

            //construction de la requête vers le tracker
            StringBuilder builder = new StringBuilder(Tracker.Url);

            builder.AppendFormat("?info_hash={0}", encoded_hash);
            builder.Append("&peer_id=adkiepeycosozpsngtoi");
            builder.Append("&uploaded=0");
            builder.Append("&downloaded=0");
            builder.AppendFormat("&compact={0}", Compact ? 1 : 0);
            builder.Append("&left=120000");
            builder.Append("&event=started");
            builder.Append("&port=6881");

            //création de la requête GET
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(builder.ToString());

            request.Method = "GET";

            //envoi de la requête
            using (WebResponse response = request.GetResponse()) {
                //récupération de la réponse
                using (Stream stream = response.GetResponseStream()) {
                    using (var reader = new StreamReader(stream, Encoding.Default)) {
                        string responseText = reader.ReadToEnd();

                        byte[] data = Encoding.Default.GetBytes(responseText);

                        BEncoding          encoding   = new BEncoding(data);
                        BEncodedDictionary dictionary = (BEncodedDictionary)encoding.Decode();

                        Complete   = (BEncodedInteger)dictionary["complete"];
                        Incomplete = (BEncodedInteger)dictionary["incomplete"];
                        Interval   = (BEncodedInteger)dictionary["interval"];

                        // la liste des peers peut être soit une liste, soit une chaine simplifiée en big endian
                        if (dictionary["peers"] is BEncodedList)
                        {
                            BEncodedList peers = (BEncodedList)dictionary["peers"];
                        }
                        else if (dictionary["peers"] is BEncodedString)
                        {
                            byte[] peers = Encoding.Default.GetBytes((BEncodedString)dictionary["peers"]);

                            for (int i = 0; i < peers.Length; i = i + 6)
                            {
                                byte[] ip   = new byte[4];
                                byte[] port = new byte[2];

                                Array.Copy(peers, i, ip, 0, 4);
                                Array.Copy(peers, i + 4, port, 0, 2);
                                Array.Reverse(port);

                                IPEndPoint ipEndPoint = new IPEndPoint(new IPAddress(ip), BitConverter.ToUInt16(port, 0));

                                Peer peer = new Peer(ipEndPoint);
                                Peers.Add(peer);
                            }
                        }
                    }
                }
            }
        }
예제 #52
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);
                }
            }
        }
예제 #53
0
 public void Add(BEncodedList nodes)
 {
     Add(Node.FromCompactNode(nodes));
 }