private void ProcessReject(IPeerWireClient client, byte[] payload)
        {
            Int32 index  = UnpackHelper.Int32(payload, 0, UnpackHelper.Endianness.Big);
            Int32 begin  = UnpackHelper.Int32(payload, 4, UnpackHelper.Endianness.Big);
            Int32 length = UnpackHelper.Int32(payload, 8, UnpackHelper.Endianness.Big);

            this.OnReject(client, index, begin, length);
        }
        private static IEnumerable <IPEndPoint> GetPeers(byte[] peerData)
        {
            for (int i = 0; i < peerData.Length; i += 6)
            {
                long   addr = UnpackHelper.UInt32(peerData, i, UnpackHelper.Endianness.Big);
                ushort port = UnpackHelper.UInt16(peerData, i + 4, UnpackHelper.Endianness.Big);

                yield return(new IPEndPoint(addr, port));
            }
        }
Esempio n. 3
0
        public bool OnCommand(IPeerWireClient client, int commandLength, byte commandId, byte[] payload)
        {
            if (commandId == 9)
            {
                UInt16 port = UnpackHelper.UInt16(payload, 0, UnpackHelper.Endianness.Big);

                this.OnPort(client, port);
                return(true);
            }

            return(false);
        }
        private void ProcessHave()
        {
            Int32 pieceIndex = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big);

            lock (this._locker)
            {
                this._internalBuffer = this._internalBuffer.GetBytes(4);
            }

            this.PeerBitField[pieceIndex] = true;
            this.OnHave(pieceIndex);
        }
        private void ProcessPiece(Int32 length)
        {
            Int32 index = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big);
            Int32 begin = UnpackHelper.Int32(this._internalBuffer, 4, UnpackHelper.Endianness.Big);

            lock (this._locker)
            {
                this._internalBuffer = this._internalBuffer.GetBytes(8);
            }

            byte[] buffer = this._internalBuffer.GetBytes(0, length - 8);

            lock (this._locker)
            {
                this._internalBuffer = this._internalBuffer.GetBytes(length - 8);
            }

            this.OnPiece(index, begin, buffer);
        }
        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    = UnpackHelper.UInt32(pexList.ByteValue, i * 6, UnpackHelper.Endianness.Little);
                    UInt16 port  = UnpackHelper.UInt16(pexList.ByteValue, (i * 6) + 4, UnpackHelper.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   = UnpackHelper.UInt32(pexList.ByteValue, i * 6, UnpackHelper.Endianness.Little);
                    UInt16 port = UnpackHelper.UInt16(pexList.ByteValue, (i * 6) + 4, UnpackHelper.Endianness.Big);

                    IPEndPoint ipAddr = new IPEndPoint(ip, port);

                    if (Dropped != null)
                    {
                        Dropped(peerWireClient, this, ipAddr);
                    }
                }
            }
        }
        private void ProcessRequest(bool cancel)
        {
            Int32 index  = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big);
            Int32 begin  = UnpackHelper.Int32(this._internalBuffer, 4, UnpackHelper.Endianness.Big);
            Int32 length = UnpackHelper.Int32(this._internalBuffer, 8, UnpackHelper.Endianness.Big);

            lock (this._locker)
            {
                this._internalBuffer = this._internalBuffer.GetBytes(12);
            }

            if (!cancel)
            {
                this.OnRequest(index, begin, length);
            }
            else
            {
                this.OnCancel(index, begin, length);
            }
        }
        public IDictionary <string, ScrapeInfo> Scrape(string url, String[] hashes)
        {
            Dictionary <string, ScrapeInfo> returnVal = new Dictionary <string, ScrapeInfo>();

            this.ValidateInput(url, hashes, ScraperType.UDP);

            Int32 transactionId = this.Random.Next(0, 65535);

            UdpClient udpClient = new UdpClient(this.Tracker, this.Port)
            {
                Client =
                {
                    SendTimeout    = this.Timeout * 1000,
                    ReceiveTimeout = this.Timeout * 1000
                }
            };

            byte[] sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(0)).Concat(PackHelper.Int32(transactionId)).ToArray();
            udpClient.Send(sendBuf, sendBuf.Length);

            IPEndPoint endPoint = null;

            byte[] recBuf = udpClient.Receive(ref endPoint);

            if (recBuf == null)
            {
                throw new NoNullAllowedException("udpClient failed to receive");
            }

            if (recBuf.Length < 0)
            {
                throw new InvalidOperationException("udpClient received no response");
            }

            if (recBuf.Length < 16)
            {
                throw new InvalidOperationException("udpClient did not receive entire response");
            }

            UInt32 recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            UInt32 recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            if (recAction != 0 || recTrasactionId != transactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            this._currentConnectionId = CopyBytes(recBuf, 8, 8);

            byte[] hashBytes = new byte[0];
            hashBytes = hashes.Aggregate(hashBytes, (current, hash) => current.Concat(PackHelper.Hex(hash)).ToArray());

            int expectedLength = 8 + (12 * hashes.Length);

            sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(2)).Concat(PackHelper.Int32(transactionId)).Concat(hashBytes).ToArray();
            udpClient.Send(sendBuf, sendBuf.Length);

            recBuf = udpClient.Receive(ref endPoint);

            if (recBuf == null)
            {
                throw new NoNullAllowedException("udpClient failed to receive");
            }

            if (recBuf.Length < 0)
            {
                throw new InvalidOperationException("udpClient received no response");
            }

            if (recBuf.Length < expectedLength)
            {
                throw new InvalidOperationException("udpClient did not receive entire response");
            }

            recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            this._currentConnectionId = CopyBytes(recBuf, 8, 8);

            if (recAction != 2 || recTrasactionId != transactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            Int32 startIndex = 8;

            foreach (string hash in hashes)
            {
                UInt32 seeders   = UnpackHelper.UInt32(recBuf, startIndex, UnpackHelper.Endianness.Big);
                UInt32 completed = UnpackHelper.UInt32(recBuf, startIndex + 4, UnpackHelper.Endianness.Big);
                UInt32 Leechers  = UnpackHelper.UInt32(recBuf, startIndex + 8, UnpackHelper.Endianness.Big);

                returnVal.Add(hash, new ScrapeInfo(seeders, completed, Leechers, ScraperType.UDP));

                startIndex += 12;
            }

            udpClient.Close();

            return(returnVal);
        }
        public AnnounceInfo Announce(string url, string hash, string peerId, Int64 bytesDownloaded, Int64 bytesLeft, Int64 bytesUploaded,
                                     Int32 eventTypeFilter, Int32 ipAddress, Int32 numWant, Int32 listenPort, Int32 extensions)
        {
            List <IPEndPoint> returnValue = new List <IPEndPoint>();

            this.ValidateInput(url, new[] { hash }, ScraperType.UDP);

            this._currentConnectionId = this.BaseCurrentConnectionId;
            Int32 trasactionId = this.Random.Next(0, 65535);

            UdpClient udpClient = new UdpClient(this.Tracker, this.Port)
            {
                DontFragment = true,
                Client       =
                {
                    SendTimeout    = this.Timeout * 1000,
                    ReceiveTimeout = this.Timeout * 1000
                }
            };

            byte[] sendBuf = this._currentConnectionId.Concat(PackHelper.Int32(0)).Concat(PackHelper.Int32(trasactionId)).ToArray();
            udpClient.Send(sendBuf, sendBuf.Length);

            IPEndPoint endPoint = null;

            byte[] recBuf;

            try
            {
                recBuf = udpClient.Receive(ref endPoint);
            }
            catch (Exception)
            {
                return(null);
            }

            if (recBuf == null)
            {
                throw new NoNullAllowedException("udpClient failed to receive");
            }

            if (recBuf.Length < 0)
            {
                throw new InvalidOperationException("udpClient received no response");
            }

            if (recBuf.Length < 16)
            {
                throw new InvalidOperationException("udpClient did not receive entire response");
            }

            UInt32 recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            UInt32 recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            if (recAction != 0 || recTrasactionId != trasactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            this._currentConnectionId = CopyBytes(recBuf, 8, 8);

            byte[] hashBytes = PackHelper.Hex(hash).ToArray();

            Int32 key = this.Random.Next(0, 65535);

            sendBuf = this._currentConnectionId.                      /*connection id*/
                      Concat(PackHelper.Int32(1)).                    /*action*/
                      Concat(PackHelper.Int32(trasactionId)).         /*trasaction Id*/
                      Concat(hashBytes).                              /*hash*/
                      Concat(Encoding.ASCII.GetBytes(peerId)).        /*my peer id*/
                      Concat(PackHelper.Int64(bytesDownloaded)).      /*bytes downloaded*/
                      Concat(PackHelper.Int64(bytesLeft)).            /*bytes left*/
                      Concat(PackHelper.Int64(bytesUploaded)).        /*bytes uploaded*/
                      Concat(PackHelper.Int32(eventTypeFilter)).      /*event, 0 for none, 2 for just started*/
                      Concat(PackHelper.Int32(ipAddress)).            /*ip, 0 for this one*/
                      Concat(PackHelper.Int32(key)).                  /*unique key*/
                      Concat(PackHelper.Int32(numWant)).              /*num want, -1 for as many as pos*/
                      Concat(PackHelper.Int32(listenPort)).           /*listen port*/
                      Concat(PackHelper.Int32(extensions)).ToArray(); /*extensions*/
            udpClient.Send(sendBuf, sendBuf.Length);

            try
            {
                recBuf = udpClient.Receive(ref endPoint);
            }
            catch (Exception)
            {
                return(null);
            }

            recAction       = UnpackHelper.UInt32(recBuf, 0, UnpackHelper.Endianness.Big);
            recTrasactionId = UnpackHelper.UInt32(recBuf, 4, UnpackHelper.Endianness.Big);

            int waitTime = (int)UnpackHelper.UInt32(recBuf, 8, UnpackHelper.Endianness.Big);
            int Leechers = (int)UnpackHelper.UInt32(recBuf, 12, UnpackHelper.Endianness.Big);
            int seeders  = (int)UnpackHelper.UInt32(recBuf, 16, UnpackHelper.Endianness.Big);

            if (recAction != 1 || recTrasactionId != trasactionId)
            {
                throw new Exception("Invalid response from tracker");
            }

            for (Int32 i = 20; i < recBuf.Length; i += 6)
            {
                UInt32 ip   = UnpackHelper.UInt32(recBuf, i, UnpackHelper.Endianness.Big);
                UInt16 port = UnpackHelper.UInt16(recBuf, i + 4, UnpackHelper.Endianness.Big);

                returnValue.Add(new IPEndPoint(ip, port));
            }

            udpClient.Close();

            return(new AnnounceInfo(returnValue, waitTime, seeders, Leechers));
        }
        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 = PackHelper.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 = UnpackHelper.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);
        }
        private void ProcessSuggest(IPeerWireClient client, byte[] payload)
        {
            Int32 index = UnpackHelper.Int32(payload, 0, UnpackHelper.Endianness.Big);

            this.OnSuggest(client, index);
        }
        private bool _process()
        {
            if (!this._receiving)
            {
                byte[] recBuffer = new byte[this._dynamicBufferSize];
                try
                {
                    this._async = this.Socket.BeginReceive(recBuffer, 0, this._dynamicBufferSize, this.OnReceived, recBuffer);
                }
                catch (Exception ex)
                {
                    Trace.TraceInformation(ex.Message);
                    return(false);
                }


                this._receiving = true;
            }

            if (this._internalBuffer.Length < 4)
            {
                this.OnNoData();

                return(this.Socket.Connected);
            }

            if (!this._handshakeComplete)
            {
                Int32 resLen = this._internalBuffer[0];
                if (resLen != 19)
                {
                    if (resLen == 0)
                    {
                        // keep alive?
                        Thread.Sleep(100);

                        this.Disconnect();
                        return(false);
                    }
                }

                this._handshakeComplete = true;

                byte[] recReserved = this._internalBuffer.GetBytes(20, 8);
                this.RemoteUsesDHT = (recReserved[7] & 0x1) == 0x1;

                byte[] remoteHashBytes = this._internalBuffer.GetBytes(28, 20);
                if (String.IsNullOrEmpty(this.Hash))
                {
                    string remoteHash = UnpackHelper.Hex(remoteHashBytes);
                    this.Hash = remoteHash;
                }

                byte[] remoteIdbytes = this._internalBuffer.GetBytes(48, 20);

                this.RemotePeerID = Encoding.ASCII.GetString(remoteIdbytes);

                lock (this._locker)
                {
                    this._internalBuffer = this._internalBuffer.GetBytes(68);
                }

                this.OnHandshake();

                if (this._handshakeSent)
                {
                    return(true);
                }

                this.Handshake();
                this.SendBitField(this.PeerBitField);

                return(true);
            }

            Int32 commandLength = UnpackHelper.Int32(this._internalBuffer, 0, UnpackHelper.Endianness.Big);

            if (commandLength > (this._internalBuffer.Length - 4))
            {
                //need more data first
                return(true);
            }

            lock (this._locker)
            {
                this._internalBuffer = this._internalBuffer.GetBytes(4);
            }

            if (commandLength == 0)
            {
                if (!this.KeepConnectionAlive)
                {
                    return(true);
                }

                this.SendKeepAlive();
                this.OnKeepAlive();

                return(true);
            }

            Int32 commandId = this._internalBuffer[0];

            lock (this._locker)
            {
                this._internalBuffer = this._internalBuffer.GetBytes(1);
            }

            switch (commandId)
            {
            case 0:
                //choke
                this.OnChoke();
                break;

            case 1:
                //unchoke
                this.OnUnChoke();
                break;

            case 2:
                //interested
                this.OnInterested();
                break;

            case 3:
                //not interested
                this.OnNotInterested();
                break;

            case 4:
                //have
                this.ProcessHave();
                break;

            case 5:
                //bitfield
                this.ProcessBitfield(commandLength - 1);
                break;

            case 6:
                //request
                this.ProcessRequest(false);
                break;

            case 7:
                //piece
                this.ProcessPiece(commandLength - 1);
                break;

            case 8:
                //cancel
                this.ProcessRequest(true);
                break;

            default:
            {
                foreach (IProtocolExtension extension in this._btProtocolExtensions)
                {
                    if (!extension.CommandIDs.Contains(b => b == commandId))
                    {
                        continue;
                    }

                    if (extension.OnCommand(this, commandLength, (byte)commandId, this._internalBuffer))
                    {
                        break;
                    }
                }

                lock (this._locker)
                {
                    this._internalBuffer = this._internalBuffer.GetBytes(commandLength - 1);
                }
            }
            break;
            }

            return(true);
        }