Example #1
0
        public void OnMessageSent(FileHash hash, PeerHash peer, byte[] payload)
        {
            BencodedValue bencoded = Bencoder.Decode(payload);
            int?          message  = bencoded.Find("msg_type", x => x?.ToInt32());
            int?          piece    = bencoded.Find("piece", x => x?.ToInt32());
            int?          size     = bencoded.Find("total_size", x => x?.ToInt32());

            if (message == 0 && piece != null)
            {
                hooks.CallMetadataRequestSent(hash, peer, piece.Value);
            }

            if (message == 1 && size != null)
            {
                hooks.CallMetadataMeasured(hash, peer, size.Value);
            }

            if (message == 1 && piece != null)
            {
                byte[] content = Bytes.Copy(payload, bencoded.Data.Length);
                hooks.MetadataPieceSent(hash, peer, piece.Value, content);
            }

            if (message == 2 && piece != null)
            {
                hooks.CallMetadataRejectSent(hash, peer, piece.Value);
            }
        }
Example #2
0
        private void OnReceived(UdpSocketReceive received)
        {
            if (received.Status == SocketStatus.OK)
            {
                IPEndPoint endpoint = received.GetEndpoint();
                byte[]     data     = Bytes.Copy(buffer.Data, buffer.Offset, received.Count);

                socket.Receive(buffer, OnReceived);
                context.Queue.Add(OnReceived(endpoint, data));
            }
        }
Example #3
0
        private static MetainfoHash[] FindPieces(BencodedValue value)
        {
            byte[] data = value.Find("pieces", x => x.Data.GetBytes());
            List <MetainfoHash> pieces = new List <MetainfoHash>();

            for (int i = 0; i < data.Length; i += 20)
            {
                pieces.Add(new MetainfoHash(Bytes.Copy(data, i, 20)));
            }

            return(pieces.ToArray());
        }
Example #4
0
        private void HandleErrorResponse(IPEndPoint endpoint, TrackerGetUdpEntry entry, byte[] data)
        {
            if (data.Length < 8)
            {
                context.CallPacketIgnored(endpoint, data.Length);
                return;
            }

            byte[] message = Bytes.Copy(data, 8);
            string reason  = Encoding.ASCII.GetString(message);

            context.CallFailed(entry.Address, entry.Request.Hash, reason);
        }
Example #5
0
        private void HandleConnectionResponse(IPEndPoint endpoint, TrackerGetUdpEntry entry, byte[] data)
        {
            if (data.Length < 16)
            {
                context.CallPacketIgnored(endpoint, data.Length);
                return;
            }

            if (Bytes.Equals(TrackerGetUdpProtocol.Connect, data, 0, 4) == false)
            {
                context.CallPacketIgnored(endpoint, data.Length);
                return;
            }

            entry.Connection = Bytes.Copy(data, 8, 8);
            entry.Status     = TrackerGetUdpStatus.Connected;

            context.CallConnected(entry.Address, entry.Request.Hash, entry.Transaction, entry.Connection);
        }
Example #6
0
        private Action OnReceived(IPEndPoint endpoint, byte[] data)
        {
            return(() =>
            {
                context.CallPacketReceived(endpoint, data.Length);

                if (data.Length < 8)
                {
                    context.CallPacketIgnored(endpoint, data.Length);
                    return;
                }

                byte[] transaction = Bytes.Copy(data, 4, 4);
                TrackerGetUdpEntry entry = collection.Find(transaction);

                if (entry != null && Bytes.Equals(TrackerGetUdpProtocol.Error, data, 0, 4))
                {
                    HandleErrorResponse(endpoint, entry, data);
                    return;
                }

                switch (entry?.Status)
                {
                case TrackerGetUdpStatus.Connecting:
                    HandleConnectionResponse(endpoint, entry, data);
                    break;

                case TrackerGetUdpStatus.Announcing:
                    HandleAnnounceResponse(endpoint, entry, data);
                    break;

                default:
                    context.CallPacketIgnored(endpoint, data.Length);
                    break;
                }
            });
        }
