Exemple #1
0
        private static void Check(IMessage message, MessageType type)
        {
            var e = message.Encode();

            Assert.AreEqual(e.Length, message.ByteLength, "#1");
            Assert.IsTrue(Toolbox.ByteMatch(e, UdpTrackerMessage.DecodeMessage(e, 0, e.Length, type).Encode()), "#2");
        }
Exemple #2
0
        async Task <UdpTrackerMessage> ReceiveAsync(UdpClient client, int transactionId, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                UdpReceiveResult received = await client.ReceiveAsync();

                var rsp = UdpTrackerMessage.DecodeMessage(received.Buffer, 0, received.Buffer.Length, MessageType.Response);

                if (transactionId == rsp.TransactionId)
                {
                    if (rsp is ErrorMessage error)
                    {
                        FailureMessage = error.Error;
                        throw new Exception("The tracker returned an error.");
                    }
                    else
                    {
                        return(rsp);
                    }
                }
            }
            // If we get here then the token will have been cancelled. We need the additional
            // 'throw' statement to keep the compiler happy.
            token.ThrowIfCancellationRequested();
            throw new OperationCanceledException("The tracker did not respond.");
        }
Exemple #3
0
        async void ReceiveAsync(UdpClient client, CancellationToken token)
        {
            Task sendTask = null;

            while (!token.IsCancellationRequested)
            {
                try
                {
                    var result = await client.ReceiveAsync();

                    byte[] data = result.Buffer;
                    if (data.Length < 16)
                    {
                        return;//bad request
                    }
                    UdpTrackerMessage request = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Request);

                    if (sendTask != null)
                    {
                        try {
                            await sendTask;
                        } catch {
                        }
                    }


                    switch (request.Action)
                    {
                    case 0:
                        sendTask = ReceiveConnect(client, (ConnectMessage)request, result.RemoteEndPoint);
                        break;

                    case 1:
                        sendTask = ReceiveAnnounce(client, (AnnounceMessage)request, result.RemoteEndPoint);
                        break;

                    case 2:
                        sendTask = ReceiveScrape(client, (ScrapeMessage)request, result.RemoteEndPoint);
                        break;

                    case 3:
                        sendTask = ReceiveError(client, (ErrorMessage)request, result.RemoteEndPoint);
                        break;

                    default:
                        throw new ProtocolException(string.Format("Invalid udp message received: {0}", request.Action));
                    }
                }
                catch (Exception e)
                {
                    Logger.Log(null, e.ToString());
                }
            }
        }
        private void ReceiveData(IAsyncResult ar)
        {
            try
            {
                System.Net.Sockets.UdpClient listener = (System.Net.Sockets.UdpClient)ar.AsyncState;
                byte[] data = listener.EndReceive(ar, ref endpoint);
#endif
                if (data.Length < 16)
                {
                    return;//bad request
                }
                UdpTrackerMessage request = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Request);

                switch (request.Action)
                {
                case 0:
                    ReceiveConnect((ConnectMessage)request);
                    break;

                case 1:
                    ReceiveAnnounce((AnnounceMessage)request);
                    break;

                case 2:
                    ReceiveScrape((ScrapeMessage)request);
                    break;

                case 3:
                    ReceiveError((ErrorMessage)request);
                    break;

                default:
                    throw new ProtocolException(string.Format("Invalid udp message received: {0}", request.Action));
                }
            }
            catch (Exception e)
            {
                Logger.Log(null, e.ToString());
            }
            finally
            {
                if (Running)
                {
#if NETSTANDARD1_5
                    result = await listener.ReceiveAsync();

                    ReceiveData(result, client);
#else
                    listener.BeginReceive(new AsyncCallback(ReceiveData), listener);
#endif
                }
            }
        }
Exemple #5
0
        public void AnnounceMessageTest()
        {
            AnnounceMessage m = new AnnounceMessage(0, 12345, announceparams);
            AnnounceMessage d = (AnnounceMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Request);

            Check(m, MessageType.Request);

            Assert.AreEqual(1, m.Action);
            Assert.AreEqual(m.Action, d.Action);
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()));
            Assert.AreEqual(12345, d.ConnectionId);
        }
