예제 #1
0
 /// <summary>
 /// Decode Bencoded torrent file and load internal dictionary from its contents
 /// for later retrieval by other modules.
 /// </summary>
 public void Parse()
 {
     try
     {
         BNodeBase bNodeRoot = _Bencode.Decode(_metaInfoData);
         GetStringOrNumeric(bNodeRoot, "announce");
         GetListOfStrings(bNodeRoot, "announce-list");
         GetStringOrNumeric(bNodeRoot, "comment");
         GetStringOrNumeric(bNodeRoot, "created by");
         GetStringOrNumeric(bNodeRoot, "creation date");
         GetStringOrNumeric(bNodeRoot, "name");
         GetStringOrNumeric(bNodeRoot, "piece length");
         GetStringOrNumeric(bNodeRoot, "pieces");
         GetStringOrNumeric(bNodeRoot, "private");
         GetStringOrNumeric(bNodeRoot, "url-list");
         if (_Bencode.GetDictionaryEntry(bNodeRoot, "files") == null)
         {
             GetStringOrNumeric(bNodeRoot, "length");
             GetStringOrNumeric(bNodeRoot, "md5sum");
         }
         else
         {
             GetListOfDictionarys(bNodeRoot, "files");
         }
         CalculateInfoHash(bNodeRoot);
         foreach (var key in metaInfoDict.Keys)
         {
             if ((key != "pieces") && (key != "info") && (key != "info hash"))
             {
                 Log.Logger.Error($"{key}={Encoding.ASCII.GetString(metaInfoDict[key])}");
             }
         }
     }
     catch (Exception ex)
     {
         Log.Logger.Error(ex);
         throw new BitTorrentException(ex.Message);
     }
 }
예제 #2
0
 private readonly Bencode _Bencode;      // Bencode encode/decode
 /// <summary>
 /// Decodes the announce request BEncoded response recieved from a tracker.
 /// </summary>
 /// <param name="announceResponse">Announce response.</param>
 /// <param name="decodedResponse">Response.</param>
 private void DecodeAnnounceResponse(Tracker tracker, byte[] announceResponse, ref AnnounceResponse decodedResponse)
 {
     if (announceResponse.Length != 0)
     {
         BNodeBase decodedAnnounce = _Bencode.Decode(announceResponse);
         decodedResponse.statusMessage = _Bencode.GetDictionaryEntryString(decodedAnnounce, "failure reason");
         if (decodedResponse.statusMessage != "")
         {
             decodedResponse.failure = true;
             return; // If failure present then ignore rest of reply.
         }
         int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "complete"), out decodedResponse.complete);
         int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "incomplete"), out decodedResponse.incomplete);
         BNodeBase field = _Bencode.GetDictionaryEntry(decodedAnnounce, "peers");
         if (field != null)
         {
             decodedResponse.peerList = new List <PeerDetails>();
             if (field is BNodeString bNodeString) // Compact peer list reply
             {
                 decodedResponse.peerList = tracker.GetCompactPeerList((bNodeString).str, 0);
             }
             else if (field is BNodeList bNodeList)  // Non-compact peer list reply
             {
                 foreach (var listItem in (bNodeList).list)
                 {
                     if (listItem is BNodeDictionary bNodeDictionary)
                     {
                         PeerDetails peer = new PeerDetails
                         {
                             infoHash = tracker.InfoHash
                         };
                         BNodeBase peerDictionaryItem = (bNodeDictionary);
                         BNodeBase peerField          = _Bencode.GetDictionaryEntry(peerDictionaryItem, "ip");
                         if (peerField != null)
                         {
                             peer.ip = Encoding.ASCII.GetString(((BitTorrentLibrary.BNodeString)peerField).str);
                         }
                         if (peer.ip.Contains(":"))
                         {
                             peer.ip = peer.ip.Substring(peer.ip.LastIndexOf(":", StringComparison.Ordinal) + 1);
                         }
                         peerField = _Bencode.GetDictionaryEntry(peerDictionaryItem, "port");
                         if (peerField != null)
                         {
                             peer.port = int.Parse(Encoding.ASCII.GetString(((BitTorrentLibrary.BNodeNumber)peerField).number));
                         }
                         if (peer.ip != tracker.Ip) // Ignore self in peers list
                         {
                             Log.Logger.Trace($"(Tracker) Peer {peer.ip} Port {peer.port} found.");
                             decodedResponse.peerList.Add(peer);
                         }
                     }
                 }
             }
         }
         int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "interval"), out decodedResponse.interval);
         int.TryParse(_Bencode.GetDictionaryEntryString(decodedAnnounce, "min interval"), out decodedResponse.minInterval);
         decodedResponse.trackerID     = _Bencode.GetDictionaryEntryString(decodedAnnounce, "tracker id");
         decodedResponse.statusMessage = _Bencode.GetDictionaryEntryString(decodedAnnounce, "warning message");
         decodedResponse.announceCount++;
     }
 }