Пример #1
0
        public void OnExtendedMessage(IPeerWireClient peerWireClient, byte[] bytes)
        {
            BDict d = (BDict)BencodingUtils.Decode(bytes);

            if (d.ContainsKey("added") && d.ContainsKey("added.f"))
            {
                BString pexList  = (BString)d["added"];
                BString pexFlags = (BString)d["added.f"];

                for (int i = 0; i < pexList.ByteValue.Length / 6; i++)
                {
                    UInt32 ip    = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little);
                    UInt16 port  = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big);
                    byte   flags = pexFlags.ByteValue[i];

                    IPEndPoint ipAddr = new IPEndPoint(ip, port);

                    if (Added != null)
                    {
                        Added(peerWireClient, this, ipAddr, flags);
                    }
                }
            }

            if (d.ContainsKey("dropped"))
            {
                BString pexList = (BString)d["dropped"];

                for (int i = 0; i < pexList.ByteValue.Length / 6; i++)
                {
                    UInt32 ip   = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little);
                    UInt16 port = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big);

                    IPEndPoint ipAddr = new IPEndPoint(ip, port);

                    if (Dropped != null)
                    {
                        Dropped(peerWireClient, this, ipAddr);
                    }
                }
            }
        }
Пример #2
0
        public void OnExtendedMessage(IPeerWireClient peerWireClient, byte[] bytes)
        {
            BDict dictionary = (BDict)BencodingUtils.Decode(bytes);

            if (!dictionary.ContainsKey(ADDED_KEY) && !dictionary.ContainsKey(ADDED_FLAGS_KEY) && !dictionary.ContainsKey(DROPPED_KEY))
            {
                return;
            }

            if (dictionary.ContainsKey(ADDED_KEY) && dictionary.ContainsKey(ADDED_FLAGS_KEY))
            {
                var pexList  = (BString)dictionary[ADDED_KEY];
                var pexFlags = (BString)dictionary[ADDED_FLAGS_KEY];

                for (int i = 0; i < pexList.ByteValue.Length / 6; i++)
                {
                    var ip    = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little);
                    var port  = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big);
                    var flags = pexFlags.ByteValue[i];

                    var ipAddr = new IPEndPoint(ip, port);

                    Added?.Invoke(peerWireClient, this, ipAddr, flags);
                }
            }
            else //if (d.ContainsKey(DROPPED_KEY))
            {
                BString pexList = (BString)dictionary[DROPPED_KEY];

                for (int i = 0; i < pexList.ByteValue.Length / 6; i++)
                {
                    var ip   = Unpack.UInt32(pexList.ByteValue, i * 6, Unpack.Endianness.Little);
                    var port = Unpack.UInt16(pexList.ByteValue, (i * 6) + 4, Unpack.Endianness.Big);

                    var ipAddr = new IPEndPoint(ip, port);

                    Dropped?.Invoke(peerWireClient, this, ipAddr);
                }
            }
        }
Пример #3
0
        public void OnHandshake(IPeerWireClient peerWireClient, byte[] handshake)
        {
            BDict dict = (BDict)BencodingUtils.Decode(handshake);

            if (dict.ContainsKey("metadata_size"))
            {
                BInt size = (BInt)dict["metadata_size"];
                this._metadataSize = size;
                this._pieceCount   = (Int64)Math.Ceiling((double)this._metadataSize / 16384);
            }

            this.RequestMetaData(peerWireClient);
        }
        public void OnExtendedMessage(IPeerWireClient peerWireClient, byte[] bytes)
        {
            BDict dict = (BDict)BencodingUtils.Decode(bytes);

            if (dict.ContainsKey("added"))
            {
                var trackerList = (BList)dict["added"];

                foreach (var tracker in trackerList)
                {
                    TrackerAdded?.Invoke(peerWireClient, this, tracker.ToString());
                }
            }
        }
Пример #5
0
        public static Torrent ReadTorrent(string filename)
        {
            // Читаем файл торрента и берем необходимый словарь info
            List <LostFile> files    = new List <LostFile>();
            BDict           torrent  = (BDict)BencodingUtils.DecodeFile(filename, Encoding.UTF8);
            BDict           fileInfo = (BDict)torrent["info"];

            string name        = ((BString)fileInfo["name"]).Value;
            int    pieceLength = (int)((BInt)fileInfo["piece length"]).Value;

            // Перечитываем торрент еще раз, чтобы взять хеш в нужном виде
            torrent = (BDict)BencodingUtils.DecodeFile(filename, Encoding.GetEncoding(437));
            char[] pieces = ((BString)((BDict)torrent["info"])["pieces"]).Value.ToCharArray();

            if (fileInfo.ContainsKey("files")) // Multifile torrent
            {
                BList filesData = (BList)fileInfo["files"];
                long  begin     = 0;

                foreach (BDict file in filesData)
                {
                    BList filePaths = (BList)file["path"];
                    long  length    = ((BInt)file["length"]).Value;

                    string fullPath = name;
                    foreach (BString partOfPath in filePaths)
                    {
                        fullPath += @"\" + partOfPath.Value;
                    }
                    files.Add(new LostFile(fullPath, length, begin));

                    begin += length;
                }
            }
            else // Singlefile torrent
            {
                long Length = ((BInt)fileInfo["length"]).Value;
                files.Add(new LostFile(name, Length, 0));
            }

            return(new Torrent(name, files, pieceLength, pieces, filename));
        }