Exemple #6
0
        public void ConnectMessageTest()
        {
            ConnectMessage m = new ConnectMessage();
            ConnectMessage d = (ConnectMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Request);

            Check(m, MessageType.Request);

            Assert.AreEqual(0, m.Action, "#0");
            Assert.AreEqual(m.Action, d.Action, "#1");
            Assert.AreEqual(m.ConnectionId, d.ConnectionId, "#2");
            Assert.AreEqual(m.TransactionId, d.TransactionId, "#3");
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()), "#4");
        }
Exemple #7
0
        public void AnnounceResponseTest()
        {
            var peers = peerEndpoints.Select(t => new Peer("", new Uri($"ipv4://{t.Address}:{t.Port}"))).ToList();
            AnnounceResponseMessage m = new AnnounceResponseMessage(12345, TimeSpan.FromSeconds(10), 43, 65, peers);
            AnnounceResponseMessage d = (AnnounceResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Response);

            Check(m, MessageType.Response);

            Assert.AreEqual(1, m.Action);
            Assert.AreEqual(m.Action, d.Action);
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()));
            Assert.AreEqual(12345, d.TransactionId);
        }
Exemple #8
0
        private UdpTrackerMessage Receive(UdpTrackerAsyncState trackerState, byte[] receivedMessage)
        {
            timeout = 0;//we have receive so unactive the timeout
            byte[]            data = receivedMessage;
            UdpTrackerMessage rsp  = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Response);

            if (trackerState.Message.TransactionId != rsp.TransactionId)
            {
                FailureMessage = "Invalid transaction Id in response from udp tracker!";
                return(null);//to raise event fail outside
            }
            return(rsp);
        }
        public void ConnectResponseTest()
        {
            ConnectResponseMessage m = new ConnectResponseMessage(5371, 12345);
            ConnectResponseMessage d = (ConnectResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), MessageType.Response);

            Check(m, MessageType.Response);

            Assert.AreEqual(0, m.Action, "#0");
            Assert.AreEqual(m.Action, d.Action, "#1");
            Assert.AreEqual(m.ConnectionId, d.ConnectionId, "#2");
            Assert.AreEqual(m.TransactionId, d.TransactionId, "#3");
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()), "#4");
            Assert.AreEqual(12345, d.ConnectionId);
            Assert.AreEqual(5371, d.TransactionId);
        }
Exemple #10
0
        public void ConnectResponseTest()
        {
            var expectedMessage = new ConnectResponseMessage(5371, 12345);
            var actualMessage   =
                (ConnectResponseMessage)
                UdpTrackerMessage.DecodeMessage(expectedMessage.Encode(), 0, expectedMessage.ByteLength, MessageType.Response);

            Check(expectedMessage, MessageType.Response);

            Assert.AreEqual(0, expectedMessage.Action, "#0");
            Assert.AreEqual(expectedMessage.Action, actualMessage.Action, "#1");
            Assert.AreEqual(expectedMessage.ConnectionId, actualMessage.ConnectionId, "#2");
            Assert.AreEqual(expectedMessage.TransactionId, actualMessage.TransactionId, "#3");
            Assert.IsTrue(Toolbox.ByteMatch(expectedMessage.Encode(), actualMessage.Encode()), "#4");
            Assert.AreEqual(12345, actualMessage.ConnectionId);
            Assert.AreEqual(5371, actualMessage.TransactionId);
        }
Exemple #11
0
        public void ScrapeResponseTest()
        {
            List <ScrapeDetails> details = new List <ScrapeDetails>();

            details.Add(new ScrapeDetails(1, 2, 3));
            details.Add(new ScrapeDetails(4, 5, 6));
            details.Add(new ScrapeDetails(7, 8, 9));

            ScrapeResponseMessage m = new ScrapeResponseMessage(12345, details);
            ScrapeResponseMessage d = (ScrapeResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Response);

            Check(m, MessageType.Response);

            Assert.AreEqual(2, m.Action);
            Assert.AreEqual(m.Action, d.Action);
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()));
            Assert.AreEqual(12345, d.TransactionId);
        }
Exemple #12
0
        public void AnnounceResponseTest()
        {
            List <Peer> peers = new List <Peer>();

            peers.Add(new Peer(new string('1', 20), new Uri("tcp://127.0.0.1:1")));
            peers.Add(new Peer(new string('2', 20), new Uri("tcp://127.0.0.1:2")));
            peers.Add(new Peer(new string('3', 20), new Uri("tcp://127.0.0.1:3")));

            AnnounceResponseMessage m = new AnnounceResponseMessage(12345, TimeSpan.FromSeconds(10), 43, 65, peers);
            AnnounceResponseMessage d = (AnnounceResponseMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Response);

            Check(m, MessageType.Response);

            Assert.AreEqual(1, m.Action);
            Assert.AreEqual(m.Action, d.Action);
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()));
            Assert.AreEqual(12345, d.TransactionId);
        }