Example #7
0
        public Bitfield Read()
        {
            if (File.Exists(context.Path) == false)
            {
                return(null);
            }

            string path = context.Path;

            byte[] data = File.ReadAllBytes(path);

            if (data.Length < 20)
            {
                return(null);
            }

            using (HashAlgorithm algorithm = SHA1.Create())
            {
                byte[] checksum = Bytes.Copy(data, 0, 20);
                byte[] computed = algorithm.ComputeHash(data, 20, data.Length - 20);

                if (Bytes.Equals(checksum, computed) == false)
                {
                    return(null);
                }
            }

            Bitfield bitfield = new Bitfield(data.Length - 20);

            for (int i = 20; i < data.Length; i++)
            {
                bitfield[i - 20] = data[i] == 1;
            }

            return(bitfield);
        }
 public byte[] ToBytes(int offset)
 {
     return(Bytes.Copy(data, offset + 1));
 }
 public byte[] ToBytes()
 {
     return(Bytes.Copy(data, 1));
 }
Example #10
0
 public byte[] ToBytes(int offset, int count)
 {
     return(Bytes.Copy(decrypted, offset, count));
 }
Example #11
0
        private TcpSocketReceiveCallback OnReceived(TrackerGetHttpEntry entry)
        {
            return(received =>
            {
                if (received.Status == SocketStatus.OK)
                {
                    context.Queue.Add(() =>
                    {
                        byte[] data = Bytes.Copy(entry.Buffer.Data, entry.Buffer.Offset, received.Count);
                        string text = Encoding.ASCII.GetString(data);

                        context.CallPacketReceived(entry.Endpoint, data.Length);

                        if (text.StartsWith(TrackerGetHttpProtocol.ResponseHeader) == false)
                        {
                            context.CallPacketIgnored(entry.Endpoint, data.Length);
                            return;
                        }

                        int counter = 0, position = 0;
                        bool r = false, n = false;

                        for (int i = 0; i < data.Length; i++)
                        {
                            if (data[i] == '\r')
                            {
                                r = true;
                                counter++;
                                continue;
                            }

                            if (data[i] == '\n')
                            {
                                n = true;
                                counter++;
                                continue;
                            }

                            if (counter == 4 && r && n)
                            {
                                position = i;
                                break;
                            }

                            if (counter == 2 && !(r && n))
                            {
                                position = i;
                                break;
                            }

                            counter = 0;
                        }

                        if (position == 0)
                        {
                            context.CallPacketIgnored(entry.Endpoint, data.Length);
                            return;
                        }

                        BencodedValue decoded = Bencoder.Decode(data, position);
                        if (decoded.Dictionary == null)
                        {
                            context.CallPacketIgnored(entry.Endpoint, data.Length);
                            return;
                        }

                        string failure = decoded.Find("failure reason", x => x?.Text?.GetString());
                        if (failure != null)
                        {
                            context.CallFailed(entry.Address, entry.Request.Hash, failure);
                            return;
                        }

                        int?interval = decoded.Find("interval", x => x?.ToInt32());
                        BencodedValue peers = decoded.Find("peers", x => x);

                        if (interval != null && peers.Text != null && peers.Text.Length % 6 == 0)
                        {
                            List <NetworkAddress> result = new List <NetworkAddress>(peers.Text.Length / 6);
                            byte[] bytes = peers.Data.GetBytes();

                            for (int i = 0; i < bytes.Length; i += 6)
                            {
                                int port = Bytes.ReadUInt16(bytes, i + 4);
                                StringBuilder address = new StringBuilder();

                                address.Append(bytes[i].ToString());
                                address.Append('.');
                                address.Append(bytes[i + 1].ToString());
                                address.Append('.');
                                address.Append(bytes[i + 2].ToString());
                                address.Append('.');
                                address.Append(bytes[i + 3].ToString());

                                if (port > 0)
                                {
                                    result.Add(new NetworkAddress(address.ToString(), port));
                                }
                            }

                            collection.Remove(entry.Socket);
                            entry.Callback.Invoke(TimeSpan.FromSeconds(interval.Value));
                            context.CallAnnounced(entry.Address, entry.Request.Hash, TimeSpan.FromSeconds(interval.Value), result.ToArray());
                        }
                    });
                }
            });
        }
Example #12
0
 public byte[] ToBytes(int offset, int count)
 {
     return(Bytes.Copy(data, offset, count));
 }