Пример #6
0
        public AnnounceInfo Announce(string url, string hash, string peerId, long bytesDownloaded, long bytesLeft, long bytesUploaded,
                                     int eventTypeFilter, int ipAddress, int numWant, int listenPort, int extensions)
        {
            byte[] hashBytes   = Pack.Hex(hash);
            byte[] peerIdBytes = Encoding.ASCII.GetBytes(peerId);

            String realUrl = url.Replace("scrape", "announce") + "?";

            String hashEncoded = "";

            foreach (byte b in hashBytes)
            {
                hashEncoded += String.Format("%{0:X2}", b);
            }

            String peerIdEncoded = "";

            foreach (byte b in peerIdBytes)
            {
                peerIdEncoded += String.Format("%{0:X2}", b);
            }

            realUrl += "info_hash=" + hashEncoded;
            realUrl += "&peer_id=" + peerIdEncoded;
            realUrl += "&port=" + listenPort;
            realUrl += "&uploaded=" + bytesUploaded;
            realUrl += "&downloaded=" + bytesDownloaded;
            realUrl += "&left=" + bytesLeft;
            realUrl += "&event=started";
            realUrl += "&compact=1";

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realUrl);

            webRequest.Accept    = "*/*";
            webRequest.UserAgent = "System.Net.Torrent";
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            Stream stream = webResponse.GetResponseStream();

            if (stream == null)
            {
                return(null);
            }

            BinaryReader binaryReader = new BinaryReader(stream);

            byte[] bytes = new byte[0];

            while (true)
            {
                try
                {
                    byte[] b = new byte[1];
                    b[0]  = binaryReader.ReadByte();
                    bytes = bytes.Concat(b).ToArray();
                }
                catch (Exception)
                {
                    break;
                }
            }

            BDict decoded = (BDict)BencodingUtils.Decode(bytes);

            if (decoded.Count == 0)
            {
                return(null);
            }

            if (!decoded.ContainsKey("peers"))
            {
                return(null);
            }

            if (!(decoded["peers"] is BString))
            {
                throw new NotSupportedException("Dictionary based peers not supported");
            }

            Int32 waitTime = 0;
            Int32 seeders  = 0;
            Int32 leachers = 0;

            if (decoded.ContainsKey("interval"))
            {
                waitTime = (BInt)decoded["interval"];
            }

            if (decoded.ContainsKey("complete"))
            {
                seeders = (BInt)decoded["complete"];
            }

            if (decoded.ContainsKey("incomplete"))
            {
                leachers = (BInt)decoded["incomplete"];
            }

            BString peerBinary = (BString)decoded["peers"];

            return(new AnnounceInfo(GetPeers(peerBinary.ByteValue), waitTime, seeders, leachers));
        }
Пример #7
0
        public IDictionary <string, ScrapeInfo> Scrape(string url, string[] hashes)
        {
            Dictionary <String, ScrapeInfo> returnVal = new Dictionary <string, ScrapeInfo>();

            String realUrl = url.Replace("announce", "scrape") + "?";

            String hashEncoded = "";

            foreach (String hash in hashes)
            {
                byte[] hashBytes = Pack.Hex(hash);

                hashEncoded = hashBytes.Aggregate(hashEncoded, (current, b) => current + String.Format("%{0:X2}", b));

                realUrl += "info_hash=" + hashEncoded + "&";
            }

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realUrl);

            webRequest.Accept    = "*/*";
            webRequest.UserAgent = "System.Net.Torrent";
            webRequest.Timeout   = this.Timeout * 1000;
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

            Stream stream = webResponse.GetResponseStream();

            if (stream == null)
            {
                return(null);
            }

            BinaryReader binaryReader = new BinaryReader(stream);

            byte[] bytes = new byte[0];

            while (true)
            {
                try
                {
                    byte[] b = new byte[1];
                    b[0]  = binaryReader.ReadByte();
                    bytes = bytes.Concat(b).ToArray();
                }
                catch (Exception)
                {
                    break;
                }
            }

            BDict decoded = (BDict)BencodingUtils.Decode(bytes);

            if (decoded.Count == 0)
            {
                return(null);
            }

            if (!decoded.ContainsKey("files"))
            {
                return(null);
            }

            BDict bDecoded = (BDict)decoded["files"];

            foreach (String k in bDecoded.Keys)
            {
                BDict d = (BDict)bDecoded[k];

                if (d.ContainsKey("complete") && d.ContainsKey("downloaded") && d.ContainsKey("incomplete"))
                {
                    String rk = Unpack.Hex(BencodingUtils.ExtendedASCIIEncoding.GetBytes(k));
                    returnVal.Add(rk, new ScrapeInfo((uint)((BInt)d["complete"]).Value, (uint)((BInt)d["downloaded"]).Value, (uint)((BInt)d["incomplete"]).Value, ScraperType.HTTP));
                }
            }

            return(returnVal);
        }