Exemple #13
0
        public void ScrapeResponseTest()
        {
            var details = new List <ScrapeDetails>
            {
                new ScrapeDetails(1, 2, 3),
                new ScrapeDetails(4, 5, 6),
                new ScrapeDetails(7, 8, 9)
            };

            var expectedMessage = new ScrapeResponseMessage(12345, details);
            var actualMessage   =
                (ScrapeResponseMessage)
                UdpTrackerMessage.DecodeMessage(expectedMessage.Encode(), 0, expectedMessage.ByteLength, MessageType.Response);

            Check(expectedMessage, MessageType.Response);

            Assert.AreEqual(2, expectedMessage.Action);
            Assert.AreEqual(expectedMessage.Action, actualMessage.Action);
            Assert.IsTrue(Toolbox.ByteMatch(expectedMessage.Encode(), actualMessage.Encode()));
            Assert.AreEqual(12345, actualMessage.TransactionId);
        }
Exemple #14
0
        async Task <UdpTrackerMessage> ReceiveAsync(UdpClient client, int transactionId, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                var received = await client.ReceiveAsync();

                UdpTrackerMessage rsp = UdpTrackerMessage.DecodeMessage(received.Buffer, 0, received.Buffer.Length, MessageType.Response);

                if (transactionId == rsp.TransactionId)
                {
                    if (rsp is ErrorMessage error)
                    {
                        FailureMessage = error.Error;
                        throw new Exception("The tracker returned an error.");
                    }
                    else
                    {
                        return(rsp);
                    }
                }
            }
            throw new Exception("The tracker did not respond.");
        }
Exemple #15
0
        public void ScrapeMessageTest()
        {
            List <byte[]> hashes = new List <byte[]>();
            Random        r      = new Random();

            byte[] hash1 = new byte[20];
            byte[] hash2 = new byte[20];
            byte[] hash3 = new byte[20];
            r.NextBytes(hash1);
            r.NextBytes(hash2);
            r.NextBytes(hash3);
            hashes.Add(hash1);
            hashes.Add(hash2);
            hashes.Add(hash3);

            ScrapeMessage m = new ScrapeMessage(12345, 123, hashes);
            ScrapeMessage d = (ScrapeMessage)UdpTrackerMessage.DecodeMessage(m.Encode(), 0, m.ByteLength, MessageType.Request);

            Check(m, MessageType.Request);

            Assert.AreEqual(2, m.Action);
            Assert.AreEqual(m.Action, d.Action);
            Assert.IsTrue(Toolbox.ByteMatch(m.Encode(), d.Encode()));
        }
        async void ReceiveAsync(UdpClient client, CancellationToken token)
        {
            Task sendTask = null;

            while (!token.IsCancellationRequested)
            {
                try {
                    UdpReceiveResult result = await client.ReceiveAsync();

                    byte[] data = result.Buffer;
                    if (data.Length < 16)
                    {
                        return; //bad request
                    }
                    var request = UdpTrackerMessage.DecodeMessage(data.AsSpan(0, data.Length), MessageType.Request);

                    if (sendTask != null)
                    {
                        try {
                            await sendTask;
                        } catch {
                        }
                    }

                    sendTask = request.Action switch {
                        0 => ReceiveConnect(client, (ConnectMessage)request, result.RemoteEndPoint),
                        1 => ReceiveAnnounce(client, (AnnounceMessage)request, result.RemoteEndPoint),
                        2 => ReceiveScrape(client, (ScrapeMessage)request, result.RemoteEndPoint),
                        3 => ReceiveError(client, (ErrorMessage)request, result.RemoteEndPoint),
                        _ => throw new InvalidOperationException($"Invalid udp message received: {request.Action}")
                    };
                } catch (Exception e) {
                    logger.Exception(e, "Exception while receiving a message");
                }
            }
        }
 void Check(UdpTrackerMessage message, MessageType type)
 {
     byte[] e = message.Encode();
     Assert.AreEqual(e.Length, message.ByteLength, "#1");
     Assert.IsTrue(Toolbox.ByteMatch(e, UdpTrackerMessage.DecodeMessage(e, type).Encode()), "#2");
 }