Пример #8
0
        /// <summary>
        /// Background thread handling all incoming traffic
        /// </summary>
        private void ReceivePackets()
        {
            while (true)
            {
                try
                {
                    // Get a datagram
                    receiveFrom = new IPEndPoint(IPAddress.Any, localPort);
                    byte[] data = udpClient.Receive(ref receiveFrom);

                    // Decode the message
                    Stream         stream      = new MemoryStream(data);
                    IBencodingType receivedMsg = BencodingUtils.Decode(stream);
                    string         decoded     = BencodingUtils.ExtendedASCIIEncoding.GetString(data.ToArray());
                    Log("Received message!");
                    //Log(decoded);

                    // t is transaction id : todo: check, since ports are reused
                    // y is e for error, r for reply, q for query
                    if (receivedMsg is BDict) // throws error.. todo: fix
                    {
                        BDict dictMsg = (BDict)receivedMsg;
                        if (dictMsg.ContainsKey("y"))
                        {
                            if (dictMsg["y"].Equals(new BString("e")))
                            {
                                // received error
                                Log("Received error! (ignored)");
                            }
                            else if (dictMsg["y"].Equals(new BString("r")))
                            {
                                // received reply
                                if (dictMsg.ContainsKey("r"))
                                {
                                    if (dictMsg["r"] is BDict)
                                    {
                                        BDict dictMsg2 = (BDict)dictMsg["r"];
                                        if (dictMsg2.ContainsKey("values") && dictMsg.ContainsKey("t"))
                                        {
                                            Log("Received list of peers for torrent!");
                                            countRecvPeerPackets++;
                                            BList peerAdrs = (BList)dictMsg2["values"];
                                            UpdateTorrentPeerList(peerAdrs, (BString)dictMsg["t"]);
                                        }
                                        else if (dictMsg2.ContainsKey("nodes") && dictMsg.ContainsKey("t"))
                                        {
                                            // could be an answer to find node or get peers
                                            Log("Received list of nodeID & IP & port!");
                                            countRecvNodePackets++;
                                            BString nodeIDString = (BString)dictMsg2["nodes"];
                                            UpdateContactList(nodeIDString, (BString)dictMsg["t"]);
                                        }
                                        else
                                        {
                                        }
                                    }
                                    else
                                    {
                                    }
                                }
                            }
                            else if (dictMsg["y"].Equals(new BString("q")))
                            {
                                // received query
                                Log("Received query! (ignored)");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log("Error receiving data: " + ex.ToString());
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Background thread handling all incoming traffic
        /// </summary>
        private void ReceivePackets()
        {
            while (true)
            {
                try
                {
                    // Get a datagram
                    receiveFrom = new IPEndPoint(IPAddress.Any, localPort);
                    // Stopwatch sw = new Stopwatch();
                    // sw.Start();
                    byte[] data = udpClientReceive.Receive(ref receiveFrom);
                    //if (sw.ElapsedMilliseconds > 10) { Console.WriteLine(sw.ElapsedMilliseconds); }
                    //sw.Stop();

                    // Decode the message
                    Stream         stream      = new MemoryStream(data);
                    IBencodingType receivedMsg = BencodingUtils.Decode(stream);
                    string         decoded     = BencodingUtils.ExtendedASCIIEncoding.GetString(data.ToArray());
                    //Log("Received message!");

                    // t is transaction id
                    // y is e for error, r for reply, q for query
                    if (receivedMsg is BDict) // throws error.. todo: fix
                    {
                        BDict dictMsg = (BDict)receivedMsg;
                        if (dictMsg.ContainsKey("y"))
                        {
                            if (dictMsg["y"].Equals(new BString("e")))
                            {
                                //Log("Received error! (ignored)");
                            }
                            else if (dictMsg["y"].Equals(new BString("r")))
                            {
                                // received reply
                                if (dictMsg.ContainsKey("r"))
                                {
                                    if (dictMsg["r"] is BDict)
                                    {
                                        BDict dictMsg2 = (BDict)dictMsg["r"];
                                        if (dictMsg2.ContainsKey("values"))
                                        {
                                            //Log("Received list of peers for torrent!");
                                            countRecvPeerPackets++;
                                        }
                                        else if (dictMsg2.ContainsKey("nodes"))
                                        {
                                            // could be an answer to find node or get peers
                                            //Log("Received list of nodeID & IP & port!");
                                            countRecvNodePackets++;
                                            BString nodeIDString = (BString)dictMsg2["nodes"];
                                            UpdateContactList(nodeIDString);
                                        }
                                        else
                                        {
                                            // no values and no nodes, assuming its a ping,
                                            // at least some form of response
                                        }
                                    }
                                    else
                                    {
                                    }
                                }
                            }
                            else if (dictMsg["y"].Equals(new BString("q")))
                            {
                                // received query
                                countRecvQuery++;
                                //Log("Received query! (ignored)");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    //Log("Error receiving data: " + ex.ToString());
                }
            }
        }
Пример #10
0
        public bool Load(Stream stream)
        {
            _root = BencodingUtils.Decode(stream);
            if (_root == null)
            {
                return(false);
            }

            BDict dictRoot = (_root as BDict);

            if (dictRoot == null)
            {
                return(false);
            }

            if (dictRoot.ContainsKey("announce"))
            {
                Announce = (BString)dictRoot["announce"];
            }

            if (dictRoot.ContainsKey("announce-list"))
            {
                BList announceList = (BList)dictRoot["announce-list"];
                foreach (IBencodingType type in announceList)
                {
                    if (type is BString)
                    {
                        AnnounceList.Add(type as BString);
                    }
                    else
                    {
                        BList list = type as BList;
                        if (list == null)
                        {
                            continue;
                        }

                        BList listType = list;
                        foreach (IBencodingType bencodingType in listType)
                        {
                            BString s = (BString)bencodingType;
                            AnnounceList.Add(s);
                        }
                    }
                }
            }

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

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

            if (dictRoot.ContainsKey("creation date"))
            {
                long ts = (BInt)dictRoot["creation date"];
                CreationDate = new DateTime(1970, 1, 1).AddSeconds(ts);
            }

            if (dictRoot.ContainsKey("info"))
            {
                BDict infoDict = (BDict)dictRoot["info"];

                using (SHA1Managed sha1 = new SHA1Managed())
                {
                    byte[] str = BencodingUtils.EncodeBytes(infoDict);
                    Hash = sha1.ComputeHash(str);
                }

                if (infoDict.ContainsKey("files"))
                {
                    //multi file mode
                    BList fileList = (BList)infoDict["files"];
                    foreach (IBencodingType bencodingType in fileList)
                    {
                        BDict fileDict = (BDict)bencodingType;

                        String filename = string.Empty;
                        Int64  filesize = default(Int64);

                        if (fileDict.ContainsKey("path"))
                        {
                            BList filenameList = (BList)fileDict["path"];
                            foreach (IBencodingType type in filenameList)
                            {
                                filename += (BString)type;
                                filename += "\\";
                            }
                            filename = filename.Trim('\\');
                        }

                        if (fileDict.ContainsKey("length"))
                        {
                            filesize = (BInt)fileDict["length"];
                        }

                        Files.Add(filename, filesize);
                    }
                }

                if (infoDict.ContainsKey("name"))
                {
                    Name = (BString)infoDict["name"];
                    if (Files.Count == 0 && infoDict.ContainsKey("length"))
                    {
                        Files.Add(Name, (BInt)infoDict["length"]);
                    }
                }

                if (infoDict.ContainsKey("private"))
                {
                    BInt isPrivate = (BInt)infoDict["private"];
                    Private = isPrivate != 0;
                }

                if (infoDict.ContainsKey("pieces"))
                {
                    BString pieces = (BString)infoDict["pieces"];
                    for (int x = 0; x < pieces.ByteValue.Length; x += 20)
                    {
                        byte[] hash = pieces.ByteValue.GetBytes(x, 20);
                        PieceHashes.Add(hash);
                    }
                }

                if (infoDict.ContainsKey("piece length"))
                {
                    PieceSize = (BInt)infoDict["piece length"];
                }
            }

            return(true);
        }